Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / gnus-sum.el
index 16eb139..9c165f9 100644 (file)
@@ -1,8 +1,11 @@
-;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
+;;; gnus-sum.el --- summary mode commands for Semi-gnus
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
-;; Keywords: news
+;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;;         Katsumi Yamaoka  <yamaoka@jpl.org>
+;; Keywords: mail, news, MIME
 
 ;; This file is part of GNU Emacs.
 
 
 ;; This file is part of GNU Emacs.
 
 (require 'gnus-int)
 (require 'gnus-undo)
 (require 'gnus-util)
 (require 'gnus-int)
 (require 'gnus-undo)
 (require 'gnus-util)
-(require 'mm-decode)
+;; Recursive :-(.
+;; (require 'gnus-art)
+(require 'nnoo)
+(require 'mime-view)
+
+(eval-when-compile
+  (require 'mime-play)
+  (require 'static))
+
+(eval-and-compile
+  (autoload 'gnus-cache-articles-in-group "gnus-cache")
+  (autoload 'pgg-decrypt-region "pgg" nil t)
+  (autoload 'pgg-verify-region "pgg" nil t))
+
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
+(autoload 'gnus-cache-write-active "gnus-cache")
+(autoload 'gnus-set-summary-default-charset "gnus-i18n" nil t)
+(autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
+(autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
+(autoload 'mm-uu-dissect "mm-uu")
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
@@ -168,10 +189,15 @@ This variable will only be used if the value of
   :type 'string)
 
 (defcustom gnus-summary-goto-unread t
   :type 'string)
 
 (defcustom gnus-summary-goto-unread t
-  "*If t, marking commands will go to the next unread article.
-If `never', commands that usually go to the next unread article, will
-go to the next article, whether it is read or not.
-If nil, only the marking commands will go to the next (un)read article."
+  "*If t, many commands will go to the next unread article.
+This applies to marking commands as well as other commands that
+\"naturally\" select the next article, like, for instance, `SPC' at
+the end of an article.
+
+If nil, the marking commands do NOT go to the next unread article
+(they go to the next article instead).  If `never', commands that
+usually go to the next unread article, will go to the next article,
+whether it is read or not."
   :group 'gnus-summary-marks
   :link '(custom-manual "(gnus)Setting Marks")
   :type '(choice (const :tag "off" nil)
   :group 'gnus-summary-marks
   :link '(custom-manual "(gnus)Setting Marks")
   :type '(choice (const :tag "off" nil)
@@ -271,6 +297,14 @@ in some newsgroups, set the variable to nil in
                 (function-item gnus-summary-first-unread-article)
                 (function-item gnus-summary-best-unread-article)))
 
                 (function-item gnus-summary-first-unread-article)
                 (function-item gnus-summary-best-unread-article)))
 
+(defcustom gnus-dont-select-after-jump-to-other-group nil
+  "If non-nil, don't select the first unread article after entering the
+other group by the command `gnus-summary-jump-to-other-group'.  If nil,
+it is depend on the value of `gnus-auto-select-first' whether to select
+or not."
+  :group 'gnus-group-select
+  :type 'boolean)
+
 (defcustom gnus-auto-select-next t
   "*If non-nil, offer to go to the next group from the end of the previous.
 If the value is t and the next newsgroup is empty, Gnus will exit
 (defcustom gnus-auto-select-next t
   "*If non-nil, offer to go to the next group from the end of the previous.
 If the value is t and the next newsgroup is empty, Gnus will exit
@@ -337,15 +371,24 @@ variable."
   :group 'gnus-article-various
   :type 'boolean)
 
   :group 'gnus-article-various
   :type 'boolean)
 
+(defcustom gnus-show-mime t
+  "*If non-nil, do mime processing of articles.
+The articles will simply be fed to the function given by
+`gnus-article-display-method-for-mime'."
+  :group 'gnus-article-mime
+  :type 'boolean)
+
 (defcustom gnus-move-split-methods nil
   "*Variable used to suggest where articles are to be moved to.
 (defcustom gnus-move-split-methods nil
   "*Variable used to suggest where articles are to be moved to.
-It uses the same syntax as the `gnus-split-methods' variable."
+It uses the same syntax as the `gnus-split-methods' variable.
+However, whereas `gnus-split-methods' specifies file names as targets,
+this variable specifies group names."
   :group 'gnus-summary-mail
   :type '(repeat (choice (list :value (fun) function)
                         (cons :value ("" "") regexp (repeat string))
                         (sexp :value nil))))
 
   :group 'gnus-summary-mail
   :type '(repeat (choice (list :value (fun) function)
                         (cons :value ("" "") regexp (repeat string))
                         (sexp :value nil))))
 
-(defcustom gnus-unread-mark ? ;Whitespace
+(defcustom gnus-unread-mark ?  ;Whitespace
   "*Mark used for unread articles."
   :group 'gnus-summary-marks
   :type 'character)
   "*Mark used for unread articles."
   :group 'gnus-summary-marks
   :type 'character)
@@ -415,6 +458,11 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-marks
   :type 'character)
 
   :group 'gnus-summary-marks
   :type 'character)
 
+(defcustom gnus-no-mark ?  ;Whitespace
+  "*Mark used for articles that have no other secondary mark."
+  :group 'gnus-summary-marks
+  :type 'character)
+
 (defcustom gnus-ancient-mark ?O
   "*Mark used for ancient articles."
   :group 'gnus-summary-marks
 (defcustom gnus-ancient-mark ?O
   "*Mark used for ancient articles."
   :group 'gnus-summary-marks
@@ -460,7 +508,7 @@ It uses the same syntax as the `gnus-split-methods' variable."
   :group 'gnus-summary-marks
   :type 'character)
 
   :group 'gnus-summary-marks
   :type 'character)
 
-(defcustom gnus-empty-thread-mark ? ;Whitespace
+(defcustom gnus-empty-thread-mark ?  ;Whitespace
   "*There is no thread under the article."
   :group 'gnus-summary-marks
   :type 'character)
   "*There is no thread under the article."
   :group 'gnus-summary-marks
   :type 'character)
@@ -480,11 +528,13 @@ It uses the same syntax as the `gnus-split-methods' variable."
        gnus-low-score-mark gnus-ancient-mark gnus-read-mark
        gnus-souped-mark gnus-duplicate-mark)
   "*The list of marks converted into expiration if a group is auto-expirable."
        gnus-low-score-mark gnus-ancient-mark gnus-read-mark
        gnus-souped-mark gnus-duplicate-mark)
   "*The list of marks converted into expiration if a group is auto-expirable."
+  :version "21.1"
   :group 'gnus-summary
   :type '(repeat character))
 
 (defcustom gnus-inhibit-user-auto-expire t
   "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
   :group 'gnus-summary
   :type '(repeat character))
 
 (defcustom gnus-inhibit-user-auto-expire t
   "*If non-nil, user marking commands will not mark an article as expirable, even if the group has auto-expire turned on."
+  :version "21.1"
   :group 'gnus-summary
   :type 'boolean)
 
   :group 'gnus-summary
   :type 'boolean)
 
@@ -542,6 +592,16 @@ with some simple extensions:
   :group 'gnus-summary-format
   :type 'string)
 
   :group 'gnus-summary-format
   :type 'string)
 
+(defcustom gnus-list-identifiers nil
+  "Regexp that matches list identifiers to be removed from subject.
+This can also be a list of regexps."
+  :version "21.1"
+  :group 'gnus-summary-format
+  :group 'gnus-article-hiding
+  :type '(choice (const :tag "none" nil)
+                (regexp :value ".*")
+                (repeat :value (".*") regexp)))
+
 (defcustom gnus-summary-mark-below 0
   "*Mark all articles with a score below this variable as read.
 This variable is local to each summary buffer and usually set by the
 (defcustom gnus-summary-mark-below 0
   "*Mark all articles with a score below this variable as read.
 This variable is local to each summary buffer and usually set by the
@@ -614,6 +674,7 @@ This variable is local to the summary buffers."
 (defcustom gnus-summary-mode-hook nil
   "*A hook for Gnus summary mode.
 This hook is run before any variables are set in the summary buffer."
 (defcustom gnus-summary-mode-hook nil
   "*A hook for Gnus summary mode.
 This hook is run before any variables are set in the summary buffer."
+  :options '(turn-on-gnus-mailing-list-mode)
   :group 'gnus-summary-various
   :type 'hook)
 
   :group 'gnus-summary-various
   :type 'hook)
 
@@ -678,13 +739,14 @@ is not run if `gnus-visual' is nil."
   :group 'gnus-summary-visual
   :type 'hook)
 
   :group 'gnus-summary-visual
   :type 'hook)
 
-(defcustom gnus-parse-headers-hook nil
+(defcustom gnus-parse-headers-hook '(gnus-set-summary-default-charset)
   "*A hook called before parsing the headers."
   :group 'gnus-various
   :type 'hook)
 
 (defcustom gnus-exit-group-hook nil
   "*A hook called before parsing the headers."
   :group 'gnus-various
   :type 'hook)
 
 (defcustom gnus-exit-group-hook nil
-  "*A hook called when exiting (not quitting) summary mode."
+  "*A hook called when exiting summary mode.
+This hook is not called from the non-updating exit commands like `Q'."
   :group 'gnus-various
   :type 'hook)
 
   :group 'gnus-various
   :type 'hook)
 
@@ -745,6 +807,9 @@ automatically when it is selected."
      . gnus-summary-high-unread-face)
     ((and (< score default) (= mark gnus-unread-mark))
      . gnus-summary-low-unread-face)
      . gnus-summary-high-unread-face)
     ((and (< score default) (= mark gnus-unread-mark))
      . gnus-summary-low-unread-face)
+    ((and (memq article gnus-newsgroup-incorporated)
+         (= mark gnus-unread-mark))
+     . gnus-summary-incorporated-face)
     ((= mark gnus-unread-mark)
      . gnus-summary-normal-unread-face)
     ((and (> score default) (memq mark (list gnus-downloadable-mark
     ((= mark gnus-unread-mark)
      . gnus-summary-normal-unread-face)
     ((and (> score default) (memq mark (list gnus-downloadable-mark
@@ -783,17 +848,20 @@ mark:    The articles mark."
 The function is called with one parameter, the article header vector,
 which it may alter in any way.")
 
 The function is called with one parameter, the article header vector,
 which it may alter in any way.")
 
-(defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
+(defvar gnus-decode-encoded-word-function
+  (mime-find-field-decoder 'From 'nov)
   "Variable that says which function should be used to decode a string with encoded words.")
 
 (defcustom gnus-extra-headers nil
   "*Extra headers to parse."
   "Variable that says which function should be used to decode a string with encoded words.")
 
 (defcustom gnus-extra-headers nil
   "*Extra headers to parse."
+  :version "21.1"
   :group 'gnus-summary
   :type '(repeat symbol))
 
 (defcustom gnus-ignored-from-addresses
   (and user-mail-address (regexp-quote user-mail-address))
   "*Regexp of From headers that may be suppressed in favor of To headers."
   :group 'gnus-summary
   :type '(repeat symbol))
 
 (defcustom gnus-ignored-from-addresses
   (and user-mail-address (regexp-quote user-mail-address))
   "*Regexp of From headers that may be suppressed in favor of To headers."
+  :version "21.1"
   :group 'gnus-summary
   :type 'regexp)
 
   :group 'gnus-summary
   :type 'regexp)
 
@@ -801,10 +869,14 @@ which it may alter in any way.")
   '(("^hk\\>\\|^tw\\>\\|\\<big5\\>" cn-big5)
     ("^cn\\>\\|\\<chinese\\>" cn-gb-2312)
     ("^fj\\>\\|^japan\\>" iso-2022-jp-2)
   '(("^hk\\>\\|^tw\\>\\|\\<big5\\>" cn-big5)
     ("^cn\\>\\|\\<chinese\\>" cn-gb-2312)
     ("^fj\\>\\|^japan\\>" iso-2022-jp-2)
+    ("^tnn\\>\\|^pin\\>\\|^sci.lang.japan" iso-2022-7bit)
     ("^relcom\\>" koi8-r)
     ("^relcom\\>" koi8-r)
+    ("^fido7\\>" koi8-r)
     ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2)
     ("^israel\\>" iso-8859-1)
     ("^han\\>" euc-kr)
     ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2)
     ("^israel\\>" iso-8859-1)
     ("^han\\>" euc-kr)
+    ("^alt.chinese.text.big5\\>" chinese-big5)
+    ("^soc.culture.vietnamese\\>" vietnamese-viqr)
     ("^\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)
     (".*" iso-8859-1))
   "Alist of regexps (to match group names) and default charsets to be used when reading."
     ("^\\(comp\\|rec\\|alt\\|sci\\|soc\\|news\\|gnu\\|bofh\\)\\>" iso-8859-1)
     (".*" iso-8859-1))
   "Alist of regexps (to match group names) and default charsets to be used when reading."
@@ -812,28 +884,104 @@ which it may alter in any way.")
                       (symbol :tag "Charset")))
   :group 'gnus-charset)
 
                       (symbol :tag "Charset")))
   :group 'gnus-charset)
 
-(defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit)
+(defcustom gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown)
   "List of charsets that should be ignored.
 When these charsets are used in the \"charset\" parameter, the
 default charset will be used instead."
   "List of charsets that should be ignored.
 When these charsets are used in the \"charset\" parameter, the
 default charset will be used instead."
+  :version "21.1"
   :type '(repeat symbol)
   :group 'gnus-charset)
 
   :type '(repeat symbol)
   :group 'gnus-charset)
 
+(defcustom gnus-group-ignored-charsets-alist
+  '(("alt\\.chinese\\.text" iso-8859-1))
+  "Alist of regexps (to match group names) and charsets that should be ignored.
+When these charsets are used in the \"charset\" parameter, the
+default charset will be used instead."
+  :type '(repeat (cons (regexp :tag "Group")
+                      (repeat symbol)))
+  :group 'gnus-charset)
+
 (defcustom gnus-group-highlight-words-alist nil
   "Alist of group regexps and highlight regexps.
 This variable uses the same syntax as `gnus-emphasis-alist'."
 (defcustom gnus-group-highlight-words-alist nil
   "Alist of group regexps and highlight regexps.
 This variable uses the same syntax as `gnus-emphasis-alist'."
+  :version "21.1"
   :type '(repeat (cons (regexp :tag "Group")
                       (repeat (list (regexp :tag "Highlight regexp")
                                     (number :tag "Group for entire word" 0)
                                     (number :tag "Group for displayed part" 0)
   :type '(repeat (cons (regexp :tag "Group")
                       (repeat (list (regexp :tag "Highlight regexp")
                                     (number :tag "Group for entire word" 0)
                                     (number :tag "Group for displayed part" 0)
-                                    (symbol :tag "Face" 
+                                    (symbol :tag "Face"
                                             gnus-emphasis-highlight-words)))))
   :group 'gnus-summary-visual)
 
                                             gnus-emphasis-highlight-words)))))
   :group 'gnus-summary-visual)
 
+(defcustom gnus-use-wheel nil
+  "Use Intelli-mouse on summary movement"
+  :type 'boolean
+  :group 'gnus-summary-maneuvering)
+
+(defcustom gnus-wheel-scroll-amount '(5 . 1)
+  "Amount to scroll messages by spinning the mouse wheel.
+This is actually a cons cell, where the first item is the amount to scroll
+on a normal wheel event, and the second is the amount to scroll when the
+wheel is moved with the shift key depressed."
+  :type '(cons (integer :tag "Shift") integer)
+  :group 'gnus-summary-maneuvering)
+
+(defcustom gnus-wheel-edge-resistance 2
+  "How hard it should be to change the current article
+by moving the mouse over the edge of the article window."
+  :type 'integer
+  :group 'gnus-summary-maneuvering)
+
+(defcustom gnus-summary-show-article-charset-alist
+  nil
+  "Alist of number and charset.
+The article will be shown with the charset corresponding to the
+numbered argument.
+For example: ((1 . cn-gb-2312) (2 . big5))."
+  :version "21.1"
+  :type '(repeat (cons (number :tag "Argument" 1)
+                      (symbol :tag "Charset")))
+  :group 'gnus-charset)
+
+(defcustom gnus-preserve-marks t
+  "Whether marks are preserved when moving, copying and respooling messages."
+  :version "21.1"
+  :type 'boolean
+  :group 'gnus-summary-marks)
+
+(defcustom gnus-alter-articles-to-read-function nil
+  "Function to be called to alter the list of articles to be selected."
+  :type 'function
+  :group 'gnus-summary)
+
+(defcustom gnus-orphan-score nil
+  "*All orphans get this score added.  Set in the score file."
+  :group 'gnus-score-default
+  :type '(choice (const nil)
+                integer))
+
+(defcustom gnus-summary-save-parts-default-mime "image/.*"
+  "*A regexp to match MIME parts when saving multiple parts of a message
+with gnus-summary-save-parts (X m). This regexp will be used by default
+when prompting the user for which type of files to save."
+  :group 'gnus-summary
+  :type 'regexp)
+
+
+(defcustom gnus-summary-save-parts-default-mime "image/.*"
+  "*A regexp to match MIME parts when saving multiple parts of a message
+with gnus-summary-save-parts (X m). This regexp will be used by default
+when prompting the user for which type of files to save."
+  :group 'gnus-summary
+  :type 'regexp)
+
+
 ;;; Internal variables
 
 (defvar gnus-article-mime-handles nil)
 (defvar gnus-article-decoded-p nil)
 ;;; Internal variables
 
 (defvar gnus-article-mime-handles nil)
 (defvar gnus-article-decoded-p nil)
+(defvar gnus-article-charset nil)
+(defvar gnus-article-ignored-charsets nil)
 (defvar gnus-scores-exclude-files nil)
 (defvar gnus-page-broken nil)
 (defvar gnus-inhibit-mime-unbuttonizing nil)
 (defvar gnus-scores-exclude-files nil)
 (defvar gnus-page-broken nil)
 (defvar gnus-inhibit-mime-unbuttonizing nil)
@@ -844,6 +992,14 @@ This variable uses the same syntax as `gnus-emphasis-alist'."
 
 (defvar gnus-thread-indent-array nil)
 (defvar gnus-thread-indent-array-level gnus-thread-indent-level)
 
 (defvar gnus-thread-indent-array nil)
 (defvar gnus-thread-indent-array-level gnus-thread-indent-level)
+(defvar gnus-sort-gathered-threads-function 'gnus-thread-sort-by-number
+  "Function called to sort the articles within a thread after it has been gathered together.")
+
+(defvar gnus-summary-save-parts-type-history nil)
+(defvar gnus-summary-save-parts-last-directory nil)
+
+(defvar gnus-summary-save-parts-type-history nil)
+(defvar gnus-summary-save-parts-last-directory nil)
 
 ;; Avoid highlighting in kill files.
 (defvar gnus-summary-inhibit-highlight nil)
 
 ;; Avoid highlighting in kill files.
 (defvar gnus-summary-inhibit-highlight nil)
@@ -866,9 +1022,10 @@ This variable uses the same syntax as `gnus-emphasis-alist'."
     (?S ,(macroexpand '(mail-header-subject gnus-tmp-header)) ?s)
     (?s gnus-tmp-subject-or-nil ?s)
     (?n gnus-tmp-name ?s)
     (?S ,(macroexpand '(mail-header-subject gnus-tmp-header)) ?s)
     (?s gnus-tmp-subject-or-nil ?s)
     (?n gnus-tmp-name ?s)
-    (?A (car (cdr (funcall gnus-extract-address-components gnus-tmp-from)))
-       ?s)
-    (?a (or (car (funcall gnus-extract-address-components gnus-tmp-from))
+    (?A (std11-address-string
+        (car (mime-entity-read-field gnus-tmp-header 'From))) ?s)
+    (?a (or (std11-full-name-string
+            (car (mime-entity-read-field gnus-tmp-header 'From)))
            gnus-tmp-from) ?s)
     (?F gnus-tmp-from ?s)
     (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s)
            gnus-tmp-from) ?s)
     (?F gnus-tmp-from ?s)
     (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s)
@@ -900,9 +1057,9 @@ This variable uses the same syntax as `gnus-emphasis-alist'."
        ?c)
     (?u gnus-tmp-user-defined ?s)
     (?P (gnus-pick-line-number) ?d))
        ?c)
     (?u gnus-tmp-user-defined ?s)
     (?P (gnus-pick-line-number) ?d))
-  "An alist of format specifications that can appear in summary lines,
-and what variables they correspond with, along with the type of the
-variable (string, integer, character, etc).")
+  "An alist of format specifications that can appear in summary lines.
+These are paired with what variables they correspond with, along with
+the type of the variable (string, integer, character, etc).")
 
 (defvar gnus-summary-dummy-line-format-alist
   `((?S gnus-tmp-subject ?s)
 
 (defvar gnus-summary-dummy-line-format-alist
   `((?S gnus-tmp-subject ?s)
@@ -930,6 +1087,11 @@ variable (string, integer, character, etc).")
 (defvar gnus-last-search-regexp nil
   "Default regexp for article search command.")
 
 (defvar gnus-last-search-regexp nil
   "Default regexp for article search command.")
 
+(defvar gnus-summary-search-article-matched-data nil
+  "Last matched data of article search command.  It is the local variable
+in `gnus-article-buffer' which consists of the list of start position,
+end position and text.")
+
 (defvar gnus-last-shell-command nil
   "Default shell command on article.")
 
 (defvar gnus-last-shell-command nil
   "Default shell command on article.")
 
@@ -999,6 +1161,9 @@ variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-scored nil
   "List of scored articles in the current newsgroup.")
 
 (defvar gnus-newsgroup-scored nil
   "List of scored articles in the current newsgroup.")
 
+(defvar gnus-newsgroup-incorporated nil
+  "List of incorporated articles in the current newsgroup.")
+
 (defvar gnus-newsgroup-headers nil
   "List of article headers in the current newsgroup.")
 
 (defvar gnus-newsgroup-headers nil
   "List of article headers in the current newsgroup.")
 
@@ -1019,6 +1184,10 @@ variable (string, integer, character, etc).")
 (defvar gnus-last-article nil)
 (defvar gnus-newsgroup-history nil)
 (defvar gnus-newsgroup-charset nil)
 (defvar gnus-last-article nil)
 (defvar gnus-newsgroup-history nil)
 (defvar gnus-newsgroup-charset nil)
+(defvar gnus-newsgroup-ephemeral-charset nil)
+(defvar gnus-newsgroup-ephemeral-ignored-charsets nil)
+
+(defvar gnus-article-before-search nil)
 
 (defconst gnus-summary-local-variables
   '(gnus-newsgroup-name
 
 (defconst gnus-summary-local-variables
   '(gnus-newsgroup-name
@@ -1043,6 +1212,7 @@ variable (string, integer, character, etc).")
     gnus-score-alist gnus-current-score-file
     (gnus-summary-expunge-below . global)
     (gnus-summary-mark-below . global)
     gnus-score-alist gnus-current-score-file
     (gnus-summary-expunge-below . global)
     (gnus-summary-mark-below . global)
+    (gnus-orphan-score . global)
     gnus-newsgroup-active gnus-scores-exclude-files
     gnus-newsgroup-history gnus-newsgroup-ancient
     gnus-newsgroup-sparse gnus-newsgroup-process-stack
     gnus-newsgroup-active gnus-scores-exclude-files
     gnus-newsgroup-history gnus-newsgroup-ancient
     gnus-newsgroup-sparse gnus-newsgroup-process-stack
@@ -1052,55 +1222,20 @@ variable (string, integer, character, etc).")
     gnus-cache-removable-articles gnus-newsgroup-cached
     gnus-newsgroup-data gnus-newsgroup-data-reverse
     gnus-newsgroup-limit gnus-newsgroup-limits
     gnus-cache-removable-articles gnus-newsgroup-cached
     gnus-newsgroup-data gnus-newsgroup-data-reverse
     gnus-newsgroup-limit gnus-newsgroup-limits
-    gnus-newsgroup-charset)
+    gnus-newsgroup-charset
+    gnus-newsgroup-incorporated)
   "Variables that are buffer-local to the summary buffers.")
 
   "Variables that are buffer-local to the summary buffers.")
 
+(defvar gnus-newsgroup-variables nil
+  "Variables that have separate values in the newsgroups.")
+
 ;; Byte-compiler warning.
 ;; Byte-compiler warning.
-(defvar gnus-article-mode-map)
-
-;; MIME stuff.
-
-(defvar gnus-decode-encoded-word-methods
-  '(mail-decode-encoded-word-string)
-  "List of methods used to decode encoded words.
-
-This variable is a list of FUNCTION or (REGEXP . FUNCTION). If item is
-FUNCTION, FUNCTION will be apply to all newsgroups. If item is a
-(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups
-whose names match REGEXP.
-
-For example:
-((\"chinese\" . gnus-decode-encoded-word-string-by-guess)
- mail-decode-encoded-word-string
- (\"chinese\" . rfc1843-decode-string))
-")
-
-(defvar gnus-decode-encoded-word-methods-cache nil)
-
-(defun gnus-multi-decode-encoded-word-string (string)
-  "Apply the functions from `gnus-encoded-word-methods' that match."
-  (unless (and gnus-decode-encoded-word-methods-cache
-              (eq gnus-newsgroup-name
-                  (car gnus-decode-encoded-word-methods-cache)))
-    (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
-    (mapc '(lambda (x)
-            (if (symbolp x)
-                (nconc gnus-decode-encoded-word-methods-cache (list x))
-              (if (and gnus-newsgroup-name
-                       (string-match (car x) gnus-newsgroup-name))
-                  (nconc gnus-decode-encoded-word-methods-cache
-                         (list (cdr x))))))
-         gnus-decode-encoded-word-methods))
-  (let ((xlist gnus-decode-encoded-word-methods-cache))
-    (pop xlist)
-    (while xlist
-      (setq string (funcall (pop xlist) string))))
-  string)
+(eval-when-compile (defvar gnus-article-mode-map))
 
 ;; Subject simplification.
 
 (defun gnus-simplify-whitespace (str)
 
 ;; Subject simplification.
 
 (defun gnus-simplify-whitespace (str)
-  "Remove excessive whitespace."
+  "Remove excessive whitespace from STR."
   (let ((mystr str))
     ;; Multiple spaces.
     (while (string-match "[ \t][ \t]+" mystr)
   (let ((mystr str))
     ;; Multiple spaces.
     (while (string-match "[ \t][ \t]+" mystr)
@@ -1145,7 +1280,7 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
 (defsubst gnus-simplify-buffer-fuzzy-step (regexp &optional newtext)
   (goto-char (point-min))
   (while (re-search-forward regexp nil t)
 (defsubst gnus-simplify-buffer-fuzzy-step (regexp &optional newtext)
   (goto-char (point-min))
   (while (re-search-forward regexp nil t)
-      (replace-match (or newtext ""))))
+    (replace-match (or newtext ""))))
 
 (defun gnus-simplify-buffer-fuzzy ()
   "Simplify string in the buffer fuzzily.
 
 (defun gnus-simplify-buffer-fuzzy ()
   "Simplify string in the buffer fuzzily.
@@ -1153,7 +1288,7 @@ The string in the accessible portion of the current buffer is simplified.
 It is assumed to be a single-line subject.
 Whitespace is generally cleaned up, and miscellaneous leading/trailing
 matter is removed.  Additional things can be deleted by setting
 It is assumed to be a single-line subject.
 Whitespace is generally cleaned up, and miscellaneous leading/trailing
 matter is removed.  Additional things can be deleted by setting
-gnus-simplify-subject-fuzzy-regexp."
+`gnus-simplify-subject-fuzzy-regexp'."
   (let ((case-fold-search t)
        (modified-tick))
     (gnus-simplify-buffer-fuzzy-step "\t" " ")
   (let ((case-fold-search t)
        (modified-tick))
     (gnus-simplify-buffer-fuzzy-step "\t" " ")
@@ -1277,6 +1412,8 @@ increase the score of each group you read."
     "\M-\C-h" gnus-summary-hide-thread
     "\M-\C-f" gnus-summary-next-thread
     "\M-\C-b" gnus-summary-prev-thread
     "\M-\C-h" gnus-summary-hide-thread
     "\M-\C-f" gnus-summary-next-thread
     "\M-\C-b" gnus-summary-prev-thread
+    [(meta down)] gnus-summary-next-thread
+    [(meta up)] gnus-summary-prev-thread
     "\M-\C-u" gnus-summary-up-thread
     "\M-\C-d" gnus-summary-down-thread
     "&" gnus-summary-execute-command
     "\M-\C-u" gnus-summary-up-thread
     "\M-\C-d" gnus-summary-down-thread
     "&" gnus-summary-execute-command
@@ -1297,6 +1434,7 @@ increase the score of each group you read."
     "\M-g" gnus-summary-rescan-group
     "w" gnus-summary-stop-page-breaking
     "\C-c\C-r" gnus-summary-caesar-message
     "\M-g" gnus-summary-rescan-group
     "w" gnus-summary-stop-page-breaking
     "\C-c\C-r" gnus-summary-caesar-message
+    "\M-t" gnus-summary-toggle-mime
     "f" gnus-summary-followup
     "F" gnus-summary-followup-with-original
     "C" gnus-summary-cancel-article
     "f" gnus-summary-followup
     "F" gnus-summary-followup-with-original
     "C" gnus-summary-cancel-article
@@ -1318,14 +1456,15 @@ increase the score of each group you read."
     "a" gnus-summary-post-news
     "x" gnus-summary-limit-to-unread
     "s" gnus-summary-isearch-article
     "a" gnus-summary-post-news
     "x" gnus-summary-limit-to-unread
     "s" gnus-summary-isearch-article
-    "t" gnus-summary-toggle-header
+    "t" gnus-article-toggle-headers
     "g" gnus-summary-show-article
     "l" gnus-summary-goto-last-article
     "g" gnus-summary-show-article
     "l" gnus-summary-goto-last-article
+    "v" gnus-summary-preview-mime-message
     "\C-c\C-v\C-v" gnus-uu-decode-uu-view
     "\C-d" gnus-summary-enter-digest-group
     "\M-\C-d" gnus-summary-read-document
     "\M-\C-e" gnus-summary-edit-parameters
     "\C-c\C-v\C-v" gnus-uu-decode-uu-view
     "\C-d" gnus-summary-enter-digest-group
     "\M-\C-d" gnus-summary-read-document
     "\M-\C-e" gnus-summary-edit-parameters
-    "\M-\C-g" gnus-summary-customize-parameters
+    "\M-\C-a" gnus-summary-customize-parameters
     "\C-c\C-b" gnus-bug
     "*" gnus-cache-enter-article
     "\M-*" gnus-cache-remove-article
     "\C-c\C-b" gnus-bug
     "*" gnus-cache-enter-article
     "\M-*" gnus-cache-remove-article
@@ -1336,9 +1475,6 @@ increase the score of each group you read."
     "\M-i" gnus-symbolic-argument
     "h" gnus-summary-select-article-buffer
 
     "\M-i" gnus-symbolic-argument
     "h" gnus-summary-select-article-buffer
 
-    "b" gnus-article-view-part
-    "\M-t" gnus-summary-toggle-display-buttonized
-
     "V" gnus-summary-score-map
     "X" gnus-uu-extract-map
     "S" gnus-summary-send-map)
     "V" gnus-summary-score-map
     "X" gnus-uu-extract-map
     "S" gnus-summary-send-map)
@@ -1387,7 +1523,7 @@ increase the score of each group you read."
     "T" gnus-summary-limit-include-thread
     "d" gnus-summary-limit-exclude-dormant
     "t" gnus-summary-limit-to-age
     "T" gnus-summary-limit-include-thread
     "d" gnus-summary-limit-exclude-dormant
     "t" gnus-summary-limit-to-age
-    "x" gnus-summary-limit-to-extra 
+    "x" gnus-summary-limit-to-extra
     "E" gnus-summary-limit-include-expunged
     "c" gnus-summary-limit-exclude-childless-dormant
     "C" gnus-summary-limit-mark-excluded-as-read)
     "E" gnus-summary-limit-include-expunged
     "c" gnus-summary-limit-exclude-childless-dormant
     "C" gnus-summary-limit-mark-excluded-as-read)
@@ -1435,6 +1571,7 @@ increase the score of each group you read."
     "c" gnus-summary-catchup-and-exit
     "C" gnus-summary-catchup-all-and-exit
     "E" gnus-summary-exit-no-update
     "c" gnus-summary-catchup-and-exit
     "C" gnus-summary-catchup-all-and-exit
     "E" gnus-summary-exit-no-update
+    "J" gnus-summary-jump-to-other-group
     "Q" gnus-summary-exit
     "Z" gnus-summary-exit
     "n" gnus-summary-catchup-and-goto-next-group
     "Q" gnus-summary-exit
     "Z" gnus-summary-exit
     "n" gnus-summary-catchup-and-goto-next-group
@@ -1464,6 +1601,7 @@ increase the score of each group you read."
     "g" gnus-summary-show-article
     "s" gnus-summary-isearch-article
     "P" gnus-summary-print-article
     "g" gnus-summary-show-article
     "s" gnus-summary-isearch-article
     "P" gnus-summary-print-article
+    "M" gnus-mailing-list-insinuate
     "t" gnus-article-babel)
 
   (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
     "t" gnus-article-babel)
 
   (gnus-define-keys (gnus-summary-wash-map "W" gnus-summary-mode-map)
@@ -1475,23 +1613,26 @@ increase the score of each group you read."
     "Q" gnus-article-fill-long-lines
     "C" gnus-article-capitalize-sentences
     "c" gnus-article-remove-cr
     "Q" gnus-article-fill-long-lines
     "C" gnus-article-capitalize-sentences
     "c" gnus-article-remove-cr
-    "q" gnus-article-de-quoted-unreadable
+    "Z" gnus-article-decode-HZ
     "f" gnus-article-display-x-face
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
     "f" gnus-article-display-x-face
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
-    "t" gnus-article-hide-headers
+    "t" gnus-article-toggle-headers
     "v" gnus-summary-verbose-headers
     "v" gnus-summary-verbose-headers
-    "h" gnus-article-treat-html
+    "m" gnus-summary-toggle-mime
     "H" gnus-article-strip-headers-in-body
     "H" gnus-article-strip-headers-in-body
-    "d" gnus-article-treat-dumbquotes)
+    "p" gnus-article-verify-x-pgp-sig
+    "d" gnus-article-treat-dumbquotes
+    "s" gnus-smiley-display)
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
-    "h" gnus-article-hide-headers
+    "h" gnus-article-toggle-headers
     "b" gnus-article-hide-boring-headers
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
     "C" gnus-article-hide-citation-in-followups
     "b" gnus-article-hide-boring-headers
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
     "C" gnus-article-hide-citation-in-followups
+    "l" gnus-article-hide-list-identifiers
     "p" gnus-article-hide-pgp
     "B" gnus-article-strip-banner
     "P" gnus-article-hide-pem
     "p" gnus-article-hide-pgp
     "B" gnus-article-strip-banner
     "P" gnus-article-hide-pem
@@ -1503,16 +1644,11 @@ increase the score of each group you read."
     "c" gnus-article-highlight-citation
     "s" gnus-article-highlight-signature)
 
     "c" gnus-article-highlight-citation
     "s" gnus-article-highlight-signature)
 
-  (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
-    "w" gnus-article-decode-mime-words
-    "c" gnus-article-decode-charset
-    "v" gnus-mime-view-all-parts
-    "b" gnus-article-view-part)
-
   (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
     "z" gnus-article-date-ut
     "u" gnus-article-date-ut
     "l" gnus-article-date-local
   (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
     "z" gnus-article-date-ut
     "u" gnus-article-date-ut
     "l" gnus-article-date-local
+    "p" gnus-article-date-english
     "e" gnus-article-date-lapsed
     "o" gnus-article-date-original
     "i" gnus-article-date-iso8601
     "e" gnus-article-date-lapsed
     "o" gnus-article-date-original
     "i" gnus-article-date-iso8601
@@ -1539,6 +1675,7 @@ increase the score of each group you read."
     "\M-\C-e" gnus-summary-expire-articles-now
     "\177" gnus-summary-delete-article
     [delete] gnus-summary-delete-article
     "\M-\C-e" gnus-summary-expire-articles-now
     "\177" gnus-summary-delete-article
     [delete] gnus-summary-delete-article
+    [backspace] gnus-summary-delete-article
     "m" gnus-summary-move-article
     "r" gnus-summary-respool-article
     "w" gnus-summary-edit-article
     "m" gnus-summary-move-article
     "r" gnus-summary-respool-article
     "w" gnus-summary-edit-article
@@ -1567,10 +1704,11 @@ increase the score of each group you read."
     "v" gnus-article-view-part
     "o" gnus-article-save-part
     "c" gnus-article-copy-part
     "v" gnus-article-view-part
     "o" gnus-article-save-part
     "c" gnus-article-copy-part
+    "C" gnus-article-view-part-as-charset
     "e" gnus-article-externalize-part
     "e" gnus-article-externalize-part
+    "E" gnus-article-encrypt-body
     "i" gnus-article-inline-part
     "i" gnus-article-inline-part
-    "|" gnus-article-pipe-part)
-  )
+    "|" gnus-article-pipe-part))
 
 (defun gnus-summary-make-menu-bar ()
   (gnus-turn-off-edit-menu 'summary)
 
 (defun gnus-summary-make-menu-bar ()
   (gnus-turn-off-edit-menu 'summary)
@@ -1583,7 +1721,6 @@ increase the score of each group you read."
       "Score"
       (nconc
        (list
       "Score"
       (nconc
        (list
-       ["Enter score..." gnus-summary-score-entry t]
        ["Customize" gnus-score-customize t])
        (gnus-make-score-map 'increase)
        (gnus-make-score-map 'lower)
        ["Customize" gnus-score-customize t])
        (gnus-make-score-map 'increase)
        (gnus-make-score-map 'lower)
@@ -1608,11 +1745,12 @@ increase the score of each group you read."
     ;; Define both the Article menu in the summary buffer and the equivalent
     ;; Commands menu in the article buffer here for consistency.
     (let ((innards
     ;; Define both the Article menu in the summary buffer and the equivalent
     ;; Commands menu in the article buffer here for consistency.
     (let ((innards
-           '(("Hide"
+           `(("Hide"
               ["All" gnus-article-hide t]
               ["All" gnus-article-hide t]
-              ["Headers" gnus-article-hide-headers t]
+              ["Headers" gnus-article-toggle-headers t]
               ["Signature" gnus-article-hide-signature t]
               ["Citation" gnus-article-hide-citation t]
               ["Signature" gnus-article-hide-signature t]
               ["Citation" gnus-article-hide-citation t]
+             ["List identifiers" gnus-article-hide-list-identifiers t]
               ["PGP" gnus-article-hide-pgp t]
              ["Banner" gnus-article-strip-banner t]
               ["Boring headers" gnus-article-hide-boring-headers t])
               ["PGP" gnus-article-hide-pgp t]
              ["Banner" gnus-article-strip-banner t]
               ["Boring headers" gnus-article-hide-boring-headers t])
@@ -1621,11 +1759,6 @@ increase the score of each group you read."
               ["Headers" gnus-article-highlight-headers t]
               ["Signature" gnus-article-highlight-signature t]
               ["Citation" gnus-article-highlight-citation t])
               ["Headers" gnus-article-highlight-headers t]
               ["Signature" gnus-article-highlight-signature t]
               ["Citation" gnus-article-highlight-citation t])
-            ("MIME"
-             ["Words" gnus-article-decode-mime-words t]
-             ["Charset" gnus-article-decode-charset t]
-             ["QP" gnus-article-de-quoted-unreadable t]
-             ["View all" gnus-mime-view-all-parts t])
              ("Date"
               ["Local" gnus-article-date-local t]
               ["ISO8601" gnus-article-date-iso8601 t]
              ("Date"
               ["Local" gnus-article-date-local t]
               ["ISO8601" gnus-article-date-iso8601 t]
@@ -1650,18 +1783,26 @@ increase the score of each group you read."
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
               ["CR" gnus-article-remove-cr t]
               ["Show X-Face" gnus-article-display-x-face t]
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
               ["CR" gnus-article-remove-cr t]
               ["Show X-Face" gnus-article-display-x-face t]
-              ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
-              ["UnHTMLize" gnus-article-treat-html t]
-              ["Rot 13" gnus-summary-caesar-message t]
+             ["Rot 13" gnus-summary-caesar-message
+              ,@(if (featurep 'xemacs) nil
+                  '(:help "\"Caesar rotate\" article by 13"))]
               ["Unix pipe" gnus-summary-pipe-message t]
               ["Add buttons" gnus-article-add-buttons t]
               ["Add buttons to head" gnus-article-add-buttons-to-head t]
               ["Stop page breaking" gnus-summary-stop-page-breaking t]
               ["Unix pipe" gnus-summary-pipe-message t]
               ["Add buttons" gnus-article-add-buttons t]
               ["Add buttons to head" gnus-article-add-buttons-to-head t]
               ["Stop page breaking" gnus-summary-stop-page-breaking t]
+              ["Toggle MIME" gnus-summary-toggle-mime t]
               ["Verbose header" gnus-summary-verbose-headers t]
               ["Verbose header" gnus-summary-verbose-headers t]
-              ["Toggle header" gnus-summary-toggle-header t])
+              ["Toggle header" gnus-summary-toggle-header t]
+             ["Toggle smileys" gnus-smiley-display t]
+             ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
+             ["HZ" gnus-article-decode-HZ t])
              ("Output"
              ("Output"
-              ["Save in default format" gnus-summary-save-article t]
-              ["Save in file" gnus-summary-save-article-file t]
+              ["Save in default format" gnus-summary-save-article
+              ,@(if (featurep 'xemacs) nil
+                  '(:help "Save article using default method"))]
+              ["Save in file" gnus-summary-save-article-file
+              ,@(if (featurep 'xemacs) nil
+                  '(:help "Save article in file"))]
               ["Save in Unix mail format" gnus-summary-save-article-mail t]
               ["Save in MH folder" gnus-summary-save-article-folder t]
               ["Save in VM folder" gnus-summary-save-article-vm t]
               ["Save in Unix mail format" gnus-summary-save-article-mail t]
               ["Save in MH folder" gnus-summary-save-article-folder t]
               ["Save in VM folder" gnus-summary-save-article-vm t]
@@ -1692,7 +1833,9 @@ increase the score of each group you read."
                (gnus-check-backend-function
                 'request-expire-articles gnus-newsgroup-name)])
              ("Extract"
                (gnus-check-backend-function
                 'request-expire-articles gnus-newsgroup-name)])
              ("Extract"
-              ["Uudecode" gnus-uu-decode-uu t]
+              ["Uudecode" gnus-uu-decode-uu
+              ,@(if (featurep 'xemacs) nil
+                  '(:help "Decode uuencoded article(s)"))]
               ["Uudecode and save" gnus-uu-decode-uu-and-save t]
               ["Unshar" gnus-uu-decode-unshar t]
               ["Unshar and save" gnus-uu-decode-unshar-and-save t]
               ["Uudecode and save" gnus-uu-decode-uu-and-save t]
               ["Unshar" gnus-uu-decode-unshar t]
               ["Unshar and save" gnus-uu-decode-unshar-and-save t]
@@ -1712,6 +1855,7 @@ increase the score of each group you read."
              ["Fetch referenced articles" gnus-summary-refer-references t]
              ["Fetch current thread" gnus-summary-refer-thread t]
              ["Fetch article with id..." gnus-summary-refer-article t]
              ["Fetch referenced articles" gnus-summary-refer-references t]
              ["Fetch current thread" gnus-summary-refer-thread t]
              ["Fetch article with id..." gnus-summary-refer-article t]
+             ["Setup Mailing List Params" gnus-mailing-list-insinuate t]
              ["Redisplay" gnus-summary-show-article t])))
       (easy-menu-define
        gnus-summary-article-menu gnus-summary-mode-map ""
              ["Redisplay" gnus-summary-show-article t])))
       (easy-menu-define
        gnus-summary-article-menu gnus-summary-mode-map ""
@@ -1737,21 +1881,30 @@ increase the score of each group you read."
        ["Mark thread as read" gnus-summary-kill-thread t]
        ["Lower thread score" gnus-summary-lower-thread t]
        ["Raise thread score" gnus-summary-raise-thread t]
        ["Mark thread as read" gnus-summary-kill-thread t]
        ["Lower thread score" gnus-summary-lower-thread t]
        ["Raise thread score" gnus-summary-raise-thread t]
-       ["Rethread current" gnus-summary-rethread-current t]
-       ))
+       ["Rethread current" gnus-summary-rethread-current t]))
 
     (easy-menu-define
      gnus-summary-post-menu gnus-summary-mode-map ""
 
     (easy-menu-define
      gnus-summary-post-menu gnus-summary-mode-map ""
-     '("Post"
-       ["Post an article" gnus-summary-post-news t]
-       ["Followup" gnus-summary-followup t]
-       ["Followup and yank" gnus-summary-followup-with-original t]
+     `("Post"
+       ["Post an article" gnus-summary-post-news
+       ,@(if (featurep 'xemacs) nil
+           '(:help "Post an article"))]
+       ["Followup" gnus-summary-followup
+       ,@(if (featurep 'xemacs) nil
+           '(:help "Post followup to this article"))]
+       ["Followup and yank" gnus-summary-followup-with-original
+       ,@(if (featurep 'xemacs) nil
+           '(:help "Post followup to this article, quoting its contents"))]
        ["Supersede article" gnus-summary-supersede-article t]
        ["Supersede article" gnus-summary-supersede-article t]
-       ["Cancel article" gnus-summary-cancel-article t]
+       ["Cancel article" gnus-summary-cancel-article
+       ,@(if (featurep 'xemacs) nil
+           '(:help "Cancel an article you posted"))]
        ["Reply" gnus-summary-reply t]
        ["Reply and yank" gnus-summary-reply-with-original t]
        ["Wide reply" gnus-summary-wide-reply t]
        ["Reply" gnus-summary-reply t]
        ["Reply and yank" gnus-summary-reply-with-original t]
        ["Wide reply" gnus-summary-wide-reply t]
-       ["Wide reply and yank" gnus-summary-wide-reply-with-original t]
+       ["Wide reply and yank" gnus-summary-wide-reply-with-original
+       ,@(if (featurep 'xemacs) nil
+           '(:help "Mail a reply, quoting this article"))]
        ["Mail forward" gnus-summary-mail-forward t]
        ["Post forward" gnus-summary-post-forward t]
        ["Digest and mail" gnus-uu-digest-mail-forward t]
        ["Mail forward" gnus-summary-mail-forward t]
        ["Post forward" gnus-summary-post-forward t]
        ["Digest and mail" gnus-uu-digest-mail-forward t]
@@ -1759,7 +1912,9 @@ increase the score of each group you read."
        ["Resend message" gnus-summary-resend-message t]
        ["Send bounced mail" gnus-summary-resend-bounced-mail t]
        ["Send a mail" gnus-summary-mail-other-window t]
        ["Resend message" gnus-summary-resend-message t]
        ["Send bounced mail" gnus-summary-resend-bounced-mail t]
        ["Send a mail" gnus-summary-mail-other-window t]
-       ["Uuencode and post" gnus-uu-post-news t]
+       ["Uuencode and post" gnus-uu-post-news
+       ,@(if (featurep 'xemacs) nil
+           '(:help "Post a uuencoded article"))]
        ["Followup via news" gnus-summary-followup-to-mail t]
        ["Followup via news and yank"
        gnus-summary-followup-to-mail-with-original t]
        ["Followup via news" gnus-summary-followup-to-mail t]
        ["Followup via news and yank"
        gnus-summary-followup-to-mail-with-original t]
@@ -1770,13 +1925,15 @@ increase the score of each group you read."
 
     (easy-menu-define
      gnus-summary-misc-menu gnus-summary-mode-map ""
 
     (easy-menu-define
      gnus-summary-misc-menu gnus-summary-mode-map ""
-     '("Misc"
+     `("Misc"
        ("Mark Read"
        ["Mark as read" gnus-summary-mark-as-read-forward t]
        ["Mark same subject and select"
         gnus-summary-kill-same-subject-and-select t]
        ["Mark same subject" gnus-summary-kill-same-subject t]
        ("Mark Read"
        ["Mark as read" gnus-summary-mark-as-read-forward t]
        ["Mark same subject and select"
         gnus-summary-kill-same-subject-and-select t]
        ["Mark same subject" gnus-summary-kill-same-subject t]
-       ["Catchup" gnus-summary-catchup t]
+       ["Catchup" gnus-summary-catchup
+        ,@(if (featurep 'xemacs) nil
+            '(:help "Mark unread articles in this group as read"))]
        ["Catchup all" gnus-summary-catchup-all t]
        ["Catchup to here" gnus-summary-catchup-to-here t]
        ["Catchup region" gnus-summary-mark-region-as-read t]
        ["Catchup all" gnus-summary-catchup-all t]
        ["Catchup to here" gnus-summary-catchup-to-here t]
        ["Catchup region" gnus-summary-mark-region-as-read t]
@@ -1826,8 +1983,12 @@ increase the score of each group you read."
          gnus-newsgroup-process-stack]
         ["Save" gnus-summary-save-process-mark t]))
        ("Scroll article"
          gnus-newsgroup-process-stack]
         ["Save" gnus-summary-save-process-mark t]))
        ("Scroll article"
-       ["Page forward" gnus-summary-next-page t]
-       ["Page backward" gnus-summary-prev-page t]
+       ["Page forward" gnus-summary-next-page
+        ,@(if (featurep 'xemacs) nil
+            '(:help "Show next page of article"))]
+       ["Page backward" gnus-summary-prev-page
+        ,@(if (featurep 'xemacs) nil
+            '(:help "Show previous page of article"))]
        ["Line forward" gnus-summary-scroll-up t])
        ("Move"
        ["Next unread article" gnus-summary-next-unread-article t]
        ["Line forward" gnus-summary-scroll-up t])
        ("Move"
        ["Next unread article" gnus-summary-next-unread-article t]
@@ -1878,10 +2039,14 @@ increase the score of each group you read."
        ["Customize group parameters" gnus-summary-customize-parameters t]
        ["Send a bug report" gnus-bug t]
        ("Exit"
        ["Customize group parameters" gnus-summary-customize-parameters t]
        ["Send a bug report" gnus-bug t]
        ("Exit"
-       ["Catchup and exit" gnus-summary-catchup-and-exit t]
+       ["Catchup and exit" gnus-summary-catchup-and-exit
+        ,@(if (featurep 'xemacs) nil
+            '(:help "Mark unread articles in this group as read, then exit"))]
        ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
        ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
        ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
        ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
-       ["Exit group" gnus-summary-exit t]
+       ["Exit group" gnus-summary-exit
+        ,@(if (featurep 'xemacs) nil
+            '(:help "Exit current group, return to group selection mode"))]
        ["Exit group without updating" gnus-summary-exit-no-update t]
        ["Exit and goto next group" gnus-summary-next-group t]
        ["Exit and goto prev group" gnus-summary-prev-group t]
        ["Exit group without updating" gnus-summary-exit-no-update t]
        ["Exit and goto next group" gnus-summary-next-group t]
        ["Exit and goto prev group" gnus-summary-prev-group t]
@@ -1891,6 +2056,50 @@ increase the score of each group you read."
 
     (gnus-run-hooks 'gnus-summary-menu-hook)))
 
 
     (gnus-run-hooks 'gnus-summary-menu-hook)))
 
+(defvar gnus-summary-tool-bar-map nil)
+
+;; Emacs 21 tool bar.  Should be no-op otherwise.
+(defun gnus-summary-make-tool-bar ()
+  (if (and (fboundp 'tool-bar-add-item-from-menu)
+          (default-value 'tool-bar-mode)
+          (not gnus-summary-tool-bar-map))
+      (setq gnus-summary-tool-bar-map
+           (let ((tool-bar-map (make-sparse-keymap))
+                 (load-path (mm-image-load-path)))
+             (tool-bar-add-item-from-menu
+              'gnus-summary-prev-unread "prev-ur" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-next-unread "next-ur" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-post-news "post" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-followup-with-original "fuwo" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-followup "followup" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-reply-with-original "reply-wo" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-reply "reply" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-caesar-message "rot13" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-uu-decode-uu "uu-decode" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-save-article-file "save-aif" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-save-article "save-art" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-uu-post-news "uu-post" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-catchup "catchup" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-catchup-and-exit "cu-exit" gnus-summary-mode-map)
+             (tool-bar-add-item-from-menu
+              'gnus-summary-exit "exit-summ" gnus-summary-mode-map)
+             tool-bar-map)))
+  (if gnus-summary-tool-bar-map
+      (set (make-local-variable 'tool-bar-map) gnus-summary-tool-bar-map)))
+
 (defun gnus-score-set-default (var value)
   "A version of set that updates the GNU Emacs menu-bar."
   (set var value)
 (defun gnus-score-set-default (var value)
   "A version of set that updates the GNU Emacs menu-bar."
   (set var value)
@@ -1961,7 +2170,8 @@ increase the score of each group you read."
                                               (list 'gnus-summary-header
                                                     (nth 1 header)))
                                             (list 'quote (nth 1 (car ts)))
                                               (list 'gnus-summary-header
                                                     (nth 1 header)))
                                             (list 'quote (nth 1 (car ts)))
-                                            (list 'gnus-score-default nil)
+                                            (list 'gnus-score-delta-default
+                                                  nil)
                                             (nth 1 (car ps))
                                             t)
                                            t)
                                             (nth 1 (car ps))
                                             t)
                                            t)
@@ -1998,10 +2208,13 @@ The following commands are available:
 
 \\{gnus-summary-mode-map}"
   (interactive)
 
 \\{gnus-summary-mode-map}"
   (interactive)
-  (when (gnus-visual-p 'summary-menu 'menu)
-    (gnus-summary-make-menu-bar))
   (kill-all-local-variables)
   (kill-all-local-variables)
+  (when (gnus-visual-p 'summary-menu 'menu)
+    (gnus-summary-make-menu-bar)
+    (gnus-summary-make-tool-bar))
   (gnus-summary-make-local-variables)
   (gnus-summary-make-local-variables)
+  (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+    (gnus-summary-make-local-variables))
   (gnus-make-thread-indent-array)
   (gnus-simplify-mode-line)
   (setq major-mode 'gnus-summary-mode)
   (gnus-make-thread-indent-array)
   (gnus-simplify-mode-line)
   (setq major-mode 'gnus-summary-mode)
@@ -2016,6 +2229,9 @@ The following commands are available:
   (gnus-summary-set-display-table)
   (gnus-set-default-directory)
   (setq gnus-newsgroup-name group)
   (gnus-summary-set-display-table)
   (gnus-set-default-directory)
   (setq gnus-newsgroup-name group)
+  (unless (gnus-news-group-p group)
+    (setq gnus-newsgroup-incorporated
+         (nnmail-new-mail-numbers (gnus-group-real-name group))))
   (make-local-variable 'gnus-summary-line-format)
   (make-local-variable 'gnus-summary-line-format-spec)
   (make-local-variable 'gnus-summary-dummy-line-format)
   (make-local-variable 'gnus-summary-line-format)
   (make-local-variable 'gnus-summary-line-format-spec)
   (make-local-variable 'gnus-summary-dummy-line-format)
@@ -2024,7 +2240,7 @@ The following commands are available:
   (make-local-hook 'pre-command-hook)
   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
   (gnus-run-hooks 'gnus-summary-mode-hook)
   (make-local-hook 'pre-command-hook)
   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
   (gnus-run-hooks 'gnus-summary-mode-hook)
-  (mm-enable-multibyte)
+  (turn-on-gnus-mailing-list-mode)
   (gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
   (gnus-update-summary-mark-positions))
 
   (gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
   (gnus-update-summary-mark-positions))
 
@@ -2077,7 +2293,7 @@ The following commands are available:
   `(nth 3 ,data))
 
 (defmacro gnus-data-set-header (data header)
   `(nth 3 ,data))
 
 (defmacro gnus-data-set-header (data header)
-  `(setf (nth 3 ,data) ,header))
+  `(setcar (nthcdr 3 ,data) ,header))
 
 (defmacro gnus-data-level (data)
   `(nth 4 ,data))
 
 (defmacro gnus-data-level (data)
   `(nth 4 ,data))
@@ -2361,12 +2577,13 @@ marks of articles."
 
 (defun gnus-restore-hidden-threads-configuration (config)
   "Restore hidden threads configuration from CONFIG."
 
 (defun gnus-restore-hidden-threads-configuration (config)
   "Restore hidden threads configuration from CONFIG."
-  (let (point buffer-read-only)
-    (while (setq point (pop config))
-      (when (and (< point (point-max))
-                (goto-char point)
-                (eq (char-after) ?\n))
-       (subst-char-in-region point (1+ point) ?\n ?\r)))))
+  (save-excursion
+    (let (point buffer-read-only)
+      (while (setq point (pop config))
+       (when (and (< point (point-max))
+                  (goto-char point)
+                  (eq (char-after) ?\n))
+         (subst-char-in-region point (1+ point) ?\n ?\r))))))
 
 ;; Various summary mode internalish functions.
 
 
 ;; Various summary mode internalish functions.
 
@@ -2376,9 +2593,10 @@ marks of articles."
   (gnus-summary-next-page nil t))
 
 (defun gnus-summary-set-display-table ()
   (gnus-summary-next-page nil t))
 
 (defun gnus-summary-set-display-table ()
-  ;; Change the display table.  Odd characters have a tendency to mess
-  ;; up nicely formatted displays - we make all possible glyphs
-  ;; display only a single character.
+  "Change the display table.
+Odd characters have a tendency to mess
+up nicely formatted displays - we make all possible glyphs
+display only a single character."
 
   ;; We start from the standard display table, if any.
   (let ((table (or (copy-sequence standard-display-table)
 
   ;; We start from the standard display table, if any.
   (let ((table (or (copy-sequence standard-display-table)
@@ -2401,9 +2619,13 @@ marks of articles."
          (aset table i [??]))))
     (setq buffer-display-table table)))
 
          (aset table i [??]))))
     (setq buffer-display-table table)))
 
+(defun gnus-summary-buffer-name (group)
+  "Return the summary buffer name of GROUP."
+  (concat "*Summary " group "*"))
+
 (defun gnus-summary-setup-buffer (group)
   "Initialize summary buffer."
 (defun gnus-summary-setup-buffer (group)
   "Initialize summary buffer."
-  (let ((buffer (concat "*Summary " group "*")))
+  (let ((buffer (gnus-summary-buffer-name group)))
     (if (get-buffer buffer)
        (progn
          (set-buffer buffer)
     (if (get-buffer buffer)
        (progn
          (set-buffer buffer)
@@ -2422,9 +2644,9 @@ marks of articles."
       t)))
 
 (defun gnus-set-global-variables ()
       t)))
 
 (defun gnus-set-global-variables ()
-  ;; Set the global equivalents of the summary buffer-local variables
-  ;; to the latest values they had.  These reflect the summary buffer
-  ;; that was in action when the last article was fetched.
+  "Set the global equivalents of the buffer-local variables.
+They are set to the latest values they had.  These reflect the summary
+buffer that was in action when the last article was fetched."
   (when (eq major-mode 'gnus-summary-mode)
     (setq gnus-summary-buffer (current-buffer))
     (let ((name gnus-newsgroup-name)
   (when (eq major-mode 'gnus-summary-mode)
     (setq gnus-summary-buffer (current-buffer))
     (let ((name gnus-newsgroup-name)
@@ -2438,7 +2660,15 @@ marks of articles."
          (gac gnus-article-current)
          (reffed gnus-reffed-article-number)
          (score-file gnus-current-score-file)
          (gac gnus-article-current)
          (reffed gnus-reffed-article-number)
          (score-file gnus-current-score-file)
-         (default-charset gnus-newsgroup-charset))
+         (default-charset gnus-newsgroup-charset)
+         vlist)
+      (let ((locals gnus-newsgroup-variables))
+       (while locals
+         (if (consp (car locals))
+             (push (eval (caar locals)) vlist)
+           (push (eval (car locals)) vlist))
+         (setq locals (cdr locals)))
+       (setq vlist (nreverse vlist)))
       (save-excursion
        (set-buffer gnus-group-buffer)
        (setq gnus-newsgroup-name name
       (save-excursion
        (set-buffer gnus-group-buffer)
        (setq gnus-newsgroup-name name
@@ -2453,6 +2683,12 @@ marks of articles."
              gnus-reffed-article-number reffed
              gnus-current-score-file score-file
              gnus-newsgroup-charset default-charset)
              gnus-reffed-article-number reffed
              gnus-current-score-file score-file
              gnus-newsgroup-charset default-charset)
+       (let ((locals gnus-newsgroup-variables))
+         (while locals
+           (if (consp (car locals))
+               (set (caar locals) (pop vlist))
+             (set (car locals) (pop vlist)))
+           (setq locals (cdr locals))))
        ;; The article buffer also has local variables.
        (when (gnus-buffer-live-p gnus-article-buffer)
          (set-buffer gnus-article-buffer)
        ;; The article buffer also has local variables.
        (when (gnus-buffer-live-p gnus-article-buffer)
          (set-buffer gnus-article-buffer)
@@ -2502,7 +2738,8 @@ marks of articles."
        (let ((gnus-summary-line-format-spec spec)
              (gnus-newsgroup-downloadable '((0 . t))))
          (gnus-summary-insert-line
        (let ((gnus-summary-line-format-spec spec)
              (gnus-newsgroup-downloadable '((0 . t))))
          (gnus-summary-insert-line
-          [0 "" "" "" "" "" 0 0 "" nil]  0 nil 128 t nil "" nil 1)
+          (make-full-mail-header 0 "" "nobody" "" "" "" 0 0 "" nil)
+          0 nil 128 t nil "" nil 1)
          (goto-char (point-min))
          (setq pos (list (cons 'unread (and (search-forward "\200" nil t)
                                             (- (point) 2)))))
          (goto-char (point-min))
          (setq pos (list (cons 'unread (and (search-forward "\200" nil t)
                                             (- (point) 2)))))
@@ -2529,7 +2766,8 @@ marks of articles."
 (defun gnus-summary-from-or-to-or-newsgroups (header)
   (let ((to (cdr (assq 'To (mail-header-extra header))))
        (newsgroups (cdr (assq 'Newsgroups (mail-header-extra header))))
 (defun gnus-summary-from-or-to-or-newsgroups (header)
   (let ((to (cdr (assq 'To (mail-header-extra header))))
        (newsgroups (cdr (assq 'Newsgroups (mail-header-extra header))))
-       (mail-parse-charset gnus-newsgroup-charset))
+       (default-mime-charset (with-current-buffer gnus-summary-buffer
+                               default-mime-charset)))
     (cond
      ((and to
           gnus-ignored-from-addresses
     (cond
      ((and to
           gnus-ignored-from-addresses
@@ -2563,7 +2801,7 @@ marks of articles."
          (if (or (null gnus-summary-default-score)
                  (<= (abs (- gnus-tmp-score gnus-summary-default-score))
                      gnus-summary-zcore-fuzz))
          (if (or (null gnus-summary-default-score)
                  (<= (abs (- gnus-tmp-score gnus-summary-default-score))
                      gnus-summary-zcore-fuzz))
-             ? ;Whitespace
+             ?  ;Whitespace
            (if (< gnus-tmp-score gnus-summary-default-score)
                gnus-score-below-mark gnus-score-over-mark)))
         (gnus-tmp-replied
            (if (< gnus-tmp-score gnus-summary-default-score)
                gnus-score-below-mark gnus-score-over-mark)))
         (gnus-tmp-replied
@@ -2573,15 +2811,14 @@ marks of articles."
                (gnus-tmp-replied gnus-replied-mark)
                ((memq gnus-tmp-current gnus-newsgroup-saved)
                 gnus-saved-mark)
                (gnus-tmp-replied gnus-replied-mark)
                ((memq gnus-tmp-current gnus-newsgroup-saved)
                 gnus-saved-mark)
-               (t gnus-unread-mark)))
+               (t gnus-no-mark)))
         (gnus-tmp-from (mail-header-from gnus-tmp-header))
         (gnus-tmp-name
          (cond
           ((string-match "<[^>]+> *$" gnus-tmp-from)
            (let ((beg (match-beginning 0)))
         (gnus-tmp-from (mail-header-from gnus-tmp-header))
         (gnus-tmp-name
          (cond
           ((string-match "<[^>]+> *$" gnus-tmp-from)
            (let ((beg (match-beginning 0)))
-             (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from)
-                      (substring gnus-tmp-from (1+ (match-beginning 0))
-                                 (1- (match-end 0))))
+             (or (and (string-match "^\".+\"" gnus-tmp-from)
+                      (substring gnus-tmp-from 1 (1- (match-end 0))))
                  (substring gnus-tmp-from 0 beg))))
           ((string-match "(.+)" gnus-tmp-from)
            (substring gnus-tmp-from
                  (substring gnus-tmp-from 0 beg))))
           ((string-match "(.+)" gnus-tmp-from)
            (substring gnus-tmp-from
@@ -2596,7 +2833,7 @@ marks of articles."
       (setq gnus-tmp-name gnus-tmp-from))
     (unless (numberp gnus-tmp-lines)
       (setq gnus-tmp-lines 0))
       (setq gnus-tmp-name gnus-tmp-from))
     (unless (numberp gnus-tmp-lines)
       (setq gnus-tmp-lines 0))
-    (gnus-put-text-property
+    (gnus-put-text-property-excluding-characters-with-faces
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
      'gnus-number gnus-tmp-number)
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
      'gnus-number gnus-tmp-number)
@@ -2606,7 +2843,7 @@ marks of articles."
       (forward-line 1))))
 
 (defun gnus-summary-update-line (&optional dont-update)
       (forward-line 1))))
 
 (defun gnus-summary-update-line (&optional dont-update)
-  ;; Update summary line after change.
+  "Update summary line after change."
   (when (and gnus-summary-default-score
             (not gnus-summary-inhibit-highlight))
     (let* ((gnus-summary-inhibit-highlight t) ; Prevent recursion.
   (when (and gnus-summary-default-score
             (not gnus-summary-inhibit-highlight))
     (let* ((gnus-summary-inhibit-highlight t) ; Prevent recursion.
@@ -2628,7 +2865,7 @@ marks of articles."
         (if (or (null gnus-summary-default-score)
                 (<= (abs (- score gnus-summary-default-score))
                     gnus-summary-zcore-fuzz))
         (if (or (null gnus-summary-default-score)
                 (<= (abs (- score gnus-summary-default-score))
                     gnus-summary-zcore-fuzz))
-            ? ;Whitespace
+            ?  ;Whitespace
           (if (< score gnus-summary-default-score)
               gnus-score-below-mark gnus-score-over-mark))
         'score))
           (if (< score gnus-summary-default-score)
               gnus-score-below-mark gnus-score-over-mark))
         'score))
@@ -2710,6 +2947,26 @@ If NO-DISPLAY, don't generate a summary buffer."
        (setq group nil)))
     result))
 
        (setq group nil)))
     result))
 
+(defun gnus-summary-jump-to-other-group (group &optional show-all)
+  "Directly jump to the other GROUP from summary buffer.
+If SHOW-ALL is non-nil, already read articles are also listed."
+  (interactive
+   (if (eq gnus-summary-buffer (current-buffer))
+       (list (completing-read
+             "Group: " gnus-active-hashtb nil t
+             (when (and gnus-newsgroup-name
+                        (string-match "[.:][^.:]+$" gnus-newsgroup-name))
+               (substring gnus-newsgroup-name 0 (1+ (match-beginning 0))))
+             'gnus-group-history)
+            current-prefix-arg)
+     (error "%s must be invoked from a gnus summary buffer." this-command)))
+  (unless (or (zerop (length group))
+             (and gnus-newsgroup-name
+                  (string-equal gnus-newsgroup-name group)))
+    (gnus-summary-exit)
+    (gnus-summary-read-group group show-all
+                            gnus-dont-select-after-jump-to-other-group)))
+
 (defun gnus-summary-read-group-1 (group show-all no-article
                                        kill-buffer no-display
                                        &optional select-articles)
 (defun gnus-summary-read-group-1 (group show-all no-article
                                        kill-buffer no-display
                                        &optional select-articles)
@@ -2779,6 +3036,7 @@ If NO-DISPLAY, don't generate a summary buffer."
       (gnus-summary-set-local-parameters gnus-newsgroup-name)
       (gnus-update-format-specifications
        nil 'summary 'summary-mode 'summary-dummy)
       (gnus-summary-set-local-parameters gnus-newsgroup-name)
       (gnus-update-format-specifications
        nil 'summary 'summary-mode 'summary-dummy)
+      (gnus-update-summary-mark-positions)
       ;; Do score processing.
       (when gnus-use-scoring
        (gnus-possibly-score-headers))
       ;; Do score processing.
       (when gnus-use-scoring
        (gnus-possibly-score-headers))
@@ -2791,6 +3049,7 @@ If NO-DISPLAY, don't generate a summary buffer."
              (let ((gnus-newsgroup-dormant nil))
                (gnus-summary-initial-limit show-all))
            (gnus-summary-initial-limit show-all))
              (let ((gnus-newsgroup-dormant nil))
                (gnus-summary-initial-limit show-all))
            (gnus-summary-initial-limit show-all))
+       ;; When untreaded, all articles are always shown.
        (setq gnus-newsgroup-limit
              (mapcar
               (lambda (header) (mail-header-number header))
        (setq gnus-newsgroup-limit
              (mapcar
               (lambda (header) (mail-header-number header))
@@ -2915,7 +3174,8 @@ If NO-DISPLAY, don't generate a summary buffer."
   "Query where the respool algorithm would put this article."
   (interactive)
   (gnus-summary-select-article)
   "Query where the respool algorithm would put this article."
   (interactive)
   (gnus-summary-select-article)
-  (message (gnus-general-simplify-subject (gnus-summary-article-subject))))
+  (message "%s"
+          (gnus-general-simplify-subject (gnus-summary-article-subject))))
 
 (defun gnus-gather-threads-by-subject (threads)
   "Gather threads by looking at Subject headers."
 
 (defun gnus-gather-threads-by-subject (threads)
   "Gather threads by looking at Subject headers."
@@ -2989,12 +3249,12 @@ If NO-DISPLAY, don't generate a summary buffer."
     result))
 
 (defun gnus-sort-gathered-threads (threads)
     result))
 
 (defun gnus-sort-gathered-threads (threads)
-  "Sort subtreads inside each gathered thread by article number."
+  "Sort subtreads inside each gathered thread by `gnus-sort-gathered-threads-function'."
   (let ((result threads))
     (while threads
       (when (stringp (caar threads))
        (setcdr (car threads)
   (let ((result threads))
     (while threads
       (when (stringp (caar threads))
        (setcdr (car threads)
-               (sort (cdar threads) 'gnus-thread-sort-by-number)))
+               (sort (cdar threads) gnus-sort-gathered-threads-function)))
       (setq threads (cdr threads)))
     result))
 
       (setq threads (cdr threads)))
     result))
 
@@ -3129,6 +3389,7 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
 
 (defun gnus-build-sparse-threads ()
   (let ((headers gnus-newsgroup-headers)
 
 (defun gnus-build-sparse-threads ()
   (let ((headers gnus-newsgroup-headers)
+       (mail-parse-charset gnus-newsgroup-charset)
        (gnus-summary-ignore-duplicates t)
        header references generation relations
        subject child end new-child date)
        (gnus-summary-ignore-duplicates t)
        header references generation relations
        subject child end new-child date)
@@ -3162,7 +3423,7 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
     (mapcar
      (lambda (relation)
        (when (gnus-dependencies-add-header
     (mapcar
      (lambda (relation)
        (when (gnus-dependencies-add-header
-             (make-full-mail-header
+             (make-full-mail-header-from-decoded-header
               gnus-reffed-article-number
               (nth 3 relation) "" (or (nth 4 relation) "")
               (nth 1 relation)
               gnus-reffed-article-number
               (nth 3 relation) "" (or (nth 4 relation) "")
               (nth 1 relation)
@@ -3181,7 +3442,8 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
   ;; fetch the headers for the articles that aren't there.  This will
   ;; build complete threads - if the roots haven't been expired by the
   ;; server, that is.
   ;; fetch the headers for the articles that aren't there.  This will
   ;; build complete threads - if the roots haven't been expired by the
   ;; server, that is.
-  (let (id heads)
+  (let ((mail-parse-charset gnus-newsgroup-charset)
+       id heads)
     (mapatoms
      (lambda (refs)
        (when (not (car (symbol-value refs)))
     (mapatoms
      (lambda (refs)
        (when (not (car (symbol-value refs)))
@@ -3213,17 +3475,17 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
          (setq header
                (make-full-mail-header
                 number                         ; number
          (setq header
                (make-full-mail-header
                 number                         ; number
-                (funcall gnus-decode-encoded-word-function
-                         (nnheader-nov-field)) ; subject
-                (funcall gnus-decode-encoded-word-function
-                         (nnheader-nov-field)) ; from
+                (nnheader-nov-field)           ; subject
+                (nnheader-nov-field)           ; from
                 (nnheader-nov-field)           ; date
                 (nnheader-nov-read-message-id) ; id
                 (nnheader-nov-field)           ; refs
                 (nnheader-nov-read-integer)    ; chars
                 (nnheader-nov-read-integer)    ; lines
                 (unless (eobp)
                 (nnheader-nov-field)           ; date
                 (nnheader-nov-read-message-id) ; id
                 (nnheader-nov-field)           ; refs
                 (nnheader-nov-read-integer)    ; chars
                 (nnheader-nov-read-integer)    ; lines
                 (unless (eobp)
-                  (nnheader-nov-field))                ; misc
+                  (if (looking-at "Xref: ")
+                      (goto-char (match-end 0)))
+                  (nnheader-nov-field))        ; Xref
                 (nnheader-nov-parse-extra))))  ; extra
 
       (widen))
                 (nnheader-nov-parse-extra))))  ; extra
 
       (widen))
@@ -3233,9 +3495,9 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
     (gnus-dependencies-add-header header dependencies force-new)))
 
 (defun gnus-build-get-header (id)
     (gnus-dependencies-add-header header dependencies force-new)))
 
 (defun gnus-build-get-header (id)
-  ;; Look through the buffer of NOV lines and find the header to
-  ;; ID.  Enter this line into the dependencies hash table, and return
-  ;; the id of the parent article (if any).
+  "Look through the buffer of NOV lines and find the header to ID.
+Enter this line into the dependencies hash table, and return
+the id of the parent article (if any)."
   (let ((deps gnus-newsgroup-dependencies)
        found header)
     (prog1
   (let ((deps gnus-newsgroup-dependencies)
        found header)
     (prog1
@@ -3270,6 +3532,7 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
 (defun gnus-build-all-threads ()
   "Read all the headers."
   (let ((gnus-summary-ignore-duplicates t)
 (defun gnus-build-all-threads ()
   "Read all the headers."
   (let ((gnus-summary-ignore-duplicates t)
+       (mail-parse-charset gnus-newsgroup-charset)
        (dependencies gnus-newsgroup-dependencies)
        header article)
     (save-excursion
        (dependencies gnus-newsgroup-dependencies)
        header article)
     (save-excursion
@@ -3279,8 +3542,7 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
        (while (not (eobp))
          (ignore-errors
            (setq article (read (current-buffer))
        (while (not (eobp))
          (ignore-errors
            (setq article (read (current-buffer))
-                 header (gnus-nov-parse-line
-                         article dependencies)))
+                 header (gnus-nov-parse-line article dependencies)))
          (when header
            (save-excursion
              (set-buffer gnus-summary-buffer)
          (when header
            (save-excursion
              (set-buffer gnus-summary-buffer)
@@ -3317,17 +3579,19 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
        (memq article gnus-newsgroup-expirable)
        ;; Only insert the Subject string when it's different
        ;; from the previous Subject string.
        (memq article gnus-newsgroup-expirable)
        ;; Only insert the Subject string when it's different
        ;; from the previous Subject string.
-       (if (gnus-subject-equal
-           (condition-case ()
-               (mail-header-subject
-                (gnus-data-header
-                 (cadr
-                  (gnus-data-find-list
-                   article
-                   (gnus-data-list t)))))
-             ;; Error on the side of excessive subjects.
-             (error ""))
-           (mail-header-subject header))
+       (if (and
+           gnus-show-threads
+           (gnus-subject-equal
+            (condition-case ()
+                (mail-header-subject
+                 (gnus-data-header
+                  (cadr
+                   (gnus-data-find-list
+                    article
+                    (gnus-data-list t)))))
+              ;; Error on the side of excessive subjects.
+              (error ""))
+            (mail-header-subject header)))
           ""
         (mail-header-subject header))
        nil (cdr (assq article gnus-newsgroup-scored))
           ""
         (mail-header-subject header))
        nil (cdr (assq article gnus-newsgroup-scored))
@@ -3541,7 +3805,6 @@ If LINE, insert the rebuilt thread starting on line LINE."
                  (while thread
                    (gnus-remove-thread-1 (car thread))
                    (setq thread (cdr thread))))
                  (while thread
                    (gnus-remove-thread-1 (car thread))
                    (setq thread (cdr thread))))
-             (gnus-summary-show-all-threads)
              (gnus-remove-thread-1 thread))))))))
 
 (defun gnus-remove-thread-1 (thread)
              (gnus-remove-thread-1 thread))))))))
 
 (defun gnus-remove-thread-1 (thread)
@@ -3553,6 +3816,7 @@ If LINE, insert the rebuilt thread starting on line LINE."
       (gnus-remove-thread-1 (pop thread)))
     (when (setq d (gnus-data-find number))
       (goto-char (gnus-data-pos d))
       (gnus-remove-thread-1 (pop thread)))
     (when (setq d (gnus-data-find number))
       (goto-char (gnus-data-pos d))
+      (gnus-summary-show-thread)
       (gnus-data-remove
        number
        (- (gnus-point-at-bol)
       (gnus-data-remove
        number
        (- (gnus-point-at-bol)
@@ -3560,13 +3824,22 @@ If LINE, insert the rebuilt thread starting on line LINE."
              (1+ (gnus-point-at-eol))
            (gnus-delete-line)))))))
 
              (1+ (gnus-point-at-eol))
            (gnus-delete-line)))))))
 
+(defun gnus-sort-threads-1 (threads func)
+  (sort (mapcar (lambda (thread)
+                 (cons (car thread)
+                       (and (cdr thread)
+                            (gnus-sort-threads-1 (cdr thread) func))))
+               threads) func))
+
 (defun gnus-sort-threads (threads)
   "Sort THREADS."
   (if (not gnus-thread-sort-functions)
       threads
     (gnus-message 8 "Sorting threads...")
     (prog1
 (defun gnus-sort-threads (threads)
   "Sort THREADS."
   (if (not gnus-thread-sort-functions)
       threads
     (gnus-message 8 "Sorting threads...")
     (prog1
-       (sort threads (gnus-make-sort-function gnus-thread-sort-functions))
+       (gnus-sort-threads-1 
+        threads 
+        (gnus-make-sort-function gnus-thread-sort-functions))
       (gnus-message 8 "Sorting threads...done"))))
 
 (defun gnus-sort-articles (articles)
       (gnus-message 8 "Sorting threads...done"))))
 
 (defun gnus-sort-articles (articles)
@@ -3581,12 +3854,12 @@ If LINE, insert the rebuilt thread starting on line LINE."
 
 ;; Written by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>.
 (defmacro gnus-thread-header (thread)
 
 ;; Written by Hallvard B Furuseth <h.b.furuseth@usit.uio.no>.
 (defmacro gnus-thread-header (thread)
-  ;; Return header of first article in THREAD.
-  ;; Note that THREAD must never, ever be anything else than a variable -
-  ;; using some other form will lead to serious barfage.
+  "Return header of first article in THREAD.
+Note that THREAD must never, ever be anything else than a variable -
+using some other form will lead to serious barfage."
   (or (symbolp thread) (signal 'wrong-type-argument '(symbolp thread)))
   ;; (8% speedup to gnus-summary-prepare, just for fun :-)
   (or (symbolp thread) (signal 'wrong-type-argument '(symbolp thread)))
   ;; (8% speedup to gnus-summary-prepare, just for fun :-)
-  (list 'byte-code "\10\211:\203\17\0\211@;\203\16\0A@@\207" ;
+  (list 'byte-code "\10\211:\203\17\0\211@;\203\16\0A@@\207"
        (vector thread) 2))
 
 (defsubst gnus-article-sort-by-number (h1 h2)
        (vector thread) 2))
 
 (defsubst gnus-article-sort-by-number (h1 h2)
@@ -3622,14 +3895,15 @@ If LINE, insert the rebuilt thread starting on line LINE."
 (defsubst gnus-article-sort-by-author (h1 h2)
   "Sort articles by root author."
   (string-lessp
 (defsubst gnus-article-sort-by-author (h1 h2)
   "Sort articles by root author."
   (string-lessp
-   (let ((extract (funcall
-                  gnus-extract-address-components
-                  (mail-header-from h1))))
-     (or (car extract) (cadr extract) ""))
-   (let ((extract (funcall
-                  gnus-extract-address-components
-                  (mail-header-from h2))))
-     (or (car extract) (cadr extract) ""))))
+   (let ((addr (car (mime-entity-read-field h1 'From))))
+     (or (std11-full-name-string addr)
+        (std11-address-string addr)
+        ""))
+   (let ((addr (car (mime-entity-read-field h2 'From))))
+     (or (std11-full-name-string addr)
+        (std11-address-string addr)
+        ""))
+   ))
 
 (defun gnus-thread-sort-by-author (h1 h2)
   "Sort threads by root author."
 
 (defun gnus-thread-sort-by-author (h1 h2)
   "Sort threads by root author."
@@ -3710,7 +3984,7 @@ Unscored articles will be counted as having a score of zero."
 (defvar gnus-tmp-root-expunged nil)
 (defvar gnus-tmp-dummy-line nil)
 
 (defvar gnus-tmp-root-expunged nil)
 (defvar gnus-tmp-dummy-line nil)
 
-(defvar gnus-tmp-header)
+(eval-when-compile (defvar gnus-tmp-header))
 (defun gnus-extra-header (type &optional header)
   "Return the extra header of TYPE."
   (or (cdr (assq type (mail-header-extra (or header gnus-tmp-header))))
 (defun gnus-extra-header (type &optional header)
   "Return the extra header of TYPE."
   (or (cdr (assq type (mail-header-extra (or header gnus-tmp-header))))
@@ -3913,7 +4187,7 @@ or a straight list of headers."
             (if (or (null gnus-summary-default-score)
                     (<= (abs (- gnus-tmp-score gnus-summary-default-score))
                         gnus-summary-zcore-fuzz))
             (if (or (null gnus-summary-default-score)
                     (<= (abs (- gnus-tmp-score gnus-summary-default-score))
                         gnus-summary-zcore-fuzz))
-                ? ;Whitespace
+                ?  ;Whitespace
               (if (< gnus-tmp-score gnus-summary-default-score)
                   gnus-score-below-mark gnus-score-over-mark))
             gnus-tmp-replied
               (if (< gnus-tmp-score gnus-summary-default-score)
                   gnus-score-below-mark gnus-score-over-mark))
             gnus-tmp-replied
@@ -3925,15 +4199,14 @@ or a straight list of headers."
                    gnus-replied-mark)
                   ((memq number gnus-newsgroup-saved)
                    gnus-saved-mark)
                    gnus-replied-mark)
                   ((memq number gnus-newsgroup-saved)
                    gnus-saved-mark)
-                  (t gnus-unread-mark))
+                  (t gnus-no-mark))
             gnus-tmp-from (mail-header-from gnus-tmp-header)
             gnus-tmp-name
             (cond
              ((string-match "<[^>]+> *$" gnus-tmp-from)
               (setq beg-match (match-beginning 0))
             gnus-tmp-from (mail-header-from gnus-tmp-header)
             gnus-tmp-name
             (cond
              ((string-match "<[^>]+> *$" gnus-tmp-from)
               (setq beg-match (match-beginning 0))
-              (or (and (string-match "^\"[^\"]*\"" gnus-tmp-from)
-                       (substring gnus-tmp-from (1+ (match-beginning 0))
-                                  (1- (match-end 0))))
+              (or (and (string-match "^\".+\"" gnus-tmp-from)
+                       (substring gnus-tmp-from 1 (1- (match-end 0))))
                   (substring gnus-tmp-from 0 beg-match)))
              ((string-match "(.+)" gnus-tmp-from)
               (substring gnus-tmp-from
                   (substring gnus-tmp-from 0 beg-match)))
              ((string-match "(.+)" gnus-tmp-from)
               (substring gnus-tmp-from
@@ -3997,6 +4270,24 @@ or a straight list of headers."
         (cdr (assq number gnus-newsgroup-scored))
         (memq number gnus-newsgroup-processable))))))
 
         (cdr (assq number gnus-newsgroup-scored))
         (memq number gnus-newsgroup-processable))))))
 
+(defun gnus-summary-remove-list-identifiers ()
+  "Remove list identifiers in `gnus-list-identifiers' from articles in the current group."
+  (let ((regexp (if (stringp gnus-list-identifiers)
+                   gnus-list-identifiers
+                 (mapconcat 'identity gnus-list-identifiers " *\\|"))))
+    (dolist (header gnus-newsgroup-headers)
+      (when (string-match (concat "\\(\\(\\(Re: +\\)?\\(" regexp
+                                 " *\\)\\)+\\(Re: +\\)?\\)")
+                         (mail-header-subject header))
+       (mail-header-set-subject
+        header (concat (substring (mail-header-subject header)
+                                  0 (match-beginning 1))
+                       (or
+                        (match-string 3 (mail-header-subject header))
+                        (match-string 5 (mail-header-subject header)))
+                       (substring (mail-header-subject header)
+                                  (match-end 1))))))))
+
 (defun gnus-select-newsgroup (group &optional read-all select-articles)
   "Select newsgroup GROUP.
 If READ-ALL is non-nil, all articles in the group are selected.
 (defun gnus-select-newsgroup (group &optional read-all select-articles)
   "Select newsgroup GROUP.
 If READ-ALL is non-nil, all articles in the group are selected.
@@ -4020,7 +4311,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
        (progn                          ; Or we bug out.
          (when (equal major-mode 'gnus-summary-mode)
            (kill-buffer (current-buffer)))
        (progn                          ; Or we bug out.
          (when (equal major-mode 'gnus-summary-mode)
            (kill-buffer (current-buffer)))
-         (error "Couldn't request group %s: %s"
+         (error "Couldn't activate group %s: %s"
                 group (gnus-status-message group))))
 
     (unless (gnus-request-group group t)
                 group (gnus-status-message group))))
 
     (unless (gnus-request-group group t)
@@ -4039,8 +4330,10 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (gnus-adjust-marked-articles info))
 
     ;; Kludge to avoid having cached articles nixed out in virtual groups.
       (gnus-adjust-marked-articles info))
 
     ;; Kludge to avoid having cached articles nixed out in virtual groups.
-    (when (gnus-virtual-group-p group)
-      (setq cached gnus-newsgroup-cached))
+    (setq cached
+         (if (gnus-virtual-group-p group)
+             gnus-newsgroup-cached
+           (gnus-cache-articles-in-group group)))
 
     (setq gnus-newsgroup-unreads
          (gnus-set-difference
 
     (setq gnus-newsgroup-unreads
          (gnus-set-difference
@@ -4071,26 +4364,16 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Retrieve the headers and read them in.
       (gnus-message 5 "Fetching headers for %s..." gnus-newsgroup-name)
       (setq gnus-newsgroup-headers
       ;; Retrieve the headers and read them in.
       (gnus-message 5 "Fetching headers for %s..." gnus-newsgroup-name)
       (setq gnus-newsgroup-headers
-           (if (eq 'nov
-                   (setq gnus-headers-retrieved-by
-                         (gnus-retrieve-headers
-                          articles gnus-newsgroup-name
-                          ;; We might want to fetch old headers, but
-                          ;; not if there is only 1 article.
-                          (and (or (and
-                                    (not (eq gnus-fetch-old-headers 'some))
-                                    (not (numberp gnus-fetch-old-headers)))
-                                   (> (length articles) 1))
-                               gnus-fetch-old-headers))))
-               (gnus-get-newsgroup-headers-xover
-                articles nil nil gnus-newsgroup-name t)
-             (gnus-get-newsgroup-headers)))
+           (gnus-retrieve-parsed-headers
+            articles gnus-newsgroup-name
+            ;; We might want to fetch old headers, but
+            ;; not if there is only 1 article.
+            (and (or (and (not (eq gnus-fetch-old-headers 'some))
+                          (not (numberp gnus-fetch-old-headers)))
+                     (> (length articles) 1))
+                 gnus-fetch-old-headers)))
       (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name)
 
       (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name)
 
-      ;; Kludge to avoid having cached articles nixed out in virtual groups.
-      (when cached
-       (setq gnus-newsgroup-cached cached))
-
       ;; Suppress duplicates?
       (when gnus-suppress-duplicates
        (gnus-dup-suppress-articles))
       ;; Suppress duplicates?
       (when gnus-suppress-duplicates
        (gnus-dup-suppress-articles))
@@ -4107,6 +4390,11 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
+
+      ;; Kludge to avoid having cached articles nixed out in virtual groups.
+      (when cached
+       (setq gnus-newsgroup-cached cached))
+
       ;; We might want to build some more threads first.
       (when (and gnus-fetch-old-headers
                 (eq gnus-headers-retrieved-by 'nov))
       ;; We might want to build some more threads first.
       (when (and gnus-fetch-old-headers
                 (eq gnus-headers-retrieved-by 'nov))
@@ -4116,6 +4404,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Let the Gnus agent mark articles as read.
       (when gnus-agent
        (gnus-agent-get-undownloaded-list))
       ;; Let the Gnus agent mark articles as read.
       (when gnus-agent
        (gnus-agent-get-undownloaded-list))
+      ;; Remove list identifiers from subject
+      (when gnus-list-identifiers
+       (gnus-summary-remove-list-identifiers))
       ;; Check whether auto-expire is to be done in this group.
       (setq gnus-newsgroup-auto-expire
            (gnus-group-auto-expirable-p group))
       ;; Check whether auto-expire is to be done in this group.
       (setq gnus-newsgroup-auto-expire
            (gnus-group-auto-expirable-p group))
@@ -4133,7 +4424,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (or gnus-newsgroup-headers t)))))
 
 (defun gnus-articles-to-read (group &optional read-all)
       (or gnus-newsgroup-headers t)))))
 
 (defun gnus-articles-to-read (group &optional read-all)
-  ;; Find out what articles the user wants to read.
+  "Find out what articles the user wants to read."
   (let* ((articles
          ;; Select all articles if `read-all' is non-nil, or if there
          ;; are no unread articles.
   (let* ((articles
          ;; Select all articles if `read-all' is non-nil, or if there
          ;; are no unread articles.
@@ -4142,7 +4433,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                       (zerop (length gnus-newsgroup-unreads)))
                  (eq (gnus-group-find-parameter group 'display)
                      'all))
                       (zerop (length gnus-newsgroup-unreads)))
                  (eq (gnus-group-find-parameter group 'display)
                      'all))
-             (gnus-uncompress-range (gnus-active group))
+             (or
+              (gnus-uncompress-range (gnus-active group))
+              (gnus-cache-articles-in-group group))
            (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked
                          (copy-sequence gnus-newsgroup-unreads))
                  '<)))
            (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked
                          (copy-sequence gnus-newsgroup-unreads))
                  '<)))
@@ -4159,15 +4452,19 @@ If SELECT-ARTICLES, only select those articles from GROUP."
            (condition-case ()
                (cond
                 ((and (or (<= scored marked) (= scored number))
            (condition-case ()
                (cond
                 ((and (or (<= scored marked) (= scored number))
-                      (numberp gnus-large-newsgroup)
+                      (natnump gnus-large-newsgroup)
                       (> number gnus-large-newsgroup))
                       (> number gnus-large-newsgroup))
-                 (let ((input
-                        (read-string
-                         (format
-                          "How many articles from %s (default %d): "
-                          (gnus-limit-string gnus-newsgroup-name 35)
-                          number))))
-                   (if (string-match "^[ \t]*$" input) number input)))
+                 (let* ((cursor-in-echo-area nil)
+                        (input (read-from-minibuffer
+                                (format
+                                 "How many articles from %s (max %d): "
+                                 (gnus-limit-string gnus-newsgroup-name 35)
+                                 number)
+                                (cons (number-to-string gnus-large-newsgroup)
+                                      0))))
+                   (if (string-match "^[ \t]*$" input)
+                       number
+                     input)))
                 ((and (> scored marked) (< scored number)
                       (> (- scored number) 20))
                  (let ((input
                 ((and (> scored marked) (< scored number)
                       (> (- scored number) 20))
                  (let ((input
@@ -4178,7 +4475,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                    (if (string-match "^[ \t]*$" input)
                        number input)))
                 (t number))
                    (if (string-match "^[ \t]*$" input)
                        number input)))
                 (t number))
-             (quit nil))))))
+             (quit
+              (message "Quit getting the articles to read")
+              nil))))))
     (setq select (if (stringp select) (string-to-number select) select))
     (if (or (null select) (zerop select))
        select
     (setq select (if (stringp select) (string-to-number select) select))
     (if (or (null select) (zerop select))
        select
@@ -4198,6 +4497,12 @@ If SELECT-ARTICLES, only select those articles from GROUP."
            (gnus-sorted-intersection
             gnus-newsgroup-unreads
             (gnus-sorted-complement gnus-newsgroup-unreads articles)))
            (gnus-sorted-intersection
             gnus-newsgroup-unreads
             (gnus-sorted-complement gnus-newsgroup-unreads articles)))
+      (when gnus-alter-articles-to-read-function
+       (setq gnus-newsgroup-unreads
+             (sort
+              (funcall gnus-alter-articles-to-read-function
+                       gnus-newsgroup-name gnus-newsgroup-unreads)
+              '<)))
       articles)))
 
 (defun gnus-killed-articles (killed articles)
       articles)))
 
 (defun gnus-killed-articles (killed articles)
@@ -4283,9 +4588,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Add all marks lists to the list of marks lists.
       (while (setq type (pop types))
        (setq list (symbol-value
       ;; Add all marks lists to the list of marks lists.
       (while (setq type (pop types))
        (setq list (symbol-value
-                         (setq symbol
-                               (intern (format "gnus-newsgroup-%s"
-                                               (car type))))))
+                   (setq symbol
+                         (intern (format "gnus-newsgroup-%s"
+                                         (car type))))))
 
        (when list
          ;; Get rid of the entries of the articles that have the
 
        (when list
          ;; Get rid of the entries of the articles that have the
@@ -4304,30 +4609,36 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                (setq arts (cdr arts)))
              (setq list (cdr all)))))
 
                (setq arts (cdr arts)))
              (setq list (cdr all)))))
 
-       (or (memq (cdr type) uncompressed)
-           (setq list (gnus-compress-sequence (set symbol (sort list '<)) t)))
-       
-       (when (gnus-check-backend-function 'request-set-mark
-                                          gnus-newsgroup-name)
-         ;; uncompressed:s are not proper flags (they are cons cells)
-         ;; cache is a internal gnus flag
-         (unless (memq (cdr type) (cons 'cache uncompressed))
-           (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
-                  (del (gnus-remove-from-range (gnus-copy-sequence old) list))
-                  (add (gnus-remove-from-range (gnus-copy-sequence list) old)))
-             (if add
-                 (push (list add 'add (list (cdr type))) delta-marks))
-             (if del
-                 (push (list del 'del (list (cdr type))) delta-marks)))))
-         
+       (unless (memq (cdr type) uncompressed)
+         (setq list (gnus-compress-sequence (set symbol (sort list '<)) t)))
+
+       (when (gnus-check-backend-function
+              'request-set-mark gnus-newsgroup-name)
+         ;; propagate flags to server, with the following exceptions:
+         ;; uncompressed:s are not proper flags (they are cons cells)
+         ;; cache is a internal gnus flag
+         ;; download are local to one gnus installation (well)
+         ;; unsend are for nndraft groups only
+         ;; xxx: generality of this?  this suits nnimap anyway
+         (unless (memq (cdr type) (append '(cache download unsend)
+                                          uncompressed))
+           (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
+                  (del (gnus-remove-from-range (gnus-copy-sequence old) list))
+                  (add (gnus-remove-from-range
+                        (gnus-copy-sequence list) old)))
+             (when add
+               (push (list add 'add (list (cdr type))) delta-marks))
+             (when del
+               (push (list del 'del (list (cdr type))) delta-marks)))))
+
        (when list
        (when list
-         (push (cons (cdr type) list) newmarked)))
+         (push (cons (cdr type) list) newmarked)))
 
       (when delta-marks
        (unless (gnus-check-group gnus-newsgroup-name)
          (error "Can't open server for %s" gnus-newsgroup-name))
        (gnus-request-set-mark gnus-newsgroup-name delta-marks))
 
       (when delta-marks
        (unless (gnus-check-group gnus-newsgroup-name)
          (error "Can't open server for %s" gnus-newsgroup-name))
        (gnus-request-set-mark gnus-newsgroup-name delta-marks))
-         
+
       ;; Enter these new marks into the info of the group.
       (if (nthcdr 3 info)
          (setcar (nthcdr 3 info) newmarked)
       ;; Enter these new marks into the info of the group.
       (if (nthcdr 3 info)
          (setcar (nthcdr 3 info) newmarked)
@@ -4343,7 +4654,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
            (setcdr (nthcdr i info) nil)))))))
 
 (defun gnus-set-mode-line (where)
            (setcdr (nthcdr i info) nil)))))))
 
 (defun gnus-set-mode-line (where)
-  "This function sets the mode line of the article or summary buffers.
+  "Set the mode line of the article or summary buffers.
 If WHERE is `summary', the summary mode line format will be used."
   ;; Is this mode line one we keep updated?
   (when (and (memq where gnus-updated-mode-lines)
 If WHERE is `summary', the summary mode line format will be used."
   ;; Is this mode line one we keep updated?
   (when (and (memq where gnus-updated-mode-lines)
@@ -4359,7 +4670,11 @@ If WHERE is `summary', the summary mode line format will be used."
        (let* ((mformat (symbol-value
                         (intern
                          (format "gnus-%s-mode-line-format-spec" where))))
        (let* ((mformat (symbol-value
                         (intern
                          (format "gnus-%s-mode-line-format-spec" where))))
-              (gnus-tmp-group-name gnus-newsgroup-name)
+              (gnus-tmp-group-name (gnus-group-name-decode
+                                    gnus-newsgroup-name
+                                    (gnus-group-name-charset
+                                     nil
+                                     gnus-newsgroup-name)))
               (gnus-tmp-article-number (or gnus-current-article 0))
               (gnus-tmp-unread gnus-newsgroup-unreads)
               (gnus-tmp-unread-and-unticked (length gnus-newsgroup-unreads))
               (gnus-tmp-article-number (or gnus-current-article 0))
               (gnus-tmp-unread gnus-newsgroup-unreads)
               (gnus-tmp-unread-and-unticked (length gnus-newsgroup-unreads))
@@ -4398,7 +4713,7 @@ If WHERE is `summary', the summary mode line format will be used."
          ;; We might have to chop a bit of the string off...
          (when (> (length mode-string) max-len)
            (setq mode-string
          ;; We might have to chop a bit of the string off...
          (when (> (length mode-string) max-len)
            (setq mode-string
-                 (concat (truncate-string-to-width mode-string (- max-len 3))
+                 (concat (gnus-truncate-string mode-string (- max-len 3))
                          "...")))
          ;; Pad the mode string a bit.
          (setq mode-string (format (format "%%-%ds" max-len) mode-string))))
                          "...")))
          ;; Pad the mode string a bit.
          (setq mode-string (format (format "%%-%ds" max-len) mode-string))))
@@ -4554,7 +4869,12 @@ The resulting hash table is returned, or nil if no Xrefs were found."
             (save-excursion (set-buffer gnus-summary-buffer)
                             gnus-newsgroup-dependencies)))
        headers id end ref
             (save-excursion (set-buffer gnus-summary-buffer)
                             gnus-newsgroup-dependencies)))
        headers id end ref
-       (mail-parse-charset gnus-newsgroup-charset))
+       (mail-parse-charset gnus-newsgroup-charset)
+       (mail-parse-ignored-charsets
+        (save-excursion (condition-case nil
+                            (set-buffer gnus-summary-buffer)
+                          (error))
+                        gnus-newsgroup-ignored-charsets)))
     (save-excursion
       (set-buffer nntp-server-buffer)
       ;; Translate all TAB characters into SPACE characters.
     (save-excursion
       (set-buffer nntp-server-buffer)
       ;; Translate all TAB characters into SPACE characters.
@@ -4562,7 +4882,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
       (subst-char-in-region (point-min) (point-max) ?\r ?  t)
       (gnus-run-hooks 'gnus-parse-headers-hook)
       (let ((case-fold-search t)
       (subst-char-in-region (point-min) (point-max) ?\r ?  t)
       (gnus-run-hooks 'gnus-parse-headers-hook)
       (let ((case-fold-search t)
-           in-reply-to header p lines chars)
+           in-reply-to header p lines chars ctype)
        (goto-char (point-min))
        ;; Search to the beginning of the next header.  Error messages
        ;; do not begin with 2 or 3.
        (goto-char (point-min))
        ;; Search to the beginning of the next header.  Error messages
        ;; do not begin with 2 or 3.
@@ -4577,7 +4897,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
          ;; doesn't always go hand in hand.
          (setq
           header
          ;; doesn't always go hand in hand.
          (setq
           header
-          (vector
+          (make-full-mail-header
            ;; Number.
            (prog1
                (read cur)
            ;; Number.
            (prog1
                (read cur)
@@ -4591,21 +4911,21 @@ The resulting hash table is returned, or nil if no Xrefs were found."
            (progn
              (goto-char p)
              (if (search-forward "\nsubject: " nil t)
            (progn
              (goto-char p)
              (if (search-forward "\nsubject: " nil t)
-                 (funcall gnus-decode-encoded-word-function
-                          (nnheader-header-value))
+                 (nnheader-header-value)
                "(none)"))
            ;; From.
            (progn
              (goto-char p)
                "(none)"))
            ;; From.
            (progn
              (goto-char p)
-             (if (search-forward "\nfrom: " nil t)
-                 (funcall gnus-decode-encoded-word-function
-                          (nnheader-header-value))
+             (if (or (search-forward "\nfrom: " nil t)
+                     (search-forward "\nfrom:" nil t))
+                 (nnheader-header-value)
                "(nobody)"))
            ;; Date.
            (progn
              (goto-char p)
              (if (search-forward "\ndate: " nil t)
                "(nobody)"))
            ;; Date.
            (progn
              (goto-char p)
              (if (search-forward "\ndate: " nil t)
-                 (nnheader-header-value) ""))
+                 (nnheader-header-value)
+               ""))
            ;; Message-ID.
            (progn
              (goto-char p)
            ;; Message-ID.
            (progn
              (goto-char p)
@@ -4629,7 +4949,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                      (setq ref
                            (buffer-substring
                             (progn
                      (setq ref
                            (buffer-substring
                             (progn
-                              (end-of-line)
+                               ;; (end-of-line)
                               (search-backward ">" end t)
                               (1+ (point)))
                             (progn
                               (search-backward ">" end t)
                               (1+ (point)))
                             (progn
@@ -4678,10 +4998,14 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                  (goto-char p)
                  (when (search-forward
                         (concat "\n" (symbol-name (car extra)) ": ") nil t)
                  (goto-char p)
                  (when (search-forward
                         (concat "\n" (symbol-name (car extra)) ": ") nil t)
-                   (push (cons (car extra) (nnheader-header-value))
-                         out))
+                   (push (cons (car extra) (nnheader-header-value)) out))
                  (pop extra))
                out))))
                  (pop extra))
                out))))
+         (goto-char p)
+         (if (and (search-forward "\ncontent-type: " nil t)
+                  (setq ctype (nnheader-header-value)))
+             (mime-entity-set-content-type-internal
+              header (mime-parse-Content-Type ctype)))
          (when (equal id ref)
            (setq ref nil))
 
          (when (equal id ref)
            (setq ref nil))
 
@@ -4702,12 +5026,14 @@ The resulting hash table is returned, or nil if no Xrefs were found."
 (defun gnus-get-newsgroup-headers-xover (sequence &optional
                                                  force-new dependencies
                                                  group also-fetch-heads)
 (defun gnus-get-newsgroup-headers-xover (sequence &optional
                                                  force-new dependencies
                                                  group also-fetch-heads)
-  "Parse the news overview data in the server buffer, and return a
-list of headers that match SEQUENCE (see `nntp-retrieve-headers')."
+  "Parse the news overview data in the server buffer.
+Return a list of headers that match SEQUENCE (see
+`nntp-retrieve-headers')."
   ;; Get the Xref when the users reads the articles since most/some
   ;; NNTP servers do not include Xrefs when using XOVER.
   (setq gnus-article-internal-prepare-hook '(gnus-article-get-xrefs))
   (let ((mail-parse-charset gnus-newsgroup-charset)
   ;; Get the Xref when the users reads the articles since most/some
   ;; NNTP servers do not include Xrefs when using XOVER.
   (setq gnus-article-internal-prepare-hook '(gnus-article-get-xrefs))
   (let ((mail-parse-charset gnus-newsgroup-charset)
+       (mail-parse-ignored-charsets gnus-newsgroup-ignored-charsets)
        (cur nntp-server-buffer)
        (dependencies (or dependencies gnus-newsgroup-dependencies))
        number headers header)
        (cur nntp-server-buffer)
        (dependencies (or dependencies gnus-newsgroup-dependencies))
        number headers header)
@@ -4750,8 +5076,8 @@ list of headers that match SEQUENCE (see `nntp-retrieve-headers')."
        (let ((gnus-nov-is-evil t))
          (nconc
           (nreverse headers)
        (let ((gnus-nov-is-evil t))
          (nconc
           (nreverse headers)
-          (when (gnus-retrieve-headers sequence group)
-            (gnus-get-newsgroup-headers))))))))
+          (gnus-retrieve-parsed-headers sequence group)
+          ))))))
 
 (defun gnus-article-get-xrefs ()
   "Fill in the Xref value in `gnus-current-headers', if necessary.
 
 (defun gnus-article-get-xrefs ()
   "Fill in the Xref value in `gnus-current-headers', if necessary.
@@ -4767,7 +5093,8 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
          (save-restriction
            (nnheader-narrow-to-headers)
            (goto-char (point-min))
          (save-restriction
            (nnheader-narrow-to-headers)
            (goto-char (point-min))
-           (when (or (and (eq (downcase (char-after)) ?x)
+           (when (or (and (not (eobp))
+                          (eq (downcase (char-after)) ?x)
                           (looking-at "Xref:"))
                      (search-forward "\nXref:" nil t))
              (goto-char (1+ (match-end 0)))
                           (looking-at "Xref:"))
                      (search-forward "\nXref:" nil t))
              (goto-char (1+ (match-end 0)))
@@ -4859,7 +5186,7 @@ current article will be taken into consideration."
       (let ((max (max (point) (mark)))
            articles article)
        (save-excursion
       (let ((max (max (point) (mark)))
            articles article)
        (save-excursion
-         (goto-char (min (min (point) (mark))))
+         (goto-char (min (point) (mark)))
          (while
              (and
               (push (setq article (gnus-summary-article-number)) articles)
          (while
              (and
               (push (setq article (gnus-summary-article-number)) articles)
@@ -5030,6 +5357,7 @@ If `gnus-auto-center-summary' is nil, or the article buffer isn't
 displayed, no centering will be performed."
   ;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle).
   ;; Recenter only when requested.  Suggested by popovich@park.cs.columbia.edu.
 displayed, no centering will be performed."
   ;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle).
   ;; Recenter only when requested.  Suggested by popovich@park.cs.columbia.edu.
+  (interactive)
   (let* ((top (cond ((< (window-height) 4) 0)
                    ((< (window-height) 7) 1)
                    (t (if (numberp gnus-auto-center-summary)
   (let* ((top (cond ((< (window-height) 4) 0)
                    ((< (window-height) 7) 1)
                    (t (if (numberp gnus-auto-center-summary)
@@ -5047,9 +5375,22 @@ displayed, no centering will be performed."
        ;; Set the window start to either `bottom', which is the biggest
        ;; possible valid number, or the second line from the top,
        ;; whichever is the least.
        ;; Set the window start to either `bottom', which is the biggest
        ;; possible valid number, or the second line from the top,
        ;; whichever is the least.
-       (set-window-start
-        window (min bottom (save-excursion
-                             (forward-line (- top)) (point)))))
+       (let ((top-pos (save-excursion (forward-line (- top)) (point))))
+         (if (> bottom top-pos)
+             ;; Keep the second line from the top visible
+             (set-window-start window top-pos t)
+           ;; Try to keep the bottom line visible; if it's partially
+           ;; obscured, either scroll one more line to make it fully
+           ;; visible, or revert to using TOP-POS.
+           (save-excursion
+             (goto-char (point-max))
+             (forward-line -1)
+             (let ((last-line-start (point)))
+               (goto-char bottom)
+               (set-window-start window (point) t)
+               (when (not (pos-visible-in-window-p last-line-start window))
+                 (forward-line 1)
+                 (set-window-start window (min (point) top-pos) t)))))))
       ;; Do horizontal recentering while we're at it.
       (when (and (get-buffer-window (current-buffer) t)
                 (not (eq gnus-auto-center-summary 'vertical)))
       ;; Do horizontal recentering while we're at it.
       (when (and (get-buffer-window (current-buffer) t)
                 (not (eq gnus-auto-center-summary 'vertical)))
@@ -5089,7 +5430,10 @@ displayed, no centering will be performed."
       ;; If the range of read articles is a single range, then the
       ;; first unread article is the article after the last read
       ;; article.  Sounds logical, doesn't it?
       ;; If the range of read articles is a single range, then the
       ;; first unread article is the article after the last read
       ;; article.  Sounds logical, doesn't it?
-      (if (not (listp (cdr read)))
+      (if (and (not (listp (cdr read)))
+              (or (< (car read) (car active))
+                  (progn (setq read (list read))
+                         nil)))
          (setq first (max (car active) (1+ (cdr read))))
        ;; `read' is a list of ranges.
        (when (/= (setq nlast (or (and (numberp (car read)) (car read))
          (setq first (max (car active) (1+ (cdr read))))
        ;; `read' is a list of ranges.
        (when (/= (setq nlast (or (and (numberp (car read)) (car read))
@@ -5146,8 +5490,7 @@ displayed, no centering will be performed."
          (key-binding
           (read-key-sequence
            (substitute-command-keys
          (key-binding
           (read-key-sequence
            (substitute-command-keys
-            "\\<gnus-summary-mode-map>\\[gnus-summary-universal-argument]"
-            ))))
+            "\\<gnus-summary-mode-map>\\[gnus-summary-universal-argument]"))))
         'undefined)
        (gnus-error 1 "Undefined key")
       (save-excursion
         'undefined)
        (gnus-error 1 "Undefined key")
       (save-excursion
@@ -5182,7 +5525,10 @@ The prefix argument ALL means to select all articles."
     (gnus-summary-jump-to-group group)
     (when rescan
       (save-excursion
     (gnus-summary-jump-to-group group)
     (when rescan
       (save-excursion
-       (gnus-group-get-new-news-this-group 1)))
+       (save-window-excursion
+         ;; Don't show group contents.
+         (set-window-start (selected-window) (point-max))
+         (gnus-group-get-new-news-this-group 1))))
     (gnus-group-read-group all t)
     (gnus-summary-goto-subject current-subject nil t)))
 
     (gnus-group-read-group all t)
     (gnus-summary-goto-subject current-subject nil t)))
 
@@ -5243,13 +5589,9 @@ If FORCE (the prefix), also save the .newsrc file(s)."
 
 (defun gnus-summary-exit (&optional temporary)
   "Exit reading current newsgroup, and then return to group selection mode.
 
 (defun gnus-summary-exit (&optional temporary)
   "Exit reading current newsgroup, and then return to group selection mode.
-gnus-exit-group-hook is called with no arguments if that value is non-nil."
+`gnus-exit-group-hook' is called with no arguments if that value is non-nil."
   (interactive)
   (gnus-set-global-variables)
   (interactive)
   (gnus-set-global-variables)
-  (when (gnus-buffer-live-p gnus-article-buffer)
-    (save-excursion
-      (set-buffer gnus-article-buffer)
-      (mm-destroy-parts gnus-article-mime-handles)))
   (gnus-kill-save-kill-buffer)
   (gnus-async-halt-prefetch)
   (let* ((group gnus-newsgroup-name)
   (gnus-kill-save-kill-buffer)
   (gnus-async-halt-prefetch)
   (let* ((group gnus-newsgroup-name)
@@ -5276,6 +5618,8 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
       (gnus-dup-enter-articles))
     (when gnus-use-trees
       (gnus-tree-close group))
       (gnus-dup-enter-articles))
     (when gnus-use-trees
       (gnus-tree-close group))
+    (when gnus-use-cache
+      (gnus-cache-write-active))
     ;; Remove entries for this group.
     (nnmail-purge-split-history (gnus-group-real-name group))
     ;; Make all changes in this group permanent.
     ;; Remove entries for this group.
     (nnmail-purge-split-history (gnus-group-real-name group))
     ;; Make all changes in this group permanent.
@@ -5309,12 +5653,16 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
        ;; not garbage-collected, it seems.  This would the lead to en
        ;; ever-growing Emacs.
        (gnus-summary-clear-local-variables)
        ;; not garbage-collected, it seems.  This would the lead to en
        ;; ever-growing Emacs.
        (gnus-summary-clear-local-variables)
+       (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+         (gnus-summary-clear-local-variables))
        (when (get-buffer gnus-article-buffer)
          (bury-buffer gnus-article-buffer))
        ;; We clear the global counterparts of the buffer-local
        ;; variables as well, just to be on the safe side.
        (set-buffer gnus-group-buffer)
        (gnus-summary-clear-local-variables)
        (when (get-buffer gnus-article-buffer)
          (bury-buffer gnus-article-buffer))
        ;; We clear the global counterparts of the buffer-local
        ;; variables as well, just to be on the safe side.
        (set-buffer gnus-group-buffer)
        (gnus-summary-clear-local-variables)
+       (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+         (gnus-summary-clear-local-variables))
        ;; Return to group mode buffer.
        (when (eq mode 'gnus-summary-mode)
          (gnus-kill-buffer buf)))
        ;; Return to group mode buffer.
        (when (eq mode 'gnus-summary-mode)
          (gnus-kill-buffer buf)))
@@ -5323,7 +5671,14 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
       (if (not quit-config)
          (progn
            (goto-char group-point)
       (if (not quit-config)
          (progn
            (goto-char group-point)
-           (gnus-configure-windows 'group 'force))
+           (gnus-configure-windows 'group 'force)
+           (unless (pos-visible-in-window-p)
+             (forward-line (/ (static-if (featurep 'xemacs)
+                                  (window-displayed-height)
+                                (1- (window-height)))
+                              -2))
+             (set-window-start (selected-window) (point))
+             (goto-char group-point)))
        (gnus-handle-ephemeral-exit quit-config))
       ;; Clear the current group name.
       (unless quit-config
        (gnus-handle-ephemeral-exit quit-config))
       ;; Clear the current group name.
       (unless quit-config
@@ -5341,11 +5696,7 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
       (gnus-async-halt-prefetch)
       (mapcar 'funcall
              (delq 'gnus-summary-expire-articles
       (gnus-async-halt-prefetch)
       (mapcar 'funcall
              (delq 'gnus-summary-expire-articles
-                   (copy-list gnus-summary-prepare-exit-hook)))
-      (when (gnus-buffer-live-p gnus-article-buffer)
-       (save-excursion
-         (set-buffer gnus-article-buffer)
-         (mm-destroy-parts gnus-article-mime-handles)))
+                   (copy-sequence gnus-summary-prepare-exit-hook)))
       ;; If we have several article buffers, we kill them at exit.
       (unless gnus-single-article-buffer
        (gnus-kill-buffer gnus-article-buffer)
       ;; If we have several article buffers, we kill them at exit.
       (unless gnus-single-article-buffer
        (gnus-kill-buffer gnus-article-buffer)
@@ -5355,8 +5706,12 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
          (gnus-deaden-summary)
        (gnus-close-group group)
        (gnus-summary-clear-local-variables)
          (gnus-deaden-summary)
        (gnus-close-group group)
        (gnus-summary-clear-local-variables)
+       (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+         (gnus-summary-clear-local-variables))
        (set-buffer gnus-group-buffer)
        (gnus-summary-clear-local-variables)
        (set-buffer gnus-group-buffer)
        (gnus-summary-clear-local-variables)
+       (let ((gnus-summary-local-variables gnus-newsgroup-variables))
+         (gnus-summary-clear-local-variables))
        (when (get-buffer gnus-summary-buffer)
          (kill-buffer gnus-summary-buffer)))
       (unless gnus-single-article-buffer
        (when (get-buffer gnus-summary-buffer)
          (kill-buffer gnus-summary-buffer)))
       (unless gnus-single-article-buffer
@@ -5407,6 +5762,14 @@ The state which existed when entering the ephemeral is reset."
       (gnus-summary-recenter)
       (gnus-summary-position-point))))
 
       (gnus-summary-recenter)
       (gnus-summary-position-point))))
 
+(defun gnus-summary-preview-mime-message ()
+  "MIME decode and play this message."
+  (interactive)
+  (let ((gnus-break-pages nil)
+       (gnus-show-mime t))
+    (gnus-summary-select-article gnus-show-all-headers t))
+  (select-window (get-buffer-window gnus-article-buffer)))
+
 ;;; Dead summaries.
 
 (defvar gnus-dead-summary-mode-map nil)
 ;;; Dead summaries.
 
 (defvar gnus-dead-summary-mode-map nil)
@@ -5453,7 +5816,8 @@ The state which existed when entering the ephemeral is reset."
       (rename-buffer
        (concat (substring name 0 (match-beginning 0)) "Dead "
               (substring name (match-beginning 0)))
       (rename-buffer
        (concat (substring name 0 (match-beginning 0)) "Dead "
               (substring name (match-beginning 0)))
-       t))))
+       t)
+      (bury-buffer))))
 
 (defun gnus-kill-or-deaden-summary (buffer)
   "Kill or deaden the summary BUFFER."
 
 (defun gnus-kill-or-deaden-summary (buffer)
   "Kill or deaden the summary BUFFER."
@@ -5620,8 +5984,8 @@ returned."
                (if backward
                    (gnus-summary-find-prev unread)
                  (gnus-summary-find-next unread)))
                (if backward
                    (gnus-summary-find-prev unread)
                  (gnus-summary-find-next unread)))
-      (gnus-summary-show-thread)
-      (setq n (1- n)))
+      (unless (zerop (setq n (1- n)))
+       (gnus-summary-show-thread)))
     (when (/= 0 n)
       (gnus-message 7 "No more%s articles"
                    (if unread " unread" "")))
     (when (/= 0 n)
       (gnus-message 7 "No more%s articles"
                    (if unread " unread" "")))
@@ -5682,13 +6046,23 @@ Given a prefix, will force an `article' buffer configuration."
 
 (defun gnus-summary-display-article (article &optional all-header)
   "Display ARTICLE in article buffer."
 
 (defun gnus-summary-display-article (article &optional all-header)
   "Display ARTICLE in article buffer."
+  (when (gnus-buffer-live-p gnus-article-buffer)
+    (with-current-buffer gnus-article-buffer
+      (mm-enable-multibyte-mule4)))
   (gnus-set-global-variables)
   (gnus-set-global-variables)
+  (when (gnus-buffer-live-p gnus-article-buffer)
+    (with-current-buffer gnus-article-buffer
+      (setq gnus-article-charset gnus-newsgroup-charset)
+      (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)))
   (if (null article)
       nil
     (prog1
        (if gnus-summary-display-article-function
            (funcall gnus-summary-display-article-function article all-header)
          (gnus-article-prepare article all-header))
   (if (null article)
       nil
     (prog1
        (if gnus-summary-display-article-function
            (funcall gnus-summary-display-article-function article all-header)
          (gnus-article-prepare article all-header))
+      (with-current-buffer gnus-article-buffer
+       (set (make-local-variable 'gnus-summary-search-article-matched-data)
+            nil))
       (gnus-run-hooks 'gnus-select-article-hook)
       (when (and gnus-current-article
                 (not (zerop gnus-current-article)))
       (gnus-run-hooks 'gnus-select-article-hook)
       (when (and gnus-current-article
                 (not (zerop gnus-current-article)))
@@ -5712,37 +6086,40 @@ be displayed."
     (set-buffer gnus-summary-buffer))
   (let ((article (or article (gnus-summary-article-number)))
        (all-headers (not (not all-headers))) ;Must be T or NIL.
     (set-buffer gnus-summary-buffer))
   (let ((article (or article (gnus-summary-article-number)))
        (all-headers (not (not all-headers))) ;Must be T or NIL.
-       gnus-summary-display-article-function
-       did)
+       gnus-summary-display-article-function)
     (and (not pseudo)
         (gnus-summary-article-pseudo-p article)
         (error "This is a pseudo-article"))
     (and (not pseudo)
         (gnus-summary-article-pseudo-p article)
         (error "This is a pseudo-article"))
-    (prog1
-       (save-excursion
-         (set-buffer gnus-summary-buffer)
-         (if (or (and gnus-single-article-buffer
-                      (or (null gnus-current-article)
-                          (null gnus-article-current)
-                          (null (get-buffer gnus-article-buffer))
-                          (not (eq article (cdr gnus-article-current)))
-                          (not (equal (car gnus-article-current)
-                                      gnus-newsgroup-name))))
-                 (and (not gnus-single-article-buffer)
-                      (or (null gnus-current-article)
-                          (not (eq gnus-current-article article))))
-                 force)
-             ;; The requested article is different from the current article.
-             (prog1
-                 (gnus-summary-display-article article all-headers)
-               (setq did article)
-               (when (or all-headers gnus-show-all-headers)
-                 (gnus-article-show-all-headers)))
+    (save-excursion
+      (set-buffer gnus-summary-buffer)
+      (if (or (and gnus-single-article-buffer
+                  (or (null gnus-current-article)
+                      (null gnus-article-current)
+                      (null (get-buffer gnus-article-buffer))
+                      (not (eq article (cdr gnus-article-current)))
+                      (not (equal (car gnus-article-current)
+                                  gnus-newsgroup-name))))
+             (and (not gnus-single-article-buffer)
+                  (or (null gnus-current-article)
+                      (not (eq gnus-current-article article))))
+             force)
+         ;; The requested article is different from the current article.
+         (progn
+           (gnus-summary-display-article article all-headers)
            (when (or all-headers gnus-show-all-headers)
              (gnus-article-show-all-headers))
            (when (or all-headers gnus-show-all-headers)
              (gnus-article-show-all-headers))
-           'old))
-      (when did
-       (gnus-article-set-window-start
-        (cdr (assq article gnus-newsgroup-bookmarks)))))))
+           (gnus-article-set-window-start
+            (cdr (assq article gnus-newsgroup-bookmarks)))
+           article)
+       (when (or all-headers gnus-show-all-headers)
+         (gnus-article-show-all-headers))
+       'old))))
+
+(defun gnus-summary-force-verify-and-decrypt ()
+  (interactive)
+  (let ((mm-verify-option 'known)
+       (mm-decrypt-option 'known))
+    (gnus-summary-select-article nil 'force)))
 
 (defun gnus-summary-set-current-mark (&optional current-mark)
   "Obsolete function."
 
 (defun gnus-summary-set-current-mark (&optional current-mark)
   "Obsolete function."
@@ -6154,7 +6531,21 @@ If given a prefix, remove all limits."
   "Limit the summary buffer to articles that are older than (or equal) AGE days.
 If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to
 articles that are younger than AGE days."
   "Limit the summary buffer to articles that are older than (or equal) AGE days.
 If YOUNGER-P (the prefix) is non-nil, limit the summary buffer to
 articles that are younger than AGE days."
-  (interactive "nLimit to articles older than (in days): \nP")
+  (interactive
+   (let ((younger current-prefix-arg)
+        (days-got nil)
+        days)
+     (while (not days-got)
+       (setq days (if younger
+                     (read-string "Limit to articles within (in days): ")
+                   (read-string "Limit to articles older than (in days): ")))
+       (when (> (length days) 0)
+        (setq days (read days)))
+       (if (numberp days)
+          (setq days-got t)
+        (message "Please enter a number.")
+        (sleep-for 1)))
+     (list days younger)))
   (prog1
       (let ((data gnus-newsgroup-data)
            (cutoff (days-to-time age))
   (prog1
       (let ((data gnus-newsgroup-data)
            (cutoff (days-to-time age))
@@ -6163,7 +6554,9 @@ articles that are younger than AGE days."
          (when (and (vectorp (gnus-data-header d))
                     (setq date (mail-header-date (gnus-data-header d))))
            (setq is-younger (time-less-p
          (when (and (vectorp (gnus-data-header d))
                     (setq date (mail-header-date (gnus-data-header d))))
            (setq is-younger (time-less-p
-                             (time-since (date-to-time date))
+                             (time-since (condition-case ()
+                                             (date-to-time date)
+                                           (error '(0 0))))
                              cutoff))
            (when (if younger-p
                      is-younger
                              cutoff))
            (when (if younger-p
                      is-younger
@@ -6178,12 +6571,12 @@ articles that are younger than AGE days."
    (let ((header
          (intern
           (gnus-completing-read
    (let ((header
          (intern
           (gnus-completing-read
-           (symbol-name (car gnus-extra-headers))      
-           "Score extra header:"       
-           (mapcar (lambda (x) 
+           (symbol-name (car gnus-extra-headers))
+           "Limit extra header:"
+           (mapcar (lambda (x)
                      (cons (symbol-name x) x))
                    gnus-extra-headers)
                      (cons (symbol-name x) x))
                    gnus-extra-headers)
-           nil                 
+           nil
            t))))
      (list header
           (read-string (format "Limit to header %s (regexp): " header)))))
            t))))
      (list header
           (read-string (format "Limit to header %s (regexp): " header)))))
@@ -6393,6 +6786,7 @@ If ALL, mark even excluded ticked and dormants as read."
   "Go forwards in the thread until we find an article that we want to display."
   (when (or (eq gnus-fetch-old-headers 'some)
            (eq gnus-fetch-old-headers 'invisible)
   "Go forwards in the thread until we find an article that we want to display."
   (when (or (eq gnus-fetch-old-headers 'some)
            (eq gnus-fetch-old-headers 'invisible)
+           (numberp gnus-fetch-old-headers)
            (eq gnus-build-sparse-threads 'some)
            (eq gnus-build-sparse-threads 'more))
     ;; Deal with old-fetched headers and sparse threads.
            (eq gnus-build-sparse-threads 'some)
            (eq gnus-build-sparse-threads 'more))
     ;; Deal with old-fetched headers and sparse threads.
@@ -6422,6 +6816,7 @@ If ALL, mark even excluded ticked and dormants as read."
   "Cut off all uninteresting articles from the beginning of threads."
   (when (or (eq gnus-fetch-old-headers 'some)
            (eq gnus-fetch-old-headers 'invisible)
   "Cut off all uninteresting articles from the beginning of threads."
   (when (or (eq gnus-fetch-old-headers 'some)
            (eq gnus-fetch-old-headers 'invisible)
+           (numberp gnus-fetch-old-headers)
            (eq gnus-build-sparse-threads 'some)
            (eq gnus-build-sparse-threads 'more))
     (let ((th threads))
            (eq gnus-build-sparse-threads 'some)
            (eq gnus-build-sparse-threads 'more))
     (let ((th threads))
@@ -6439,6 +6834,7 @@ fetch-old-headers verbiage, and so on."
   (if (or gnus-inhibit-limiting
          (and (null gnus-newsgroup-dormant)
               (not (eq gnus-fetch-old-headers 'some))
   (if (or gnus-inhibit-limiting
          (and (null gnus-newsgroup-dormant)
               (not (eq gnus-fetch-old-headers 'some))
+              (not (numberp gnus-fetch-old-headers))
               (not (eq gnus-fetch-old-headers 'invisible))
               (null gnus-summary-expunge-below)
               (not (eq gnus-build-sparse-threads 'some))
               (not (eq gnus-fetch-old-headers 'invisible))
               (null gnus-summary-expunge-below)
               (not (eq gnus-build-sparse-threads 'some))
@@ -6492,7 +6888,8 @@ fetch-old-headers verbiage, and so on."
                 (zerop children))
            ;; If this is "fetch-old-headered" and there is no
            ;; visible children, then we don't want this article.
                 (zerop children))
            ;; If this is "fetch-old-headered" and there is no
            ;; visible children, then we don't want this article.
-           (and (eq gnus-fetch-old-headers 'some)
+           (and (or (eq gnus-fetch-old-headers 'some)
+                    (numberp gnus-fetch-old-headers))
                 (gnus-summary-article-ancient-p number)
                 (zerop children))
            ;; If this is "fetch-old-headered" and `invisible', then
                 (gnus-summary-article-ancient-p number)
                 (zerop children))
            ;; If this is "fetch-old-headered" and `invisible', then
@@ -6643,11 +7040,9 @@ of what's specified by the `gnus-refer-thread-limit' variable."
       (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name))
     (gnus-summary-limit-include-thread id)))
 
       (gnus-message 5 "Fetching headers for %s...done" gnus-newsgroup-name))
     (gnus-summary-limit-include-thread id)))
 
-(defun gnus-summary-refer-article (message-id &optional arg)
-  "Fetch an article specified by MESSAGE-ID.
-If ARG (the prefix), fetch the article using `gnus-refer-article-method'
-or `gnus-select-method', no matter what backend the article comes from."
-  (interactive "sMessage-ID: \nP")
+(defun gnus-summary-refer-article (message-id)
+  "Fetch an article specified by MESSAGE-ID."
+  (interactive "sMessage-ID: ")
   (when (and (stringp message-id)
             (not (zerop (length message-id))))
     ;; Construct the correct Message-ID if necessary.
   (when (and (stringp message-id)
             (not (zerop (length message-id))))
     ;; Construct the correct Message-ID if necessary.
@@ -6661,7 +7056,8 @@ or `gnus-select-method', no matter what backend the article comes from."
                        (gnus-summary-article-sparse-p
                         (mail-header-number header))
                        (memq (mail-header-number header)
                        (gnus-summary-article-sparse-p
                         (mail-header-number header))
                        (memq (mail-header-number header)
-                             gnus-newsgroup-limit))))
+                             gnus-newsgroup-limit)))
+          number)
       (cond
        ;; If the article is present in the buffer we just go to it.
        ((and header
       (cond
        ;; If the article is present in the buffer we just go to it.
        ((and header
@@ -6674,22 +7070,38 @@ or `gnus-select-method', no matter what backend the article comes from."
          (when sparse
            (gnus-summary-update-article (mail-header-number header)))))
        (t
          (when sparse
            (gnus-summary-update-article (mail-header-number header)))))
        (t
-       ;; We fetch the article
-       (let ((gnus-override-method
-              (cond ((gnus-news-group-p gnus-newsgroup-name)
-                     gnus-refer-article-method)
-                    (arg
-                     (or gnus-refer-article-method gnus-select-method))
-                    (t nil)))
-             number)
-         ;; Start the special refer-article method, if necessary.
-         (when (and gnus-refer-article-method
-                    (gnus-news-group-p gnus-newsgroup-name))
-           (gnus-check-server gnus-refer-article-method))
-         ;; Fetch the header, and display the article.
-         (if (setq number (gnus-summary-insert-subject message-id))
+       ;; We fetch the article.
+       (catch 'found
+         (dolist (gnus-override-method (gnus-refer-article-methods))
+           (gnus-check-server gnus-override-method)
+           ;; Fetch the header, and display the article.
+           (when (setq number (gnus-summary-insert-subject message-id))
              (gnus-summary-select-article nil nil nil number)
              (gnus-summary-select-article nil nil nil number)
-           (gnus-message 3 "Couldn't fetch article %s" message-id))))))))
+             (throw 'found t)))
+         (gnus-message 3 "Couldn't fetch article %s" message-id)))))))
+
+(defun gnus-refer-article-methods ()
+  "Return a list of referrable methods."
+  (cond
+   ;; No method, so we default to current and native.
+   ((null gnus-refer-article-method)
+    (list gnus-current-select-method gnus-select-method))
+   ;; Current.
+   ((eq 'current gnus-refer-article-method)
+    (list gnus-current-select-method))
+   ;; List of select methods.
+   ((not (and (symbolp (car gnus-refer-article-method))
+             (assq (car gnus-refer-article-method) nnoo-definition-alist)))
+    (let (out)
+      (dolist (method gnus-refer-article-method)
+       (push (if (eq 'current method)
+                 gnus-current-select-method
+               method)
+             out))
+      (nreverse out)))
+   ;; One single select method.
+   (t
+    (list gnus-refer-article-method))))
 
 (defun gnus-summary-edit-parameters ()
   "Edit the group parameters of the current group."
 
 (defun gnus-summary-edit-parameters ()
   "Edit the group parameters of the current group."
@@ -6722,8 +7134,17 @@ to guess what the document format is."
                           (list (cons 'save-article-group ogroup))))
           (case-fold-search t)
           (buf (current-buffer))
                           (list (cons 'save-article-group ogroup))))
           (case-fold-search t)
           (buf (current-buffer))
-          dig)
+          dig to-address)
       (save-excursion
       (save-excursion
+       (set-buffer gnus-original-article-buffer)
+       ;; Have the digest group inherit the main mail address of
+       ;; the parent article.
+       (when (setq to-address (or (message-fetch-field "reply-to")
+                                  (message-fetch-field "from")))
+         (setq params (append 
+                       (list (cons 'to-address 
+                                   (funcall gnus-decode-encoded-word-function
+                                            to-address))))))
        (setq dig (nnheader-set-temp-buffer " *gnus digest buffer*"))
        (insert-buffer-substring gnus-original-article-buffer)
        ;; Remove lines that may lead nndoc to misinterpret the
        (setq dig (nnheader-set-temp-buffer " *gnus digest buffer*"))
        (insert-buffer-substring gnus-original-article-buffer)
        ;; Remove lines that may lead nndoc to misinterpret the
@@ -6732,14 +7153,17 @@ to guess what the document format is."
         (goto-char (point-min))
         (or (search-forward "\n\n" nil t) (point)))
        (goto-char (point-min))
         (goto-char (point-min))
         (or (search-forward "\n\n" nil t) (point)))
        (goto-char (point-min))
-       (delete-matching-lines "^\\(Path\\):\\|^From ")
+       (delete-matching-lines "^Path:\\|^From ")
        (widen))
       (unwind-protect
        (widen))
       (unwind-protect
-          (if (gnus-group-read-ephemeral-group
-               name `(nndoc ,name (nndoc-address ,(get-buffer dig))
-                            (nndoc-article-type
-                             ,(if force 'digest 'guess))) t)
-              ;; Make all postings to this group go to the parent group.
+          (if (let ((gnus-newsgroup-ephemeral-charset gnus-newsgroup-charset)
+                   (gnus-newsgroup-ephemeral-ignored-charsets
+                    gnus-newsgroup-ignored-charsets))
+               (gnus-group-read-ephemeral-group
+                name `(nndoc ,name (nndoc-address ,(get-buffer dig))
+                             (nndoc-article-type
+                              ,(if force 'mbox 'guess))) t))
+             ;; Make all postings to this group go to the parent group.
               (nconc (gnus-info-params (gnus-get-info name))
                      params)
             ;; Couldn't select this doc group.
               (nconc (gnus-info-params (gnus-get-info name))
                      params)
             ;; Couldn't select this doc group.
@@ -6803,12 +7227,16 @@ Obeys the standard process/prefix convention."
   "Do incremental search forward on the current article.
 If REGEXP-P (the prefix) is non-nil, do regexp isearch."
   (interactive "P")
   "Do incremental search forward on the current article.
 If REGEXP-P (the prefix) is non-nil, do regexp isearch."
   (interactive "P")
-  (gnus-summary-select-article)
-  (gnus-configure-windows 'article)
-  (gnus-eval-in-buffer-window gnus-article-buffer
-    (save-restriction
-      (widen)
-      (isearch-forward regexp-p))))
+  (let* ((gnus-inhibit-treatment t)
+        (old (gnus-summary-select-article)))
+    (gnus-configure-windows 'article)
+    (gnus-eval-in-buffer-window gnus-article-buffer
+      (save-restriction
+       (widen)
+       (when (eq 'old old)
+         (gnus-article-show-all-headers))
+       (goto-char (point-min))
+       (isearch-forward regexp-p)))))
 
 (defun gnus-summary-search-article-forward (regexp &optional backward)
   "Search for an article containing REGEXP forward.
 
 (defun gnus-summary-search-article-forward (regexp &optional backward)
   "Search for an article containing REGEXP forward.
@@ -6823,10 +7251,14 @@ If BACKWARD, search backward instead."
         current-prefix-arg))
   (if (string-equal regexp "")
       (setq regexp (or gnus-last-search-regexp ""))
         current-prefix-arg))
   (if (string-equal regexp "")
       (setq regexp (or gnus-last-search-regexp ""))
-    (setq gnus-last-search-regexp regexp))
-  (if (gnus-summary-search-article regexp backward)
-      (gnus-summary-show-thread)
-    (error "Search failed: \"%s\"" regexp)))
+    (setq gnus-last-search-regexp regexp)
+    (setq gnus-article-before-search gnus-current-article))
+  ;; Intentionally set gnus-last-article.
+  (setq gnus-last-article gnus-article-before-search)
+  (let ((gnus-last-article gnus-last-article))
+    (if (gnus-summary-search-article regexp backward)
+       (gnus-summary-show-thread)
+      (error "Search failed: \"%s\"" regexp))))
 
 (defun gnus-summary-search-article-backward (regexp)
   "Search for an article containing REGEXP backward."
 
 (defun gnus-summary-search-article-backward (regexp)
   "Search for an article containing REGEXP backward."
@@ -6838,6 +7270,84 @@ If BACKWARD, search backward instead."
                    "")))))
   (gnus-summary-search-article-forward regexp 'backward))
 
                    "")))))
   (gnus-summary-search-article-forward regexp 'backward))
 
+(eval-when-compile
+  (defmacro gnus-summary-search-article-position-point (regexp backward)
+    "Dehighlight the last matched text and goto the beginning position."
+    (` (if (and gnus-summary-search-article-matched-data
+               (let ((text (caddr gnus-summary-search-article-matched-data))
+                     (inhibit-read-only t)
+                     buffer-read-only)
+                 (delete-region
+                  (goto-char (car gnus-summary-search-article-matched-data))
+                  (cadr gnus-summary-search-article-matched-data))
+                 (insert text)
+                 (string-match (, regexp) text)))
+          (if (, backward) (beginning-of-line) (end-of-line))
+        (goto-char (if (, backward) (point-max) (point-min))))))
+
+  (defmacro gnus-summary-search-article-highlight-goto-x-face (opoint)
+    "Place point where X-Face image is displayed."
+    (if (featurep 'xemacs)
+       (` (let ((end (if (search-forward "\n\n" nil t)
+                         (goto-char (1- (point)))
+                       (point-min)))
+                extent)
+            (or (search-backward "\n\n" nil t) (goto-char (point-min)))
+            (unless (and (re-search-forward "^From:" end t)
+                         (setq extent (extent-at (point)))
+                         (extent-begin-glyph extent))
+              (goto-char (, opoint)))))
+      (` (let ((end (if (search-forward "\n\n" nil t)
+                       (goto-char (1- (point)))
+                     (point-min)))
+              (start (or (search-backward "\n\n" nil t) (point-min))))
+          (goto-char
+           (or (text-property-any start end 'x-face-image t);; x-face-e21
+               (text-property-any start end 'x-face-mule-bitmap-image t)
+               (, opoint)))))))
+
+  (defmacro gnus-summary-search-article-highlight-matched-text
+    (backward treated x-face)
+    "Highlight matched text in the function `gnus-summary-search-article'."
+    (` (let ((start (set-marker (make-marker) (match-beginning 0)))
+            (end (set-marker (make-marker) (match-end 0)))
+            (inhibit-read-only t)
+            buffer-read-only)
+        (unless treated
+          (let ((,@
+                 (let ((items (mapcar 'car gnus-treatment-function-alist)))
+                   (mapcar
+                    (lambda (item) (setq items (delq item items)))
+                    '(gnus-treat-buttonize
+                      gnus-treat-fill-article
+                      gnus-treat-fill-long-lines
+                      gnus-treat-emphasize
+                      gnus-treat-highlight-headers
+                      gnus-treat-highlight-citation
+                      gnus-treat-highlight-signature
+                      gnus-treat-overstrike
+                      gnus-treat-display-xface
+                      gnus-treat-buttonize-head
+                      gnus-treat-decode-article-as-default-mime-charset))
+                   (static-if (featurep 'xemacs)
+                       items
+                     (cons '(x-face-mule-delete-x-face-field
+                             (quote never))
+                           items))))
+                (gnus-treat-display-xface
+                 (when (, x-face) gnus-treat-display-xface)))
+            (gnus-article-prepare-mime-display)))
+        (goto-char (if (, backward) start end))
+        (when (, x-face)
+          (gnus-summary-search-article-highlight-goto-x-face (point)))
+        (setq gnus-summary-search-article-matched-data
+              (list start end (buffer-substring start end)))
+        (unless (eq start end);; matched text has been deleted. :-<
+          (put-text-property start end 'face
+                             (or (find-face 'isearch)
+                                 'secondary-selection))))))
+  )
+
 (defun gnus-summary-search-article (regexp &optional backward)
   "Search for an article containing REGEXP.
 Optional argument BACKWARD means do search for backward.
 (defun gnus-summary-search-article (regexp &optional backward)
   "Search for an article containing REGEXP.
 Optional argument BACKWARD means do search for backward.
@@ -6847,19 +7357,45 @@ Optional argument BACKWARD means do search for backward.
   (require 'gnus-async)
   (require 'gnus-art)
   (let ((gnus-select-article-hook nil) ;Disable hook.
   (require 'gnus-async)
   (require 'gnus-art)
   (let ((gnus-select-article-hook nil) ;Disable hook.
+       (gnus-article-display-hook nil)
+       (gnus-article-prepare-hook nil)
        (gnus-mark-article-hook nil)    ;Inhibit marking as read.
        (gnus-use-article-prefetch nil)
        (gnus-xmas-force-redisplay nil) ;Inhibit XEmacs redisplay.
        (gnus-use-trees nil)            ;Inhibit updating tree buffer.
        (sum (current-buffer))
        (gnus-mark-article-hook nil)    ;Inhibit marking as read.
        (gnus-use-article-prefetch nil)
        (gnus-xmas-force-redisplay nil) ;Inhibit XEmacs redisplay.
        (gnus-use-trees nil)            ;Inhibit updating tree buffer.
        (sum (current-buffer))
-       (gnus-display-mime-function nil)
        (found nil)
        (found nil)
-       point)
+       point treated)
     (gnus-save-hidden-threads
     (gnus-save-hidden-threads
-      (gnus-summary-select-article)
+      (static-if (featurep 'xemacs)
+         (let ((gnus-inhibit-treatment t))
+           (setq treated (eq 'old (gnus-summary-select-article)))
+           (when (and treated
+                      (not (and (gnus-buffer-live-p gnus-article-buffer)
+                                (window-live-p (get-buffer-window
+                                                gnus-article-buffer t)))))
+             (gnus-summary-select-article nil t)
+             (setq treated nil)))
+       (let ((gnus-inhibit-treatment t)
+             (x-face-mule-delete-x-face-field 'never))
+         (setq treated (eq 'old (gnus-summary-select-article)))
+         (when (and treated
+                    (not
+                     (and (gnus-buffer-live-p gnus-article-buffer)
+                          (window-live-p (get-buffer-window
+                                          gnus-article-buffer t))
+                          (or (not (string-match "^\\^X-Face:" regexp))
+                              (with-current-buffer gnus-article-buffer
+                                gnus-summary-search-article-matched-data)))))
+           (gnus-summary-select-article nil t)
+           (setq treated nil))))
       (set-buffer gnus-article-buffer)
       (set-buffer gnus-article-buffer)
-      (when backward
-       (forward-line -1))
+      (widen)
+      (if treated
+         (progn
+           (gnus-article-show-all-headers)
+           (gnus-summary-search-article-position-point regexp backward))
+       (goto-char (if backward (point-max) (point-min))))
       (while (not found)
        (gnus-message 7 "Searching article: %d..." (cdr gnus-article-current))
        (if (if backward
       (while (not found)
        (gnus-message 7 "Searching article: %d..." (cdr gnus-article-current))
        (if (if backward
@@ -6867,12 +7403,16 @@ Optional argument BACKWARD means do search for backward.
              (re-search-forward regexp nil t))
            ;; We found the regexp.
            (progn
              (re-search-forward regexp nil t))
            ;; We found the regexp.
            (progn
+             (gnus-summary-search-article-highlight-matched-text
+              backward treated (string-match "^\\^X-Face:" regexp))
              (setq found 'found)
              (setq found 'found)
-             (beginning-of-line)
+             (forward-line
+              (/ (- 2 (window-height
+                       (get-buffer-window gnus-article-buffer t)))
+                 2))
              (set-window-start
               (get-buffer-window (current-buffer))
               (point))
              (set-window-start
               (get-buffer-window (current-buffer))
               (point))
-             (forward-line 1)
              (set-buffer sum)
              (setq point (point)))
          ;; We didn't find it, so we go to the next article.
              (set-buffer sum)
              (setq point (point)))
          ;; We didn't find it, so we go to the next article.
@@ -6887,7 +7427,9 @@ Optional argument BACKWARD means do search for backward.
              (unless (gnus-summary-article-sparse-p
                       (gnus-summary-article-number))
                (setq found nil)
              (unless (gnus-summary-article-sparse-p
                       (gnus-summary-article-number))
                (setq found nil)
-               (gnus-summary-select-article)
+               (let ((gnus-inhibit-treatment t))
+                 (gnus-summary-select-article))
+               (setq treated nil)
                (set-buffer gnus-article-buffer)
                (widen)
                (goto-char (if backward (point-max) (point-min))))))))
                (set-buffer gnus-article-buffer)
                (widen)
                (goto-char (if backward (point-max) (point-min))))))))
@@ -7024,29 +7566,54 @@ to save in."
 
 (defun gnus-summary-show-article (&optional arg)
   "Force re-fetching of the current article.
 
 (defun gnus-summary-show-article (&optional arg)
   "Force re-fetching of the current article.
-If ARG (the prefix) is non-nil, show the raw article without any
-article massaging functions being run."
+If ARG (the prefix) is a number, show the article with the charset
+defined in `gnus-summary-show-article-charset-alist', or the charset
+inputed.
+If ARG (the prefix) is non-nil and not a number, show the raw article
+without any article massaging functions being run."
   (interactive "P")
   (interactive "P")
-  (if (not arg)
-      ;; Select the article the normal way.
+  (cond
+   ((numberp arg)
+    (let ((gnus-newsgroup-charset
+          (or (cdr (assq arg gnus-summary-show-article-charset-alist))
+              (read-coding-system "Charset: ")))
+         (gnus-newsgroup-ignored-charsets 'gnus-all))
       (gnus-summary-select-article nil 'force)
       (gnus-summary-select-article nil 'force)
+      (let ((deps gnus-newsgroup-dependencies)
+           head header)
+       (save-excursion
+         (set-buffer gnus-original-article-buffer)
+         (save-restriction
+           (message-narrow-to-head)
+           (setq head (buffer-string)))
+         (with-temp-buffer
+           (insert (format "211 %d Article retrieved.\n"
+                           (cdr gnus-article-current)))
+           (insert head)
+           (insert ".\n")
+           (let ((nntp-server-buffer (current-buffer)))
+             (setq header (car (gnus-get-newsgroup-headers deps t))))))
+       (gnus-data-set-header
+        (gnus-data-find (cdr gnus-article-current))
+        header)
+       (gnus-summary-update-article-line
+        (cdr gnus-article-current) header))))
+   ((not arg)
+    ;; Select the article the normal way.
+    (gnus-summary-select-article nil 'force))
+   (t
     ;; We have to require this here to make sure that the following
     ;; dynamic binding isn't shadowed by autoloading.
     (require 'gnus-async)
     (require 'gnus-art)
     ;; Bind the article treatment functions to nil.
     (let ((gnus-have-all-headers t)
     ;; We have to require this here to make sure that the following
     ;; dynamic binding isn't shadowed by autoloading.
     (require 'gnus-async)
     (require 'gnus-art)
     ;; Bind the article treatment functions to nil.
     (let ((gnus-have-all-headers t)
+         gnus-article-display-hook
          gnus-article-prepare-hook
          gnus-article-decode-hook
          gnus-article-prepare-hook
          gnus-article-decode-hook
-         gnus-display-mime-function
          gnus-break-pages
          gnus-break-pages
-         gnus-visual)
-      ;; Destroy any MIME parts.
-      (when (gnus-buffer-live-p gnus-article-buffer)
-       (save-excursion
-         (set-buffer gnus-article-buffer)
-         (mm-destroy-parts gnus-article-mime-handles)))
-      (gnus-summary-select-article nil 'force)))
+         gnus-show-mime)
+      (gnus-summary-select-article nil 'force))))
   (gnus-summary-goto-subject gnus-current-article)
   (gnus-summary-position-point))
 
   (gnus-summary-goto-subject gnus-current-article)
   (gnus-summary-position-point))
 
@@ -7074,9 +7641,12 @@ If ARG is a negative number, hide the unwanted header lines."
       (let* ((buffer-read-only nil)
             (inhibit-point-motion-hooks t)
             hidden e)
       (let* ((buffer-read-only nil)
             (inhibit-point-motion-hooks t)
             hidden e)
-       (save-restriction 
-         (article-narrow-to-head)
-         (setq hidden (gnus-article-hidden-text-p 'headers)))
+       (setq hidden
+             (if (numberp arg)
+                 (>= arg 0)
+               (save-restriction
+                 (article-narrow-to-head)
+                 (gnus-article-hidden-text-p 'headers))))
        (goto-char (point-min))
        (when (search-forward "\n\n" nil t)
          (delete-region (point-min) (1- (point))))
        (goto-char (point-min))
        (when (search-forward "\n\n" nil t)
          (delete-region (point-min) (1- (point))))
@@ -7089,18 +7659,30 @@ If ARG is a negative number, hide the unwanted header lines."
        (save-restriction
          (narrow-to-region (point-min) (point))
          (article-decode-encoded-words)
        (save-restriction
          (narrow-to-region (point-min) (point))
          (article-decode-encoded-words)
-         (if (or hidden
-                 (and (numberp arg) (< arg 0)))
+         (if  hidden
              (let ((gnus-treat-hide-headers nil)
                    (gnus-treat-hide-boring-headers nil))
              (let ((gnus-treat-hide-headers nil)
                    (gnus-treat-hide-boring-headers nil))
+               (setq gnus-article-wash-types
+                     (delq 'headers gnus-article-wash-types))
                (gnus-treat-article 'head))
                (gnus-treat-article 'head))
-           (gnus-treat-article 'head)))))))
+           (gnus-treat-article 'head)))
+       (gnus-set-mode-line 'article)))))
 
 (defun gnus-summary-show-all-headers ()
   "Make all header lines visible."
   (interactive)
   (gnus-article-show-all-headers))
 
 
 (defun gnus-summary-show-all-headers ()
   "Make all header lines visible."
   (interactive)
   (gnus-article-show-all-headers))
 
+(defun gnus-summary-toggle-mime (&optional arg)
+  "Toggle MIME processing.
+If ARG is a positive number, turn MIME processing on."
+  (interactive "P")
+  (setq gnus-show-mime
+       (if (null arg)
+           (not gnus-show-mime)
+         (> (prefix-numeric-value arg) 0)))
+  (gnus-summary-select-article t 'force))
+
 (defun gnus-summary-caesar-message (&optional arg)
   "Caesar rotate the current article by 13.
 The numerical prefix specifies how many places to rotate each letter
 (defun gnus-summary-caesar-message (&optional arg)
   "Caesar rotate the current article by 13.
 The numerical prefix specifies how many places to rotate each letter
@@ -7141,7 +7723,9 @@ re-spool using this method.
 
 For this function to work, both the current newsgroup and the
 newsgroup that you want to move to have to support the `request-move'
 
 For this function to work, both the current newsgroup and the
 newsgroup that you want to move to have to support the `request-move'
-and `request-accept' functions."
+and `request-accept' functions.
+
+ACTION can be either `move' (the default), `crosspost' or `copy'."
   (interactive "P")
   (unless action
     (setq action 'move))
   (interactive "P")
   (unless action
     (setq action 'move))
@@ -7159,12 +7743,18 @@ and `request-accept' functions."
                    'request-replace-article gnus-newsgroup-name)))
         (error "The current group does not support article editing")))
   (let ((articles (gnus-summary-work-articles n))
                    'request-replace-article gnus-newsgroup-name)))
         (error "The current group does not support article editing")))
   (let ((articles (gnus-summary-work-articles n))
-       (prefix (gnus-group-real-prefix gnus-newsgroup-name))
+       (prefix (if (gnus-check-backend-function
+                   'request-move-article gnus-newsgroup-name)
+                   (gnus-group-real-prefix gnus-newsgroup-name)
+                 ""))
        (names '((move "Move" "Moving")
                 (copy "Copy" "Copying")
                 (crosspost "Crosspost" "Crossposting")))
        (copy-buf (save-excursion
                    (nnheader-set-temp-buffer " *copy article*")))
        (names '((move "Move" "Moving")
                 (copy "Copy" "Copying")
                 (crosspost "Crosspost" "Crossposting")))
        (copy-buf (save-excursion
                    (nnheader-set-temp-buffer " *copy article*")))
+       (default-marks gnus-article-mark-lists)
+       (no-expire-marks (delete '(expirable . expire)
+                                (copy-sequence gnus-article-mark-lists)))
        art-group to-method new-xref article to-groups)
     (unless (assq action names)
       (error "Unknown action %s" action))
        art-group to-method new-xref article to-groups)
     (unless (assq action names)
       (error "Unknown action %s" action))
@@ -7178,7 +7768,8 @@ and `request-accept' functions."
             articles prefix))
       (set (intern (format "gnus-current-%s-group" action)) to-newsgroup))
     (setq to-method (or select-method
             articles prefix))
       (set (intern (format "gnus-current-%s-group" action)) to-newsgroup))
     (setq to-method (or select-method
-                       (gnus-group-name-to-method to-newsgroup)))
+                       (gnus-server-to-method
+                        (gnus-group-method to-newsgroup))))
     ;; Check the method we are to move this article to...
     (unless (gnus-check-backend-function
             'request-accept-article (car to-method))
     ;; Check the method we are to move this article to...
     (unless (gnus-check-backend-function
             'request-accept-article (car to-method))
@@ -7204,7 +7795,7 @@ and `request-accept' functions."
                  gnus-newsgroup-name)) ; Server
          (list 'gnus-request-accept-article
                to-newsgroup (list 'quote select-method)
                  gnus-newsgroup-name)) ; Server
          (list 'gnus-request-accept-article
                to-newsgroup (list 'quote select-method)
-               (not articles) t)               ; Accept form
+               (not articles) t)       ; Accept form
          (not articles)))              ; Only save nov last time
        ;; Copy the article.
        ((eq action 'copy)
          (not articles)))              ; Only save nov last time
        ;; Copy the article.
        ((eq action 'copy)
@@ -7245,19 +7836,21 @@ and `request-accept' functions."
               art-group))))))
       (cond
        ((not art-group)
               art-group))))))
       (cond
        ((not art-group)
-       (gnus-message 1 "Couldn't %s article %s"
-                     (cadr (assq action names)) article))
-       ((and (eq art-group 'junk)
-            (eq action 'move))
-       (gnus-summary-mark-article article gnus-canceled-mark)
-       (gnus-message 4 "Deleted article %s" article))
+       (gnus-message 1 "Couldn't %s article %s: %s"
+                     (cadr (assq action names)) article
+                     (nnheader-get-report (car to-method))))
+       ((eq art-group 'junk)
+       (when (eq action 'move)
+         (gnus-summary-mark-article article gnus-canceled-mark)
+         (gnus-message 4 "Deleted article %s" article)))
        (t
        (let* ((pto-group (gnus-group-prefixed-name
                           (car art-group) to-method))
               (entry
                (gnus-gethash pto-group gnus-newsrc-hashtb))
               (info (nth 2 entry))
        (t
        (let* ((pto-group (gnus-group-prefixed-name
                           (car art-group) to-method))
               (entry
                (gnus-gethash pto-group gnus-newsrc-hashtb))
               (info (nth 2 entry))
-              (to-group (gnus-info-group info)))
+               (to-group (gnus-info-group info))
+              to-marks)
          ;; Update the group that has been moved to.
          (when (and info
                     (memq action '(move copy)))
          ;; Update the group that has been moved to.
          (when (and info
                     (memq action '(move copy)))
@@ -7265,45 +7858,60 @@ and `request-accept' functions."
              (push to-group to-groups))
 
            (unless (memq article gnus-newsgroup-unreads)
              (push to-group to-groups))
 
            (unless (memq article gnus-newsgroup-unreads)
+             (push 'read to-marks)
              (gnus-info-set-read
               info (gnus-add-to-range (gnus-info-read info)
                                       (list (cdr art-group)))))
 
              (gnus-info-set-read
               info (gnus-add-to-range (gnus-info-read info)
                                       (list (cdr art-group)))))
 
-           ;; Copy any marks over to the new group.
-           (let ((marks gnus-article-mark-lists)
+           ;; See whether the article is to be put in the cache.
+           (let ((marks (if (gnus-group-auto-expirable-p to-group)
+                            default-marks
+                          no-expire-marks))
                  (to-article (cdr art-group)))
 
                  (to-article (cdr art-group)))
 
-             ;; See whether the article is to be put in the cache.
+             ;; Enter the article into the cache in the new group,
+             ;; if that is required.
              (when gnus-use-cache
                (gnus-cache-possibly-enter-article
                 to-group to-article
              (when gnus-use-cache
                (gnus-cache-possibly-enter-article
                 to-group to-article
+                (let ((header (copy-sequence
+                               (gnus-summary-article-header article))))
+                  (mail-header-set-number header to-article)
+                  header)
                 (memq article gnus-newsgroup-marked)
                 (memq article gnus-newsgroup-dormant)
                 (memq article gnus-newsgroup-unreads)))
 
                 (memq article gnus-newsgroup-marked)
                 (memq article gnus-newsgroup-dormant)
                 (memq article gnus-newsgroup-unreads)))
 
-             (when (and (equal to-group gnus-newsgroup-name)
-                        (not (memq article gnus-newsgroup-unreads)))
-               ;; Mark this article as read in this group.
-               (push (cons to-article gnus-read-mark) gnus-newsgroup-reads)
-               (setcdr (gnus-active to-group) to-article)
-               (setcdr gnus-newsgroup-active to-article))
-
-             (while marks
-               (when (memq article (symbol-value
-                                    (intern (format "gnus-newsgroup-%s"
-                                                    (caar marks)))))
-                 ;; If the other group is the same as this group,
-                 ;; then we have to add the mark to the list.
-                 (when (equal to-group gnus-newsgroup-name)
-                   (set (intern (format "gnus-newsgroup-%s" (caar marks)))
-                        (cons to-article
-                              (symbol-value
-                               (intern (format "gnus-newsgroup-%s"
-                                               (caar marks)))))))
-                 ;; Copy the marks to other group.
-                 (gnus-add-marked-articles
-                  to-group (cdar marks) (list to-article) info))
-               (setq marks (cdr marks)))
+             (when gnus-preserve-marks
+               ;; Copy any marks over to the new group.
+               (when (and (equal to-group gnus-newsgroup-name)
+                          (not (memq article gnus-newsgroup-unreads)))
+                 ;; Mark this article as read in this group.
+                 (push (cons to-article gnus-read-mark) gnus-newsgroup-reads)
+                 (setcdr (gnus-active to-group) to-article)
+                 (setcdr gnus-newsgroup-active to-article))
+
+               (while marks
+                 (when (memq article (symbol-value
+                                      (intern (format "gnus-newsgroup-%s"
+                                                      (caar marks)))))
+                   (push (cdar marks) to-marks)
+                   ;; If the other group is the same as this group,
+                   ;; then we have to add the mark to the list.
+                   (when (equal to-group gnus-newsgroup-name)
+                     (set (intern (format "gnus-newsgroup-%s" (caar marks)))
+                          (cons to-article
+                                (symbol-value
+                                 (intern (format "gnus-newsgroup-%s"
+                                                 (caar marks)))))))
+                   ;; Copy the marks to other group.
+                   (gnus-add-marked-articles
+                    to-group (cdar marks) (list to-article) info))
+                 (setq marks (cdr marks)))
+
+               (gnus-request-set-mark to-group (list (list (list to-article)
+                                                           'set
+                                                           to-marks))))
 
              (gnus-dribble-enter
               (concat "(gnus-group-set-info '"
 
              (gnus-dribble-enter
               (concat "(gnus-group-set-info '"
@@ -7417,7 +8025,7 @@ latter case, they will be copied into the relevant groups."
     (save-excursion
       (set-buffer (gnus-get-buffer-create " *import file*"))
       (erase-buffer)
     (save-excursion
       (set-buffer (gnus-get-buffer-create " *import file*"))
       (erase-buffer)
-      (insert-file-contents file)
+      (nnheader-insert-file-contents file)
       (goto-char (point-min))
       (unless (nnheader-article-p)
        ;; This doesn't look like an article, so we fudge some headers.
       (goto-char (point-min))
       (unless (nnheader-article-p)
        ;; This doesn't look like an article, so we fudge some headers.
@@ -7434,12 +8042,11 @@ latter case, they will be copied into the relevant groups."
       (kill-buffer (current-buffer)))))
 
 (defun gnus-summary-article-posted-p ()
       (kill-buffer (current-buffer)))))
 
 (defun gnus-summary-article-posted-p ()
-  "Say whether the current (mail) article is available from `gnus-select-method' as well.
+  "Say whether the current (mail) article is available from news as well.
 This will be the case if the article has both been mailed and posted."
   (interactive)
   (let ((id (mail-header-references (gnus-summary-article-header)))
 This will be the case if the article has both been mailed and posted."
   (interactive)
   (let ((id (mail-header-references (gnus-summary-article-header)))
-       (gnus-override-method
-        (or gnus-refer-article-method gnus-select-method)))
+       (gnus-override-method (car (gnus-refer-article-methods))))
     (if (gnus-request-head id "")
        (gnus-message 2 "The current message was found on %s"
                      gnus-override-method)
     (if (gnus-request-head id "")
        (gnus-message 2 "The current message was found on %s"
                      gnus-override-method)
@@ -7467,6 +8074,9 @@ This will be the case if the article has both been mailed and posted."
           (expiry-wait (if now 'immediate
                          (gnus-group-find-parameter
                           gnus-newsgroup-name 'expiry-wait)))
           (expiry-wait (if now 'immediate
                          (gnus-group-find-parameter
                           gnus-newsgroup-name 'expiry-wait)))
+          (nnmail-expiry-target
+           (or (gnus-group-find-parameter gnus-newsgroup-name 'expiry-target)
+               nnmail-expiry-target))
           es)
       (when expirable
        ;; There are expirable articles in this group, so we run them
           es)
       (when expirable
        ;; There are expirable articles in this group, so we run them
@@ -7482,19 +8092,19 @@ This will be the case if the article has both been mailed and posted."
                (setq es (gnus-request-expire-articles
                          expirable gnus-newsgroup-name)))
            (setq es (gnus-request-expire-articles
                (setq es (gnus-request-expire-articles
                          expirable gnus-newsgroup-name)))
            (setq es (gnus-request-expire-articles
-                     expirable gnus-newsgroup-name))))
-       (unless total
-         (setq gnus-newsgroup-expirable es))
-       ;; We go through the old list of expirable, and mark all
-       ;; really expired articles as nonexistent.
-       (unless (eq es expirable)       ;If nothing was expired, we don't mark.
-         (let ((gnus-use-cache nil))
-           (while expirable
-             (unless (memq (car expirable) es)
-               (when (gnus-data-find (car expirable))
-                 (gnus-summary-mark-article
-                  (car expirable) gnus-canceled-mark)))
-             (setq expirable (cdr expirable)))))
+                     expirable gnus-newsgroup-name)))
+         (unless total
+           (setq gnus-newsgroup-expirable es))
+         ;; We go through the old list of expirable, and mark all
+         ;; really expired articles as nonexistent.
+         (unless (eq es expirable)     ;If nothing was expired, we don't mark.
+           (let ((gnus-use-cache nil))
+             (while expirable
+               (unless (memq (car expirable) es)
+                 (when (gnus-data-find (car expirable))
+                   (gnus-summary-mark-article
+                    (car expirable) gnus-canceled-mark)))
+               (setq expirable (cdr expirable))))))
        (gnus-message 6 "Expiring articles...done")))))
 
 (defun gnus-summary-expire-articles-now ()
        (gnus-message 6 "Expiring articles...done")))))
 
 (defun gnus-summary-expire-articles-now ()
@@ -7521,6 +8131,8 @@ delete these instead."
   (unless (gnus-check-backend-function 'request-expire-articles
                                       gnus-newsgroup-name)
     (error "The current newsgroup does not support article deletion"))
   (unless (gnus-check-backend-function 'request-expire-articles
                                       gnus-newsgroup-name)
     (error "The current newsgroup does not support article deletion"))
+  (unless (gnus-check-server (gnus-find-method-for-group gnus-newsgroup-name))
+    (error "Couldn't open server"))
   ;; Compute the list of articles to delete.
   (let ((articles (sort (copy-sequence (gnus-summary-work-articles n)) '<))
        not-deleted)
   ;; Compute the list of articles to delete.
   (let ((articles (sort (copy-sequence (gnus-summary-work-articles n)) '<))
        not-deleted)
@@ -7553,19 +8165,23 @@ This will have permanent effect only in mail groups.
 If FORCE is non-nil, allow editing of articles even in read-only
 groups."
   (interactive "P")
 If FORCE is non-nil, allow editing of articles even in read-only
 groups."
   (interactive "P")
-  (let ((mail-parse-charset gnus-newsgroup-charset))
-    (save-excursion
-      (set-buffer gnus-summary-buffer)
+  (save-excursion
+    (set-buffer gnus-summary-buffer)
+    (let ((mail-parse-charset gnus-newsgroup-charset)
+         (mail-parse-ignored-charsets gnus-newsgroup-ignored-charsets))
       (gnus-set-global-variables)
       (when (and (not force)
                 (gnus-group-read-only-p))
        (error "The current newsgroup does not support article editing"))
       (gnus-summary-show-article t)
       (gnus-article-edit-article
       (gnus-set-global-variables)
       (when (and (not force)
                 (gnus-group-read-only-p))
        (error "The current newsgroup does not support article editing"))
       (gnus-summary-show-article t)
       (gnus-article-edit-article
-       'mime-to-mml
+       'ignore
        `(lambda (no-highlight)
        `(lambda (no-highlight)
-         (let ((mail-parse-charset ',gnus-newsgroup-charset))
-           (mml-to-mime)
+         (let ((mail-parse-charset ',gnus-newsgroup-charset)
+               (message-options message-options)
+               (message-options-set-recipient)
+               (mail-parse-ignored-charsets
+                ',gnus-newsgroup-ignored-charsets))
            (gnus-summary-edit-article-done
             ,(or (mail-header-references gnus-current-headers) "")
             ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))))))
            (gnus-summary-edit-article-done
             ,(or (mail-header-references gnus-current-headers) "")
             ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))))))
@@ -7576,14 +8192,35 @@ groups."
                                                 no-highlight)
   "Make edits to the current article permanent."
   (interactive)
                                                 no-highlight)
   "Make edits to the current article permanent."
   (interactive)
+  (save-excursion
+    ;; The buffer restriction contains the entire article if it exists.
+    (when (article-goto-body)
+      (let ((lines (count-lines (point) (point-max)))
+           (length (- (point-max) (point)))
+           (case-fold-search t)
+           (body (copy-marker (point))))
+       (goto-char (point-min))
+       (when (re-search-forward "^content-length:[ \t]\\([0-9]+\\)" body t)
+         (delete-region (match-beginning 1) (match-end 1))
+         (insert (number-to-string length)))
+       (goto-char (point-min))
+       (when (re-search-forward
+              "^x-content-length:[ \t]\\([0-9]+\\)" body t)
+         (delete-region (match-beginning 1) (match-end 1))
+         (insert (number-to-string length)))
+       (goto-char (point-min))
+       (when (re-search-forward "^lines:[ \t]\\([0-9]+\\)" body t)
+         (delete-region (match-beginning 1) (match-end 1))
+         (insert (number-to-string lines))))))
   ;; Replace the article.
   (let ((buf (current-buffer)))
     (with-temp-buffer
       (insert-buffer-substring buf)
   ;; Replace the article.
   (let ((buf (current-buffer)))
     (with-temp-buffer
       (insert-buffer-substring buf)
+      
       (if (and (not read-only)
               (not (gnus-request-replace-article
                     (cdr gnus-article-current) (car gnus-article-current)
       (if (and (not read-only)
               (not (gnus-request-replace-article
                     (cdr gnus-article-current) (car gnus-article-current)
-                    (current-buffer) t)))
+                    (current-buffer) t)))
          (error "Couldn't replace article")
        ;; Update the summary buffer.
        (if (and references
          (error "Couldn't replace article")
        ;; Update the summary buffer.
        (if (and references
@@ -7774,6 +8411,20 @@ the actual number of articles unmarked is returned."
       (gnus-summary-remove-process-mark (car gnus-newsgroup-processable))))
   (gnus-summary-position-point))
 
       (gnus-summary-remove-process-mark (car gnus-newsgroup-processable))))
   (gnus-summary-position-point))
 
+(defun gnus-summary-add-mark (article type)
+  "Mark ARTICLE with a mark of TYPE."
+  (let ((vtype (car (assq type gnus-article-mark-lists)))
+       var)
+    (if (not vtype)
+       (error "No such mark type: %s" type)
+      (setq var (intern (format "gnus-newsgroup-%s" type)))
+      (set var (cons article (symbol-value var)))
+      (if (memq type '(processable cached replied saved))
+         (gnus-summary-update-secondary-mark article)
+       ;;; !!! This is bobus.  We should find out what primary
+       ;;; !!! mark we want to set.
+       (gnus-summary-update-mark gnus-del-mark 'unread)))))
+       
 (defun gnus-summary-mark-as-expirable (n)
   "Mark N articles forward as expirable.
 If N is negative, mark backward instead.  The difference between N and
 (defun gnus-summary-mark-as-expirable (n)
   "Mark N articles forward as expirable.
 If N is negative, mark backward instead.  The difference between N and
@@ -7865,7 +8516,8 @@ the actual number of articles marked is returned."
   "Mark N articles as read forwards.
 If N is negative, mark backwards instead.  Mark with MARK, ?r by default.
 The difference between N and the actual number of articles marked is
   "Mark N articles as read forwards.
 If N is negative, mark backwards instead.  Mark with MARK, ?r by default.
 The difference between N and the actual number of articles marked is
-returned."
+returned.
+Iff NO-EXPIRE, auto-expiry will be inhibited."
   (interactive "p")
   (gnus-summary-show-thread)
   (let ((backward (< n 0))
   (interactive "p")
   (gnus-summary-show-thread)
   (let ((backward (< n 0))
@@ -7944,6 +8596,7 @@ returned."
             (save-excursion
               (gnus-cache-possibly-enter-article
                gnus-newsgroup-name article
             (save-excursion
               (gnus-cache-possibly-enter-article
                gnus-newsgroup-name article
+               (gnus-summary-article-header article)
                (= mark gnus-ticked-mark)
                (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
 
                (= mark gnus-ticked-mark)
                (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
 
@@ -7957,7 +8610,8 @@ Four MARK strings are reserved: `? ' (unread), `?!' (ticked),
 `??' (dormant) and `?E' (expirable).
 If MARK is nil, then the default character `?r' is used.
 If ARTICLE is nil, then the article on the current line will be
 `??' (dormant) and `?E' (expirable).
 If MARK is nil, then the default character `?r' is used.
 If ARTICLE is nil, then the article on the current line will be
-marked."
+marked.
+Iff NO-EXPIRE, auto-expiry will be inhibited."
   ;; The mark might be a string.
   (when (stringp mark)
     (setq mark (aref mark 0)))
   ;; The mark might be a string.
   (when (stringp mark)
     (setq mark (aref mark 0)))
@@ -7989,6 +8643,7 @@ marked."
             (save-excursion
               (gnus-cache-possibly-enter-article
                gnus-newsgroup-name article
             (save-excursion
               (gnus-cache-possibly-enter-article
                gnus-newsgroup-name article
+               (gnus-summary-article-header article)
                (= mark gnus-ticked-mark)
                (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
 
                (= mark gnus-ticked-mark)
                (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
 
@@ -8010,7 +8665,7 @@ marked."
          gnus-replied-mark)
         ((memq article gnus-newsgroup-saved)
          gnus-saved-mark)
          gnus-replied-mark)
         ((memq article gnus-newsgroup-saved)
          gnus-saved-mark)
-        (t gnus-unread-mark))
+        (t gnus-no-mark))
    'replied)
   (when (gnus-visual-p 'summary-highlight 'highlight)
     (gnus-run-hooks 'gnus-summary-update-hook))
    'replied)
   (when (gnus-visual-p 'summary-highlight 'highlight)
     (gnus-run-hooks 'gnus-summary-update-hook))
@@ -8154,6 +8809,11 @@ The difference between N and the number of marks cleared is returned."
              (gnus-read-mark-p mark))
       (gnus-summary-mark-article gnus-current-article gnus-read-mark))))
 
              (gnus-read-mark-p mark))
       (gnus-summary-mark-article gnus-current-article gnus-read-mark))))
 
+(defun gnus-summary-mark-unread-as-ticked ()
+   "Intended to be used by `gnus-summary-mark-article-hook'."
+  (when (memq gnus-current-article gnus-newsgroup-unreads)
+    (gnus-summary-mark-article gnus-current-article gnus-ticked-mark)))
+
 (defun gnus-summary-mark-region-as-read (point mark all)
   "Mark all unread articles between point and mark as read.
 If given a prefix, mark all articles between point and mark as read,
 (defun gnus-summary-mark-region-as-read (point mark all)
   "Mark all unread articles between point and mark as read.
 If given a prefix, mark all articles between point and mark as read,
@@ -8227,7 +8887,7 @@ even ticked and dormant ones."
     (let ((scored gnus-newsgroup-scored)
          headers h)
       (while scored
     (let ((scored gnus-newsgroup-scored)
          headers h)
       (while scored
-       (unless (gnus-summary-goto-subject (caar scored))
+       (unless (gnus-number-to-header (caar scored))
          (and (setq h (gnus-summary-article-header (caar scored)))
               (< (cdar scored) gnus-summary-expunge-below)
               (push h headers)))
          (and (setq h (gnus-summary-article-header (caar scored)))
               (< (cdar scored) gnus-summary-expunge-below)
               (push h headers)))
@@ -8302,7 +8962,7 @@ If ALL is non-nil, also mark ticked and dormant articles as read."
   (gnus-summary-catchup t quietly))
 
 (defun gnus-summary-catchup-and-exit (&optional all quietly)
   (gnus-summary-catchup t quietly))
 
 (defun gnus-summary-catchup-and-exit (&optional all quietly)
-  "Mark all articles not marked as unread in this newsgroup as read, then exit.
+  "Mark all unread articles in this group as read, then exit.
 If prefix argument ALL is non-nil, all articles are marked as read."
   (interactive "P")
   (when (gnus-summary-catchup all quietly nil 'fast)
 If prefix argument ALL is non-nil, all articles are marked as read."
   (interactive "P")
   (when (gnus-summary-catchup all quietly nil 'fast)
@@ -8317,7 +8977,6 @@ If prefix argument ALL is non-nil, all articles are marked as read."
   (interactive "P")
   (gnus-summary-catchup-and-exit t quietly))
 
   (interactive "P")
   (gnus-summary-catchup-and-exit t quietly))
 
-;; Suggested by "Arne Eofsson" <arne@hodgkin.mbi.ucla.edu>.
 (defun gnus-summary-catchup-and-goto-next-group (&optional all)
   "Mark all articles in this group as read and select the next group.
 If given a prefix, mark all articles, unread as well as ticked, as
 (defun gnus-summary-catchup-and-goto-next-group (&optional all)
   "Mark all articles in this group as read and select the next group.
 If given a prefix, mark all articles, unread as well as ticked, as
@@ -8325,7 +8984,38 @@ read."
   (interactive "P")
   (save-excursion
     (gnus-summary-catchup all))
   (interactive "P")
   (save-excursion
     (gnus-summary-catchup all))
-  (gnus-summary-next-article t nil nil t))
+  (gnus-summary-next-group))
+
+;;;
+;;; with article
+;;;
+
+(defmacro gnus-with-article (article &rest forms)
+  "Select ARTICLE and perform FORMS in the original article buffer.
+Then replace the article with the result."
+  `(progn
+     ;; We don't want the article to be marked as read.
+     (let (gnus-mark-article-hook)
+       (gnus-summary-select-article t t nil ,article))
+     (set-buffer gnus-original-article-buffer)
+     ,@forms
+     (if (not (gnus-check-backend-function
+              'request-replace-article (car gnus-article-current)))
+        (gnus-message 5 "Read-only group; not replacing")
+       (unless (gnus-request-replace-article
+               ,article (car gnus-article-current)
+               (current-buffer) t)
+        (error "Couldn't replace article")))
+     ;; The cache and backlog have to be flushed somewhat.
+     (when gnus-keep-backlog
+       (gnus-backlog-remove-article
+       (car gnus-article-current) (cdr gnus-article-current)))
+     (when gnus-use-cache
+       (gnus-cache-update-article
+       (car gnus-article-current) (cdr gnus-article-current)))))
+
+(put 'gnus-with-article 'lisp-indent-function 1)
+(put 'gnus-with-article 'edebug-form-spec '(form body))
 
 ;; Thread-based commands.
 
 
 ;; Thread-based commands.
 
@@ -8405,14 +9095,16 @@ is non-nil or the Subject: of both articles are the same."
        (unless (and message-id (not (equal message-id "")))
          (error "No message-id in desired parent"))
        (gnus-with-article current-article
        (unless (and message-id (not (equal message-id "")))
          (error "No message-id in desired parent"))
        (gnus-with-article current-article
-         (goto-char (point-min))
-         (if (re-search-forward "^References: " nil t)
-             (progn
-               (re-search-forward "^[^ \t]" nil t)
-               (forward-line -1)
-               (end-of-line)
-               (insert " " message-id))
-           (insert "References: " message-id "\n")))
+         (save-restriction
+           (goto-char (point-min))
+           (message-narrow-to-head)
+           (if (re-search-forward "^References: " nil t)
+               (progn
+                 (re-search-forward "^[^ \t]" nil t)
+                 (forward-line -1)
+                 (end-of-line)
+                 (insert " " message-id))
+             (insert "References: " message-id "\n"))))
        (set-buffer gnus-summary-buffer)
        (gnus-summary-unmark-all-processable)
        (gnus-summary-update-article current-article)
        (set-buffer gnus-summary-buffer)
        (gnus-summary-unmark-all-processable)
        (gnus-summary-update-article current-article)
@@ -8487,9 +9179,7 @@ Returns nil if no threads were there to be hidden."
                (subst-char-in-region start (point) ?\n ?\^M)
                (gnus-summary-goto-subject article))
            (goto-char start)
                (subst-char-in-region start (point) ?\n ?\^M)
                (gnus-summary-goto-subject article))
            (goto-char start)
-           nil)
-       ;;(gnus-summary-position-point)
-       ))))
+           nil)))))
 
 (defun gnus-summary-go-to-next-thread (&optional previous)
   "Go to the same level (or less) next thread.
 
 (defun gnus-summary-go-to-next-thread (&optional previous)
   "Go to the same level (or less) next thread.
@@ -8621,14 +9311,14 @@ Argument REVERSE means reverse order."
 
 (defun gnus-summary-sort-by-author (&optional reverse)
   "Sort the summary buffer by author name alphabetically.
 
 (defun gnus-summary-sort-by-author (&optional reverse)
   "Sort the summary buffer by author name alphabetically.
-If case-fold-search is non-nil, case of letters is ignored.
+If `case-fold-search' is non-nil, case of letters is ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort 'author reverse))
 
 (defun gnus-summary-sort-by-subject (&optional reverse)
   "Sort the summary buffer by subject alphabetically.  `Re:'s are ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort 'author reverse))
 
 (defun gnus-summary-sort-by-subject (&optional reverse)
   "Sort the summary buffer by subject alphabetically.  `Re:'s are ignored.
-If case-fold-search is non-nil, case of letters is ignored.
+If `case-fold-search' is non-nil, case of letters is ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort 'subject reverse))
 Argument REVERSE means reverse order."
   (interactive "P")
   (gnus-summary-sort 'subject reverse))
@@ -8655,7 +9345,7 @@ Argument REVERSE means reverse order."
   "Sort the summary buffer by article length.
 Argument REVERSE means reverse order."
   (interactive "P")
   "Sort the summary buffer by article length.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-summary-sort 'chars reverse))  
+  (gnus-summary-sort 'chars reverse))
 
 (defun gnus-summary-sort (predicate reverse)
   "Sort summary buffer by PREDICATE.  REVERSE means reverse order."
 
 (defun gnus-summary-sort (predicate reverse)
   "Sort summary buffer by PREDICATE.  REVERSE means reverse order."
@@ -8666,6 +9356,8 @@ Argument REVERSE means reverse order."
              thread
            `(lambda (t1 t2)
               (,thread t2 t1))))
              thread
            `(lambda (t1 t2)
               (,thread t2 t1))))
+        (gnus-sort-gathered-threads-function
+         gnus-thread-sort-functions)
         (gnus-article-sort-functions
          (if (not reverse)
              article
         (gnus-article-sort-functions
          (if (not reverse)
              article
@@ -8724,6 +9416,7 @@ If N is a negative number, pipe the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 pipe those articles instead."
   (interactive "P")
 If N is nil and any articles have been marked with the process mark,
 pipe those articles instead."
   (interactive "P")
+  (require 'gnus-art)
   (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe))
     (gnus-summary-save-article arg t))
   (gnus-configure-windows 'pipe))
   (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe))
     (gnus-summary-save-article arg t))
   (gnus-configure-windows 'pipe))
@@ -8735,6 +9428,7 @@ If N is a negative number, save the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
+  (require 'gnus-art)
   (let ((gnus-default-article-saver 'gnus-summary-save-in-mail))
     (gnus-summary-save-article arg)))
 
   (let ((gnus-default-article-saver 'gnus-summary-save-in-mail))
     (gnus-summary-save-article arg)))
 
@@ -8745,7 +9439,8 @@ If N is a negative number, save the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
-  (let ((gnus-default-article-saver 'rmail-output-to-rmail-file))
+  (require 'gnus-art)
+  (let ((gnus-default-article-saver 'gnus-summary-save-in-rmail))
     (gnus-summary-save-article arg)))
 
 (defun gnus-summary-save-article-file (&optional arg)
     (gnus-summary-save-article arg)))
 
 (defun gnus-summary-save-article-file (&optional arg)
@@ -8755,6 +9450,7 @@ If N is a negative number, save the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
+  (require 'gnus-art)
   (let ((gnus-default-article-saver 'gnus-summary-save-in-file))
     (gnus-summary-save-article arg)))
 
   (let ((gnus-default-article-saver 'gnus-summary-save-in-file))
     (gnus-summary-save-article arg)))
 
@@ -8765,6 +9461,7 @@ If N is a negative number, save the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
+  (require 'gnus-art)
   (let ((gnus-default-article-saver 'gnus-summary-write-to-file))
     (gnus-summary-save-article arg)))
 
   (let ((gnus-default-article-saver 'gnus-summary-write-to-file))
     (gnus-summary-save-article arg)))
 
@@ -8775,6 +9472,7 @@ If N is a negative number, save the N previous articles.
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
 If N is nil and any articles have been marked with the process mark,
 save those articles instead."
   (interactive "P")
+  (require 'gnus-art)
   (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file))
     (gnus-summary-save-article arg)))
 
   (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file))
     (gnus-summary-save-article arg)))
 
@@ -8799,7 +9497,7 @@ save those articles instead."
        (set-buffer gnus-original-article-buffer)
        (save-restriction
          (nnheader-narrow-to-headers)
        (set-buffer gnus-original-article-buffer)
        (save-restriction
          (nnheader-narrow-to-headers)
-         (while methods
+         (while (and methods (not split-name))
            (goto-char (point-min))
            (setq method (pop methods))
            (setq match (car method))
            (goto-char (point-min))
            (setq method (pop methods))
            (setq match (car method))
@@ -8818,7 +9516,7 @@ save those articles instead."
                    (save-restriction
                      (widen)
                      (setq result (eval match)))))
                    (save-restriction
                      (widen)
                      (setq result (eval match)))))
-             (setq split-name (append (cdr method) split-name))
+             (setq split-name (cdr method))
              (cond ((stringp result)
                     (push (expand-file-name
                            result gnus-article-save-directory)
              (cond ((stringp result)
                     (push (expand-file-name
                            result gnus-article-save-directory)
@@ -8863,7 +9561,8 @@ save those articles instead."
                                  (mapcar (lambda (el) (list el))
                                          (nreverse split-name))
                                  nil nil nil
                                  (mapcar (lambda (el) (list el))
                                          (nreverse split-name))
                                  nil nil nil
-                                 'gnus-group-history)))))
+                                 'gnus-group-history))))
+         (to-method (gnus-server-to-method (gnus-group-method to-newsgroup))))
     (when to-newsgroup
       (if (or (string= to-newsgroup "")
              (string= to-newsgroup prefix))
     (when to-newsgroup
       (if (or (string= to-newsgroup "")
              (string= to-newsgroup prefix))
@@ -8871,24 +9570,29 @@ save those articles instead."
       (unless to-newsgroup
        (error "No group name entered"))
       (or (gnus-active to-newsgroup)
       (unless to-newsgroup
        (error "No group name entered"))
       (or (gnus-active to-newsgroup)
-         (gnus-activate-group to-newsgroup)
+         (gnus-activate-group to-newsgroup nil nil to-method)
          (if (gnus-y-or-n-p (format "No such group: %s.  Create it? "
                                     to-newsgroup))
          (if (gnus-y-or-n-p (format "No such group: %s.  Create it? "
                                     to-newsgroup))
-             (or (and (gnus-request-create-group
-                       to-newsgroup (gnus-group-name-to-method to-newsgroup))
-                      (gnus-activate-group to-newsgroup nil nil
-                                           (gnus-group-name-to-method
-                                            to-newsgroup)))
+             (or (and (gnus-request-create-group to-newsgroup to-method)
+                      (gnus-activate-group
+                       to-newsgroup nil nil to-method)
+                      (gnus-subscribe-group to-newsgroup))
                  (error "Couldn't create group %s" to-newsgroup)))
          (error "No such group: %s" to-newsgroup)))
     to-newsgroup))
 
                  (error "Couldn't create group %s" to-newsgroup)))
          (error "No such group: %s" to-newsgroup)))
     to-newsgroup))
 
-(defun gnus-summary-save-parts (type dir n reverse)
+(defun gnus-summary-save-parts (type dir n &optional reverse)
   "Save parts matching TYPE to DIR.
 If REVERSE, save parts that do not match TYPE."
   (interactive
   "Save parts matching TYPE to DIR.
 If REVERSE, save parts that do not match TYPE."
   (interactive
-   (list (read-string "Save parts of type: " "image/.*")
-        (read-file-name "Save to directory: " t nil t)
+   (list (read-string "Save parts of type: " 
+                     (or (car gnus-summary-save-parts-type-history)
+                         gnus-summary-save-parts-default-mime)
+                     'gnus-summary-save-parts-type-history)
+        (setq gnus-summary-save-parts-last-directory
+              (read-file-name "Save to directory: " 
+                              gnus-summary-save-parts-last-directory
+                              nil t))
         current-prefix-arg))
   (gnus-summary-iterate n
     (let ((gnus-display-mime-function nil)
         current-prefix-arg))
   (gnus-summary-iterate n
     (let ((gnus-display-mime-function nil)
@@ -8896,23 +9600,28 @@ If REVERSE, save parts that do not match TYPE."
       (gnus-summary-select-article))
     (save-excursion
       (set-buffer gnus-article-buffer)
       (gnus-summary-select-article))
     (save-excursion
       (set-buffer gnus-article-buffer)
-      (let ((handles (or (mm-dissect-buffer) (mm-uu-dissect))))
+      (let ((handles (or gnus-article-mime-handles
+                        (mm-dissect-buffer) (mm-uu-dissect))))
        (when handles
        (when handles
-         (gnus-summary-save-parts-1 type dir handles reverse))))))
+         (gnus-summary-save-parts-1 type dir handles reverse)
+         (unless gnus-article-mime-handles ;; Don't destroy this case.
+           (mm-destroy-parts handles)))))))
 
 (defun gnus-summary-save-parts-1 (type dir handle reverse)
   (if (stringp (car handle))
       (mapcar (lambda (h) (gnus-summary-save-parts-1 type dir h reverse))
              (cdr handle))
     (when (if reverse
 
 (defun gnus-summary-save-parts-1 (type dir handle reverse)
   (if (stringp (car handle))
       (mapcar (lambda (h) (gnus-summary-save-parts-1 type dir h reverse))
              (cdr handle))
     (when (if reverse
-             (not (string-match type (car (mm-handle-type handle))))
-           (string-match type (car (mm-handle-type handle))))
+             (not (string-match type (mm-handle-media-type handle)))
+           (string-match type (mm-handle-media-type handle)))
       (let ((file (expand-file-name
                   (file-name-nondirectory
                    (or
                     (mail-content-type-get
                      (mm-handle-disposition handle) 'filename)
       (let ((file (expand-file-name
                   (file-name-nondirectory
                    (or
                     (mail-content-type-get
                      (mm-handle-disposition handle) 'filename)
-                    (concat gnus-newsgroup-name "." gnus-current-article)))
+                    (concat gnus-newsgroup-name
+                            "." (number-to-string
+                                 (cdr gnus-article-current)))))
                   dir)))
        (unless (file-exists-p file)
          (mm-save-part-to-file handle file))))))
                   dir)))
        (unless (file-exists-p file)
          (mm-save-part-to-file handle file))))))
@@ -8952,7 +9661,7 @@ If REVERSE, save parts that do not match TYPE."
                                (lambda (f)
                                  (if (equal f " ")
                                      f
                                (lambda (f)
                                  (if (equal f " ")
                                      f
-                                   (mm-quote-arg f)))
+                                   (gnus-quote-arg-for-sh-or-csh f)))
                                files " ")))))
          (setq ps (cdr ps)))))
     (if (and gnus-view-pseudos (not not-view))
                                files " ")))))
          (setq ps (cdr ps)))))
     (if (and gnus-view-pseudos (not not-view))
@@ -9029,8 +9738,10 @@ If REVERSE, save parts that do not match TYPE."
   "Read the headers of article ID and enter them into the Gnus system."
   (let ((group gnus-newsgroup-name)
        (gnus-override-method
   "Read the headers of article ID and enter them into the Gnus system."
   (let ((group gnus-newsgroup-name)
        (gnus-override-method
-        (and (gnus-news-group-p gnus-newsgroup-name)
-             gnus-refer-article-method))
+        (or
+         gnus-override-method
+         (and (gnus-news-group-p gnus-newsgroup-name)
+              (car (gnus-refer-article-methods)))))
        where)
     ;; First we check to see whether the header in question is already
     ;; fetched.
        where)
     ;; First we check to see whether the header in question is already
     ;; fetched.
@@ -9104,8 +9815,8 @@ If REVERSE, save parts that do not match TYPE."
 ;;;
 
 (defun gnus-highlight-selected-summary ()
 ;;;
 
 (defun gnus-highlight-selected-summary ()
+  "Highlight selected article in summary buffer."
   ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
   ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
-  ;; Highlight selected article in summary buffer
   (when gnus-summary-selected-face
     (save-excursion
       (let* ((beg (progn (beginning-of-line) (point)))
   (when gnus-summary-selected-face
     (save-excursion
       (let* ((beg (progn (beginning-of-line) (point)))
@@ -9200,23 +9911,32 @@ If REVERSE, save parts that do not match TYPE."
       (if compute
          read
        (save-excursion
       (if compute
          read
        (save-excursion
-         (set-buffer gnus-group-buffer)
-         (gnus-undo-register
-           `(progn
-              (gnus-info-set-marks ',info ',(gnus-info-marks info) t)
-              (gnus-info-set-read ',info ',(gnus-info-read info))
-              (gnus-get-unread-articles-in-group ',info (gnus-active ,group))
-              (gnus-group-update-group ,group t))))
-       ;; Propagate the read marks to the backend.
-       (if (gnus-check-backend-function 'request-set-mark group)
-           (let ((del (gnus-remove-from-range (gnus-info-read info) read))
-                 (add (gnus-remove-from-range read (gnus-info-read info))))
-             (when (or add del)
-              (unless (gnus-check-group group)
-                (error "Can't open server for %s" group))
-               (gnus-request-set-mark
-                group (delq nil (list (if add (list add 'add '(read)))
-                                      (if del (list del 'del '(read)))))))))
+         (let (setmarkundo)
+           ;; Propagate the read marks to the backend.
+           (when (gnus-check-backend-function 'request-set-mark group)
+             (let ((del (gnus-remove-from-range (gnus-info-read info) read))
+                   (add (gnus-remove-from-range read (gnus-info-read info))))
+               (when (or add del)
+                 (unless (gnus-check-group group)
+                   (error "Can't open server for %s" group))
+                 (gnus-request-set-mark
+                  group (delq nil (list (if add (list add 'add '(read)))
+                                        (if del (list del 'del '(read))))))
+                 (setq setmarkundo
+                       `(gnus-request-set-mark
+                         ,group
+                         ',(delq nil (list
+                                      (if del (list del 'add '(read)))
+                                      (if add (list add 'del '(read))))))))))
+           (set-buffer gnus-group-buffer)
+           (gnus-undo-register
+             `(progn
+                (gnus-info-set-marks ',info ',(gnus-info-marks info) t)
+                (gnus-info-set-read ',info ',(gnus-info-read info))
+                (gnus-get-unread-articles-in-group ',info 
+                                                   (gnus-active ,group))
+                (gnus-group-update-group ,group t)
+                ,setmarkundo))))
        ;; Enter this list into the group info.
        (gnus-info-set-read info read)
        ;; Set the number of unread articles in gnus-newsrc-hashtb.
        ;; Enter this list into the group info.
        (gnus-info-set-read info read)
        ;; Set the number of unread articles in gnus-newsrc-hashtb.
@@ -9251,23 +9971,155 @@ If REVERSE, save parts that do not match TYPE."
           (gnus-summary-exit))
         buffers)))))
 
           (gnus-summary-exit))
         buffers)))))
 
+
+;;; @ for mime-partial
+;;;
+
+(defun gnus-request-partial-message ()
+  (save-excursion
+    (let ((number (gnus-summary-article-number))
+         (group gnus-newsgroup-name)
+         (mother gnus-article-buffer))
+      (set-buffer (get-buffer-create " *Partial Article*"))
+      (erase-buffer)
+      (setq mime-preview-buffer mother)
+      (gnus-request-article-this-buffer number group)
+      (mime-parse-buffer)
+      )))
+
+(autoload 'mime-combine-message/partial-pieces-automatically
+  "mime-partial"
+  "Internal method to combine message/partial messages automatically.")
+
+(mime-add-condition
+ 'action '((type . message)(subtype . partial)
+          (major-mode . gnus-original-article-mode)
+          (method . mime-combine-message/partial-pieces-automatically)
+          (summary-buffer-exp . gnus-summary-buffer)
+          (request-partial-message-method . gnus-request-partial-message)
+          ))
+
+
+;;; @ for message/rfc822
+;;;
+
+(defun gnus-mime-extract-message/rfc822 (entity situation)
+  (let (group article num cwin swin cur)
+    (with-temp-buffer
+      (mime-insert-entity-content entity)
+      (setq group (or (cdr (assq 'group situation))
+                     (completing-read "Group: "
+                                      gnus-active-hashtb
+                                      nil
+                                      (gnus-read-active-file-p)
+                                      gnus-newsgroup-name))
+           article (gnus-request-accept-article group)))
+    (when (and (consp article)
+              (numberp (setq article (cdr article))))
+      (setq num (1+ (or (cdr (assq 'number situation)) 0))
+           cwin (get-buffer-window (current-buffer) t))
+      (save-window-excursion
+       (if (setq swin (get-buffer-window gnus-summary-buffer t))
+           (select-window swin)
+         (set-buffer gnus-summary-buffer))
+       (setq cur gnus-current-article)
+       (forward-line num)
+       (let (gnus-show-threads)
+         (gnus-summary-goto-subject article t))
+       (gnus-summary-clear-mark-forward 1)
+       (gnus-summary-goto-subject cur))
+      (when (and cwin (window-frame cwin))
+       (select-frame (window-frame cwin)))
+      (when (boundp 'mime-acting-situation-to-override)
+       (set-alist 'mime-acting-situation-to-override
+                  'group
+                  group)
+       (set-alist 'mime-acting-situation-to-override
+                  'after-method
+                  `(progn
+                     (save-current-buffer
+                       (set-buffer gnus-group-buffer)
+                       (gnus-activate-group ,group))
+                     (gnus-summary-goto-article ,cur
+                                                gnus-show-all-headers)))
+       (set-alist 'mime-acting-situation-to-override
+                  'number num)))))
+
+(mime-add-condition
+ 'action '((type . message)(subtype . rfc822)
+          (major-mode . gnus-original-article-mode)
+          (method . gnus-mime-extract-message/rfc822)
+          (mode . "extract")
+          ))
+
+(mime-add-condition
+ 'action '((type . message)(subtype . news)
+          (major-mode . gnus-original-article-mode)
+          (method . gnus-mime-extract-message/rfc822)
+          (mode . "extract")
+          ))
+
+(defun gnus-mime-extract-multipart (entity situation)
+  (let ((children (mime-entity-children entity))
+       mime-acting-situation-to-override
+       f)
+    (while children
+      (mime-play-entity (car children)
+                       (cons (assq 'mode situation)
+                             mime-acting-situation-to-override))
+      (setq children (cdr children)))
+    (if (setq f (cdr (assq 'after-method
+                          mime-acting-situation-to-override)))
+       (eval f)
+      )))
+
+(mime-add-condition
+ 'action '((type . multipart)
+          (method . gnus-mime-extract-multipart)
+          (mode . "extract")
+          )
+ 'with-default)
+
+
+;;; @ end
+;;;
+
 (defun gnus-summary-setup-default-charset ()
   "Setup newsgroup default charset."
 (defun gnus-summary-setup-default-charset ()
   "Setup newsgroup default charset."
-  (let ((name (and gnus-newsgroup-name
-                  (gnus-group-real-name gnus-newsgroup-name))))
-    (setq gnus-newsgroup-charset
-         (or (and gnus-newsgroup-name
-                  (or (gnus-group-find-parameter gnus-newsgroup-name
-                                                 'charset)
-                      (let ((alist gnus-group-charset-alist)
-                            elem (charset nil))
-                        (while (setq elem (pop alist))
-                          (when (and name
-                                     (string-match (car elem) name))
-                            (setq alist nil
-                                  charset (cadr elem))))
-                        charset)))
-             gnus-default-charset))))
+  (if (equal gnus-newsgroup-name "nndraft:drafts")
+      (setq gnus-newsgroup-charset nil)
+    (let* ((name (and gnus-newsgroup-name
+                     (gnus-group-real-name gnus-newsgroup-name)))
+          (ignored-charsets
+           (or gnus-newsgroup-ephemeral-ignored-charsets
+               (append
+                (and gnus-newsgroup-name
+                     (or (gnus-group-find-parameter gnus-newsgroup-name
+                                                    'ignored-charsets t)
+                         (let ((alist gnus-group-ignored-charsets-alist)
+                               elem (charsets nil))
+                           (while (setq elem (pop alist))
+                             (when (and name
+                                        (string-match (car elem) name))
+                               (setq alist nil
+                                     charsets (cdr elem))))
+                           charsets)))
+                gnus-newsgroup-ignored-charsets))))
+      (setq gnus-newsgroup-charset
+           (or gnus-newsgroup-ephemeral-charset
+               (and gnus-newsgroup-name
+                    (or (gnus-group-find-parameter gnus-newsgroup-name 'charset)
+                        (let ((alist gnus-group-charset-alist)
+                              elem charset)
+                          (while (setq elem (pop alist))
+                            (when (and name
+                                       (string-match (car elem) name))
+                              (setq alist nil
+                                    charset (cadr elem))))
+                          charset)))
+               gnus-default-charset))
+      (set (make-local-variable 'gnus-newsgroup-ignored-charsets)
+          ignored-charsets))))
 
 ;;;
 ;;; Mime Commands
 
 ;;;
 ;;; Mime Commands
@@ -9288,17 +10140,17 @@ treated as multipart/mixed."
   (interactive (list (gnus-summary-article-number)))
   (gnus-with-article article
     (message-narrow-to-head)
   (interactive (list (gnus-summary-article-number)))
   (gnus-with-article article
     (message-narrow-to-head)
+    (message-remove-header "Mime-Version")
     (goto-char (point-max))
     (goto-char (point-max))
+    (insert "Mime-Version: 1.0\n")
     (widen)
     (when (search-forward "\n--" nil t)
       (let ((separator (buffer-substring (point) (gnus-point-at-eol))))
        (message-narrow-to-head)
     (widen)
     (when (search-forward "\n--" nil t)
       (let ((separator (buffer-substring (point) (gnus-point-at-eol))))
        (message-narrow-to-head)
-       (message-remove-header "Mime-Version")
        (message-remove-header "Content-Type")
        (goto-char (point-max))
        (insert (format "Content-Type: multipart/mixed; boundary=\"%s\"\n"
                        separator))
        (message-remove-header "Content-Type")
        (goto-char (point-max))
        (insert (format "Content-Type: multipart/mixed; boundary=\"%s\"\n"
                        separator))
-       (insert "Mime-Version: 1.0\n")
        (widen))))
   (let (gnus-mark-article-hook)
     (gnus-summary-select-article t t nil article)))
        (widen))))
   (let (gnus-mark-article-hook)
     (gnus-summary-select-article t t nil article)))
@@ -9314,35 +10166,102 @@ treated as multipart/mixed."
     (gnus-summary-show-article)))
 
 ;;;
     (gnus-summary-show-article)))
 
 ;;;
-;;; with article
+;;; Intelli-mouse commmands
 ;;;
 
 ;;;
 
-(defmacro gnus-with-article (article &rest forms)
-  "Select ARTICLE and perform FORMS in the original article buffer.
-Then replace the article with the result."
-  `(progn
-     ;; We don't want the article to be marked as read.
-     (let (gnus-mark-article-hook)
-       (gnus-summary-select-article t t nil ,article))
-     (set-buffer gnus-original-article-buffer)
-     ,@forms
-     (if (not (gnus-check-backend-function
-              'request-replace-article (car gnus-article-current)))
-        (gnus-message 5 "Read-only group; not replacing")
-       (unless (gnus-request-replace-article
-               ,article (car gnus-article-current)
-               (current-buffer) t)
-        (error "Couldn't replace article")))
-     ;; The cache and backlog have to be flushed somewhat.
-     (when gnus-keep-backlog
-       (gnus-backlog-remove-article
-       (car gnus-article-current) (cdr gnus-article-current)))
-     (when gnus-use-cache
-       (gnus-cache-update-article
-       (car gnus-article-current) (cdr gnus-article-current)))))
+(defun gnus-wheel-summary-scroll (event)
+  (interactive "e")
+  (let ((amount (if (memq 'shift (event-modifiers event))
+                   (car gnus-wheel-scroll-amount)
+                 (cdr gnus-wheel-scroll-amount)))
+       (direction (- (* (static-if (featurep 'xemacs)
+                            (event-button event)
+                          (cond ((eq 'mouse-4 (event-basic-type event))
+                                 4)
+                                ((eq 'mouse-5 (event-basic-type event))
+                                 5)))
+                        2) 9))
+       edge)
+    (gnus-summary-scroll-up (* amount direction))
+    (when (gnus-eval-in-buffer-window gnus-article-buffer
+           (save-restriction
+             (widen)
+             (and (if (< 0 direction)
+                      (gnus-article-next-page 0)
+                    (gnus-article-prev-page 0)
+                    (bobp))
+                  (if (setq edge (get-text-property
+                                  (point-min) 'gnus-wheel-edge))
+                      (setq edge (* edge direction))
+                    (setq edge -1))
+                  (or (plusp edge)
+                      (let ((buffer-read-only nil)
+                            (inhibit-read-only t))
+                        (put-text-property (point-min) (point-max)
+                                           'gnus-wheel-edge direction)
+                        nil))
+                  (or (> edge gnus-wheel-edge-resistance)
+                      (let ((buffer-read-only nil)
+                            (inhibit-read-only t))
+                        (put-text-property (point-min) (point-max)
+                                           'gnus-wheel-edge
+                                           (* (1+ edge) direction))
+                        nil))
+                  (eq last-command 'gnus-wheel-summary-scroll))))
+      (gnus-summary-next-article nil nil (minusp direction)))))
+
+(defun gnus-wheel-install ()
+  "Enable mouse wheel support on summary window."
+  (when gnus-use-wheel
+    (let ((keys
+          '([(mouse-4)] [(shift mouse-4)] [(mouse-5)] [(shift mouse-5)])))
+      (dolist (key keys)
+       (define-key gnus-summary-mode-map key
+         'gnus-wheel-summary-scroll)))))
+
+(add-hook 'gnus-summary-mode-hook 'gnus-wheel-install)
 
 
-(put 'gnus-with-article 'lisp-indent-function 1)
-(put 'gnus-with-article 'edebug-form-spec '(form body))
+;;;
+;;; Traditional PGP commmands
+;;;
+
+(defun gnus-summary-decrypt-article (&optional force)
+  "Decrypt the current article in traditional PGP way.
+This will have permanent effect only in mail groups.
+If FORCE is non-nil, allow editing of articles even in read-only
+groups."
+  (interactive "P")
+  (gnus-summary-select-article t)
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (save-excursion
+      (save-restriction
+       (widen)
+       (goto-char (point-min))
+       (unless (re-search-forward (car pgg-armor-header-lines) nil t)
+         (error "Not a traditional PGP message!"))
+       (let ((armor-start (match-beginning 0)))
+         (if (and (pgg-decrypt-region armor-start (point-max))
+                  (or force (not (gnus-group-read-only-p))))
+             (let ((inhibit-read-only t)
+                   buffer-read-only)
+               (delete-region armor-start
+                              (progn
+                                (re-search-forward "^-+END PGP" nil t)
+                                (beginning-of-line 2)
+                                (point)))
+               (insert-buffer-substring pgg-output-buffer))))))))
+
+(defun gnus-summary-verify-article ()
+  "Verify the current article in traditional PGP way."
+  (interactive)
+  (save-excursion
+    (set-buffer gnus-original-article-buffer)
+    (goto-char (point-min))
+    (unless (re-search-forward "^-+BEGIN PGP SIGNED MESSAGE" nil t)
+      (error "Not a traditional PGP message!"))
+    (re-search-forward "^-+END PGP" nil t)
+    (beginning-of-line 2)
+    (call-interactively (function pgg-verify-region))))
 
 ;;;
 ;;; Generic summary marking commands
 
 ;;;
 ;;; Generic summary marking commands
@@ -9376,8 +10295,8 @@ Then replace the article with the result."
                   mark (car lway) lway name)))
        (setq func (eval func))
        (define-key map (nth 4 lway) func)))))
                   mark (car lway) lway name)))
        (setq func (eval func))
        (define-key map (nth 4 lway) func)))))
-      
-(defun gnus-summary-make-marking-command-1 (mark way lway name)      
+
+(defun gnus-summary-make-marking-command-1 (mark way lway name)
   `(defun ,(intern
            (format "gnus-summary-put-mark-as-%s%s"
                    name (if (eq way 'nomove)
   `(defun ,(intern
            (format "gnus-summary-put-mark-as-%s%s"
                    name (if (eq way 'nomove)
@@ -9390,10 +10309,10 @@ If N, the prefix, then repeat N times.
 If N is negative, move in reverse order.
 The difference between N and the actual number of articles marked is
 returned."
 If N is negative, move in reverse order.
 The difference between N and the actual number of articles marked is
 returned."
-       name (cadr lway))
+       name (car (cdr lway)))
      (interactive "p")
      (gnus-summary-generic-mark n ,mark ',(nth 2 lway) ,(nth 3 lway))))
      (interactive "p")
      (gnus-summary-generic-mark n ,mark ',(nth 2 lway) ,(nth 3 lway))))
-    
+
 (defun gnus-summary-generic-mark (n mark move unread)
   "Mark N articles with MARK."
   (unless (eq major-mode 'gnus-summary-mode)
 (defun gnus-summary-generic-mark (n mark move unread)
   "Mark N articles with MARK."
   (unless (eq major-mode 'gnus-summary-mode)