Patch by Ed L. Cashin to make gnus-move-split-methods move to
[gnus] / lisp / gnus-sum.el
index bd05317..1896c85 100644 (file)
@@ -1,5 +1,6 @@
 ;;; gnus-sum.el --- summary mode commands for Gnus
 ;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000
+;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Keywords: news
@@ -36,6 +37,7 @@
 (require 'gnus-util)
 (require 'mm-decode)
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (require 'gnus-util)
 (require 'mm-decode)
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
+(autoload 'gnus-cache-write-active "gnus-cache")
 
 (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 +170,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)
@@ -345,7 +352,7 @@ It uses the same syntax as the `gnus-split-methods' variable."
                         (cons :value ("" "") regexp (repeat string))
                         (sexp :value nil))))
 
                         (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)
@@ -460,7 +467,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)
@@ -693,7 +700,8 @@ is not run if `gnus-visual' is nil."
   :type 'hook)
 
 (defcustom gnus-exit-group-hook nil
   :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)
 
@@ -810,11 +818,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)
     ("^fido7\\>" koi8-r)
     ("^\\(cz\\|hun\\|pl\\|sk\\|hr\\)\\>" iso-8859-2)
     ("^israel\\>" iso-8859-1)
     ("^han\\>" euc-kr)
     ("^relcom\\>" koi8-r)
     ("^fido7\\>" koi8-r)
     ("^\\(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."
@@ -829,7 +840,7 @@ default charset will be used instead."
   :type '(repeat symbol)
   :group 'gnus-charset)
 
   :type '(repeat symbol)
   :group 'gnus-charset)
 
-(defcustom gnus-group-ignored-charsets-alist 
+(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
   '(("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
@@ -845,7 +856,7 @@ This variable uses the same syntax as `gnus-emphasis-alist'."
                       (repeat (list (regexp :tag "Highlight regexp")
                                     (number :tag "Group for entire word" 0)
                                     (number :tag "Group for displayed part" 0)
                       (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)
 
@@ -859,6 +870,29 @@ For example: ((1 . cn-gb-2312) (2 . big5))."
                       (symbol :tag "Charset")))
   :group 'gnus-charset)
 
                       (symbol :tag "Charset")))
   :group 'gnus-charset)
 
+(defcustom gnus-preserve-marks t
+  "Whether marks are preserved when moving, copying and respooling messages."
+  :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)
+
 
 ;;; Internal variables
 
 
 ;;; Internal variables
 
@@ -875,8 +909,10 @@ For example: ((1 . cn-gb-2312) (2 . big5))."
 (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
 (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.")
+  "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)
 
 ;; Avoid highlighting in kill files.
 (defvar gnus-summary-inhibit-highlight nil)
 
 ;; Avoid highlighting in kill files.
 (defvar gnus-summary-inhibit-highlight nil)
@@ -933,9 +969,9 @@ been gathered together.")
        ?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)
@@ -1078,6 +1114,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
@@ -1099,16 +1136,15 @@ variable (string, integer, character, etc).")
   '(mail-decode-encoded-word-string)
   "List of methods used to decode encoded words.
 
   '(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
+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
 (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))
-")
+ (\"chinese\" . rfc1843-decode-string))")
 
 (defvar gnus-decode-encoded-word-methods-cache nil)
 
 
 (defvar gnus-decode-encoded-word-methods-cache nil)
 
@@ -1118,13 +1154,13 @@ For example:
               (eq gnus-newsgroup-name
                   (car gnus-decode-encoded-word-methods-cache)))
     (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
               (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))))))
+    (mapcar (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)
          gnus-decode-encoded-word-methods))
   (let ((xlist gnus-decode-encoded-word-methods-cache))
     (pop xlist)
@@ -1135,7 +1171,7 @@ For example:
 ;; 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)
@@ -1180,7 +1216,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.
@@ -1188,7 +1224,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" " ")
@@ -1312,6 +1348,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
@@ -1360,7 +1398,7 @@ increase the score of each group you read."
     "\C-d" gnus-summary-enter-digest-group
     "\M-\C-d" gnus-summary-read-document
     "\M-\C-e" gnus-summary-edit-parameters
     "\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
@@ -1422,7 +1460,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)
@@ -1511,10 +1549,13 @@ increase the score of each group you read."
     "C" gnus-article-capitalize-sentences
     "c" gnus-article-remove-cr
     "q" gnus-article-de-quoted-unreadable
     "C" gnus-article-capitalize-sentences
     "c" gnus-article-remove-cr
     "q" gnus-article-de-quoted-unreadable
+    "6" gnus-article-de-base64-unreadable
+    "Z" gnus-article-decode-HZ
+    "h" gnus-article-wash-html
     "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-summary-toggle-header
     "v" gnus-summary-verbose-headers
     "H" gnus-article-strip-headers-in-body
     "d" gnus-article-treat-dumbquotes)
     "v" gnus-summary-verbose-headers
     "H" gnus-article-strip-headers-in-body
     "d" gnus-article-treat-dumbquotes)
@@ -1605,8 +1646,7 @@ increase the score of each group you read."
     "c" gnus-article-copy-part
     "e" gnus-article-externalize-part
     "i" gnus-article-inline-part
     "c" gnus-article-copy-part
     "e" gnus-article-externalize-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)
@@ -1662,6 +1702,7 @@ increase the score of each group you read."
              ["Words" gnus-article-decode-mime-words t]
              ["Charset" gnus-article-decode-charset t]
              ["QP" gnus-article-de-quoted-unreadable t]
              ["Words" gnus-article-decode-mime-words t]
              ["Charset" gnus-article-decode-charset t]
              ["QP" gnus-article-de-quoted-unreadable t]
+             ["Base64" gnus-article-de-base64-unreadable t]
              ["View all" gnus-mime-view-all-parts t])
              ("Date"
               ["Local" gnus-article-date-local t]
              ["View all" gnus-mime-view-all-parts t])
              ("Date"
               ["Local" gnus-article-date-local t]
@@ -1688,13 +1729,16 @@ increase the score of each group you read."
               ["CR" gnus-article-remove-cr t]
               ["Show X-Face" gnus-article-display-x-face t]
               ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
               ["CR" gnus-article-remove-cr t]
               ["Show X-Face" gnus-article-display-x-face t]
               ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
+              ["Base64" gnus-article-de-base64-unreadable t]
               ["Rot 13" gnus-summary-caesar-message 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]
               ["Verbose header" gnus-summary-verbose-headers t]
               ["Rot 13" gnus-summary-caesar-message 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]
               ["Verbose header" gnus-summary-verbose-headers t]
-              ["Toggle header" gnus-summary-toggle-header t])
+              ["Toggle header" gnus-summary-toggle-header t]
+             ["Html" gnus-article-wash-html t]
+             ["HZ" gnus-article-decode-HZ t])
              ("Output"
               ["Save in default format" gnus-summary-save-article t]
               ["Save in file" gnus-summary-save-article-file t]
              ("Output"
               ["Save in default format" gnus-summary-save-article t]
               ["Save in file" gnus-summary-save-article-file t]
@@ -1773,8 +1817,7 @@ 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 ""
@@ -1997,7 +2040,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)
@@ -2060,7 +2104,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)
+  (mm-enable-multibyte-mule4)
   (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))
 
@@ -2397,12 +2441,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.
 
@@ -2412,9 +2457,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)
@@ -2458,9 +2504,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)
@@ -2566,7 +2612,7 @@ marks of articles."
   (let ((to (cdr (assq 'To (mail-header-extra header))))
        (newsgroups (cdr (assq 'Newsgroups (mail-header-extra header))))
        (mail-parse-charset gnus-newsgroup-charset)
   (let ((to (cdr (assq 'To (mail-header-extra header))))
        (newsgroups (cdr (assq 'Newsgroups (mail-header-extra header))))
        (mail-parse-charset gnus-newsgroup-charset)
-       (mail-parse-ignored-charsets 
+       (mail-parse-ignored-charsets
         (save-excursion (set-buffer gnus-summary-buffer)
                         gnus-newsgroup-ignored-charsets)))
     (cond
         (save-excursion (set-buffer gnus-summary-buffer)
                         gnus-newsgroup-ignored-charsets)))
     (cond
@@ -2602,7 +2648,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
@@ -2645,7 +2691,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.
@@ -2667,7 +2713,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))
@@ -3030,7 +3076,7 @@ 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))
   (let ((result threads))
     (while threads
       (when (stringp (caar threads))
@@ -3255,19 +3301,21 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
 
          (setq header
                (make-full-mail-header
 
          (setq header
                (make-full-mail-header
-                number                         ; number
+                number                 ; number
                 (funcall gnus-decode-encoded-word-function
                          (nnheader-nov-field)) ; subject
                 (funcall gnus-decode-encoded-word-function
                          (nnheader-nov-field)) ; from
                 (funcall gnus-decode-encoded-word-function
                          (nnheader-nov-field)) ; subject
                 (funcall gnus-decode-encoded-word-function
                          (nnheader-nov-field)) ; from
-                (nnheader-nov-field)           ; date
+                (nnheader-nov-field)   ; date
                 (nnheader-nov-read-message-id) ; id
                 (nnheader-nov-read-message-id) ; id
-                (nnheader-nov-field)           ; refs
-                (nnheader-nov-read-integer)    ; chars
-                (nnheader-nov-read-integer)    ; lines
+                (nnheader-nov-field)   ; refs
+                (nnheader-nov-read-integer) ; chars
+                (nnheader-nov-read-integer) ; lines
                 (unless (eobp)
                 (unless (eobp)
-                  (nnheader-nov-field))                ; misc
-                (nnheader-nov-parse-extra))))  ; extra
+                  (if (looking-at "Xref: ")
+                      (goto-char (match-end 0)))
+                  (nnheader-nov-field)) ; Xref
+                (nnheader-nov-parse-extra)))) ; extra
 
       (widen))
 
 
       (widen))
 
@@ -3276,9 +3324,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
@@ -3360,17 +3408,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))
@@ -3584,7 +3634,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)
@@ -3596,6 +3645,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)
@@ -3603,13 +3653,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)
@@ -3624,12 +3683,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)
@@ -3956,7 +4015,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
@@ -4046,13 +4105,17 @@ or a straight list of headers."
                    gnus-list-identifiers
                  (mapconcat 'identity gnus-list-identifiers " *\\|"))))
     (dolist (header gnus-newsgroup-headers)
                    gnus-list-identifiers
                  (mapconcat 'identity gnus-list-identifiers " *\\|"))))
     (dolist (header gnus-newsgroup-headers)
-      (when (string-match (concat "\\(Re: +\\)?\\(" regexp " *\\)")
+      (when (string-match (concat "\\(\\(\\(Re: +\\)?\\(" regexp 
+                                 " *\\)\\)+\\(Re: +\\)?\\)")
                          (mail-header-subject header))
        (mail-header-set-subject
         header (concat (substring (mail-header-subject header)
                          (mail-header-subject header))
        (mail-header-set-subject
         header (concat (substring (mail-header-subject header)
-                                  0 (match-beginning 2))
+                                  0 (match-beginning 1))
+                       (or
+                        (match-string 3 (mail-header-subject header))
+                        (match-string 5 (mail-header-subject header)))
                        (substring (mail-header-subject header)
                        (substring (mail-header-subject header)
-                                  (match-end 2))))))))
+                                  (match-end 1))))))))
 
 (defun gnus-select-newsgroup (group &optional read-all select-articles)
   "Select newsgroup GROUP.
 
 (defun gnus-select-newsgroup (group &optional read-all select-articles)
   "Select newsgroup GROUP.
@@ -4193,7 +4256,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.
@@ -4240,7 +4303,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
@@ -4260,6 +4325,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)
@@ -4345,9 +4416,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
@@ -4366,24 +4437,30 @@ 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)))
+       (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)
-         ;; 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)))))
+       (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)
 
       (when delta-marks
        (unless (gnus-check-group gnus-newsgroup-name)
@@ -4405,7 +4482,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)
@@ -4421,7 +4498,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))
@@ -4617,11 +4698,11 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                             gnus-newsgroup-dependencies)))
        headers id end ref
        (mail-parse-charset gnus-newsgroup-charset)
                             gnus-newsgroup-dependencies)))
        headers id end ref
        (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)))
+       (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.
@@ -4769,8 +4850,9 @@ 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))
   ;; 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))
@@ -5099,6 +5181,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)
@@ -5159,7 +5242,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))
@@ -5216,8 +5302,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
@@ -5313,13 +5398,16 @@ 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)
   (when (gnus-buffer-live-p gnus-article-buffer)
     (save-excursion
       (set-buffer gnus-article-buffer)
   (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)))
+      (mm-destroy-parts gnus-article-mime-handles)
+      ;; Set it to nil for safety reason.
+      (setq gnus-article-mime-handle-alist nil)
+      (setq gnus-article-mime-handles nil)))
   (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)
@@ -5346,6 +5434,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.
@@ -5411,11 +5501,14 @@ 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)))
+                   (copy-sequence gnus-summary-prepare-exit-hook)))
       (when (gnus-buffer-live-p gnus-article-buffer)
        (save-excursion
          (set-buffer gnus-article-buffer)
       (when (gnus-buffer-live-p gnus-article-buffer)
        (save-excursion
          (set-buffer gnus-article-buffer)
-         (mm-destroy-parts gnus-article-mime-handles)))
+         (mm-destroy-parts gnus-article-mime-handles)
+         ;; Set it to nil for safety reason.
+         (setq gnus-article-mime-handle-alist nil)
+         (setq gnus-article-mime-handles nil)))
       ;; 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)
@@ -5523,7 +5616,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."
@@ -5690,8 +5784,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" "")))
@@ -5752,6 +5846,9 @@ 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)
   (if (null article)
       nil
   (gnus-set-global-variables)
   (if (null article)
       nil
@@ -5782,37 +5879,38 @@ 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 (gnus-buffer-live-p gnus-article-buffer)
+              (with-current-buffer gnus-article-buffer
+               (if (not gnus-article-decoded-p) ;; a local variable
+                   (mm-disable-multibyte-mule4))))
            (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-set-current-mark (&optional current-mark)
   "Obsolete function."
 
 (defun gnus-summary-set-current-mark (&optional current-mark)
   "Obsolete function."
@@ -6264,12 +6362,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))      
-           "Limit 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)))))
@@ -6765,15 +6863,7 @@ of what's specified by the `gnus-refer-thread-limit' variable."
        (t
        ;; We fetch the article.
        (catch 'found
        (t
        ;; We fetch the article.
        (catch 'found
-         (dolist (gnus-override-method
-                  (cond ((null gnus-refer-article-method)
-                         (list 'current gnus-select-method))
-                        ((consp (car gnus-refer-article-method))
-                         gnus-refer-article-method)
-                        (t
-                         (list gnus-refer-article-method))))
-           (when (eq 'current gnus-override-method)
-             (setq gnus-override-method gnus-current-select-method))
+         (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-check-server gnus-override-method)
            ;; Fetch the header, and display the article.
            (when (setq number (gnus-summary-insert-subject message-id))
@@ -6781,6 +6871,28 @@ of what's specified by the `gnus-refer-thread-limit' variable."
              (throw 'found t)))
          (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 (stringp (cadr gnus-refer-article-method)))
+    (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."
   (interactive)
 (defun gnus-summary-edit-parameters ()
   "Edit the group parameters of the current group."
   (interactive)
@@ -6819,7 +6931,10 @@ to guess what the document format is."
        ;; the parent article.
        (when (setq to-address (or (message-fetch-field "reply-to")
                                   (message-fetch-field "from")))
        ;; the parent article.
        (when (setq to-address (or (message-fetch-field "reply-to")
                                   (message-fetch-field "from")))
-         (setq params (append (list (cons 'to-address to-address)))))
+         (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
@@ -6958,6 +7073,7 @@ Optional argument BACKWARD means do search for backward.
     (gnus-save-hidden-threads
       (gnus-summary-select-article)
       (set-buffer gnus-article-buffer)
     (gnus-save-hidden-threads
       (gnus-summary-select-article)
       (set-buffer gnus-article-buffer)
+      (goto-char (window-point (get-buffer-window (current-buffer))))
       (when backward
        (forward-line -1))
       (while (not found)
       (when backward
        (forward-line -1))
       (while (not found)
@@ -7127,15 +7243,15 @@ 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 a number, show the article with the charset 
+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.
 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 
+If ARG (the prefix) is non-nil and not a number, show the raw article
 without any article massaging functions being run."
   (interactive "P")
 without any article massaging functions being run."
   (interactive "P")
-  (cond 
+  (cond
    ((numberp arg)
    ((numberp arg)
-    (let ((gnus-newsgroup-charset 
+    (let ((gnus-newsgroup-charset
           (or (cdr (assq arg gnus-summary-show-article-charset-alist))
               (read-coding-system "Charset: ")))
          (gnus-newsgroup-ignored-charsets 'gnus-all))
           (or (cdr (assq arg gnus-summary-show-article-charset-alist))
               (read-coding-system "Charset: ")))
          (gnus-newsgroup-ignored-charsets 'gnus-all))
@@ -7153,13 +7269,15 @@ without any article massaging functions being run."
          gnus-article-prepare-hook
          gnus-article-decode-hook
          gnus-display-mime-function
          gnus-article-prepare-hook
          gnus-article-decode-hook
          gnus-display-mime-function
-         gnus-break-pages
-         gnus-visual)
+         gnus-break-pages)
       ;; Destroy any MIME parts.
       (when (gnus-buffer-live-p gnus-article-buffer)
        (save-excursion
          (set-buffer gnus-article-buffer)
       ;; 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)))
+         (mm-destroy-parts gnus-article-mime-handles)
+         ;; Set it to nil for safety reason.
+         (setq gnus-article-mime-handle-alist nil)
+         (setq gnus-article-mime-handles nil)))
       (gnus-summary-select-article nil 'force))))
   (gnus-summary-goto-subject gnus-current-article)
   (gnus-summary-position-point))
       (gnus-summary-select-article nil 'force))))
   (gnus-summary-goto-subject gnus-current-article)
   (gnus-summary-position-point))
@@ -7191,7 +7309,7 @@ If ARG is a negative number, hide the unwanted header lines."
        (setq hidden
              (if (numberp arg)
                  (>= arg 0)
        (setq hidden
              (if (numberp arg)
                  (>= arg 0)
-               (save-restriction 
+               (save-restriction
                  (article-narrow-to-head)
                  (gnus-article-hidden-text-p 'headers))))
        (goto-char (point-min))
                  (article-narrow-to-head)
                  (gnus-article-hidden-text-p 'headers))))
        (goto-char (point-min))
@@ -7209,8 +7327,11 @@ If ARG is a negative number, hide the unwanted header lines."
          (if  hidden
              (let ((gnus-treat-hide-headers nil)
                    (gnus-treat-hide-boring-headers nil))
          (if  hidden
              (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."
 
 (defun gnus-summary-show-all-headers ()
   "Make all header lines visible."
@@ -7257,7 +7378,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))
@@ -7275,7 +7398,10 @@ 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")))
        (names '((move "Move" "Moving")
                 (copy "Copy" "Copying")
                 (crosspost "Crosspost" "Crossposting")))
@@ -7294,7 +7420,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))
@@ -7320,7 +7447,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)
@@ -7361,13 +7488,13 @@ and `request-accept' functions."
               art-group))))))
       (cond
        ((not art-group)
               art-group))))))
       (cond
        ((not art-group)
-       (gnus-message 1 "Couldn't %s article %s: %s"
-                     (cadr (assq action names)) article
-                     (nnheader-get-report (car to-method))))
-       ((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))
        (t
        (let* ((pto-group (gnus-group-prefixed-name
                           (car art-group) to-method))
@@ -7388,11 +7515,12 @@ and `request-accept' functions."
               info (gnus-add-to-range (gnus-info-read info)
                                       (list (cdr art-group)))))
 
               info (gnus-add-to-range (gnus-info-read info)
                                       (list (cdr art-group)))))
 
-           ;; Copy any marks over to the new group.
+           ;; See whether the article is to be put in the cache.
            (let ((marks gnus-article-mark-lists)
                  (to-article (cdr art-group)))
 
            (let ((marks gnus-article-mark-lists)
                  (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
@@ -7400,34 +7528,36 @@ and `request-accept' functions."
                 (memq article gnus-newsgroup-dormant)
                 (memq article gnus-newsgroup-unreads)))
 
                 (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)))))
-                  (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)))
+             (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 '"
@@ -7541,7 +7671,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.
@@ -7558,12 +7688,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)
@@ -7591,6 +7720,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
@@ -7645,6 +7777,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)
@@ -7671,31 +7805,63 @@ delete these instead."
     (gnus-set-mode-line 'summary)
     not-deleted))
 
     (gnus-set-mode-line 'summary)
     not-deleted))
 
-(defun gnus-summary-edit-article (&optional force)
+(defun gnus-summary-edit-article (&optional arg)
   "Edit the current article.
 This will have permanent effect only in mail groups.
   "Edit the current article.
 This will have permanent effect only in mail groups.
-If FORCE is non-nil, allow editing of articles even in read-only
+If ARG is nil, edit the decoded articles.
+If ARG is 1, edit the raw articles. 
+If ARG is 2, edit the raw articles even in read-only groups.
+Otherwise, allow editing of articles even in read-only
 groups."
   (interactive "P")
 groups."
   (interactive "P")
-  (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
-       'mime-to-mml
-       `(lambda (no-highlight)
-         (let ((mail-parse-charset ',gnus-newsgroup-charset)
-               (mail-parse-ignored-charsets 
-                ',gnus-newsgroup-ignored-charsets))
-           (mml-to-mime)
-           (gnus-summary-edit-article-done
-            ,(or (mail-header-references gnus-current-headers) "")
-            ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))))))
+  (let (force raw)
+    (cond 
+     ((null arg))
+     ((eq arg 1) (setq raw t))
+     ((eq arg 2) (setq raw t
+                      force t))
+     (t (setq force t)))
+    (if (and raw (not force) (equal gnus-newsgroup-name "nndraft:drafts"))
+       (error "Can't edit the raw article in group nndraft:drafts."))
+    (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)
+       (when (and (not raw) (gnus-buffer-live-p gnus-article-buffer))
+         (with-current-buffer gnus-article-buffer
+           (mm-enable-multibyte-mule4)))
+       (if (equal gnus-newsgroup-name "nndraft:drafts")
+           (setq raw t))
+       (gnus-article-edit-article
+        (if raw 'ignore 
+          #'(lambda () 
+              (let ((mbl mml-buffer-list))
+                (setq mml-buffer-list nil)
+                (mime-to-mml)
+                (make-local-hook 'kill-buffer-hook)
+                (let ((mml-buffer-list mml-buffer-list))
+                  (setq mml-buffer-list mbl)
+                  (make-local-variable 'mml-buffer-list))
+                (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))))
+        `(lambda (no-highlight)
+           (let ((mail-parse-charset ',gnus-newsgroup-charset)
+                 (mail-parse-ignored-charsets 
+                  ',gnus-newsgroup-ignored-charsets))
+             ,(if (not raw) '(progn 
+                               (mml-to-mime)
+                               (mml-destroy-buffers)
+                               (remove-hook 'kill-buffer-hook 
+                                            'mml-destroy-buffers t)
+                               (kill-local-variable 'mml-buffer-list)))
+             (gnus-summary-edit-article-done
+              ,(or (mail-header-references gnus-current-headers) "")
+              ,(gnus-group-read-only-p) 
+              ,gnus-summary-buffer no-highlight))))))))
 
 (defalias 'gnus-summary-edit-article-postpone 'gnus-article-edit-exit)
 
 
 (defalias 'gnus-summary-edit-article-postpone 'gnus-article-edit-exit)
 
@@ -7992,7 +8158,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))
@@ -8084,7 +8251,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)))
@@ -8453,6 +8621,37 @@ read."
     (gnus-summary-catchup all))
   (gnus-summary-next-group))
 
     (gnus-summary-catchup all))
   (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.
 
 (defun gnus-summary-articles-in-thread (&optional article)
 ;; Thread-based commands.
 
 (defun gnus-summary-articles-in-thread (&optional article)
@@ -8531,14 +8730,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)
@@ -8613,9 +8814,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.
@@ -8747,14 +8946,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))
@@ -8781,7 +8980,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."
@@ -8792,6 +8991,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
@@ -8871,7 +9072,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")
-  (let ((gnus-default-article-saver 'rmail-output-to-rmail-file))
+  (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)
@@ -8925,7 +9126,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))
@@ -8944,7 +9145,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)
@@ -8989,7 +9190,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))
@@ -8997,25 +9199,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))
+             (or (and (gnus-request-create-group to-newsgroup to-method)
                       (gnus-activate-group
                       (gnus-activate-group
-                       to-newsgroup nil nil
-                       (gnus-group-name-to-method to-newsgroup))
+                       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))
 
                       (gnus-subscribe-group 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)
@@ -9023,10 +9229,12 @@ 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
          (gnus-summary-save-parts-1 type dir handles reverse)
        (when handles
          (gnus-summary-save-parts-1 type dir handles reverse)
-         (mm-destroy-parts handles))))))
+         (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))
 
 (defun gnus-summary-save-parts-1 (type dir handle reverse)
   (if (stringp (car handle))
@@ -9040,7 +9248,9 @@ If REVERSE, save parts that do not match TYPE."
                    (or
                     (mail-content-type-get
                      (mm-handle-disposition handle) 'filename)
                    (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))))))
@@ -9157,8 +9367,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.
@@ -9232,8 +9444,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)))
@@ -9328,23 +9540,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.
@@ -9383,39 +9604,38 @@ If REVERSE, save parts that do not match TYPE."
   "Setup newsgroup default charset."
   (if (equal gnus-newsgroup-name "nndraft:drafts")
       (setq gnus-newsgroup-charset nil)
   "Setup newsgroup 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 nil))
-                        (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))))
+    (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
@@ -9461,37 +9681,6 @@ treated as multipart/mixed."
        (gnus-summary-show-article))
     (gnus-summary-show-article)))
 
        (gnus-summary-show-article))
     (gnus-summary-show-article)))
 
-;;;
-;;; 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))
-
 ;;;
 ;;; Generic summary marking commands
 ;;;
 ;;;
 ;;; Generic summary marking commands
 ;;;
@@ -9525,7 +9714,7 @@ Then replace the article with the result."
        (setq func (eval func))
        (define-key map (nth 4 lway) func)))))
       
        (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)