* gnus.el: We don't need gnus-article-show-all-headers.
[gnus] / lisp / gnus-sum.el
index 4c3b4ba..de8df4e 100644 (file)
@@ -1,5 +1,5 @@
 ;;; gnus-sum.el --- summary mode commands for Gnus
 ;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
@@ -36,9 +36,8 @@
 (require 'gnus-undo)
 (require 'gnus-util)
 (require 'mm-decode)
 (require 'gnus-undo)
 (require 'gnus-util)
 (require 'mm-decode)
-;; Recursive :-(.
-;; (require 'gnus-art)
 (require 'nnoo)
 (require 'nnoo)
+
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (autoload 'gnus-cache-write-active "gnus-cache")
 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (autoload 'gnus-cache-write-active "gnus-cache")
 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
@@ -235,6 +234,7 @@ simplification is selected."
 
 (defcustom gnus-thread-hide-subtree nil
   "*If non-nil, hide all threads initially.
 
 (defcustom gnus-thread-hide-subtree nil
   "*If non-nil, hide all threads initially.
+This can be a predicate specifier which says which threads to hide.
 If threads are hidden, you have to run the command
 `gnus-summary-show-thread' by hand or use `gnus-select-article-hook'
 to expose hidden threads."
 If threads are hidden, you have to run the command
 `gnus-summary-show-thread' by hand or use `gnus-select-article-hook'
 to expose hidden threads."
@@ -278,25 +278,30 @@ equal will be included."
   :type 'boolean)
 
 (defcustom gnus-auto-select-first t
   :type 'boolean)
 
 (defcustom gnus-auto-select-first t
-  "*If nil, don't select the first unread article when entering a group.
-If this variable is `best', select the highest-scored unread article
-in the group.  If t, select the first unread article.
-
-This variable can also be a function to place point on a likely
-subject line.  Useful values include `gnus-summary-first-unread-subject',
-`gnus-summary-first-unread-article' and
-`gnus-summary-best-unread-article'.
-
-If you want to prevent automatic selection of the first unread article
-in some newsgroups, set the variable to nil in
-`gnus-select-group-hook'."
+  "*If non-nil, select the article under point.
+Which article this is is controlled by the `gnus-auto-select-subject'
+variable.
+
+If you want to prevent automatic selection of articles in some
+newsgroups, set the variable to nil in `gnus-select-group-hook'."
   :group 'gnus-group-select
   :type '(choice (const :tag "none" nil)
   :group 'gnus-group-select
   :type '(choice (const :tag "none" nil)
-                (const best)
-                (sexp :menu-tag "first" t)
-                (function-item gnus-summary-first-unread-subject)
-                (function-item gnus-summary-first-unread-article)
-                (function-item gnus-summary-best-unread-article)))
+                (sexp :menu-tag "first" t)))
+
+(defcustom gnus-auto-select-subject 'unread
+  "*Says what subject to place under point when entering a group.
+
+This variable can either be the symbols `first' (place point on the
+first subject), `unread' (place point on the subject line of the first
+unread article), `best' (place point on the subject line of the
+higest-scored article), `unseen' (place point on the subject line of
+the first unseen article), or a function to be called to place point on
+some subject line.."
+  :group 'gnus-group-select
+  :type '(choice (const best)
+                (const unread)
+                (const first)
+                (const unseen)))
 
 (defcustom gnus-auto-select-next t
   "*If non-nil, offer to go to the next group from the end of the previous.
 
 (defcustom gnus-auto-select-next t
   "*If non-nil, offer to go to the next group from the end of the previous.
@@ -374,7 +379,7 @@ this variable specifies group names."
                         (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)
@@ -434,22 +439,32 @@ this variable specifies group names."
   :group 'gnus-summary-marks
   :type 'character)
 
   :group 'gnus-summary-marks
   :type 'character)
 
-(defcustom gnus-forwarded-mark ?O
+(defcustom gnus-forwarded-mark ?F
   "*Mark used for articles that have been forwarded."
   :group 'gnus-summary-marks
   :type 'character)
 
   "*Mark used for articles that have been forwarded."
   :group 'gnus-summary-marks
   :type 'character)
 
+(defcustom gnus-recent-mark ?N
+  "*Mark used for articles that are recent."
+  :group 'gnus-summary-marks
+  :type 'character)
+
 (defcustom gnus-cached-mark ?*
   "*Mark used for articles that are in the cache."
   :group 'gnus-summary-marks
   :type 'character)
 
 (defcustom gnus-saved-mark ?S
 (defcustom gnus-cached-mark ?*
   "*Mark used for articles that are in the cache."
   :group 'gnus-summary-marks
   :type 'character)
 
 (defcustom gnus-saved-mark ?S
-  "*Mark used for articles that have been saved to."
+  "*Mark used for articles that have been saved."
+  :group 'gnus-summary-marks
+  :type 'character)
+
+(defcustom gnus-unseen-mark ?.
+  "*Mark used for articles that haven't been seen."
   :group 'gnus-summary-marks
   :type 'character)
 
   :group 'gnus-summary-marks
   :type 'character)
 
-(defcustom gnus-no-mark ?  ;Whitespace
+(defcustom gnus-no-mark ?               ;Whitespace
   "*Mark used for articles that have no other secondary mark."
   :group 'gnus-summary-marks
   :type 'character)
   "*Mark used for articles that have no other secondary mark."
   :group 'gnus-summary-marks
   :type 'character)
@@ -499,7 +514,7 @@ this variable specifies group names."
   :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)
@@ -556,7 +571,11 @@ list of parameters to that command."
 It works along the same lines as a normal formatting string,
 with some simple extensions.
 
 It works along the same lines as a normal formatting string,
 with some simple extensions.
 
-%S  The subject"
+%S  The subject
+
+General format specifiers can also be used.  
+See (gnus)Formatting Variables."
+  :link '(custom-manual "(gnus)Formatting Variables")
   :group 'gnus-threading
   :type 'string)
 
   :group 'gnus-threading
   :type 'string)
 
@@ -641,7 +660,9 @@ was sent, sorting by number means sorting by arrival time.)
 
 Ready-made functions include `gnus-thread-sort-by-number',
 `gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
 
 Ready-made functions include `gnus-thread-sort-by-number',
 `gnus-thread-sort-by-author', `gnus-thread-sort-by-subject',
-`gnus-thread-sort-by-date', `gnus-thread-sort-by-score' and
+`gnus-thread-sort-by-date', `gnus-thread-sort-by-score',
+`gnus-thread-sort-by-most-recent-number',
+`gnus-thread-sort-by-most-recent-date', and
 `gnus-thread-sort-by-total-score' (see `gnus-thread-score-function').
 
 When threading is turned off, the variable
 `gnus-thread-sort-by-total-score' (see `gnus-thread-score-function').
 
 When threading is turned off, the variable
@@ -686,7 +707,7 @@ This variable is local to the summary buffers."
 (defcustom gnus-summary-mode-hook nil
   "*A hook for Gnus summary mode.
 This hook is run before any variables are set in the summary buffer."
 (defcustom gnus-summary-mode-hook nil
   "*A hook for Gnus summary mode.
 This hook is run before any variables are set in the summary buffer."
-  :options '(turn-on-gnus-mailing-list-mode)
+  :options '(turn-on-gnus-mailing-list-mode gnus-pick-mode)
   :group 'gnus-summary-various
   :type 'hook)
 
   :group 'gnus-summary-various
   :type 'hook)
 
@@ -733,15 +754,14 @@ If you'd like to simplify subjects like the
 `gnus-summary-next-same-subject' command does, you can use the
 following hook:
 
 `gnus-summary-next-same-subject' command does, you can use the
 following hook:
 
- (setq gnus-select-group-hook
-      (list
-       (lambda ()
-         (mapcar (lambda (header)
-                    (mail-header-set-subject
-                     header
-                     (gnus-simplify-subject
-                      (mail-header-subject header) 're-only)))
-                 gnus-newsgroup-headers))))"
+ (add-hook gnus-select-group-hook
+          (lambda ()
+            (mapcar (lambda (header)
+                      (mail-header-set-subject
+                       header
+                       (gnus-simplify-subject
+                        (mail-header-subject header) 're-only)))
+                    gnus-newsgroup-headers)))"
   :group 'gnus-group-select
   :type 'hook)
 
   :group 'gnus-group-select
   :type 'hook)
 
@@ -837,10 +857,10 @@ automatically when it is selected."
     ((= mark gnus-unread-mark)
      . gnus-summary-normal-unread-face)
     ((and (> score default-high) (memq mark (list gnus-downloadable-mark
     ((= mark gnus-unread-mark)
      . gnus-summary-normal-unread-face)
     ((and (> score default-high) (memq mark (list gnus-downloadable-mark
-                                            gnus-undownloaded-mark)))
+                                                 gnus-undownloaded-mark)))
      . gnus-summary-high-unread-face)
     ((and (< score default-low) (memq mark (list gnus-downloadable-mark
      . gnus-summary-high-unread-face)
     ((and (< score default-low) (memq mark (list gnus-downloadable-mark
-                                            gnus-undownloaded-mark)))
+                                                gnus-undownloaded-mark)))
      . gnus-summary-low-unread-face)
     ((and (memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
          (memq article gnus-newsgroup-unreads))
      . gnus-summary-low-unread-face)
     ((and (memq mark (list gnus-downloadable-mark gnus-undownloaded-mark))
          (memq article gnus-newsgroup-unreads))
@@ -880,7 +900,7 @@ which it may alter in any way.")
 (defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
   "Variable that says which function should be used to decode a string with encoded words.")
 
 (defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
   "Variable that says which function should be used to decode a string with encoded words.")
 
-(defcustom gnus-extra-headers nil
+(defcustom gnus-extra-headers '(To Newsgroups)
   "*Extra headers to parse."
   :version "21.1"
   :group 'gnus-summary
   "*Extra headers to parse."
   :version "21.1"
   :group 'gnus-summary
@@ -907,7 +927,7 @@ default charset will be used instead."
  :function-document
  "Return the ignored charsets of GROUP."
  :variable gnus-group-ignored-charsets-alist
  :function-document
  "Return the ignored charsets of GROUP."
  :variable gnus-group-ignored-charsets-alist
- :variable-default 
+ :variable-default
  '(("alt\\.chinese\\.text" iso-8859-1))
  :variable-document
  "Alist of regexps (to match group names) and charsets that should be ignored.
  '(("alt\\.chinese\\.text" iso-8859-1))
  :variable-document
  "Alist of regexps (to match group names) and charsets that should be ignored.
@@ -916,7 +936,7 @@ default charset will be used instead."
  :variable-group gnus-charset
  :variable-type '(repeat (cons (regexp :tag "Group")
                               (repeat symbol)))
  :variable-group gnus-charset
  :variable-type '(repeat (cons (regexp :tag "Group")
                               (repeat symbol)))
- :parameter-type '(choice :tag "Ignored charsets" 
+ :parameter-type '(choice :tag "Ignored charsets"
                          :value nil
                          (repeat (symbol)))
  :parameter-document       "\
                          :value nil
                          (repeat (symbol)))
  :parameter-document       "\
@@ -988,8 +1008,14 @@ that were fetched.  Say, for nnultimate groups."
   :group 'gnus-summary
   :type '(choice boolean regexp))
 
   :group 'gnus-summary
   :type '(choice boolean regexp))
 
+(defcustom gnus-summary-muttprint-program "muttprint"
+  "Command (and optional arguments) used to run Muttprint."
+  :group 'gnus-summary
+  :type 'string)
+
 ;;; Internal variables
 
 ;;; Internal variables
 
+(defvar gnus-summary-display-cache nil)
 (defvar gnus-article-mime-handles nil)
 (defvar gnus-article-decoded-p nil)
 (defvar gnus-article-charset nil)
 (defvar gnus-article-mime-handles nil)
 (defvar gnus-article-decoded-p nil)
 (defvar gnus-article-charset nil)
@@ -1022,6 +1048,7 @@ that were fetched.  Say, for nnultimate groups."
 (defvar gnus-current-move-group nil)
 (defvar gnus-current-copy-group nil)
 (defvar gnus-current-crosspost-group nil)
 (defvar gnus-current-move-group nil)
 (defvar gnus-current-copy-group nil)
 (defvar gnus-current-crosspost-group nil)
+(defvar gnus-newsgroup-display nil)
 
 (defvar gnus-newsgroup-dependencies nil)
 (defvar gnus-newsgroup-adaptive nil)
 
 (defvar gnus-newsgroup-dependencies nil)
 (defvar gnus-newsgroup-adaptive nil)
@@ -1059,7 +1086,8 @@ that were fetched.  Say, for nnultimate groups."
     (?l (bbb-grouplens-score gnus-tmp-header) ?s)
     (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d)
     (?U gnus-tmp-unread ?c)
     (?l (bbb-grouplens-score gnus-tmp-header) ?s)
     (?V (gnus-thread-total-score (and (boundp 'thread) (car thread))) ?d)
     (?U gnus-tmp-unread ?c)
-    (?f (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header) ?s)
+    (?f (gnus-summary-from-or-to-or-newsgroups gnus-tmp-header gnus-tmp-from)
+       ?s)
     (?t (gnus-summary-number-of-articles-in-thread
         (and (boundp 'thread) (car thread)) gnus-tmp-level)
        ?d)
     (?t (gnus-summary-number-of-articles-in-thread
         (and (boundp 'thread) (car thread)) gnus-tmp-level)
        ?d)
@@ -1068,7 +1096,9 @@ that were fetched.  Say, for nnultimate groups."
        ?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)
-    (?B gnus-tmp-thread-tree-header-string ?s))
+    (?B gnus-tmp-thread-tree-header-string ?s)
+    (user-date (gnus-user-date
+               ,(macroexpand '(mail-header-date gnus-tmp-header))) ?s))
   "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).")
   "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).")
@@ -1147,6 +1177,9 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-forwarded nil
   "List of articles that have been forwarded in the current newsgroup.")
 
 (defvar gnus-newsgroup-forwarded nil
   "List of articles that have been forwarded in the current newsgroup.")
 
+(defvar gnus-newsgroup-recent nil
+  "List of articles that have are recent in the current newsgroup.")
+
 (defvar gnus-newsgroup-expirable nil
   "List of articles in the current newsgroup that can be expired.")
 
 (defvar gnus-newsgroup-expirable nil
   "List of articles in the current newsgroup that can be expired.")
 
@@ -1168,6 +1201,15 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-dormant nil
   "List of dormant articles in the current newsgroup.")
 
 (defvar gnus-newsgroup-dormant nil
   "List of dormant articles in the current newsgroup.")
 
+(defvar gnus-newsgroup-unseen nil
+  "List of unseen articles in the current newsgroup.")
+
+(defvar gnus-newsgroup-seen nil
+  "Range of seen articles in the current newsgroup.")
+
+(defvar gnus-newsgroup-articles nil
+  "List of articles in the current newsgroup.")
+
 (defvar gnus-newsgroup-scored nil
   "List of scored articles in the current newsgroup.")
 
 (defvar gnus-newsgroup-scored nil
   "List of scored articles in the current newsgroup.")
 
@@ -1205,10 +1247,12 @@ the type of the variable (string, integer, character, etc).")
     gnus-newsgroup-unselected gnus-newsgroup-marked
     gnus-newsgroup-reads gnus-newsgroup-saved
     gnus-newsgroup-replied gnus-newsgroup-forwarded
     gnus-newsgroup-unselected gnus-newsgroup-marked
     gnus-newsgroup-reads gnus-newsgroup-saved
     gnus-newsgroup-replied gnus-newsgroup-forwarded
+    gnus-newsgroup-recent
     gnus-newsgroup-expirable
     gnus-newsgroup-processable gnus-newsgroup-killed
     gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
     gnus-newsgroup-expirable
     gnus-newsgroup-processable gnus-newsgroup-killed
     gnus-newsgroup-downloadable gnus-newsgroup-undownloaded
-    gnus-newsgroup-unsendable
+    gnus-newsgroup-unsendable gnus-newsgroup-unseen
+    gnus-newsgroup-seen gnus-newsgroup-articles
     gnus-newsgroup-bookmarks gnus-newsgroup-dormant
     gnus-newsgroup-headers gnus-newsgroup-threads
     gnus-newsgroup-prepared gnus-summary-highlight-line-function
     gnus-newsgroup-bookmarks gnus-newsgroup-dormant
     gnus-newsgroup-headers gnus-newsgroup-threads
     gnus-newsgroup-prepared gnus-summary-highlight-line-function
@@ -1230,11 +1274,23 @@ the type of the variable (string, integer, character, etc).")
     gnus-cache-removable-articles gnus-newsgroup-cached
     gnus-newsgroup-data gnus-newsgroup-data-reverse
     gnus-newsgroup-limit gnus-newsgroup-limits
     gnus-cache-removable-articles gnus-newsgroup-cached
     gnus-newsgroup-data gnus-newsgroup-data-reverse
     gnus-newsgroup-limit gnus-newsgroup-limits
-    gnus-newsgroup-charset)
+    gnus-newsgroup-charset gnus-newsgroup-display)
   "Variables that are buffer-local to the summary buffers.")
 
 (defvar gnus-newsgroup-variables nil
   "Variables that are buffer-local to the summary buffers.")
 
 (defvar gnus-newsgroup-variables nil
-  "Variables that have separate values in the newsgroups.")
+  "A list of variables that have separate values in different newsgroups.
+A list of newsgroup (summary buffer) local variables, or cons of
+variables and their default values (when the default values are not
+nil), that should be made global while the summary buffer is active.
+These variables can be used to set variables in the group parameters
+while still allowing them to affect operations done in other
+buffers. For example:
+
+\(setq gnus-newsgroup-variables
+     '(message-use-followup-to
+       (gnus-visible-headers .
+        \"^From:\\\\|^Newsgroups:\\\\|^Subject:\\\\|^Date:\\\\|^To:\")))
+")
 
 ;; Byte-compiler warning.
 (eval-when-compile (defvar gnus-article-mode-map))
 
 ;; Byte-compiler warning.
 (eval-when-compile (defvar gnus-article-mode-map))
@@ -1245,13 +1301,13 @@ the type of the 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
-(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups
+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:
 whose names match REGEXP.
 
 For example:
-((\"chinese\" . gnus-decode-encoded-word-string-by-guess)
+\((\"chinese\" . gnus-decode-encoded-word-string-by-guess)
  mail-decode-encoded-word-string
  (\"chinese\" . rfc1843-decode-string))")
 
  mail-decode-encoded-word-string
  (\"chinese\" . rfc1843-decode-string))")
 
@@ -1270,7 +1326,7 @@ For example:
                         (string-match (car x) gnus-newsgroup-name))
                    (nconc gnus-decode-encoded-word-methods-cache
                           (list (cdr x))))))
                         (string-match (car x) gnus-newsgroup-name))
                    (nconc gnus-decode-encoded-word-methods-cache
                           (list (cdr x))))))
-         gnus-decode-encoded-word-methods))
+           gnus-decode-encoded-word-methods))
   (let ((xlist gnus-decode-encoded-word-methods-cache))
     (pop xlist)
     (while xlist
   (let ((xlist gnus-decode-encoded-word-methods-cache))
     (pop xlist)
     (while xlist
@@ -1285,8 +1341,8 @@ For example:
     ;; Multiple spaces.
     (while (string-match "[ \t][ \t]+" mystr)
       (setq mystr (concat (substring mystr 0 (match-beginning 0))
     ;; Multiple spaces.
     (while (string-match "[ \t][ \t]+" mystr)
       (setq mystr (concat (substring mystr 0 (match-beginning 0))
-                          " "
-                          (substring mystr (match-end 0)))))
+                         " "
+                         (substring mystr (match-end 0)))))
     ;; Leading spaces.
     (when (string-match "^[ \t]+" mystr)
       (setq mystr (substring mystr (match-end 0))))
     ;; Leading spaces.
     (when (string-match "^[ \t]+" mystr)
       (setq mystr (substring mystr (match-end 0))))
@@ -1501,6 +1557,7 @@ increase the score of each group you read."
     gnus-mouse-2 gnus-mouse-pick-article
     "m" gnus-summary-mail-other-window
     "a" gnus-summary-post-news
     gnus-mouse-2 gnus-mouse-pick-article
     "m" gnus-summary-mail-other-window
     "a" gnus-summary-post-news
+    "i" gnus-summary-news-other-window
     "x" gnus-summary-limit-to-unread
     "s" gnus-summary-isearch-article
     "t" gnus-summary-toggle-header
     "x" gnus-summary-limit-to-unread
     "s" gnus-summary-isearch-article
     "t" gnus-summary-toggle-header
@@ -1574,6 +1631,7 @@ increase the score of each group you read."
     "d" gnus-summary-limit-exclude-dormant
     "t" gnus-summary-limit-to-age
     "x" gnus-summary-limit-to-extra
     "d" gnus-summary-limit-exclude-dormant
     "t" gnus-summary-limit-to-age
     "x" gnus-summary-limit-to-extra
+    "p" gnus-summary-limit-to-display-predicate
     "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
@@ -1673,6 +1731,7 @@ increase the score of each group you read."
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
     "t" gnus-summary-toggle-header
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
     "t" gnus-summary-toggle-header
+    "g" gnus-treat-smiley
     "v" gnus-summary-verbose-headers
     "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
     "p" gnus-article-verify-x-pgp-sig
     "v" gnus-summary-verbose-headers
     "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
     "p" gnus-article-verify-x-pgp-sig
@@ -1697,6 +1756,19 @@ increase the score of each group you read."
     "c" gnus-article-highlight-citation
     "s" gnus-article-highlight-signature)
 
     "c" gnus-article-highlight-citation
     "s" gnus-article-highlight-signature)
 
+  (gnus-define-keys (gnus-summary-wash-header-map "G" gnus-summary-wash-map)
+    "f" gnus-article-treat-fold-headers
+    "u" gnus-article-treat-unfold-headers
+    "n" gnus-article-treat-fold-newsgroups)
+
+  (gnus-define-keys (gnus-summary-wash-display-map "D" gnus-summary-wash-map)
+    "x" gnus-article-display-x-face
+    "s" gnus-treat-smiley
+    "D" gnus-article-remove-images
+    "f" gnus-treat-from-picon
+    "m" gnus-treat-mail-picon
+    "n" gnus-treat-newsgroups-picon)
+
   (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
     "w" gnus-article-decode-mime-words
     "c" gnus-article-decode-charset
   (gnus-define-keys (gnus-summary-wash-mime-map "M" gnus-summary-wash-map)
     "w" gnus-article-decode-mime-words
     "c" gnus-article-decode-charset
@@ -1757,6 +1829,7 @@ increase the score of each group you read."
     "h" gnus-summary-save-article-folder
     "v" gnus-summary-save-article-vm
     "p" gnus-summary-pipe-output
     "h" gnus-summary-save-article-folder
     "v" gnus-summary-save-article-vm
     "p" gnus-summary-pipe-output
+    "P" gnus-summary-muttprint
     "s" gnus-soup-add-article)
 
   (gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
     "s" gnus-soup-add-article)
 
   (gnus-define-keys (gnus-summary-mime-map "K" gnus-summary-mode-map)
@@ -1779,49 +1852,50 @@ increase the score of each group you read."
   (unless (boundp 'gnus-summary-misc-menu)
 
     (easy-menu-define
   (unless (boundp 'gnus-summary-misc-menu)
 
     (easy-menu-define
-     gnus-summary-kill-menu gnus-summary-mode-map ""
-     (cons
-      "Score"
-      (nconc
-       (list
-       ["Customize" gnus-score-customize t])
-       (gnus-make-score-map 'increase)
-       (gnus-make-score-map 'lower)
-       '(("Mark"
-         ["Kill below" gnus-summary-kill-below t]
-         ["Mark above" gnus-summary-mark-above t]
-         ["Tick above" gnus-summary-tick-above t]
-         ["Clear above" gnus-summary-clear-above t])
-        ["Current score" gnus-summary-current-score t]
-        ["Set score" gnus-summary-set-score t]
-        ["Switch current score file..." gnus-score-change-score-file t]
-        ["Set mark below..." gnus-score-set-mark-below t]
-        ["Set expunge below..." gnus-score-set-expunge-below t]
-        ["Edit current score file" gnus-score-edit-current-scores t]
-        ["Edit score file" gnus-score-edit-file t]
-        ["Trace score" gnus-score-find-trace t]
-        ["Find words" gnus-score-find-favourite-words t]
-        ["Rescore buffer" gnus-summary-rescore t]
-        ["Increase score..." gnus-summary-increase-score t]
-        ["Lower score..." gnus-summary-lower-score t]))))
-
-    ;; Define both the Article menu in the summary buffer and the equivalent
-    ;; Commands menu in the article buffer here for consistency.
+      gnus-summary-kill-menu gnus-summary-mode-map ""
+      (cons
+       "Score"
+       (nconc
+       (list
+        ["Customize" gnus-score-customize t])
+       (gnus-make-score-map 'increase)
+       (gnus-make-score-map 'lower)
+       '(("Mark"
+          ["Kill below" gnus-summary-kill-below t]
+          ["Mark above" gnus-summary-mark-above t]
+          ["Tick above" gnus-summary-tick-above t]
+          ["Clear above" gnus-summary-clear-above t])
+         ["Current score" gnus-summary-current-score t]
+         ["Set score" gnus-summary-set-score t]
+         ["Switch current score file..." gnus-score-change-score-file t]
+         ["Set mark below..." gnus-score-set-mark-below t]
+         ["Set expunge below..." gnus-score-set-expunge-below t]
+         ["Edit current score file" gnus-score-edit-current-scores t]
+         ["Edit score file" gnus-score-edit-file t]
+         ["Trace score" gnus-score-find-trace t]
+         ["Find words" gnus-score-find-favourite-words t]
+         ["Rescore buffer" gnus-summary-rescore t]
+         ["Increase score..." gnus-summary-increase-score t]
+         ["Lower score..." gnus-summary-lower-score t]))))
+
+    ;; Define both the Article menu in the summary buffer and the
+    ;; equivalent Commands menu in the article buffer here for
+    ;; consistency.
     (let ((innards
     (let ((innards
-           `(("Hide"
-              ["All" gnus-article-hide t]
-              ["Headers" gnus-article-hide-headers t]
-              ["Signature" gnus-article-hide-signature t]
-              ["Citation" gnus-article-hide-citation t]
+          `(("Hide"
+             ["All" gnus-article-hide t]
+             ["Headers" gnus-article-hide-headers t]
+             ["Signature" gnus-article-hide-signature t]
+             ["Citation" gnus-article-hide-citation t]
              ["List identifiers" gnus-article-hide-list-identifiers t]
              ["List identifiers" gnus-article-hide-list-identifiers t]
-              ["PGP" gnus-article-hide-pgp t]
+             ["PGP" gnus-article-hide-pgp t]
              ["Banner" gnus-article-strip-banner t]
              ["Banner" gnus-article-strip-banner t]
-              ["Boring headers" gnus-article-hide-boring-headers t])
-             ("Highlight"
-              ["All" gnus-article-highlight t]
-              ["Headers" gnus-article-highlight-headers t]
-              ["Signature" gnus-article-highlight-signature t]
-              ["Citation" gnus-article-highlight-citation t])
+             ["Boring headers" gnus-article-hide-boring-headers t])
+            ("Highlight"
+             ["All" gnus-article-highlight t]
+             ["Headers" gnus-article-highlight-headers t]
+             ["Signature" gnus-article-highlight-signature t]
+             ["Citation" gnus-article-highlight-citation t])
             ("MIME"
              ["Words" gnus-article-decode-mime-words t]
              ["Charset" gnus-article-decode-charset t]
             ("MIME"
              ["Words" gnus-article-decode-mime-words t]
              ["Charset" gnus-article-decode-charset t]
@@ -1830,182 +1904,196 @@ increase the score of each group you read."
              ["View all" gnus-mime-view-all-parts t]
              ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
              ["Encrypt body" gnus-article-encrypt-body t])
              ["View all" gnus-mime-view-all-parts t]
              ["Verify and Decrypt" gnus-summary-force-verify-and-decrypt t]
              ["Encrypt body" gnus-article-encrypt-body t])
-             ("Date"
-              ["Local" gnus-article-date-local t]
-              ["ISO8601" gnus-article-date-iso8601 t]
-              ["UT" gnus-article-date-ut t]
-              ["Original" gnus-article-date-original t]
-              ["Lapsed" gnus-article-date-lapsed t]
-              ["User-defined" gnus-article-date-user t])
-             ("Washing"
-              ("Remove Blanks"
-               ["Leading" gnus-article-strip-leading-blank-lines t]
-               ["Multiple" gnus-article-strip-multiple-blank-lines t]
-               ["Trailing" gnus-article-remove-trailing-blank-lines t]
-               ["All of the above" gnus-article-strip-blank-lines t]
-               ["All" gnus-article-strip-all-blank-lines t]
-               ["Leading space" gnus-article-strip-leading-space t]
+            ("Date"
+             ["Local" gnus-article-date-local t]
+             ["ISO8601" gnus-article-date-iso8601 t]
+             ["UT" gnus-article-date-ut t]
+             ["Original" gnus-article-date-original t]
+             ["Lapsed" gnus-article-date-lapsed t]
+             ["User-defined" gnus-article-date-user t])
+            ("Display"
+             ["Remove images" gnus-article-remove-images t]
+             ["Toggle smiley" gnus-treat-smiley t]
+             ["Show X-Face" gnus-article-display-x-face t]
+             ["Show picons in From" gnus-treat-from-picon t]
+             ["Show picons in mail headers" gnus-treat-mail-picon t]
+             ["Show picons in news headers" gnus-treat-newsgroups-picon t])
+            ("Washing"
+             ("Remove Blanks"
+              ["Leading" gnus-article-strip-leading-blank-lines t]
+              ["Multiple" gnus-article-strip-multiple-blank-lines t]
+              ["Trailing" gnus-article-remove-trailing-blank-lines t]
+              ["All of the above" gnus-article-strip-blank-lines t]
+              ["All" gnus-article-strip-all-blank-lines t]
+              ["Leading space" gnus-article-strip-leading-space t]
               ["Trailing space" gnus-article-strip-trailing-space t]
               ["Trailing space" gnus-article-strip-trailing-space t]
-               ["Leading space in headers" 
+              ["Leading space in headers"
                gnus-article-remove-leading-whitespace t])
                gnus-article-remove-leading-whitespace t])
-              ["Overstrike" gnus-article-treat-overstrike t]
-              ["Dumb quotes" gnus-article-treat-dumbquotes t]
-              ["Emphasis" gnus-article-emphasize t]
-              ["Word wrap" gnus-article-fill-cited-article t]
+             ["Overstrike" gnus-article-treat-overstrike t]
+             ["Dumb quotes" gnus-article-treat-dumbquotes t]
+             ["Emphasis" gnus-article-emphasize t]
+             ["Word wrap" gnus-article-fill-cited-article t]
              ["Fill long lines" gnus-article-fill-long-lines t]
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
              ["Fill long lines" gnus-article-fill-long-lines t]
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
-              ["CR" gnus-article-remove-cr t]
-              ["Show X-Face" gnus-article-display-x-face t]
-              ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
-              ["Base64" gnus-article-de-base64-unreadable t]
-              ["Rot 13" gnus-summary-caesar-message
+             ["CR" gnus-article-remove-cr t]
+             ["Quoted-Printable" gnus-article-de-quoted-unreadable t]
+             ["Base64" gnus-article-de-base64-unreadable t]
+             ["Rot 13" gnus-summary-caesar-message
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "\"Caesar rotate\" article by 13"))]
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "\"Caesar rotate\" article by 13"))]
-              ["Unix pipe" gnus-summary-pipe-message t]
-              ["Add buttons" gnus-article-add-buttons t]
-              ["Add buttons to head" gnus-article-add-buttons-to-head t]
-              ["Stop page breaking" gnus-summary-stop-page-breaking t]
-              ["Verbose header" gnus-summary-verbose-headers t]
-              ["Toggle header" gnus-summary-toggle-header 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]
+             ["Unfold headers" gnus-article-treat-unfold-headers t]
+             ["Fold newsgroups" gnus-article-treat-fold-newsgroups t]
              ["Html" gnus-article-wash-html t]
              ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["HZ" gnus-article-decode-HZ t])
              ["Html" gnus-article-wash-html t]
              ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
              ["HZ" gnus-article-decode-HZ t])
-             ("Output"
-              ["Save in default format" gnus-summary-save-article
+            ("Output"
+             ["Save in default format" gnus-summary-save-article
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "Save article using default method"))]
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "Save article using default method"))]
-              ["Save in file" gnus-summary-save-article-file
+             ["Save in file" gnus-summary-save-article-file
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "Save article in file"))]
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "Save article in file"))]
-              ["Save in Unix mail format" gnus-summary-save-article-mail t]
-              ["Save in MH folder" gnus-summary-save-article-folder t]
-              ["Save in VM folder" gnus-summary-save-article-vm t]
-              ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
-              ["Save body in file" gnus-summary-save-article-body-file t]
-              ["Pipe through a filter" gnus-summary-pipe-output t]
-              ["Add to SOUP packet" gnus-soup-add-article t]
-              ["Print" gnus-summary-print-article t])
-             ("Backend"
-              ["Respool article..." gnus-summary-respool-article t]
-              ["Move article..." gnus-summary-move-article
-               (gnus-check-backend-function
-                'request-move-article gnus-newsgroup-name)]
-              ["Copy article..." gnus-summary-copy-article t]
-              ["Crosspost article..." gnus-summary-crosspost-article
-               (gnus-check-backend-function
-                'request-replace-article gnus-newsgroup-name)]
-              ["Import file..." gnus-summary-import-article t]
-              ["Create article..." gnus-summary-create-article t]
-              ["Check if posted" gnus-summary-article-posted-p t]
-              ["Edit article" gnus-summary-edit-article
-               (not (gnus-group-read-only-p))]
-              ["Delete article" gnus-summary-delete-article
-               (gnus-check-backend-function
-                'request-expire-articles gnus-newsgroup-name)]
-              ["Query respool" gnus-summary-respool-query t]
+             ["Save in Unix mail format" gnus-summary-save-article-mail t]
+             ["Save in MH folder" gnus-summary-save-article-folder t]
+             ["Save in VM folder" gnus-summary-save-article-vm t]
+             ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
+             ["Save body in file" gnus-summary-save-article-body-file t]
+             ["Pipe through a filter" gnus-summary-pipe-output t]
+             ["Add to SOUP packet" gnus-soup-add-article t]
+             ["Print with Muttprint" gnus-summary-muttprint t]
+             ["Print" gnus-summary-print-article t])
+            ("Backend"
+             ["Respool article..." gnus-summary-respool-article t]
+             ["Move article..." gnus-summary-move-article
+              (gnus-check-backend-function
+               'request-move-article gnus-newsgroup-name)]
+             ["Copy article..." gnus-summary-copy-article t]
+             ["Crosspost article..." gnus-summary-crosspost-article
+              (gnus-check-backend-function
+               'request-replace-article gnus-newsgroup-name)]
+             ["Import file..." gnus-summary-import-article t]
+             ["Create article..." gnus-summary-create-article t]
+             ["Check if posted" gnus-summary-article-posted-p t]
+             ["Edit article" gnus-summary-edit-article
+              (not (gnus-group-read-only-p))]
+             ["Delete article" gnus-summary-delete-article
+              (gnus-check-backend-function
+               'request-expire-articles gnus-newsgroup-name)]
+             ["Query respool" gnus-summary-respool-query t]
              ["Trace respool" gnus-summary-respool-trace t]
              ["Trace respool" gnus-summary-respool-trace t]
-              ["Delete expirable articles" gnus-summary-expire-articles-now
-               (gnus-check-backend-function
-                'request-expire-articles gnus-newsgroup-name)])
-             ("Extract"
-              ["Uudecode" gnus-uu-decode-uu
+             ["Delete expirable articles" gnus-summary-expire-articles-now
+              (gnus-check-backend-function
+               'request-expire-articles gnus-newsgroup-name)])
+            ("Extract"
+             ["Uudecode" gnus-uu-decode-uu
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "Decode uuencoded article(s)"))]
               ,@(if (featurep 'xemacs) '(t)
                   '(:help "Decode uuencoded article(s)"))]
-              ["Uudecode and save" gnus-uu-decode-uu-and-save t]
-              ["Unshar" gnus-uu-decode-unshar t]
-              ["Unshar and save" gnus-uu-decode-unshar-and-save t]
-              ["Save" gnus-uu-decode-save t]
-              ["Binhex" gnus-uu-decode-binhex t]
-              ["Postscript" gnus-uu-decode-postscript t])
-             ("Cache"
-              ["Enter article" gnus-cache-enter-article t]
-              ["Remove article" gnus-cache-remove-article t])
+             ["Uudecode and save" gnus-uu-decode-uu-and-save t]
+             ["Unshar" gnus-uu-decode-unshar t]
+             ["Unshar and save" gnus-uu-decode-unshar-and-save t]
+             ["Save" gnus-uu-decode-save t]
+             ["Binhex" gnus-uu-decode-binhex t]
+             ["Postscript" gnus-uu-decode-postscript t])
+            ("Cache"
+             ["Enter article" gnus-cache-enter-article t]
+             ["Remove article" gnus-cache-remove-article t])
             ["Translate" gnus-article-babel t]
             ["Translate" gnus-article-babel t]
-             ["Select article buffer" gnus-summary-select-article-buffer t]
-             ["Enter digest buffer" gnus-summary-enter-digest-group t]
-             ["Isearch article..." gnus-summary-isearch-article t]
-             ["Beginning of the article" gnus-summary-beginning-of-article t]
-             ["End of the article" gnus-summary-end-of-article t]
-             ["Fetch parent of article" gnus-summary-refer-parent-article t]
-             ["Fetch referenced articles" gnus-summary-refer-references t]
-             ["Fetch current thread" gnus-summary-refer-thread t]
-             ["Fetch article with id..." gnus-summary-refer-article t]
-             ["Setup Mailing List Params" gnus-mailing-list-insinuate t]
-             ["Redisplay" gnus-summary-show-article t]
-             ["Raw article" gnus-summary-show-raw-article t])))
+            ["Select article buffer" gnus-summary-select-article-buffer t]
+            ["Enter digest buffer" gnus-summary-enter-digest-group t]
+            ["Isearch article..." gnus-summary-isearch-article t]
+            ["Beginning of the article" gnus-summary-beginning-of-article t]
+            ["End of the article" gnus-summary-end-of-article t]
+            ["Fetch parent of article" gnus-summary-refer-parent-article t]
+            ["Fetch referenced articles" gnus-summary-refer-references t]
+            ["Fetch current thread" gnus-summary-refer-thread t]
+            ["Fetch article with id..." gnus-summary-refer-article t]
+            ["Setup Mailing List Params" gnus-mailing-list-insinuate t]
+            ["Redisplay" gnus-summary-show-article t]
+            ["Raw article" gnus-summary-show-raw-article :keys "C-u g"])))
       (easy-menu-define
       (easy-menu-define
-       gnus-summary-article-menu gnus-summary-mode-map ""
-       (cons "Article" innards))
+       gnus-summary-article-menu gnus-summary-mode-map ""
+       (cons "Article" innards))
 
       (if (not (keymapp gnus-summary-article-menu))
          (easy-menu-define
            gnus-article-commands-menu gnus-article-mode-map ""
            (cons "Commands" innards))
        ;; in Emacs, don't share menu.
 
       (if (not (keymapp gnus-summary-article-menu))
          (easy-menu-define
            gnus-article-commands-menu gnus-article-mode-map ""
            (cons "Commands" innards))
        ;; in Emacs, don't share menu.
-       (setq gnus-article-commands-menu 
+       (setq gnus-article-commands-menu
              (copy-keymap gnus-summary-article-menu))
        (define-key gnus-article-mode-map [menu-bar commands]
          (cons "Commands" gnus-article-commands-menu))))
 
     (easy-menu-define
              (copy-keymap gnus-summary-article-menu))
        (define-key gnus-article-mode-map [menu-bar commands]
          (cons "Commands" gnus-article-commands-menu))))
 
     (easy-menu-define
-     gnus-summary-thread-menu gnus-summary-mode-map ""
-     '("Threads"
-       ["Toggle threading" gnus-summary-toggle-threads t]
-       ["Hide threads" gnus-summary-hide-all-threads t]
-       ["Show threads" gnus-summary-show-all-threads t]
-       ["Hide thread" gnus-summary-hide-thread t]
-       ["Show thread" gnus-summary-show-thread t]
-       ["Go to next thread" gnus-summary-next-thread t]
-       ["Go to previous thread" gnus-summary-prev-thread t]
-       ["Go down thread" gnus-summary-down-thread t]
-       ["Go up thread" gnus-summary-up-thread t]
-       ["Top of thread" gnus-summary-top-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]))
+      gnus-summary-thread-menu gnus-summary-mode-map ""
+      '("Threads"
+       ["Toggle threading" gnus-summary-toggle-threads t]
+       ["Hide threads" gnus-summary-hide-all-threads t]
+       ["Show threads" gnus-summary-show-all-threads t]
+       ["Hide thread" gnus-summary-hide-thread t]
+       ["Show thread" gnus-summary-show-thread t]
+       ["Go to next thread" gnus-summary-next-thread t]
+       ["Go to previous thread" gnus-summary-prev-thread t]
+       ["Go down thread" gnus-summary-down-thread t]
+       ["Go up thread" gnus-summary-up-thread t]
+       ["Top of thread" gnus-summary-top-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]))
 
     (easy-menu-define
 
     (easy-menu-define
-     gnus-summary-post-menu gnus-summary-mode-map ""
-     `("Post"
-       ["Post an article" gnus-summary-post-news
-       ,@(if (featurep 'xemacs) '(t)
-           '(:help "Post an article"))]
-       ["Followup" gnus-summary-followup
-       ,@(if (featurep 'xemacs) '(t)
-           '(:help "Post followup to this article"))]
-       ["Followup and yank" gnus-summary-followup-with-original
-       ,@(if (featurep 'xemacs) '(t)
-           '(:help "Post followup to this article, quoting its contents"))]
-       ["Supersede article" gnus-summary-supersede-article t]
-       ["Cancel article" gnus-summary-cancel-article
-       ,@(if (featurep 'xemacs) '(t)
-           '(:help "Cancel an article you posted"))]
-       ["Reply" gnus-summary-reply t]
-       ["Reply and yank" gnus-summary-reply-with-original t]
-       ["Wide reply" gnus-summary-wide-reply t]
-       ["Wide reply and yank" gnus-summary-wide-reply-with-original
-       ,@(if (featurep 'xemacs) '(t)
-           '(:help "Mail a reply, quoting this article"))]
-       ["Mail forward" gnus-summary-mail-forward t]
-       ["Post forward" gnus-summary-post-forward t]
-       ["Digest and mail" gnus-uu-digest-mail-forward t]
-       ["Digest and post" gnus-uu-digest-post-forward t]
-       ["Resend message" gnus-summary-resend-message t]
-       ["Send bounced mail" gnus-summary-resend-bounced-mail t]
-       ["Send a mail" gnus-summary-mail-other-window t]
-       ["Uuencode and post" gnus-uu-post-news
-       ,@(if (featurep 'xemacs) '(t)
-           '(:help "Post a uuencoded article"))]
-       ["Followup via news" gnus-summary-followup-to-mail t]
-       ["Followup via news and yank"
-       gnus-summary-followup-to-mail-with-original t]
-       ;;("Draft"
-       ;;["Send" gnus-summary-send-draft t]
-       ;;["Send bounced" gnus-resend-bounced-mail t])
-       ))
-
-    (cond 
+      gnus-summary-post-menu gnus-summary-mode-map ""
+      `("Post"
+       ["Send a message (mail or news)" gnus-summary-post-news
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post an article"))]
+       ["Followup" gnus-summary-followup
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post followup to this article"))]
+       ["Followup and yank" gnus-summary-followup-with-original
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post followup to this article, quoting its contents"))]
+       ["Supersede article" gnus-summary-supersede-article t]
+       ["Cancel article" gnus-summary-cancel-article
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Cancel an article you posted"))]
+       ["Reply" gnus-summary-reply t]
+       ["Reply and yank" gnus-summary-reply-with-original t]
+       ["Wide reply" gnus-summary-wide-reply t]
+       ["Wide reply and yank" gnus-summary-wide-reply-with-original
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Mail a reply, quoting this article"))]
+        ["Very wide reply" gnus-summary-very-wide-reply t]
+        ["Very wide reply and yank" gnus-summary-very-wide-reply-with-original
+       ,@(if (featurep 'xemacs) '(t)
+           '(:help "Mail a very wide reply, quoting this article"))]
+       ["Mail forward" gnus-summary-mail-forward t]
+       ["Post forward" gnus-summary-post-forward t]
+       ["Digest and mail" gnus-uu-digest-mail-forward t]
+       ["Digest and post" gnus-uu-digest-post-forward t]
+       ["Resend message" gnus-summary-resend-message t]
+       ["Send bounced mail" gnus-summary-resend-bounced-mail t]
+       ["Send a mail" gnus-summary-mail-other-window t]
+       ["Create a local message" gnus-summary-news-other-window t]
+       ["Uuencode and post" gnus-uu-post-news
+        ,@(if (featurep 'xemacs) '(t)
+            '(:help "Post a uuencoded article"))]
+       ["Followup via news" gnus-summary-followup-to-mail t]
+       ["Followup via news and yank"
+        gnus-summary-followup-to-mail-with-original t]
+       ;;("Draft"
+       ;;["Send" gnus-summary-send-draft t]
+       ;;["Send bounced" gnus-resend-bounced-mail t])
+       ))
+
+    (cond
      ((not (keymapp gnus-summary-post-menu))
       (setq gnus-article-post-menu gnus-summary-post-menu))
      ((not gnus-article-post-menu)
      ((not (keymapp gnus-summary-post-menu))
       (setq gnus-article-post-menu gnus-summary-post-menu))
      ((not gnus-article-post-menu)
@@ -2016,139 +2104,140 @@ increase the score of each group you read."
       (cons "Post" gnus-article-post-menu))
 
     (easy-menu-define
       (cons "Post" gnus-article-post-menu))
 
     (easy-menu-define
-     gnus-summary-misc-menu gnus-summary-mode-map ""
-     `("Misc"
-       ("Mark Read"
-       ["Mark as read" gnus-summary-mark-as-read-forward t]
-       ["Mark same subject and select"
-        gnus-summary-kill-same-subject-and-select t]
-       ["Mark same subject" gnus-summary-kill-same-subject t]
-       ["Catchup" gnus-summary-catchup
-        ,@(if (featurep 'xemacs) '(t)
-            '(:help "Mark unread articles in this group as read"))]
-       ["Catchup all" gnus-summary-catchup-all t]
-       ["Catchup to here" gnus-summary-catchup-to-here t]
-       ["Catchup from here" gnus-summary-catchup-from-here t]
-       ["Catchup region" gnus-summary-mark-region-as-read t]
-       ["Mark excluded" gnus-summary-limit-mark-excluded-as-read t])
-       ("Mark Various"
-       ["Tick" gnus-summary-tick-article-forward t]
-       ["Mark as dormant" gnus-summary-mark-as-dormant t]
-       ["Remove marks" gnus-summary-clear-mark-forward t]
-       ["Set expirable mark" gnus-summary-mark-as-expirable t]
-       ["Set bookmark" gnus-summary-set-bookmark t]
-       ["Remove bookmark" gnus-summary-remove-bookmark t])
-       ("Mark Limit"
-       ["Marks..." gnus-summary-limit-to-marks t]
-       ["Subject..." gnus-summary-limit-to-subject t]
-       ["Author..." gnus-summary-limit-to-author t]
-       ["Age..." gnus-summary-limit-to-age t]
-       ["Extra..." gnus-summary-limit-to-extra t]
-       ["Score" gnus-summary-limit-to-score t]
-       ["Unread" gnus-summary-limit-to-unread t]
-       ["Non-dormant" gnus-summary-limit-exclude-dormant t]
-       ["Articles" gnus-summary-limit-to-articles t]
-       ["Pop limit" gnus-summary-pop-limit t]
-       ["Show dormant" gnus-summary-limit-include-dormant t]
-       ["Hide childless dormant"
-        gnus-summary-limit-exclude-childless-dormant t]
-       ;;["Hide thread" gnus-summary-limit-exclude-thread t]
-       ["Hide marked" gnus-summary-limit-exclude-marks t]
-       ["Show expunged" gnus-summary-limit-include-expunged t])
-       ("Process Mark"
-       ["Set mark" gnus-summary-mark-as-processable t]
-       ["Remove mark" gnus-summary-unmark-as-processable t]
-       ["Remove all marks" gnus-summary-unmark-all-processable t]
-       ["Mark above" gnus-uu-mark-over t]
-       ["Mark series" gnus-uu-mark-series t]
-       ["Mark region" gnus-uu-mark-region t]
-       ["Unmark region" gnus-uu-unmark-region t]
-       ["Mark by regexp..." gnus-uu-mark-by-regexp t]
-        ["Unmark by regexp..." gnus-uu-unmark-by-regexp t]
-       ["Mark all" gnus-uu-mark-all t]
-       ["Mark buffer" gnus-uu-mark-buffer t]
-       ["Mark sparse" gnus-uu-mark-sparse t]
-       ["Mark thread" gnus-uu-mark-thread t]
-       ["Unmark thread" gnus-uu-unmark-thread t]
-       ("Process Mark Sets"
-        ["Kill" gnus-summary-kill-process-mark t]
-        ["Yank" gnus-summary-yank-process-mark
-         gnus-newsgroup-process-stack]
-        ["Save" gnus-summary-save-process-mark t]))
-       ("Scroll article"
-       ["Page forward" gnus-summary-next-page
-        ,@(if (featurep 'xemacs) '(t)
-            '(:help "Show next page of article"))]
-       ["Page backward" gnus-summary-prev-page
-        ,@(if (featurep 'xemacs) '(t)
-            '(:help "Show previous page of article"))]
-       ["Line forward" gnus-summary-scroll-up t])
-       ("Move"
-       ["Next unread article" gnus-summary-next-unread-article t]
-       ["Previous unread article" gnus-summary-prev-unread-article t]
-       ["Next article" gnus-summary-next-article t]
-       ["Previous article" gnus-summary-prev-article t]
-       ["Next unread subject" gnus-summary-next-unread-subject t]
-       ["Previous unread subject" gnus-summary-prev-unread-subject t]
-       ["Next article same subject" gnus-summary-next-same-subject t]
-       ["Previous article same subject" gnus-summary-prev-same-subject t]
-       ["First unread article" gnus-summary-first-unread-article t]
-       ["Best unread article" gnus-summary-best-unread-article t]
-       ["Go to subject number..." gnus-summary-goto-subject t]
-       ["Go to article number..." gnus-summary-goto-article t]
-       ["Go to the last article" gnus-summary-goto-last-article t]
-       ["Pop article off history" gnus-summary-pop-article t])
-       ("Sort"
-       ["Sort by number" gnus-summary-sort-by-number t]
-       ["Sort by author" gnus-summary-sort-by-author t]
-       ["Sort by subject" gnus-summary-sort-by-subject t]
-       ["Sort by date" gnus-summary-sort-by-date t]
-       ["Sort by score" gnus-summary-sort-by-score t]
-       ["Sort by lines" gnus-summary-sort-by-lines t]
-       ["Sort by characters" gnus-summary-sort-by-chars t]
-       ["Original sort" gnus-summary-sort-by-original t])
-       ("Help"
-       ["Fetch group FAQ" gnus-summary-fetch-faq t]
-       ["Describe group" gnus-summary-describe-group t]
-       ["Read manual" gnus-info-find-node t])
-       ("Modes"
-       ["Pick and read" gnus-pick-mode t]
-       ["Binary" gnus-binary-mode t])
-       ("Regeneration"
-       ["Regenerate" gnus-summary-prepare t]
-       ["Insert cached articles" gnus-summary-insert-cached-articles t]
-       ["Toggle threading" gnus-summary-toggle-threads t])
-       ["See old articles" gnus-summary-insert-old-articles t]
-       ["See new articles" gnus-summary-insert-new-articles t]
-       ["Filter articles..." gnus-summary-execute-command t]
-       ["Run command on subjects..." gnus-summary-universal-argument t]
-       ["Search articles forward..." gnus-summary-search-article-forward t]
-       ["Search articles backward..." gnus-summary-search-article-backward t]
-       ["Toggle line truncation" gnus-summary-toggle-truncation t]
-       ["Expand window" gnus-summary-expand-window t]
-       ["Expire expirable articles" gnus-summary-expire-articles
-       (gnus-check-backend-function
-        'request-expire-articles gnus-newsgroup-name)]
-       ["Edit local kill file" gnus-summary-edit-local-kill t]
-       ["Edit main kill file" gnus-summary-edit-global-kill t]
-       ["Edit group parameters" gnus-summary-edit-parameters t]
-       ["Customize group parameters" gnus-summary-customize-parameters t]
-       ["Send a bug report" gnus-bug t]
-       ("Exit"
-       ["Catchup and exit" gnus-summary-catchup-and-exit
-        ,@(if (featurep 'xemacs) '(t)
-            '(:help "Mark unread articles in this group as read, then exit"))]
-       ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
-       ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
-       ["Exit group" gnus-summary-exit
-        ,@(if (featurep 'xemacs) '(t)
-            '(:help "Exit current group, return to group selection mode"))]
-       ["Exit group without updating" gnus-summary-exit-no-update t]
-       ["Exit and goto next group" gnus-summary-next-group t]
-       ["Exit and goto prev group" gnus-summary-prev-group t]
-       ["Reselect group" gnus-summary-reselect-current-group t]
-       ["Rescan group" gnus-summary-rescan-group t]
-       ["Update dribble" gnus-summary-save-newsrc t])))
+      gnus-summary-misc-menu gnus-summary-mode-map ""
+      `("Gnus"
+       ("Mark Read"
+        ["Mark as read" gnus-summary-mark-as-read-forward t]
+        ["Mark same subject and select"
+         gnus-summary-kill-same-subject-and-select t]
+        ["Mark same subject" gnus-summary-kill-same-subject t]
+        ["Catchup" gnus-summary-catchup
+         ,@(if (featurep 'xemacs) '(t)
+             '(:help "Mark unread articles in this group as read"))]
+        ["Catchup all" gnus-summary-catchup-all t]
+        ["Catchup to here" gnus-summary-catchup-to-here t]
+        ["Catchup from here" gnus-summary-catchup-from-here t]
+        ["Catchup region" gnus-summary-mark-region-as-read t]
+        ["Mark excluded" gnus-summary-limit-mark-excluded-as-read t])
+       ("Mark Various"
+        ["Tick" gnus-summary-tick-article-forward t]
+        ["Mark as dormant" gnus-summary-mark-as-dormant t]
+        ["Remove marks" gnus-summary-clear-mark-forward t]
+        ["Set expirable mark" gnus-summary-mark-as-expirable t]
+        ["Set bookmark" gnus-summary-set-bookmark t]
+        ["Remove bookmark" gnus-summary-remove-bookmark t])
+       ("Limit to"
+        ["Marks..." gnus-summary-limit-to-marks t]
+        ["Subject..." gnus-summary-limit-to-subject t]
+        ["Author..." gnus-summary-limit-to-author t]
+        ["Age..." gnus-summary-limit-to-age t]
+        ["Extra..." gnus-summary-limit-to-extra t]
+        ["Score" gnus-summary-limit-to-score t]
+        ["Display Predicate" gnus-summary-limit-to-display-predicate t]
+        ["Unread" gnus-summary-limit-to-unread t]
+        ["Non-dormant" gnus-summary-limit-exclude-dormant t]
+        ["Articles" gnus-summary-limit-to-articles t]
+        ["Pop limit" gnus-summary-pop-limit t]
+        ["Show dormant" gnus-summary-limit-include-dormant t]
+        ["Hide childless dormant"
+         gnus-summary-limit-exclude-childless-dormant t]
+        ;;["Hide thread" gnus-summary-limit-exclude-thread t]
+        ["Hide marked" gnus-summary-limit-exclude-marks t]
+        ["Show expunged" gnus-summary-limit-include-expunged t])
+       ("Process Mark"
+        ["Set mark" gnus-summary-mark-as-processable t]
+        ["Remove mark" gnus-summary-unmark-as-processable t]
+        ["Remove all marks" gnus-summary-unmark-all-processable t]
+        ["Mark above" gnus-uu-mark-over t]
+        ["Mark series" gnus-uu-mark-series t]
+        ["Mark region" gnus-uu-mark-region t]
+        ["Unmark region" gnus-uu-unmark-region t]
+        ["Mark by regexp..." gnus-uu-mark-by-regexp t]
+        ["Unmark by regexp..." gnus-uu-unmark-by-regexp t]
+        ["Mark all" gnus-uu-mark-all t]
+        ["Mark buffer" gnus-uu-mark-buffer t]
+        ["Mark sparse" gnus-uu-mark-sparse t]
+        ["Mark thread" gnus-uu-mark-thread t]
+        ["Unmark thread" gnus-uu-unmark-thread t]
+        ("Process Mark Sets"
+         ["Kill" gnus-summary-kill-process-mark t]
+         ["Yank" gnus-summary-yank-process-mark
+          gnus-newsgroup-process-stack]
+         ["Save" gnus-summary-save-process-mark t]))
+       ("Scroll article"
+        ["Page forward" gnus-summary-next-page
+         ,@(if (featurep 'xemacs) '(t)
+             '(:help "Show next page of article"))]
+        ["Page backward" gnus-summary-prev-page
+         ,@(if (featurep 'xemacs) '(t)
+             '(:help "Show previous page of article"))]
+        ["Line forward" gnus-summary-scroll-up t])
+       ("Move"
+        ["Next unread article" gnus-summary-next-unread-article t]
+        ["Previous unread article" gnus-summary-prev-unread-article t]
+        ["Next article" gnus-summary-next-article t]
+        ["Previous article" gnus-summary-prev-article t]
+        ["Next unread subject" gnus-summary-next-unread-subject t]
+        ["Previous unread subject" gnus-summary-prev-unread-subject t]
+        ["Next article same subject" gnus-summary-next-same-subject t]
+        ["Previous article same subject" gnus-summary-prev-same-subject t]
+        ["First unread article" gnus-summary-first-unread-article t]
+        ["Best unread article" gnus-summary-best-unread-article t]
+        ["Go to subject number..." gnus-summary-goto-subject t]
+        ["Go to article number..." gnus-summary-goto-article t]
+        ["Go to the last article" gnus-summary-goto-last-article t]
+        ["Pop article off history" gnus-summary-pop-article t])
+       ("Sort"
+        ["Sort by number" gnus-summary-sort-by-number t]
+        ["Sort by author" gnus-summary-sort-by-author t]
+        ["Sort by subject" gnus-summary-sort-by-subject t]
+        ["Sort by date" gnus-summary-sort-by-date t]
+        ["Sort by score" gnus-summary-sort-by-score t]
+        ["Sort by lines" gnus-summary-sort-by-lines t]
+        ["Sort by characters" gnus-summary-sort-by-chars t]
+        ["Original sort" gnus-summary-sort-by-original t])
+       ("Help"
+        ["Fetch group FAQ" gnus-summary-fetch-faq t]
+        ["Describe group" gnus-summary-describe-group t]
+        ["Read manual" gnus-info-find-node t])
+       ("Modes"
+        ["Pick and read" gnus-pick-mode t]
+        ["Binary" gnus-binary-mode t])
+       ("Regeneration"
+        ["Regenerate" gnus-summary-prepare t]
+        ["Insert cached articles" gnus-summary-insert-cached-articles t]
+        ["Toggle threading" gnus-summary-toggle-threads t])
+       ["See old articles" gnus-summary-insert-old-articles t]
+       ["See new articles" gnus-summary-insert-new-articles t]
+       ["Filter articles..." gnus-summary-execute-command t]
+       ["Run command on subjects..." gnus-summary-universal-argument t]
+       ["Search articles forward..." gnus-summary-search-article-forward t]
+       ["Search articles backward..." gnus-summary-search-article-backward t]
+       ["Toggle line truncation" gnus-summary-toggle-truncation t]
+       ["Expand window" gnus-summary-expand-window t]
+       ["Expire expirable articles" gnus-summary-expire-articles
+        (gnus-check-backend-function
+         'request-expire-articles gnus-newsgroup-name)]
+       ["Edit local kill file" gnus-summary-edit-local-kill t]
+       ["Edit main kill file" gnus-summary-edit-global-kill t]
+       ["Edit group parameters" gnus-summary-edit-parameters t]
+       ["Customize group parameters" gnus-summary-customize-parameters t]
+       ["Send a bug report" gnus-bug t]
+       ("Exit"
+        ["Catchup and exit" gnus-summary-catchup-and-exit
+         ,@(if (featurep 'xemacs) '(t)
+             '(:help "Mark unread articles in this group as read, then exit"))]
+        ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
+        ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
+        ["Exit group" gnus-summary-exit
+         ,@(if (featurep 'xemacs) '(t)
+             '(:help "Exit current group, return to group selection mode"))]
+        ["Exit group without updating" gnus-summary-exit-no-update t]
+        ["Exit and goto next group" gnus-summary-next-group t]
+        ["Exit and goto prev group" gnus-summary-prev-group t]
+        ["Reselect group" gnus-summary-reselect-current-group t]
+        ["Rescan group" gnus-summary-rescan-group t]
+        ["Update dribble" gnus-summary-save-newsrc t])))
 
     (gnus-run-hooks 'gnus-summary-menu-hook)))
 
 
     (gnus-run-hooks 'gnus-summary-menu-hook)))
 
@@ -2334,7 +2423,7 @@ The following commands are available:
   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
   (gnus-run-hooks 'gnus-summary-mode-hook)
   (turn-on-gnus-mailing-list-mode)
   (add-hook 'pre-command-hook 'gnus-set-global-variables nil t)
   (gnus-run-hooks 'gnus-summary-mode-hook)
   (turn-on-gnus-mailing-list-mode)
-  (mm-enable-multibyte-mule4)
+  (mm-enable-multibyte)
   (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))
 
@@ -2431,7 +2520,7 @@ The following commands are available:
            (setq gnus-newsgroup-data (nconc list gnus-newsgroup-data))
            (when offset
              (gnus-data-update-list odata offset)))
            (setq gnus-newsgroup-data (nconc list gnus-newsgroup-data))
            (when offset
              (gnus-data-update-list odata offset)))
-       ;; Find the last element in the list to be spliced into the main
+      ;; Find the last element in the list to be spliced into the main
        ;; list.
        (while (cdr list)
          (setq list (cdr list)))
        ;; list.
        (while (cdr list)
          (setq list (cdr list)))
@@ -2493,7 +2582,7 @@ The following commands are available:
 (defun gnus-article-parent-p (number)
   "Say whether this article is a parent or not."
   (let ((data (gnus-data-find-list number)))
 (defun gnus-article-parent-p (number)
   "Say whether this article is a parent or not."
   (let ((data (gnus-data-find-list number)))
-    (and (cdr data)                    ; There has to be an article after...
+    (and (cdr data)              ; There has to be an article after...
         (< (gnus-data-level (car data)) ; And it has to have a higher level.
            (gnus-data-level (nth 1 data))))))
 
         (< (gnus-data-level (car data)) ; And it has to have a higher level.
            (gnus-data-level (nth 1 data))))))
 
@@ -2633,9 +2722,6 @@ marks of articles."
 
 ;; Saving hidden threads.
 
 
 ;; Saving hidden threads.
 
-(put 'gnus-save-hidden-threads 'lisp-indent-function 0)
-(put 'gnus-save-hidden-threads 'edebug-form-spec '(body))
-
 (defmacro gnus-save-hidden-threads (&rest forms)
   "Save hidden threads, eval FORMS, and restore the hidden threads."
   (let ((config (make-symbol "config")))
 (defmacro gnus-save-hidden-threads (&rest forms)
   "Save hidden threads, eval FORMS, and restore the hidden threads."
   (let ((config (make-symbol "config")))
@@ -2644,6 +2730,8 @@ marks of articles."
           (save-excursion
             ,@forms)
         (gnus-restore-hidden-threads-configuration ,config)))))
           (save-excursion
             ,@forms)
         (gnus-restore-hidden-threads-configuration ,config)))))
+(put 'gnus-save-hidden-threads 'lisp-indent-function 0)
+(put 'gnus-save-hidden-threads 'edebug-form-spec '(body))
 
 (defun gnus-data-compute-positions ()
   "Compute the positions of all articles."
 
 (defun gnus-data-compute-positions ()
   "Compute the positions of all articles."
@@ -2699,7 +2787,7 @@ display only a single character."
     ;; Nix out all the control chars...
     (while (>= (setq i (1- i)) 0)
       (aset table i [??]))
     ;; Nix out all the control chars...
     (while (>= (setq i (1- i)) 0)
       (aset table i [??]))
-    ;; ... but not newline and cr, of course.  (cr is necessary for the
+   ;; ... but not newline and cr, of course.  (cr is necessary for the
     ;; selective display).
     (aset table ?\n nil)
     (aset table ?\r nil)
     ;; selective display).
     (aset table ?\n nil)
     (aset table ?\r nil)
@@ -2730,11 +2818,16 @@ display only a single character."
 
 (defun gnus-summary-buffer-name (group)
   "Return the summary buffer name of GROUP."
 
 (defun gnus-summary-buffer-name (group)
   "Return the summary buffer name of GROUP."
-  (concat "*Summary " group "*"))
+  (concat "*Summary " (gnus-group-decoded-name group) "*"))
 
 (defun gnus-summary-setup-buffer (group)
   "Initialize summary buffer."
 
 (defun gnus-summary-setup-buffer (group)
   "Initialize summary buffer."
-  (let ((buffer (gnus-summary-buffer-name group)))
+  (let ((buffer (gnus-summary-buffer-name group))
+       (dead-name (concat "*Dead Summary "
+                          (gnus-group-decoded-name group) "*")))
+    ;; If a dead summary buffer exists, we kill it.
+    (when (gnus-buffer-live-p dead-name)
+      (gnus-kill-buffer dead-name))
     (if (get-buffer buffer)
        (progn
          (set-buffer buffer)
     (if (get-buffer buffer)
        (progn
          (set-buffer buffer)
@@ -2874,32 +2967,31 @@ buffer that was in action when the last article was fetched."
    (point) (progn (eval gnus-summary-dummy-line-format-spec) (point))
    (list 'gnus-number gnus-tmp-number 'gnus-intangible gnus-tmp-number)))
 
    (point) (progn (eval gnus-summary-dummy-line-format-spec) (point))
    (list 'gnus-number gnus-tmp-number 'gnus-intangible gnus-tmp-number)))
 
-(defun gnus-summary-from-or-to-or-newsgroups (header)
-  (let ((to (cdr (assq 'To (mail-header-extra header))))
-       (newsgroups (cdr (assq 'Newsgroups (mail-header-extra header))))
-       (mail-parse-charset gnus-newsgroup-charset)
+(defun gnus-summary-extract-address-component (from)
+  (or (car (funcall gnus-extract-address-components from))
+      from))
+
+(defun gnus-summary-from-or-to-or-newsgroups (header gnus-tmp-from)
+  (let ((mail-parse-charset gnus-newsgroup-charset)
+       ; Is it really necessary to do this next part for each summary line?
+       ; Luckily, doesn't seem to slow things down much.
        (mail-parse-ignored-charsets
         (save-excursion (set-buffer gnus-summary-buffer)
                         gnus-newsgroup-ignored-charsets)))
        (mail-parse-ignored-charsets
         (save-excursion (set-buffer gnus-summary-buffer)
                         gnus-newsgroup-ignored-charsets)))
-    (cond
-     ((and to
-          gnus-ignored-from-addresses
-          (string-match gnus-ignored-from-addresses
-                        (mail-header-from header)))
-      (concat "-> "
-             (or (car (funcall gnus-extract-address-components
-                               (funcall
-                                gnus-decode-encoded-word-function to)))
-                 (funcall gnus-decode-encoded-word-function to))))
-     ((and newsgroups
-          gnus-ignored-from-addresses
-          (string-match gnus-ignored-from-addresses
-                        (mail-header-from header)))
-      (concat "=> " newsgroups))
-     (t
-      (or (car (funcall gnus-extract-address-components
-                       (mail-header-from header)))
-         (mail-header-from header))))))
+    (or
+     (and gnus-ignored-from-addresses
+         (string-match gnus-ignored-from-addresses gnus-tmp-from)
+         (let ((extra-headers (mail-header-extra header))
+               to
+               newsgroups)
+           (cond
+            ((setq to (cdr (assq 'To extra-headers)))
+             (concat "-> "
+                     (gnus-summary-extract-address-component
+                      (funcall gnus-decode-encoded-word-function to))))
+            ((setq newsgroups (cdr (assq 'Newsgroups extra-headers)))
+             (concat "=> " newsgroups)))))
+     (gnus-summary-extract-address-component gnus-tmp-from))))
 
 (defun gnus-summary-insert-line (gnus-tmp-header
                                 gnus-tmp-level gnus-tmp-current
 
 (defun gnus-summary-insert-line (gnus-tmp-header
                                 gnus-tmp-level gnus-tmp-current
@@ -2914,16 +3006,23 @@ buffer that was in action when the last article was fetched."
          (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)))
            (if (< gnus-tmp-score gnus-summary-default-score)
                gnus-score-below-mark gnus-score-over-mark)))
+        (gnus-tmp-number (mail-header-number gnus-tmp-header))
         (gnus-tmp-replied
          (cond (gnus-tmp-process gnus-process-mark)
                ((memq gnus-tmp-current gnus-newsgroup-cached)
                 gnus-cached-mark)
                (gnus-tmp-replied gnus-replied-mark)
         (gnus-tmp-replied
          (cond (gnus-tmp-process gnus-process-mark)
                ((memq gnus-tmp-current gnus-newsgroup-cached)
                 gnus-cached-mark)
                (gnus-tmp-replied gnus-replied-mark)
+               ((memq gnus-tmp-current gnus-newsgroup-forwarded)
+                gnus-forwarded-mark)
                ((memq gnus-tmp-current gnus-newsgroup-saved)
                 gnus-saved-mark)
                ((memq gnus-tmp-current gnus-newsgroup-saved)
                 gnus-saved-mark)
+               ((memq gnus-tmp-number gnus-newsgroup-recent)
+                gnus-recent-mark)
+               ((memq gnus-tmp-number gnus-newsgroup-unseen)
+                gnus-unseen-mark)
                (t gnus-no-mark)))
         (gnus-tmp-from (mail-header-from gnus-tmp-header))
         (gnus-tmp-name
                (t gnus-no-mark)))
         (gnus-tmp-from (mail-header-from gnus-tmp-header))
         (gnus-tmp-name
@@ -2938,7 +3037,6 @@ buffer that was in action when the last article was fetched."
                       (1+ (match-beginning 0)) (1- (match-end 0))))
           (t gnus-tmp-from)))
         (gnus-tmp-subject (mail-header-subject gnus-tmp-header))
                       (1+ (match-beginning 0)) (1- (match-end 0))))
           (t gnus-tmp-from)))
         (gnus-tmp-subject (mail-header-subject gnus-tmp-header))
-        (gnus-tmp-number (mail-header-number gnus-tmp-header))
         (gnus-tmp-opening-bracket (if gnus-tmp-dummy ?\< ?\[))
         (gnus-tmp-closing-bracket (if gnus-tmp-dummy ?\> ?\]))
         (buffer-read-only nil))
         (gnus-tmp-opening-bracket (if gnus-tmp-dummy ?\< ?\[))
         (gnus-tmp-closing-bracket (if gnus-tmp-dummy ?\> ?\]))
         (buffer-read-only nil))
@@ -2946,8 +3044,9 @@ buffer that was in action when the last article was fetched."
       (setq gnus-tmp-name gnus-tmp-from))
     (unless (numberp gnus-tmp-lines)
       (setq gnus-tmp-lines -1))
       (setq gnus-tmp-name gnus-tmp-from))
     (unless (numberp gnus-tmp-lines)
       (setq gnus-tmp-lines -1))
-    (when (= gnus-tmp-lines -1)
-      (setq gnus-tmp-lines "?"))
+    (if (= gnus-tmp-lines -1)
+       (setq gnus-tmp-lines "?")
+      (setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
     (gnus-put-text-property
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
     (gnus-put-text-property
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
@@ -2980,7 +3079,7 @@ buffer that was in action when the last article was fetched."
         (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))
@@ -2995,7 +3094,7 @@ buffer that was in action when the last article was fetched."
 This may be 0 in some cases -- if none of the articles in
 the thread are to be displayed."
   (let* ((number
 This may be 0 in some cases -- if none of the articles in
 the thread are to be displayed."
   (let* ((number
-         ;; Fix by Luc Van Eycken <Luc.VanEycken@esat.kuleuven.ac.be>.
+        ;; Fix by Luc Van Eycken <Luc.VanEycken@esat.kuleuven.ac.be>.
          (cond
           ((not (listp thread))
            1)
          (cond
           ((not (listp thread))
            1)
@@ -3021,7 +3120,7 @@ the thread are to be displayed."
 (defun gnus-summary-set-local-parameters (group)
   "Go through the local params of GROUP and set all variable specs in that list."
   (let ((params (gnus-group-find-parameter group))
 (defun gnus-summary-set-local-parameters (group)
   "Go through the local params of GROUP and set all variable specs in that list."
   (let ((params (gnus-group-find-parameter group))
-        (vars '(quit-config)) ; Ignore quit-config.
+       (vars '(quit-config))           ; Ignore quit-config.
        elem)
     (while params
       (setq elem (car params)
        elem)
     (while params
       (setq elem (car params)
@@ -3029,9 +3128,9 @@ the thread are to be displayed."
       (and (consp elem)                        ; Has to be a cons.
           (consp (cdr elem))           ; The cdr has to be a list.
           (symbolp (car elem))         ; Has to be a symbol in there.
       (and (consp elem)                        ; Has to be a cons.
           (consp (cdr elem))           ; The cdr has to be a list.
           (symbolp (car elem))         ; Has to be a symbol in there.
-           (not (memq (car elem) vars))
+          (not (memq (car elem) vars))
           (ignore-errors               ; So we set it.
           (ignore-errors               ; So we set it.
-             (push (car elem) vars)
+            (push (car elem) vars)
             (make-local-variable (car elem))
             (set (car elem) (eval (nth 1 elem))))))))
 
             (make-local-variable (car elem))
             (set (car elem) (eval (nth 1 elem))))))))
 
@@ -3071,7 +3170,7 @@ If NO-DISPLAY, don't generate a summary buffer."
   ;;  (when (and (not (gnus-group-native-p group))
   ;;        (not (gnus-gethash group gnus-newsrc-hashtb)))
   ;;    (error "Dead non-native groups can't be entered"))
   ;;  (when (and (not (gnus-group-native-p group))
   ;;        (not (gnus-gethash group gnus-newsrc-hashtb)))
   ;;    (error "Dead non-native groups can't be entered"))
-  (gnus-message 5 "Retrieving newsgroup: %s..." 
+  (gnus-message 5 "Retrieving newsgroup: %s..."
                (gnus-group-decoded-name group))
   (let* ((new-group (gnus-summary-setup-buffer group))
         (quit-config (gnus-group-quit-config group))
                (gnus-group-decoded-name group))
   (let* ((new-group (gnus-summary-setup-buffer group))
         (quit-config (gnus-group-quit-config group))
@@ -3103,10 +3202,10 @@ If NO-DISPLAY, don't generate a summary buffer."
              (gnus-group-next-unread-group 1))
          (gnus-handle-ephemeral-exit quit-config)))
       (let ((grpinfo (gnus-get-info group)))
              (gnus-group-next-unread-group 1))
          (gnus-handle-ephemeral-exit quit-config)))
       (let ((grpinfo (gnus-get-info group)))
-        (if (null (gnus-info-read grpinfo))
-            (gnus-message 3 "Group %s contains no messages" 
+       (if (null (gnus-info-read grpinfo))
+           (gnus-message 3 "Group %s contains no messages"
                          (gnus-group-decoded-name group))
                          (gnus-group-decoded-name group))
-          (gnus-message 3 "Can't select group")))
+         (gnus-message 3 "Can't select group")))
       nil)
      ;; The user did a `C-g' while prompting for number of articles,
      ;; so we exit this group.
       nil)
      ;; The user did a `C-g' while prompting for number of articles,
      ;; so we exit this group.
@@ -3185,11 +3284,10 @@ If NO-DISPLAY, don't generate a summary buffer."
        ;; Hide conversation thread subtrees.  We cannot do this in
        ;; gnus-summary-prepare-hook since kill processing may not
        ;; work with hidden articles.
        ;; Hide conversation thread subtrees.  We cannot do this in
        ;; gnus-summary-prepare-hook since kill processing may not
        ;; work with hidden articles.
-       (and gnus-show-threads
-            gnus-thread-hide-subtree
-            (gnus-summary-hide-all-threads))
+       (gnus-summary-maybe-hide-threads)
        (when kill-buffer
          (gnus-kill-or-deaden-summary kill-buffer))
        (when kill-buffer
          (gnus-kill-or-deaden-summary kill-buffer))
+       (gnus-summary-auto-select-subject)
        ;; Show first unread article if requested.
        (if (and (not no-article)
                 (not no-display)
        ;; Show first unread article if requested.
        (if (and (not no-article)
                 (not no-display)
@@ -3197,16 +3295,11 @@ If NO-DISPLAY, don't generate a summary buffer."
                 gnus-auto-select-first)
            (progn
              (gnus-configure-windows 'summary)
                 gnus-auto-select-first)
            (progn
              (gnus-configure-windows 'summary)
-             (cond
-              ((eq gnus-auto-select-first 'best)
-               (gnus-summary-best-unread-article))
-              ((eq gnus-auto-select-first t)
-               (gnus-summary-first-unread-article))
-              ((gnus-functionp gnus-auto-select-first)
-               (funcall gnus-auto-select-first))))
-         ;; Don't select any articles, just move point to the first
-         ;; article in the group.
-         (goto-char (point-min))
+             (let ((art (gnus-summary-article-number)))
+               (unless (or (memq art gnus-newsgroup-undownloaded)
+                           (memq art gnus-newsgroup-downloadable))
+                 (gnus-summary-goto-article art))))
+         ;; Don't select any articles.
          (gnus-summary-position-point)
          (gnus-configure-windows 'summary 'force)
          (gnus-set-mode-line 'summary))
          (gnus-summary-position-point)
          (gnus-configure-windows 'summary 'force)
          (gnus-set-mode-line 'summary))
@@ -3223,6 +3316,22 @@ If NO-DISPLAY, don't generate a summary buffer."
        (gnus-run-hooks 'gnus-summary-prepared-hook)
        t)))))
 
        (gnus-run-hooks 'gnus-summary-prepared-hook)
        t)))))
 
+(defun gnus-summary-auto-select-subject ()
+  "Select the subject line on initial group entry."
+  (goto-char (point-min))
+  (cond
+   ((eq gnus-auto-select-subject 'best)
+    (gnus-summary-best-unread-subject))
+   ((eq gnus-auto-select-subject 'unread)
+    (gnus-summary-first-unread-subject))
+   ((eq gnus-auto-select-subject 'unseen)
+    (gnus-summary-first-unseen-subject))
+   ((eq gnus-auto-select-subject 'first)
+    ;; Do nothing.
+    )
+   ((gnus-functionp gnus-auto-select-subject)
+    (funcall gnus-auto-select-subject))))
+
 (defun gnus-summary-prepare ()
   "Generate the summary buffer."
   (interactive)
 (defun gnus-summary-prepare ()
   "Generate the summary buffer."
   (interactive)
@@ -3267,7 +3376,7 @@ If NO-DISPLAY, don't generate a summary buffer."
 
   (if (and gnus-summary-gather-exclude-subject
           (string-match gnus-summary-gather-exclude-subject subject))
 
   (if (and gnus-summary-gather-exclude-subject
           (string-match gnus-summary-gather-exclude-subject subject))
-      nil                              ; This article shouldn't be gathered
+      nil                         ; This article shouldn't be gathered
     subject))
 
 (defun gnus-summary-simplify-subject-query ()
     subject))
 
 (defun gnus-summary-simplify-subject-query ()
@@ -3402,7 +3511,7 @@ If NO-DISPLAY, don't generate a summary buffer."
                  (setq threads nil)
                  (throw 'infloop t))
                (unless (car (symbol-value refs))
                  (setq threads nil)
                  (throw 'infloop t))
                (unless (car (symbol-value refs))
-                 ;; These threads do not refer back to any other articles,
+            ;; These threads do not refer back to any other articles,
                  ;; so they're roots.
                  (setq threads (append (cdr (symbol-value refs)) threads))))
              gnus-newsgroup-dependencies)))
                  ;; so they're roots.
                  (setq threads (append (cdr (symbol-value refs)) threads))))
              gnus-newsgroup-dependencies)))
@@ -3724,7 +3833,7 @@ the id of the parent article (if any)."
        (when parent
          (delq thread parent)))
       (if (gnus-summary-insert-subject id header)
        (when parent
          (delq thread parent)))
       (if (gnus-summary-insert-subject id header)
-         ;; Set the (possibly) new article number in the data structure.
+       ;; Set the (possibly) new article number in the data structure.
          (gnus-data-set-number data (gnus-id-to-article id))
        (setcar thread old)
        nil))))
          (gnus-data-set-number data (gnus-id-to-article id))
        (setcar thread old)
        nil))))
@@ -4054,15 +4163,47 @@ Unscored articles will be counted as having a score of zero."
 
 (defun gnus-thread-total-score (thread)
   ;; This function find the total score of THREAD.
 
 (defun gnus-thread-total-score (thread)
   ;; This function find the total score of THREAD.
-  (cond ((null thread)
-        0)
-       ((consp thread)
-        (if (stringp (car thread))
-            (apply gnus-thread-score-function 0
-                   (mapcar 'gnus-thread-total-score-1 (cdr thread)))
-          (gnus-thread-total-score-1 thread)))
-       (t
-        (gnus-thread-total-score-1 (list thread)))))
+  (cond
+   ((null thread)
+    0)
+   ((consp thread)
+    (if (stringp (car thread))
+       (apply gnus-thread-score-function 0
+              (mapcar 'gnus-thread-total-score-1 (cdr thread)))
+      (gnus-thread-total-score-1 thread)))
+   (t
+    (gnus-thread-total-score-1 (list thread)))))
+
+(defun gnus-thread-sort-by-most-recent-number (h1 h2)
+  "Sort threads such that the thread with the most recently arrived article comes first."
+  (> (gnus-thread-highest-number h1) (gnus-thread-highest-number h2)))
+
+(defun gnus-thread-highest-number (thread)
+  "Return the highest article number in THREAD."
+  (apply 'max (mapcar (lambda (header)
+                       (mail-header-number header))
+                     (message-flatten-list thread))))
+
+(defun gnus-thread-sort-by-most-recent-date (h1 h2)
+  "Sort threads such that the thread with the most recently dated article comes first."
+  (> (gnus-thread-latest-date h1) (gnus-thread-latest-date h2)))
+
+(defun gnus-thread-latest-date (thread)
+  "Return the highest article date in THREAD."
+  (let ((previous-time 0))
+    (apply 'max (mapcar
+                (lambda (header)
+                  (setq previous-time
+                        (time-to-seconds
+                         (mail-header-parse-date
+                          (condition-case ()
+                              (mail-header-date header)
+                            (error previous-time))))))
+                (sort
+                 (message-flatten-list thread)
+                 (lambda (h1 h2)
+                   (< (mail-header-number h1)
+                      (mail-header-number h2))))))))
 
 (defun gnus-thread-total-score-1 (root)
   ;; This function find the total score of the thread below ROOT.
 
 (defun gnus-thread-total-score-1 (root)
   ;; This function find the total score of the thread below ROOT.
@@ -4092,12 +4233,20 @@ Unscored articles will be counted as having a score of zero."
 
 (defvar gnus-tmp-thread-tree-header-string "")
 
 
 (defvar gnus-tmp-thread-tree-header-string "")
 
-(defvar gnus-sum-thread-tree-root "> ")
-(defvar gnus-sum-thread-tree-single-indent "")
-(defvar gnus-sum-thread-tree-vertical "| ")
-(defvar gnus-sum-thread-tree-indent "  ")
-(defvar gnus-sum-thread-tree-leaf-with-other "+-> ")
-(defvar gnus-sum-thread-tree-single-leaf "\\-> ")
+(defvar gnus-sum-thread-tree-root "> "
+  "With %B spec, used for the root of a thread.
+If nil, use subject instead.")
+(defvar gnus-sum-thread-tree-single-indent ""
+  "With %B spec, used for a thread with just one message.
+If nil, use subject instead.")
+(defvar gnus-sum-thread-tree-vertical "| "
+  "With %B spec, used for drawing a vertical line.")
+(defvar gnus-sum-thread-tree-indent "  "
+  "With %B spec, used for indenting.")
+(defvar gnus-sum-thread-tree-leaf-with-other "+-> "
+  "With %B spec, used for a leaf with brothers.")
+(defvar gnus-sum-thread-tree-single-leaf "\\-> "
+  "With %B spec, used for a leaf without brothers.")
 
 (defun gnus-summary-prepare-threads (threads)
   "Prepare summary buffer from THREADS and indentation LEVEL.
 
 (defun gnus-summary-prepare-threads (threads)
   "Prepare summary buffer from THREADS and indentation LEVEL.
@@ -4118,7 +4267,7 @@ or a straight list of headers."
        gnus-tmp-dummy gnus-tmp-indentation gnus-tmp-lines gnus-tmp-score
        gnus-tmp-score-char gnus-tmp-from gnus-tmp-name
        gnus-tmp-number gnus-tmp-opening-bracket gnus-tmp-closing-bracket
        gnus-tmp-dummy gnus-tmp-indentation gnus-tmp-lines gnus-tmp-score
        gnus-tmp-score-char gnus-tmp-from gnus-tmp-name
        gnus-tmp-number gnus-tmp-opening-bracket gnus-tmp-closing-bracket
-        tree-stack)
+       tree-stack)
 
     (setq gnus-tmp-prev-subject nil)
 
 
     (setq gnus-tmp-prev-subject nil)
 
@@ -4156,7 +4305,7 @@ or a straight list of headers."
            ;; the stack.
            (setq state (car stack)
                  gnus-tmp-level (car state)
            ;; the stack.
            (setq state (car stack)
                  gnus-tmp-level (car state)
-                  tree-stack (cadr state)
+                 tree-stack (cadr state)
                  thread (caddr state)
                  stack (cdr stack)
                  gnus-tmp-header (caar thread))))
                  thread (caddr state)
                  stack (cdr stack)
                  gnus-tmp-header (caar thread))))
@@ -4298,7 +4447,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
@@ -4312,6 +4461,10 @@ or a straight list of headers."
                    gnus-forwarded-mark)
                   ((memq number gnus-newsgroup-saved)
                    gnus-saved-mark)
                    gnus-forwarded-mark)
                   ((memq number gnus-newsgroup-saved)
                    gnus-saved-mark)
+                  ((memq number gnus-newsgroup-recent)
+                   gnus-recent-mark)
+                  ((memq number gnus-newsgroup-unseen)
+                   gnus-unseen-mark)
                   (t gnus-no-mark))
             gnus-tmp-from (mail-header-from gnus-tmp-header)
             gnus-tmp-name
                   (t gnus-no-mark))
             gnus-tmp-from (mail-header-from gnus-tmp-header)
             gnus-tmp-name
@@ -4325,27 +4478,30 @@ or a straight list of headers."
               (substring gnus-tmp-from
                          (1+ (match-beginning 0)) (1- (match-end 0))))
              (t gnus-tmp-from))
               (substring gnus-tmp-from
                          (1+ (match-beginning 0)) (1- (match-end 0))))
              (t gnus-tmp-from))
-             gnus-tmp-thread-tree-header-string 
-             (if (zerop gnus-tmp-level)
-                 (if (cdar thread) 
-                     gnus-sum-thread-tree-root
-                   gnus-sum-thread-tree-single-indent)
-               (concat (apply 'concat
-                              (mapcar (lambda (item) 
-                                        (if (= item 1) 
-                                            gnus-sum-thread-tree-vertical
-                                          gnus-sum-thread-tree-indent))
-                                      (cdr (reverse tree-stack))))
-                       (if (nth 1 thread) 
-                           gnus-sum-thread-tree-leaf-with-other
-                         gnus-sum-thread-tree-single-leaf))))
-
+            gnus-tmp-thread-tree-header-string
+            (cond
+             ((not gnus-show-threads) "")
+             ((zerop gnus-tmp-level)
+              (if (cdar thread)
+                  (or gnus-sum-thread-tree-root subject)
+                (or gnus-sum-thread-tree-single-indent subject)))
+             (t
+              (concat (apply 'concat
+                             (mapcar (lambda (item)
+                                       (if (= item 1)
+                                           gnus-sum-thread-tree-vertical
+                                         gnus-sum-thread-tree-indent))
+                                     (cdr (reverse tree-stack))))
+                      (if (nth 1 thread)
+                          gnus-sum-thread-tree-leaf-with-other
+                        gnus-sum-thread-tree-single-leaf)))))
            (when (string= gnus-tmp-name "")
              (setq gnus-tmp-name gnus-tmp-from))
            (unless (numberp gnus-tmp-lines)
              (setq gnus-tmp-lines -1))
            (when (string= gnus-tmp-name "")
              (setq gnus-tmp-name gnus-tmp-from))
            (unless (numberp gnus-tmp-lines)
              (setq gnus-tmp-lines -1))
-           (when (= gnus-tmp-lines -1)
-             (setq gnus-tmp-lines "?"))
+           (if (= gnus-tmp-lines -1)
+               (setq gnus-tmp-lines "?")
+             (setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
            (gnus-put-text-property
             (point)
             (progn (eval gnus-summary-line-format-spec) (point))
            (gnus-put-text-property
             (point)
             (progn (eval gnus-summary-line-format-spec) (point))
@@ -4358,11 +4514,11 @@ or a straight list of headers."
            (setq gnus-tmp-prev-subject subject)))
 
        (when (nth 1 thread)
            (setq gnus-tmp-prev-subject subject)))
 
        (when (nth 1 thread)
-         (push (list (max 0 gnus-tmp-level) 
-                      (copy-list tree-stack)
-                      (nthcdr 1 thread))
-                stack))        
-        (push (if (nth 1 thread) 1 0) tree-stack)
+         (push (list (max 0 gnus-tmp-level)
+                     (copy-list tree-stack)
+                     (nthcdr 1 thread))
+               stack))
+       (push (if (nth 1 thread) 1 0) tree-stack)
        (incf gnus-tmp-level)
        (setq threads (if thread-end nil (cdar thread)))
        (unless threads
        (incf gnus-tmp-level)
        (setq threads (if thread-end nil (cdar thread)))
        (unless threads
@@ -4458,15 +4614,15 @@ If SELECT-ARTICLES, only select those articles from GROUP."
   (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
         ;;!!! Dirty hack; should be removed.
         (gnus-summary-ignore-duplicates
   (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
         ;;!!! Dirty hack; should be removed.
         (gnus-summary-ignore-duplicates
-         (if (eq (car (gnus-find-method-for-group group)) 'nnvirtual)
+         (if (eq (car (gnus-find-method-for-group group)) 'nnvirtual)
              t
            gnus-summary-ignore-duplicates))
         (info (nth 2 entry))
         articles fetched-articles cached)
 
     (unless (gnus-check-server
              t
            gnus-summary-ignore-duplicates))
         (info (nth 2 entry))
         articles fetched-articles cached)
 
     (unless (gnus-check-server
-            (setq gnus-current-select-method
-                  (gnus-find-method-for-group group)))
+            (set (make-local-variable 'gnus-current-select-method)
+                 (gnus-find-method-for-group group)))
       (error "Couldn't open server"))
 
     (or (and entry (not (eq (car entry) t))) ; Either it's active...
       (error "Couldn't open server"))
 
     (or (and entry (not (eq (car entry) t))) ; Either it's active...
@@ -4483,14 +4639,43 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (error "Couldn't request group %s: %s"
             group (gnus-status-message group)))
 
       (error "Couldn't request group %s: %s"
             group (gnus-status-message group)))
 
-    (setq gnus-newsgroup-name group)
-    (setq gnus-newsgroup-unselected nil)
-    (setq gnus-newsgroup-unreads (gnus-list-of-unread-articles group))
-    (gnus-summary-setup-default-charset)
+    (setq gnus-newsgroup-name group
+         gnus-newsgroup-unselected nil
+         gnus-newsgroup-unreads (gnus-list-of-unread-articles group))
 
 
-    ;; Adjust and set lists of article marks.
-    (when info
-      (gnus-adjust-marked-articles info))
+    (let ((display (gnus-group-find-parameter group 'display)))
+      (setq gnus-newsgroup-display
+           (cond
+            ((not (zerop (or (car-safe read-all) 0)))
+             ;; The user entered the group with C-u SPC/RET, let's show
+             ;; all articles.
+             'gnus-not-ignore)
+            ((eq display 'all)
+             'gnus-not-ignore)
+            ((arrayp display)
+             (gnus-summary-display-make-predicate (mapcar 'identity display)))
+            ((numberp display)
+             ;; The following is probably the "correct" solution, but
+             ;; it makes Gnus fetch all headers and then limit the
+             ;; articles (which is slow), so instead we hack the
+             ;; select-articles parameter instead. -- Simon Josefsson
+             ;; <jas@kth.se>
+             ;;
+             ;; (gnus-byte-compile
+             ;;  `(lambda () (> number ,(- (cdr (gnus-active group))
+             ;;                         display)))))
+             (setq select-articles
+                   (gnus-uncompress-range
+                    (cons (let ((tmp (- (cdr (gnus-active group)) display)))
+                            (if (> tmp 0)
+                                tmp
+                              1))
+                          (cdr (gnus-active group)))))
+             nil)
+            (t
+             nil))))
+
+    (gnus-summary-setup-default-charset)
 
     ;; Kludge to avoid having cached articles nixed out in virtual groups.
     (when (gnus-virtual-group-p group)
 
     ;; Kludge to avoid having cached articles nixed out in virtual groups.
     (when (gnus-virtual-group-p group)
@@ -4505,6 +4690,10 @@ If SELECT-ARTICLES, only select those articles from GROUP."
 
     (gnus-update-read-articles group gnus-newsgroup-unreads)
 
 
     (gnus-update-read-articles group gnus-newsgroup-unreads)
 
+    ;; Adjust and set lists of article marks.
+    (when info
+      (gnus-adjust-marked-articles info))
+
     (if (setq articles select-articles)
        (setq gnus-newsgroup-unselected
              (gnus-sorted-intersection
     (if (setq articles select-articles)
        (setq gnus-newsgroup-unselected
              (gnus-sorted-intersection
@@ -4536,12 +4725,22 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; Set the initial limit.
       (setq gnus-newsgroup-limit (copy-sequence articles))
       ;; Remove canceled articles from the list of unread articles.
       ;; Set the initial limit.
       (setq gnus-newsgroup-limit (copy-sequence articles))
       ;; Remove canceled articles from the list of unread articles.
+      (setq fetched-articles
+           (mapcar (lambda (headers) (mail-header-number headers))
+                   gnus-newsgroup-headers))
+      (setq gnus-newsgroup-articles fetched-articles)
       (setq gnus-newsgroup-unreads
            (gnus-set-sorted-intersection
       (setq gnus-newsgroup-unreads
            (gnus-set-sorted-intersection
-            gnus-newsgroup-unreads
-            (setq fetched-articles
-                  (mapcar (lambda (headers) (mail-header-number headers))
-                          gnus-newsgroup-headers))))
+            gnus-newsgroup-unreads fetched-articles))
+
+      ;; The `seen' marks are treated specially.
+      (if (not gnus-newsgroup-seen)
+         (setq gnus-newsgroup-unseen gnus-newsgroup-articles)
+       (dolist (article gnus-newsgroup-articles)
+         (unless (gnus-member-of-range article gnus-newsgroup-seen)
+           (push article gnus-newsgroup-unseen)))
+       (setq gnus-newsgroup-unseen (nreverse gnus-newsgroup-unseen)))
+
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
@@ -4573,6 +4772,62 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; GROUP is successfully selected.
       (or gnus-newsgroup-headers t)))))
 
       ;; GROUP is successfully selected.
       (or gnus-newsgroup-headers t)))))
 
+(defun gnus-summary-display-make-predicate (display)
+  (require 'gnus-agent)
+  (when (= (length display) 1)
+    (setq display (car display)))
+  (unless gnus-summary-display-cache
+    (dolist (elem (append (list (cons 'read 'read)
+                               (cons 'unseen 'unseen))
+                         gnus-article-mark-lists))
+      (push (cons (cdr elem)
+                 (gnus-byte-compile
+                  `(lambda () (gnus-article-marked-p ',(cdr elem)))))
+           gnus-summary-display-cache)))
+  (let ((gnus-category-predicate-alist gnus-summary-display-cache))
+    (gnus-get-predicate display)))
+
+;; Uses the dynamically bound `number' variable.
+(defvar number)
+(defun gnus-article-marked-p (type &optional article)
+  (let ((article (or article number)))
+    (cond
+     ((eq type 'tick)
+      (memq article gnus-newsgroup-marked))
+     ((eq type 'unsend)
+      (memq article gnus-newsgroup-unsendable))
+     ((eq type 'undownload)
+      (memq article gnus-newsgroup-undownloaded))
+     ((eq type 'download)
+      (memq article gnus-newsgroup-downloadable))
+     ((eq type 'unread)
+      (memq article gnus-newsgroup-unreads))
+     ((eq type 'read)
+      (memq article gnus-newsgroup-reads))
+     ((eq type 'dormant)
+      (memq article gnus-newsgroup-dormant) )
+     ((eq type 'expire)
+      (memq article gnus-newsgroup-expirable))
+     ((eq type 'reply)
+      (memq article gnus-newsgroup-replied))
+     ((eq type 'killed)
+      (memq article gnus-newsgroup-killed))
+     ((eq type 'bookmark)
+      (assq article gnus-newsgroup-bookmarks))
+     ((eq type 'score)
+      (assq article gnus-newsgroup-scored))
+     ((eq type 'save)
+      (memq article gnus-newsgroup-saved))
+     ((eq type 'cache)
+      (memq article gnus-newsgroup-cached))
+     ((eq type 'forward)
+      (memq article gnus-newsgroup-forwarded))
+     ((eq type 'seen)
+      (not (memq article gnus-newsgroup-unseen)))
+     ((eq type 'recent)
+      (memq article gnus-newsgroup-recent))
+     (t t))))
+
 (defun gnus-articles-to-read (group &optional read-all)
   "Find out what articles the user wants to read."
   (let* ((articles
 (defun gnus-articles-to-read (group &optional read-all)
   "Find out what articles the user wants to read."
   (let* ((articles
@@ -4581,11 +4836,15 @@ If SELECT-ARTICLES, only select those articles from GROUP."
          (if (or read-all
                  (and (zerop (length gnus-newsgroup-marked))
                       (zerop (length gnus-newsgroup-unreads)))
          (if (or read-all
                  (and (zerop (length gnus-newsgroup-marked))
                       (zerop (length gnus-newsgroup-unreads)))
-                 (eq (gnus-group-find-parameter group 'display)
-                     'all))
+                 (eq gnus-newsgroup-display 'gnus-not-ignore))
+             ;; We want to select the headers for all the articles in
+             ;; the group, so we select either all the active
+             ;; articles in the group, or (if that's nil), the
+             ;; articles in the cache.
              (or
               (gnus-uncompress-range (gnus-active group))
               (gnus-cache-articles-in-group group))
              (or
               (gnus-uncompress-range (gnus-active group))
               (gnus-cache-articles-in-group group))
+           ;; Select only the "normal" subset of articles.
            (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked
                          (copy-sequence gnus-newsgroup-unreads))
                  '<)))
            (sort (append gnus-newsgroup-dormant gnus-newsgroup-marked
                          (copy-sequence gnus-newsgroup-unreads))
                  '<)))
@@ -4608,9 +4867,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                         (read-string
                          (format
                           "How many articles from %s (default %d): "
                         (read-string
                          (format
                           "How many articles from %s (default %d): "
-                          (gnus-limit-string 
-                            (gnus-group-decoded-name gnus-newsgroup-name)
-                            35)        
+                          (gnus-limit-string
+                           (gnus-group-decoded-name gnus-newsgroup-name)
+                           35)
                           number))))
                    (if (string-match "^[ \t]*$" input) number input)))
                 ((and (> scored marked) (< scored number)
                           number))))
                    (if (string-match "^[ \t]*$" input) number input)))
                 ((and (> scored marked) (< scored number)
@@ -4620,7 +4879,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                          (format "%s %s (%d scored, %d total): "
                                  "How many articles from"
                                  (gnus-group-decoded-name group)
                          (format "%s %s (%d scored, %d total): "
                                  "How many articles from"
                                  (gnus-group-decoded-name group)
-                                  scored number))))
+                                 scored number))))
                    (if (string-match "^[ \t]*$" input)
                        number input)))
                 (t number))
                    (if (string-match "^[ \t]*$" input)
                        number input)))
                 (t number))
@@ -4673,6 +4932,15 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (setq marks (cdr marks)))
     out))
 
       (setq marks (cdr marks)))
     out))
 
+(defun gnus-article-mark-to-type (mark)
+  "Return the type of MARK."
+  (or (cadr (assq mark gnus-article-special-mark-lists))
+      'list))
+
+(defun gnus-article-unpropagatable-p (mark)
+  "Return whether MARK should be propagated to backend."
+  (memq mark gnus-article-unpropagated-mark-lists))
+
 (defun gnus-adjust-marked-articles (info)
   "Set all article lists and remove all marks that are no longer valid."
   (let* ((marked-lists (gnus-info-marks info))
 (defun gnus-adjust-marked-articles (info)
   "Set all article lists and remove all marks that are no longer valid."
   (let* ((marked-lists (gnus-info-marks info))
@@ -4680,28 +4948,26 @@ If SELECT-ARTICLES, only select those articles from GROUP."
         (min (car active))
         (max (cdr active))
         (types gnus-article-mark-lists)
         (min (car active))
         (max (cdr active))
         (types gnus-article-mark-lists)
-        (uncompressed '(score bookmark killed))
-        marks var articles article mark)
+        marks var articles article mark mark-type)
 
 
-    (while marked-lists
-      (setq marks (pop marked-lists))
-      (set (setq var (intern (format "gnus-newsgroup-%s"
-                                    (car (rassq (setq mark (car marks))
-                                                types)))))
-          (if (memq (car marks) uncompressed) (cdr marks)
-            (gnus-uncompress-range (cdr marks))))
+    (dolist (marks marked-lists)
+      (setq mark (car marks)
+           mark-type (gnus-article-mark-to-type mark)
+           var (intern (format "gnus-newsgroup-%s" (car (rassq mark types)))))
 
 
-      (setq articles (symbol-value var))
-
-      ;; All articles have to be subsets of the active articles.
+      ;; We set the variable according to the type of the marks list,
+      ;; and then adjust the marks to a subset of the active articles.
       (cond
        ;; Adjust "simple" lists.
       (cond
        ;; Adjust "simple" lists.
-       ((memq mark '(tick dormant expire reply save))
-       (while articles
-         (when (or (< (setq article (pop articles)) min) (> article max))
-           (set var (delq article (symbol-value var))))))
+       ((eq mark-type 'list)
+       (set var (setq articles (gnus-uncompress-range (cdr marks))))
+       (when (memq mark '(tick dormant expire reply save))
+         (while articles
+           (when (or (< (setq article (pop articles)) min) (> article max))
+             (set var (delq article (symbol-value var)))))))
        ;; Adjust assocs.
        ;; Adjust assocs.
-       ((memq mark uncompressed)
+       ((eq mark-type 'tuple)
+       (set var (setq articles (cdr marks)))
        (when (not (listp (cdr (symbol-value var))))
          (set var (list (symbol-value var))))
        (when (not (listp (cdr articles)))
        (when (not (listp (cdr (symbol-value var))))
          (set var (list (symbol-value var))))
        (when (not (listp (cdr articles)))
@@ -4710,36 +4976,46 @@ If SELECT-ARTICLES, only select those articles from GROUP."
          (when (or (not (consp (setq article (pop articles))))
                    (< (car article) min)
                    (> (car article) max))
          (when (or (not (consp (setq article (pop articles))))
                    (< (car article) min)
                    (> (car article) max))
-           (set var (delq article (symbol-value var))))))))))
+           (set var (delq article (symbol-value var))))))
+       ;; Adjust ranges (sloppily).
+       ((eq mark-type 'range)
+       (cond
+        ((eq mark 'seen)
+         (setq articles (cdr marks))
+         (while (and articles
+                     (or (and (consp (car articles))
+                              (> min (cdar articles)))
+                         (and (numberp (car articles))
+                              (> min (car articles)))))
+           (pop articles))
+         (set var articles))))))))
 
 (defun gnus-update-missing-marks (missing)
   "Go through the list of MISSING articles and remove them from the mark lists."
   (when missing
 
 (defun gnus-update-missing-marks (missing)
   "Go through the list of MISSING articles and remove them from the mark lists."
   (when missing
-    (let ((types gnus-article-mark-lists)
-         var m)
+    (let (var m)
       ;; Go through all types.
       ;; Go through all types.
-      (while types
-       (setq var (intern (format "gnus-newsgroup-%s" (car (pop types)))))
-       (when (symbol-value var)
-         ;; This list has articles.  So we delete all missing articles
-         ;; from it.
-         (setq m missing)
-         (while m
-           (set var (delq (pop m) (symbol-value var)))))))))
+      (dolist (elem gnus-article-mark-lists)
+       (when (eq (gnus-article-mark-to-type (cdr elem)) 'list)
+         (setq var (intern (format "gnus-newsgroup-%s" (car elem))))
+         (when (symbol-value var)
+           ;; This list has articles.  So we delete all missing
+           ;; articles from it.
+           (setq m missing)
+           (while m
+             (set var (delq (pop m) (symbol-value var))))))))))
 
 (defun gnus-update-marks ()
   "Enter the various lists of marked articles into the newsgroup info list."
   (let ((types gnus-article-mark-lists)
        (info (gnus-get-info gnus-newsgroup-name))
 
 (defun gnus-update-marks ()
   "Enter the various lists of marked articles into the newsgroup info list."
   (let ((types gnus-article-mark-lists)
        (info (gnus-get-info gnus-newsgroup-name))
-       (uncompressed '(score bookmark killed))
        type list newmarked symbol delta-marks)
     (when info
       ;; Add all marks lists to the list of marks lists.
       (while (setq type (pop types))
        (setq list (symbol-value
                    (setq symbol
        type list newmarked symbol delta-marks)
     (when info
       ;; 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))))))
+                         (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
@@ -4758,27 +5034,23 @@ 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)))))
 
-       (unless (memq (cdr type) uncompressed)
+       (when (eq (cdr type) 'seen)
+         (setq list (gnus-range-add list gnus-newsgroup-unseen)))
+
+       (when (eq (gnus-article-mark-to-type (cdr type)) 'list)
          (setq list (gnus-compress-sequence (set symbol (sort list '<)) t)))
 
          (setq list (gnus-compress-sequence (set symbol (sort list '<)) t)))
 
-       (when (gnus-check-backend-function
-              'request-set-mark gnus-newsgroup-name)
-         ;; propagate flags to server, with the following exceptions:
-         ;; uncompressed:s are not proper flags (they are cons cells)
-         ;; cache is a internal gnus flag
-         ;; download are local to one gnus installation (well)
-         ;; unsend are for nndraft groups only
-         ;; xxx: generality of this?  this suits nnimap anyway
-         (unless (memq (cdr type) (append '(cache download unsend)
-                                          uncompressed))
-           (let* ((old (cdr (assq (cdr type) (gnus-info-marks info))))
-                  (del (gnus-remove-from-range (gnus-copy-sequence old) list))
-                  (add (gnus-remove-from-range
-                        (gnus-copy-sequence list) old)))
-             (when add
-               (push (list add 'add (list (cdr type))) delta-marks))
-             (when del
-               (push (list del 'del (list (cdr type))) delta-marks)))))
+       (when (and (gnus-check-backend-function
+                   'request-set-mark gnus-newsgroup-name)
+                  (not (gnus-article-unpropagatable-p (cdr type))))
+         (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
          (push (cons (cdr type) list) newmarked)))
 
        (when list
          (push (cons (cdr type) list) newmarked)))
@@ -4814,12 +5086,12 @@ If WHERE is `summary', the summary mode line format will be used."
        ;; We evaluate this in the summary buffer since these
        ;; variables are buffer-local to that buffer.
        (set-buffer gnus-summary-buffer)
        ;; We evaluate this in the summary buffer since these
        ;; variables are buffer-local to that buffer.
        (set-buffer gnus-summary-buffer)
-       ;; We bind all these variables that are used in the `eval' form
+       ;; We bind all these variables that are used in the `eval' form
        ;; below.
        (let* ((mformat (symbol-value
                         (intern
                          (format "gnus-%s-mode-line-format-spec" where))))
        ;; below.
        (let* ((mformat (symbol-value
                         (intern
                          (format "gnus-%s-mode-line-format-spec" where))))
-              (gnus-tmp-group-name (gnus-group-decoded-name 
+              (gnus-tmp-group-name (gnus-group-decoded-name
                                     gnus-newsgroup-name))
               (gnus-tmp-article-number (or gnus-current-article 0))
               (gnus-tmp-unread gnus-newsgroup-unreads)
                                     gnus-newsgroup-name))
               (gnus-tmp-article-number (or gnus-current-article 0))
               (gnus-tmp-unread gnus-newsgroup-unreads)
@@ -4841,7 +5113,7 @@ If WHERE is `summary', the summary mode line format will be used."
                     (mail-header-subject gnus-current-headers))
                  ""))
               bufname-length max-len
                     (mail-header-subject gnus-current-headers))
                  ""))
               bufname-length max-len
-              gnus-tmp-header);; passed as argument to any user-format-funcs
+              gnus-tmp-header) ;; passed as argument to any user-format-funcs
          (setq mode-string (eval mformat))
          (setq bufname-length (if (string-match "%b" mode-string)
                                   (- (length
          (setq mode-string (eval mformat))
          (setq bufname-length (if (string-match "%b" mode-string)
                                   (- (length
@@ -4982,9 +5254,11 @@ The resulting hash table is returned, or nil if no Xrefs were found."
             (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-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-request-set-mark ,group (list (list ',range 'del '(read))))
             (gnus-group-update-group ,group t))))
       ;; Add the read articles to the range.
       (gnus-info-set-read info range)
             (gnus-group-update-group ,group t))))
       ;; Add the read articles to the range.
       (gnus-info-set-read info range)
+      (gnus-request-set-mark group (list (list range 'add '(read))))
       ;; Then we have to re-compute how many unread
       ;; articles there are in this group.
       (when active
       ;; Then we have to re-compute how many unread
       ;; articles there are in this group.
       (when active
@@ -5508,7 +5782,7 @@ Also do horizontal recentering."
 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).
 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.
+;; Recenter only when requested.  Suggested by popovich@park.cs.columbia.edu.
   (interactive)
   (let* ((top (cond ((< (window-height) 4) 0)
                    ((< (window-height) 7) 1)
   (interactive)
   (let* ((top (cond ((< (window-height) 4) 0)
                    ((< (window-height) 7) 1)
@@ -5524,7 +5798,7 @@ displayed, no centering will be performed."
     (when gnus-auto-center-summary
       (when (get-buffer-window gnus-article-buffer)
        ;; Only do recentering when the article buffer is displayed,
     (when gnus-auto-center-summary
       (when (get-buffer-window gnus-article-buffer)
        ;; Only do recentering when the article buffer is displayed,
-       ;; Set the window start to either `bottom', which is the biggest
+      ;; Set the window start to either `bottom', which is the biggest
        ;; possible valid number, or the second line from the top,
        ;; whichever is the least.
        (let ((top-pos (save-excursion (forward-line (- top)) (point))))
        ;; possible valid number, or the second line from the top,
        ;; whichever is the least.
        (let ((top-pos (save-excursion (forward-line (- top)) (point))))
@@ -5753,7 +6027,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
   (let* ((group gnus-newsgroup-name)
         (quit-config (gnus-group-quit-config gnus-newsgroup-name))
         (mode major-mode)
   (let* ((group gnus-newsgroup-name)
         (quit-config (gnus-group-quit-config gnus-newsgroup-name))
         (mode major-mode)
-         (group-point nil)
+        (group-point nil)
         (buf (current-buffer)))
     (unless quit-config
       ;; Do adaptive scoring, and possibly save score files.
         (buf (current-buffer)))
     (unless quit-config
       ;; Do adaptive scoring, and possibly save score files.
@@ -5806,7 +6080,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
          (progn
            (gnus-deaden-summary)
            (setq mode nil))
          (progn
            (gnus-deaden-summary)
            (setq mode nil))
-       ;; We set all buffer-local variables to nil.  It is unclear why
+       ;; We set all buffer-local variables to nil.  It is unclear why
        ;; this is needed, but if we don't, buffer-local variables are
        ;; not garbage-collected, it seems.  This would the lead to en
        ;; ever-growing Emacs.
        ;; this is needed, but if we don't, buffer-local variables are
        ;; not garbage-collected, it seems.  This would the lead to en
        ;; ever-growing Emacs.
@@ -5886,7 +6160,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (when (equal (gnus-group-group-name) group)
        (gnus-group-next-unread-group 1))
       (when quit-config
       (when (equal (gnus-group-group-name) group)
        (gnus-group-next-unread-group 1))
       (when quit-config
-        (gnus-handle-ephemeral-exit quit-config)))))
+       (gnus-handle-ephemeral-exit quit-config)))))
 
 (defun gnus-handle-ephemeral-exit (quit-config)
   "Handle movement when leaving an ephemeral group.
 
 (defun gnus-handle-ephemeral-exit (quit-config)
   "Handle movement when leaving an ephemeral group.
@@ -5895,25 +6169,25 @@ The state which existed when entering the ephemeral is reset."
       (gnus-configure-windows 'group 'force)
     (set-buffer (car quit-config))
     (cond ((eq major-mode 'gnus-summary-mode)
       (gnus-configure-windows 'group 'force)
     (set-buffer (car quit-config))
     (cond ((eq major-mode 'gnus-summary-mode)
-           (gnus-set-global-variables))
-          ((eq major-mode 'gnus-article-mode)
-           (save-excursion
-             ;; The `gnus-summary-buffer' variable may point
-             ;; to the old summary buffer when using a single
-             ;; article buffer.
-             (unless (gnus-buffer-live-p gnus-summary-buffer)
-               (set-buffer gnus-group-buffer))
-             (set-buffer gnus-summary-buffer)
-             (gnus-set-global-variables))))
+          (gnus-set-global-variables))
+         ((eq major-mode 'gnus-article-mode)
+          (save-excursion
+            ;; The `gnus-summary-buffer' variable may point
+            ;; to the old summary buffer when using a single
+            ;; article buffer.
+            (unless (gnus-buffer-live-p gnus-summary-buffer)
+              (set-buffer gnus-group-buffer))
+            (set-buffer gnus-summary-buffer)
+            (gnus-set-global-variables))))
     (if (or (eq (cdr quit-config) 'article)
     (if (or (eq (cdr quit-config) 'article)
-            (eq (cdr quit-config) 'pick))
-        (progn
-          ;; The current article may be from the ephemeral group
-          ;; thus it is best that we reload this article
-          (gnus-summary-show-article)
-          (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode))
-              (gnus-configure-windows 'pick 'force)
-            (gnus-configure-windows (cdr quit-config) 'force)))
+           (eq (cdr quit-config) 'pick))
+       (progn
+         ;; The current article may be from the ephemeral group
+         ;; thus it is best that we reload this article
+         (gnus-summary-show-article)
+         (if (and (boundp 'gnus-pick-mode) (symbol-value 'gnus-pick-mode))
+             (gnus-configure-windows 'pick 'force)
+           (gnus-configure-windows (cdr quit-config) 'force)))
       (gnus-configure-windows (cdr quit-config) 'force))
     (when (eq major-mode 'gnus-summary-mode)
       (gnus-summary-next-subject 1 nil t)
       (gnus-configure-windows (cdr quit-config) 'force))
     (when (eq major-mode 'gnus-summary-mode)
       (gnus-summary-next-subject 1 nil t)
@@ -5929,10 +6203,11 @@ The state which existed when entering the ephemeral is reset."
   (suppress-keymap gnus-dead-summary-mode-map)
   (substitute-key-definition
    'undefined 'gnus-summary-wake-up-the-dead gnus-dead-summary-mode-map)
   (suppress-keymap gnus-dead-summary-mode-map)
   (substitute-key-definition
    'undefined 'gnus-summary-wake-up-the-dead gnus-dead-summary-mode-map)
-  (let ((keys '("\C-d" "\r" "\177" [delete])))
-    (while keys
-      (define-key gnus-dead-summary-mode-map
-       (pop keys) 'gnus-summary-wake-up-the-dead))))
+  (dolist (key '("\C-d" "\r" "\177" [delete]))
+    (define-key gnus-dead-summary-mode-map
+      key 'gnus-summary-wake-up-the-dead))
+  (dolist (key '("q" "Q"))
+    (define-key gnus-dead-summary-mode-map key 'bury-buffer)))
 
 (defvar gnus-dead-summary-mode nil
   "Minor mode for Gnus summary buffers.")
 
 (defvar gnus-dead-summary-mode nil
   "Minor mode for Gnus summary buffers.")
@@ -5978,17 +6253,20 @@ The state which existed when entering the ephemeral is reset."
        (set-buffer buffer)
        (gnus-kill-buffer gnus-article-buffer)
        (gnus-kill-buffer gnus-original-article-buffer)))
        (set-buffer buffer)
        (gnus-kill-buffer gnus-article-buffer)
        (gnus-kill-buffer gnus-original-article-buffer)))
-    (cond (gnus-kill-summary-on-exit
-          (when (and gnus-use-trees
-                     (gnus-buffer-exists-p buffer))
-            (save-excursion
-              (set-buffer buffer)
-              (gnus-tree-close gnus-newsgroup-name)))
-          (gnus-kill-buffer buffer))
-         ((gnus-buffer-exists-p buffer)
-          (save-excursion
-            (set-buffer buffer)
-            (gnus-deaden-summary))))))
+    (cond
+     ;; Kill the buffer.
+     (gnus-kill-summary-on-exit
+      (when (and gnus-use-trees
+                (gnus-buffer-exists-p buffer))
+       (save-excursion
+         (set-buffer buffer)
+         (gnus-tree-close gnus-newsgroup-name)))
+      (gnus-kill-buffer buffer))
+     ;; Deaden the buffer.
+     ((gnus-buffer-exists-p buffer)
+      (save-excursion
+       (set-buffer buffer)
+       (gnus-deaden-summary))))))
 
 (defun gnus-summary-wake-up-the-dead (&rest args)
   "Wake up the dead summary buffer."
 
 (defun gnus-summary-wake-up-the-dead (&rest args)
   "Wake up the dead summary buffer."
@@ -6043,7 +6321,7 @@ previous group instead."
   (let ((current-group gnus-newsgroup-name)
        (current-buffer (current-buffer))
        entered)
   (let ((current-group gnus-newsgroup-name)
        (current-buffer (current-buffer))
        entered)
-    ;; First we semi-exit this group to update Xrefs and all variables.
+   ;; First we semi-exit this group to update Xrefs and all variables.
     ;; We can't do a real exit, because the window conf must remain
     ;; the same in case the user is prompted for info, and we don't
     ;; want the window conf to change before that...
     ;; We can't do a real exit, because the window conf must remain
     ;; the same in case the user is prompted for info, and we don't
     ;; want the window conf to change before that...
@@ -6088,7 +6366,7 @@ If prefix argument NO-ARTICLE is non-nil, no article is selected initially."
 
 ;; Walking around summary lines.
 
 
 ;; Walking around summary lines.
 
-(defun gnus-summary-first-subject (&optional unread undownloaded)
+(defun gnus-summary-first-subject (&optional unread undownloaded unseen)
   "Go to the first unread subject.
 If UNREAD is non-nil, go to the first unread article.
 Returns the article selected or nil if there are no unread articles."
   "Go to the first unread subject.
 If UNREAD is non-nil, go to the first unread article.
 Returns the article selected or nil if there are no unread articles."
@@ -6114,7 +6392,12 @@ Returns the article selected or nil if there are no unread articles."
                      (and (not (and undownloaded
                                     (eq gnus-undownloaded-mark
                                         (gnus-data-mark (car data)))))
                      (and (not (and undownloaded
                                     (eq gnus-undownloaded-mark
                                         (gnus-data-mark (car data)))))
-                          (not (gnus-data-unread-p (car data)))))
+                          (if unseen
+                              (or (not (memq
+                                        (gnus-data-number (car data))
+                                        gnus-newsgroup-unseen))
+                                  (not (gnus-data-unread-p (car data))))
+                            (not (gnus-data-unread-p (car data))))))
            (setq data (cdr data)))
          (when data
            (goto-char (gnus-data-pos (car data)))
            (setq data (cdr data)))
          (when data
            (goto-char (gnus-data-pos (car data)))
@@ -6200,13 +6483,13 @@ Given a prefix, will force an `article' buffer configuration."
   "Display ARTICLE in article buffer."
   (when (gnus-buffer-live-p gnus-article-buffer)
     (with-current-buffer gnus-article-buffer
   "Display ARTICLE in article buffer."
   (when (gnus-buffer-live-p gnus-article-buffer)
     (with-current-buffer gnus-article-buffer
-      (mm-enable-multibyte-mule4)))
+      (mm-enable-multibyte)))
   (gnus-set-global-variables)
   (when (gnus-buffer-live-p gnus-article-buffer)
     (with-current-buffer gnus-article-buffer
       (setq gnus-article-charset gnus-newsgroup-charset)
       (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)
   (gnus-set-global-variables)
   (when (gnus-buffer-live-p gnus-article-buffer)
     (with-current-buffer gnus-article-buffer
       (setq gnus-article-charset gnus-newsgroup-charset)
       (setq gnus-article-ignored-charsets gnus-newsgroup-ignored-charsets)
-      (mm-enable-multibyte-mule4)))
+      (mm-enable-multibyte)))
   (if (null article)
       nil
     (prog1
   (if (null article)
       nil
     (prog1
@@ -6235,7 +6518,7 @@ be displayed."
   (unless (eq major-mode 'gnus-summary-mode)
     (set-buffer gnus-summary-buffer))
   (let ((article (or article (gnus-summary-article-number)))
   (unless (eq major-mode 'gnus-summary-mode)
     (set-buffer gnus-summary-buffer))
   (let ((article (or article (gnus-summary-article-number)))
-       (all-headers (not (not all-headers))) ;Must be T or NIL.
+       (all-headers (not (not all-headers))) ;Must be t or nil.
        gnus-summary-display-article-function)
     (and (not pseudo)
         (gnus-summary-article-pseudo-p article)
        gnus-summary-display-article-function)
     (and (not pseudo)
         (gnus-summary-article-pseudo-p article)
@@ -6257,16 +6540,17 @@ be displayed."
          (progn
            (gnus-summary-display-article article all-headers)
            (when (gnus-buffer-live-p gnus-article-buffer)
          (progn
            (gnus-summary-display-article article all-headers)
            (when (gnus-buffer-live-p gnus-article-buffer)
-              (with-current-buffer gnus-article-buffer
+             (with-current-buffer gnus-article-buffer
                (if (not gnus-article-decoded-p) ;; a local variable
                (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))
+                   (mm-disable-multibyte))))
+;;; Hidden headers are not hidden text any more.
+;;         (when (or all-headers gnus-show-all-headers)
+;;           (gnus-article-show-all-headers))
            (gnus-article-set-window-start
             (cdr (assq article gnus-newsgroup-bookmarks)))
            article)
            (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))
+;;     (when (or all-headers gnus-show-all-headers)
+;;       (gnus-article-show-all-headers))
        'old))))
 
 (defun gnus-summary-force-verify-and-decrypt ()
        'old))))
 
 (defun gnus-summary-force-verify-and-decrypt ()
@@ -6555,6 +6839,16 @@ Return nil if there are no unread articles."
        (gnus-summary-first-subject t))
     (gnus-summary-position-point)))
 
        (gnus-summary-first-subject t))
     (gnus-summary-position-point)))
 
+(defun gnus-summary-first-unseen-subject ()
+  "Place the point on the subject line of the first unseen article.
+Return nil if there are no unseen articles."
+  (interactive)
+  (prog1
+      (when (gnus-summary-first-subject t t t)
+       (gnus-summary-show-thread)
+       (gnus-summary-first-subject t t t))
+    (gnus-summary-position-point)))
+
 (defun gnus-summary-first-article ()
   "Select the first article.
 Return nil if there are no articles."
 (defun gnus-summary-first-article ()
   "Select the first article.
 Return nil if there are no articles."
@@ -6566,8 +6860,20 @@ Return nil if there are no articles."
        (gnus-summary-display-article (gnus-summary-article-number)))
     (gnus-summary-position-point)))
 
        (gnus-summary-display-article (gnus-summary-article-number)))
     (gnus-summary-position-point)))
 
-(defun gnus-summary-best-unread-article ()
-  "Select the unread article with the highest score."
+(defun gnus-summary-best-unread-article (&optional arg)
+  "Select the unread article with the highest score.
+If given a prefix argument, select the next unread article that has a
+score higher than the default score."
+  (interactive "P")
+  (let ((article (if arg
+                    (gnus-summary-better-unread-subject)
+                  (gnus-summary-best-unread-subject))))
+    (if article
+       (gnus-summary-goto-article article)
+      (error "No unread articles"))))
+
+(defun gnus-summary-best-unread-subject ()
+  "Select the unread subject with the highest score."
   (interactive)
   (let ((best -1000000)
        (data gnus-newsgroup-data)
   (interactive)
   (let ((best -1000000)
        (data gnus-newsgroup-data)
@@ -6580,11 +6886,25 @@ Return nil if there are no articles."
           (setq best score
                 article (gnus-data-number (car data))))
       (setq data (cdr data)))
           (setq best score
                 article (gnus-data-number (car data))))
       (setq data (cdr data)))
-    (prog1
-       (if article
-           (gnus-summary-goto-article article)
-         (error "No unread articles"))
-      (gnus-summary-position-point))))
+    (when article
+      (gnus-summary-goto-subject article))
+    (gnus-summary-position-point)
+    article))
+
+(defun gnus-summary-better-unread-subject ()
+  "Select the first unread subject that has a score over the default score."
+  (interactive)
+  (let ((data gnus-newsgroup-data)
+       article score)
+    (while (and (setq article (gnus-data-number (car data)))
+               (or (gnus-data-read-p (car data))
+                   (not (> (gnus-summary-article-score article)
+                           gnus-summary-default-score))))
+      (setq data (cdr data)))
+    (when article
+      (gnus-summary-goto-subject article))
+    (gnus-summary-position-point)
+    article))
 
 (defun gnus-summary-last-subject ()
   "Go to the last displayed subject line in the group."
 
 (defun gnus-summary-last-subject ()
   "Go to the last displayed subject line in the group."
@@ -6662,24 +6982,35 @@ If given a prefix, remove all limits."
       (gnus-summary-limit nil 'pop)
     (gnus-summary-position-point)))
 
       (gnus-summary-limit nil 'pop)
     (gnus-summary-position-point)))
 
-(defun gnus-summary-limit-to-subject (subject &optional header)
-  "Limit the summary buffer to articles that have subjects that match a regexp."
-  (interactive "sLimit to subject (regexp): ")
+(defun gnus-summary-limit-to-subject (subject &optional header not-matching)
+  "Limit the summary buffer to articles that have subjects that match a regexp.
+If NOT-MATCHING, excluding articles that have subjects that match a regexp."
+  (interactive
+   (list (read-string (if current-prefix-arg
+                         "Exclude subject (regexp): "
+                       "Limit to subject (regexp): "))
+        nil current-prefix-arg))
   (unless header
     (setq header "subject"))
   (when (not (equal "" subject))
     (prog1
        (let ((articles (gnus-summary-find-matching
   (unless header
     (setq header "subject"))
   (when (not (equal "" subject))
     (prog1
        (let ((articles (gnus-summary-find-matching
-                        (or header "subject") subject 'all)))
+                        (or header "subject") subject 'all nil nil
+                        not-matching)))
          (unless articles
            (error "Found no matches for \"%s\"" subject))
          (gnus-summary-limit articles))
       (gnus-summary-position-point))))
 
          (unless articles
            (error "Found no matches for \"%s\"" subject))
          (gnus-summary-limit articles))
       (gnus-summary-position-point))))
 
-(defun gnus-summary-limit-to-author (from)
-  "Limit the summary buffer to articles that have authors that match a regexp."
-  (interactive "sLimit to author (regexp): ")
-  (gnus-summary-limit-to-subject from "from"))
+(defun gnus-summary-limit-to-author (from &optional not-matching)
+  "Limit the summary buffer to articles that have authors that match a regexp.
+If NOT-MATCHING, excluding articles that have authors that match a regexp."
+  (interactive
+   (list (read-string (if current-prefix-arg
+                         "Exclude author (regexp): "
+                       "Limit to author (regexp): "))
+        current-prefix-arg))
+  (gnus-summary-limit-to-subject from "from" not-matching))
 
 (defun gnus-summary-limit-to-age (age &optional younger-p)
   "Limit the summary buffer to articles that are older than (or equal) AGE days.
 
 (defun gnus-summary-limit-to-age (age &optional younger-p)
   "Limit the summary buffer to articles that are older than (or equal) AGE days.
@@ -6696,7 +7027,12 @@ articles that are younger than AGE days."
        (when (> (length days) 0)
         (setq days (read days)))
        (if (numberp days)
        (when (> (length days) 0)
         (setq days (read days)))
        (if (numberp days)
-          (setq days-got t)
+          (progn 
+            (setq days-got t)
+            (if (< days 0)
+                (progn 
+                  (setq younger (not younger))
+                  (setq days (* days -1)))))
         (message "Please enter a number.")
         (sleep-for 1)))
      (list days younger)))
         (message "Please enter a number.")
         (sleep-for 1)))
      (list days younger)))
@@ -6719,30 +7055,48 @@ articles that are younger than AGE days."
        (gnus-summary-limit (nreverse articles)))
     (gnus-summary-position-point)))
 
        (gnus-summary-limit (nreverse articles)))
     (gnus-summary-position-point)))
 
-(defun gnus-summary-limit-to-extra (header regexp)
+(defun gnus-summary-limit-to-extra (header regexp &optional not-matching)
   "Limit the summary buffer to articles that match an 'extra' header."
   (interactive
    (let ((header
          (intern
           (gnus-completing-read
            (symbol-name (car gnus-extra-headers))
   "Limit the summary buffer to articles that match an 'extra' header."
   (interactive
    (let ((header
          (intern
           (gnus-completing-read
            (symbol-name (car gnus-extra-headers))
-           "Limit extra header:"
+           (if current-prefix-arg
+               "Exclude extra header:"
+             "Limit extra header:")
            (mapcar (lambda (x)
                      (cons (symbol-name x) x))
                    gnus-extra-headers)
            nil
            t))))
      (list header
            (mapcar (lambda (x)
                      (cons (symbol-name x) x))
                    gnus-extra-headers)
            nil
            t))))
      (list header
-          (read-string (format "Limit to header %s (regexp): " header)))))
+          (read-string (format "%s header %s (regexp): "
+                               (if current-prefix-arg "Exclude" "Limit to")
+                               header))
+          current-prefix-arg)))
   (when (not (equal "" regexp))
     (prog1
        (let ((articles (gnus-summary-find-matching
   (when (not (equal "" regexp))
     (prog1
        (let ((articles (gnus-summary-find-matching
-                        (cons 'extra header) regexp 'all)))
+                        (cons 'extra header) regexp 'all nil nil
+                        not-matching)))
          (unless articles
            (error "Found no matches for \"%s\"" regexp))
          (gnus-summary-limit articles))
       (gnus-summary-position-point))))
 
          (unless articles
            (error "Found no matches for \"%s\"" regexp))
          (gnus-summary-limit articles))
       (gnus-summary-position-point))))
 
+(defun gnus-summary-limit-to-display-predicate ()
+  "Limit the summary buffer to the predicated in the `display' group parameter."
+  (interactive)
+  (unless gnus-newsgroup-display
+    (error "There is no `display' group parameter"))
+  (let (articles)
+    (dolist (number gnus-newsgroup-articles)
+      (when (funcall gnus-newsgroup-display)
+       (push number articles)))
+    (gnus-summary-limit articles))
+  (gnus-summary-position-point))
+
 (defalias 'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread)
 (make-obsolete
  'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread)
 (defalias 'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread)
 (make-obsolete
  'gnus-summary-delete-marked-as-read 'gnus-summary-limit-to-unread)
@@ -6795,12 +7149,9 @@ Returns how many articles were removed."
        (gnus-summary-limit articles))
     (gnus-summary-position-point)))
 
        (gnus-summary-limit articles))
     (gnus-summary-position-point)))
 
-(defun gnus-summary-limit-to-score (&optional score)
+(defun gnus-summary-limit-to-score (score)
   "Limit to articles with score at or above SCORE."
   "Limit to articles with score at or above SCORE."
-  (interactive "P")
-  (setq score (if score
-                 (prefix-numeric-value score)
-               (or gnus-summary-default-score 0)))
+  (interactive "NLimit to articles with score of at least: ")
   (let ((data gnus-newsgroup-data)
        articles)
     (while data
   (let ((data gnus-newsgroup-data)
        articles)
     (while data
@@ -6821,10 +7172,10 @@ article."
                   (gnus-id-to-thread (gnus-root-id id)))))
     (prog1
        (gnus-summary-limit (nconc articles gnus-newsgroup-limit))
                   (gnus-id-to-thread (gnus-root-id id)))))
     (prog1
        (gnus-summary-limit (nconc articles gnus-newsgroup-limit))
-       (gnus-summary-limit-include-matching-articles
-        "subject"
-        (regexp-quote (gnus-simplify-subject-re
-                       (mail-header-subject (gnus-id-to-header id)))))
+      (gnus-summary-limit-include-matching-articles
+       "subject"
+       (regexp-quote (gnus-simplify-subject-re
+                     (mail-header-subject (gnus-id-to-header id)))))
       (gnus-summary-position-point))))
 
 (defun gnus-summary-limit-include-matching-articles (header regexp)
       (gnus-summary-position-point))))
 
 (defun gnus-summary-limit-include-matching-articles (header regexp)
@@ -6920,9 +7271,7 @@ If ALL, mark even excluded ticked and dormants as read."
     ;; according to the new limit.
     (gnus-summary-prepare)
     ;; Hide any threads, possibly.
     ;; according to the new limit.
     (gnus-summary-prepare)
     ;; Hide any threads, possibly.
-    (and gnus-show-threads
-        gnus-thread-hide-subtree
-        (gnus-summary-hide-all-threads))
+    (gnus-summary-maybe-hide-threads)
     ;; Try to return to the article you were at, or one in the
     ;; neighborhood.
     (when data
     ;; Try to return to the article you were at, or one in the
     ;; neighborhood.
     (when data
@@ -7002,6 +7351,7 @@ fetch-old-headers verbiage, and so on."
   ;; Most groups have nothing to remove.
   (if (or gnus-inhibit-limiting
          (and (null gnus-newsgroup-dormant)
   ;; Most groups have nothing to remove.
   (if (or gnus-inhibit-limiting
          (and (null gnus-newsgroup-dormant)
+              (eq gnus-newsgroup-display 'gnus-not-ignore)
               (not (eq gnus-fetch-old-headers 'some))
               (not (numberp gnus-fetch-old-headers))
               (not (eq gnus-fetch-old-headers 'invisible))
               (not (eq gnus-fetch-old-headers 'some))
               (not (numberp gnus-fetch-old-headers))
               (not (eq gnus-fetch-old-headers 'invisible))
@@ -7090,6 +7440,9 @@ fetch-old-headers verbiage, and so on."
                  (push (cons number gnus-low-score-mark)
                        gnus-newsgroup-reads)))
              t)
                  (push (cons number gnus-low-score-mark)
                        gnus-newsgroup-reads)))
              t)
+           ;; Do the `display' group parameter.
+           (and gnus-newsgroup-display
+                (not (funcall gnus-newsgroup-display)))
            ;; Check NoCeM things.
            (if (and gnus-use-nocem
                     (gnus-nocem-unwanted-article-p
            ;; Check NoCeM things.
            (if (and gnus-use-nocem
                     (gnus-nocem-unwanted-article-p
@@ -7325,21 +7678,24 @@ to guess what the document format is."
        (delete-matching-lines "^Path:\\|^From ")
        (widen))
       (unwind-protect
        (delete-matching-lines "^Path:\\|^From ")
        (widen))
       (unwind-protect
-          (if (let ((gnus-newsgroup-ephemeral-charset gnus-newsgroup-charset)
+         (if (let ((gnus-newsgroup-ephemeral-charset gnus-newsgroup-charset)
                    (gnus-newsgroup-ephemeral-ignored-charsets
                     gnus-newsgroup-ignored-charsets))
                (gnus-group-read-ephemeral-group
                 name `(nndoc ,name (nndoc-address ,(get-buffer dig))
                              (nndoc-article-type
                    (gnus-newsgroup-ephemeral-ignored-charsets
                     gnus-newsgroup-ignored-charsets))
                (gnus-group-read-ephemeral-group
                 name `(nndoc ,name (nndoc-address ,(get-buffer dig))
                              (nndoc-article-type
-                              ,(if force 'mbox 'guess))) t))
+                              ,(if force 'mbox 'guess)))
+                t nil nil nil
+                `((adapt-file . ,(gnus-score-file-name gnus-newsgroup-name
+                                                       "ADAPT")))))
              ;; Make all postings to this group go to the parent group.
              ;; Make all postings to this group go to the parent group.
-              (nconc (gnus-info-params (gnus-get-info name))
-                     params)
-            ;; Couldn't select this doc group.
-            (switch-to-buffer buf)
-            (gnus-set-global-variables)
-            (gnus-configure-windows 'summary)
-            (gnus-message 3 "Article couldn't be entered?"))
+             (nconc (gnus-info-params (gnus-get-info name))
+                    params)
+           ;; Couldn't select this doc group.
+           (switch-to-buffer buf)
+           (gnus-set-global-variables)
+           (gnus-configure-windows 'summary)
+           (gnus-message 3 "Article couldn't be entered?"))
        (kill-buffer dig)))))
 
 (defun gnus-summary-read-document (n)
        (kill-buffer dig)))))
 
 (defun gnus-summary-read-document (n)
@@ -7372,7 +7728,7 @@ Obeys the standard process/prefix convention."
                                     (nndoc-article-type guess))
                       t nil t))
                (progn
                                     (nndoc-article-type guess))
                       t nil t))
                (progn
-                 ;; Make all postings to this group go to the parent group.
+           ;; Make all postings to this group go to the parent group.
                  (nconc (gnus-info-params (gnus-get-info egroup))
                         params)
                  (push egroup groups))
                  (nconc (gnus-info-params (gnus-get-info egroup))
                         params)
                  (push egroup groups))
@@ -7515,13 +7871,14 @@ fetched headers for, whether they are displayed or not."
     (nreverse articles)))
 
 (defun gnus-summary-find-matching (header regexp &optional backward unread
     (nreverse articles)))
 
 (defun gnus-summary-find-matching (header regexp &optional backward unread
-                                         not-case-fold)
+                                         not-case-fold not-matching)
   "Return a list of all articles that match REGEXP on HEADER.
 The search stars on the current article and goes forwards unless
 BACKWARD is non-nil.  If BACKWARD is `all', do all articles.
 If UNREAD is non-nil, only unread articles will
 be taken into consideration.  If NOT-CASE-FOLD, case won't be folded
   "Return a list of all articles that match REGEXP on HEADER.
 The search stars on the current article and goes forwards unless
 BACKWARD is non-nil.  If BACKWARD is `all', do all articles.
 If UNREAD is non-nil, only unread articles will
 be taken into consideration.  If NOT-CASE-FOLD, case won't be folded
-in the comparisons."
+in the comparisons. If NOT-MATCHING, return a list of all articles that
+not match REGEXP on HEADER."
   (let ((case-fold-search (not not-case-fold))
        articles d func)
     (if (consp header)
   (let ((case-fold-search (not not-case-fold))
        articles d func)
     (if (consp header)
@@ -7542,8 +7899,12 @@ in the comparisons."
       (when (and (or (not unread)      ; We want all articles...
                     (gnus-data-unread-p d)) ; Or just unreads.
                 (vectorp (gnus-data-header d)) ; It's not a pseudo.
       (when (and (or (not unread)      ; We want all articles...
                     (gnus-data-unread-p d)) ; Or just unreads.
                 (vectorp (gnus-data-header d)) ; It's not a pseudo.
-                (string-match regexp
-                              (funcall func (gnus-data-header d)))) ; Match.
+                (if not-matching
+                    (not (string-match
+                          regexp
+                          (funcall func (gnus-data-header d))))
+                  (string-match regexp
+                                (funcall func (gnus-data-header d)))))
        (push (gnus-data-number d) articles))) ; Success!
     (nreverse articles)))
 
        (push (gnus-data-number d) articles))) ; Success!
     (nreverse articles)))
 
@@ -7572,7 +7933,7 @@ article.  If BACKWARD (the prefix) is non-nil, search backward instead."
   (save-excursion
     (save-window-excursion
       (gnus-message 6 "Executing %s..." (key-description command))
   (save-excursion
     (save-window-excursion
       (gnus-message 6 "Executing %s..." (key-description command))
-      ;; We'd like to execute COMMAND interactively so as to give arguments.
+;; We'd like to execute COMMAND interactively so as to give arguments.
       (gnus-execute header regexp
                    `(call-interactively ',(key-binding command))
                    backward)
       (gnus-execute header regexp
                    `(call-interactively ',(key-binding command))
                    backward)
@@ -7601,6 +7962,13 @@ article.  If BACKWARD (the prefix) is non-nil, search backward instead."
     (when gnus-page-broken
       (gnus-narrow-to-page))))
 
     (when gnus-page-broken
       (gnus-narrow-to-page))))
 
+(defun gnus-summary-print-truncate-and-quote (string &optional len)
+  "Truncate to LEN and quote all \"(\"'s in STRING."
+  (gnus-replace-in-string (if (and len (> (length string) len))
+                             (substring string 0 len)
+                           string)
+                         "[()]" "\\\\\\&"))
+
 (defun gnus-summary-print-article (&optional filename n)
   "Generate and print a PostScript image of the N next (mail) articles.
 
 (defun gnus-summary-print-article (&optional filename n)
   "Generate and print a PostScript image of the N next (mail) articles.
 
@@ -7615,64 +7983,83 @@ to save in."
   (dolist (article (gnus-summary-work-articles n))
     (gnus-summary-select-article nil nil 'pseudo article)
     (gnus-eval-in-buffer-window gnus-article-buffer
   (dolist (article (gnus-summary-work-articles n))
     (gnus-summary-select-article nil nil 'pseudo article)
     (gnus-eval-in-buffer-window gnus-article-buffer
-      (let ((buffer (generate-new-buffer " *print*")))
-       (unwind-protect
-           (progn
-             (copy-to-buffer buffer (point-min) (point-max))
-             (set-buffer buffer)
-             (gnus-article-delete-invisible-text)
-             (when (gnus-visual-p 'article-highlight 'highlight)
-               ;; Copy-to-buffer doesn't copy overlay.  So redo
-               ;; highlight.
-               (let ((gnus-article-buffer buffer))
-                 (gnus-article-highlight-citation t)
-                 (gnus-article-highlight-signature)))
-             (let ((ps-left-header
-                    (list
-                     (concat "("
-                             (mail-header-subject gnus-current-headers) ")")
-                     (concat "("
-                             (mail-header-from gnus-current-headers) ")")))
-                   (ps-right-header
-                    (list
-                     "/pagenumberstring load"
-                     (concat "("
-                             (mail-header-date gnus-current-headers) ")"))))
-               (gnus-run-hooks 'gnus-ps-print-hook)
-               (save-excursion
-                 (if window-system
-                     (ps-spool-buffer-with-faces)
-                   (ps-spool-buffer)))))
-         (kill-buffer buffer))))
+      (gnus-print-buffer))
     (gnus-summary-remove-process-mark article))
   (ps-despool filename))
 
     (gnus-summary-remove-process-mark article))
   (ps-despool filename))
 
+(defun gnus-print-buffer ()
+  (let ((buffer (generate-new-buffer " *print*")))
+    (unwind-protect
+       (progn
+         (copy-to-buffer buffer (point-min) (point-max))
+         (set-buffer buffer)
+         (gnus-article-delete-invisible-text)
+         (when (gnus-visual-p 'article-highlight 'highlight)
+           ;; Copy-to-buffer doesn't copy overlay.  So redo
+           ;; highlight.
+           (let ((gnus-article-buffer buffer))
+             (gnus-article-highlight-citation t)
+             (gnus-article-highlight-signature)))
+         (let ((ps-left-header
+                (list
+                 (concat "("
+                         (gnus-summary-print-truncate-and-quote
+                          (mail-header-subject gnus-current-headers)
+                          66) ")")
+                 (concat "("
+                         (gnus-summary-print-truncate-and-quote
+                          (mail-header-from gnus-current-headers)
+                          45) ")")))
+               (ps-right-header
+                (list
+                 "/pagenumberstring load"
+                 (concat "("
+                         (mail-header-date gnus-current-headers) ")"))))
+           (gnus-run-hooks 'gnus-ps-print-hook)
+           (save-excursion
+             (if window-system
+                 (ps-spool-buffer-with-faces)
+               (ps-spool-buffer)))))
+      (kill-buffer buffer))))
+
 (defun gnus-summary-show-article (&optional arg)
 (defun gnus-summary-show-article (&optional arg)
-  "Force re-fetching of the current article.
+  "Force redisplaying of the current article.
 If ARG (the prefix) is a number, show the article with the charset
 defined in `gnus-summary-show-article-charset-alist', or 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.
+input.
 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."
+without any article massaging functions being run.  Normally, the key strokes 
+are `C-u g'."
   (interactive "P")
   (cond
    ((numberp arg)
   (interactive "P")
   (cond
    ((numberp arg)
+    (gnus-summary-show-article t)
     (let ((gnus-newsgroup-charset
           (or (cdr (assq arg gnus-summary-show-article-charset-alist))
     (let ((gnus-newsgroup-charset
           (or (cdr (assq arg gnus-summary-show-article-charset-alist))
-              (mm-read-coding-system "Charset: ")))
+              (mm-read-coding-system
+               "View as charset: " ;; actually it is coding system.
+               (save-excursion
+                 (set-buffer gnus-article-buffer)
+                 (mm-detect-coding-region (point) (point-max))))))
          (gnus-newsgroup-ignored-charsets 'gnus-all))
       (gnus-summary-select-article nil 'force)
       (let ((deps gnus-newsgroup-dependencies)
          (gnus-newsgroup-ignored-charsets 'gnus-all))
       (gnus-summary-select-article nil 'force)
       (let ((deps gnus-newsgroup-dependencies)
-           head header)
+           head header lines)
        (save-excursion
          (set-buffer gnus-original-article-buffer)
          (save-restriction
            (message-narrow-to-head)
        (save-excursion
          (set-buffer gnus-original-article-buffer)
          (save-restriction
            (message-narrow-to-head)
-           (setq head (buffer-string)))
+           (setq head (buffer-string))
+           (goto-char (point-min))
+           (unless (re-search-forward "^lines:[ \t]\\([0-9]+\\)" nil t)
+             (goto-char (point-max))
+             (widen)
+             (setq lines (1- (count-lines (point) (point-max))))))
          (with-temp-buffer
            (insert (format "211 %d Article retrieved.\n"
                            (cdr gnus-article-current)))
            (insert head)
          (with-temp-buffer
            (insert (format "211 %d Article retrieved.\n"
                            (cdr gnus-article-current)))
            (insert head)
+           (if lines (insert (format "Lines: %d\n" lines)))
            (insert ".\n")
            (let ((nntp-server-buffer (current-buffer)))
              (setq header (car (gnus-get-newsgroup-headers deps t))))))
            (insert ".\n")
            (let ((nntp-server-buffer (current-buffer)))
              (setq header (car (gnus-get-newsgroup-headers deps t))))))
@@ -7680,7 +8067,9 @@ without any article massaging functions being run."
         (gnus-data-find (cdr gnus-article-current))
         header)
        (gnus-summary-update-article-line
         (gnus-data-find (cdr gnus-article-current))
         header)
        (gnus-summary-update-article-line
-        (cdr gnus-article-current) header))))
+        (cdr gnus-article-current) header)
+       (when (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
+         (gnus-summary-update-secondary-mark (cdr gnus-article-current))))))
    ((not arg)
     ;; Select the article the normal way.
     (gnus-summary-select-article nil 'force))
    ((not arg)
     ;; Select the article the normal way.
     (gnus-summary-select-article nil 'force))
@@ -7757,8 +8146,7 @@ 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-delete-wash-type 'headers)
                (gnus-treat-article 'head))
            (gnus-treat-article 'head)))
        (gnus-set-mode-line 'article)))))
                (gnus-treat-article 'head))
            (gnus-treat-article 'head)))
        (gnus-set-mode-line 'article)))))
@@ -7814,10 +8202,6 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
   (interactive "P")
   (unless action
     (setq action 'move))
   (interactive "P")
   (unless action
     (setq action 'move))
-  ;; Disable marking as read.
-  (let (gnus-mark-article-hook)
-    (save-window-excursion
-      (gnus-summary-select-article)))
   ;; Check whether the source group supports the required functions.
   (cond ((and (eq action 'move)
              (not (gnus-check-backend-function
   ;; Check whether the source group supports the required functions.
   (cond ((and (eq action 'move)
              (not (gnus-check-backend-function
@@ -7829,7 +8213,7 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
         (error "The current group does not support article editing")))
   (let ((articles (gnus-summary-work-articles n))
        (prefix (if (gnus-check-backend-function
         (error "The current group does not support article editing")))
   (let ((articles (gnus-summary-work-articles n))
        (prefix (if (gnus-check-backend-function
-                   'request-move-article gnus-newsgroup-name)
+                    'request-move-article gnus-newsgroup-name)
                    (gnus-group-real-prefix gnus-newsgroup-name)
                  ""))
        (names '((move "Move" "Moving")
                    (gnus-group-real-prefix gnus-newsgroup-name)
                  ""))
        (names '((move "Move" "Moving")
@@ -7840,6 +8224,13 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
        art-group to-method new-xref article to-groups)
     (unless (assq action names)
       (error "Unknown action %s" action))
        art-group to-method new-xref article to-groups)
     (unless (assq action names)
       (error "Unknown action %s" action))
+    ;; We have to select an article to give
+    ;; `gnus-read-move-group-name' an opportunity to suggest an
+    ;; appropriate default.
+    (unless (gnus-buffer-live-p gnus-original-article-buffer)
+      (let ((gnus-display-mime-function nil)
+           (gnus-article-prepare-hook nil))
+       (gnus-summary-select-article nil nil nil (car articles))))
     ;; Read the newsgroup name.
     (when (and (not to-newsgroup)
               (not select-method))
     ;; Read the newsgroup name.
     (when (and (not to-newsgroup)
               (not select-method))
@@ -7892,7 +8283,7 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                      (mail-header-xref (gnus-summary-article-header article))
                      " ")))
           (setq new-xref (concat (gnus-group-real-name gnus-newsgroup-name)
                      (mail-header-xref (gnus-summary-article-header article))
                      " ")))
           (setq new-xref (concat (gnus-group-real-name gnus-newsgroup-name)
-                                 ":" article))
+                                 ":" (number-to-string article)))
           (unless xref
             (setq xref (list (system-name))))
           (setq new-xref
           (unless xref
             (setq xref (list (system-name))))
           (setq new-xref
@@ -7909,7 +8300,8 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                                (gnus-request-accept-article
                                 to-newsgroup select-method (not articles))))
               (setq new-xref (concat new-xref " " (car art-group)
                                (gnus-request-accept-article
                                 to-newsgroup select-method (not articles))))
               (setq new-xref (concat new-xref " " (car art-group)
-                                     ":" (cdr art-group)))
+                                     ":"
+                                     (number-to-string (cdr art-group))))
               ;; Now we have the new Xrefs header, so we insert
               ;; it and replace the new article.
               (nnheader-replace-header "Xref" new-xref)
               ;; Now we have the new Xrefs header, so we insert
               ;; it and replace the new article.
               (nnheader-replace-header "Xref" new-xref)
@@ -7931,7 +8323,7 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
               (entry
                (gnus-gethash pto-group gnus-newsrc-hashtb))
               (info (nth 2 entry))
               (entry
                (gnus-gethash pto-group gnus-newsrc-hashtb))
               (info (nth 2 entry))
-               (to-group (gnus-info-group info))
+              (to-group (gnus-info-group info))
               to-marks)
          ;; Update the group that has been moved to.
          (when (and info
               to-marks)
          ;; Update the group that has been moved to.
          (when (and info
@@ -7968,25 +8360,26 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                  (setcdr gnus-newsgroup-active to-article))
 
                (while marks
                  (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))
+                 (when (eq (gnus-article-mark-to-type (cdar marks)) 'list)
+                   (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)
                  (setq marks (cdr marks)))
 
                (gnus-request-set-mark to-group (list (list (list to-article)
-                                                           'set
+                                                           'add
                                                            to-marks))))
 
              (gnus-dribble-enter
                                                            to-marks))))
 
              (gnus-dribble-enter
@@ -8012,12 +8405,10 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
          (gnus-summary-mark-article article gnus-canceled-mark))))
       (gnus-summary-remove-process-mark article))
     ;; Re-activate all groups that have been moved to.
          (gnus-summary-mark-article article gnus-canceled-mark))))
       (gnus-summary-remove-process-mark article))
     ;; Re-activate all groups that have been moved to.
-    (while to-groups
-      (save-excursion
-       (set-buffer gnus-group-buffer)
-       (when (gnus-group-goto-group (car to-groups) t)
-         (gnus-group-get-new-news-this-group 1 t))
-       (pop to-groups)))
+    (save-excursion
+      (set-buffer gnus-group-buffer)
+      (let ((gnus-group-marked to-groups))
+       (gnus-group-get-new-news-this-group nil t)))
 
     (gnus-kill-buffer copy-buf)
     (gnus-summary-position-point)
 
     (gnus-kill-buffer copy-buf)
     (gnus-summary-position-point)
@@ -8037,10 +8428,9 @@ re-spool using this method."
   (gnus-summary-move-article n nil nil 'crosspost))
 
 (defcustom gnus-summary-respool-default-method nil
   (gnus-summary-move-article n nil nil 'crosspost))
 
 (defcustom gnus-summary-respool-default-method nil
-  "Default method for respooling an article.
+  "Default method type for respooling an article.
 If nil, use to the current newsgroup method."
 If nil, use to the current newsgroup method."
-  :type '(choice (gnus-select-method :value (nnml ""))
-                (const nil))
+  :type 'symbol
   :group 'gnus-summary-mail)
 
 (defun gnus-summary-respool-article (&optional n method)
   :group 'gnus-summary-mail)
 
 (defun gnus-summary-respool-article (&optional n method)
@@ -8104,15 +8494,15 @@ latter case, they will be copied into the relevant groups."
       (nnheader-insert-file-contents file)
       (goto-char (point-min))
       (if (nnheader-article-p)
       (nnheader-insert-file-contents file)
       (goto-char (point-min))
       (if (nnheader-article-p)
-          (save-restriction
-            (goto-char (point-min))
-            (search-forward "\n\n" nil t)
-            (narrow-to-region (point-min) (1- (point)))
-            (goto-char (point-min))
-            (unless (re-search-forward "^date:" nil t)
-              (goto-char (point-max))
-              (insert "Date: " (message-make-date (nth 5 atts)) "\n")))
-       ;; This doesn't look like an article, so we fudge some headers.
+         (save-restriction
+           (goto-char (point-min))
+           (search-forward "\n\n" nil t)
+           (narrow-to-region (point-min) (1- (point)))
+           (goto-char (point-min))
+           (unless (re-search-forward "^date:" nil t)
+             (goto-char (point-max))
+             (insert "Date: " (message-make-date (nth 5 atts)) "\n")))
+       ;; This doesn't look like an article, so we fudge some headers.
        (setq atts (file-attributes file)
              lines (count-lines (point-min) (point-max)))
        (insert "From: " (read-string "From: ") "\n"
        (setq atts (file-attributes file)
              lines (count-lines (point-min) (point-max)))
        (insert "From: " (read-string "From: ") "\n"
@@ -8209,7 +8599,7 @@ This will be the case if the article has both been mailed and posted."
            (setq gnus-newsgroup-expirable es))
          ;; We go through the old list of expirable, and mark all
          ;; really expired articles as nonexistent.
            (setq gnus-newsgroup-expirable es))
          ;; We go through the old list of expirable, and mark all
          ;; really expired articles as nonexistent.
-         (unless (eq es expirable)     ;If nothing was expired, we don't mark.
+         (unless (eq es expirable) ;If nothing was expired, we don't mark.
            (let ((gnus-use-cache nil))
              (while expirable
                (unless (memq (car expirable) es)
            (let ((gnus-use-cache nil))
              (while expirable
                (unless (memq (car expirable) es)
@@ -8284,18 +8674,22 @@ groups."
   (let (force raw current-handles)
     (cond
      ((null arg))
   (let (force raw current-handles)
     (cond
      ((null arg))
-     ((eq arg 1) (setq raw t))
-     ((eq arg 2) (setq raw t
-                      force t))
-     ((eq arg 3) (setq current-handles
-                      (and (gnus-buffer-live-p gnus-article-buffer)
-                           (with-current-buffer gnus-article-buffer
-                             (prog1
-                                 gnus-article-mime-handles
-                                 (setq gnus-article-mime-handles nil))))))
-     (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"))
+     ((eq arg 1)
+      (setq raw t))
+     ((eq arg 2)
+      (setq raw t
+           force t))
+     ((eq arg 3)
+      (setq current-handles
+           (and (gnus-buffer-live-p gnus-article-buffer)
+                (with-current-buffer gnus-article-buffer
+                  (prog1
+                      gnus-article-mime-handles
+                    (setq gnus-article-mime-handles nil))))))
+     (t
+      (setq force t)))
+    (when (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)
     (save-excursion
       (set-buffer gnus-summary-buffer)
       (let ((mail-parse-charset gnus-newsgroup-charset)
@@ -8307,7 +8701,7 @@ groups."
        (gnus-summary-show-article t)
        (when (and (not raw) (gnus-buffer-live-p gnus-article-buffer))
          (with-current-buffer gnus-article-buffer
        (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)))
+           (mm-enable-multibyte)))
        (if (equal gnus-newsgroup-name "nndraft:drafts")
            (setq raw t))
        (gnus-article-edit-article
        (if (equal gnus-newsgroup-name "nndraft:drafts")
            (setq raw t))
        (gnus-article-edit-article
@@ -8345,7 +8739,7 @@ groups."
   "Make edits to the current article permanent."
   (interactive)
   (save-excursion
   "Make edits to the current article permanent."
   (interactive)
   (save-excursion
-    ;; The buffer restriction contains the entire article if it exists.
+   ;; The buffer restriction contains the entire article if it exists.
     (when (article-goto-body)
       (let ((lines (count-lines (point) (point-max)))
            (length (- (point-max) (point)))
     (when (article-goto-body)
       (let ((lines (count-lines (point) (point-max)))
            (length (- (point-max) (point)))
@@ -8402,10 +8796,17 @@ groups."
                       (gnus-data-find (cdr gnus-article-current))
                       header)
                      (gnus-summary-update-article-line
                       (gnus-data-find (cdr gnus-article-current))
                       header)
                      (gnus-summary-update-article-line
-                      (cdr gnus-article-current) header))))))
+                      (cdr gnus-article-current) header)
+                     (if (gnus-summary-goto-subject
+                          (cdr gnus-article-current) nil t)
+                         (gnus-summary-update-secondary-mark
+                          (cdr gnus-article-current))))))))
          ;; Update threads.
          (set-buffer (or buffer gnus-summary-buffer))
          ;; Update threads.
          (set-buffer (or buffer gnus-summary-buffer))
-         (gnus-summary-update-article (cdr gnus-article-current)))
+         (gnus-summary-update-article (cdr gnus-article-current))
+         (if (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
+             (gnus-summary-update-secondary-mark
+              (cdr gnus-article-current))))
        ;; Prettify the article buffer again.
        (unless no-highlight
          (save-excursion
        ;; Prettify the article buffer again.
        (unless no-highlight
          (save-excursion
@@ -8540,8 +8941,8 @@ number of articles marked is returned."
       (while (and
              (> n 0)
              (if unmark
       (while (and
              (> n 0)
              (if unmark
-               (gnus-summary-remove-process-mark
-                (gnus-summary-article-number))
+                 (gnus-summary-remove-process-mark
+                  (gnus-summary-article-number))
                (gnus-summary-set-process-mark (gnus-summary-article-number)))
              (zerop (gnus-summary-next-subject (if backward -1 1) nil t)))
        (setq n (1- n)))
                (gnus-summary-set-process-mark (gnus-summary-article-number)))
              (zerop (gnus-summary-next-subject (if backward -1 1) nil t)))
        (setq n (1- n)))
@@ -8574,9 +8975,9 @@ the actual number of articles unmarked is returned."
        (error "No such mark type: %s" type)
       (setq var (intern (format "gnus-newsgroup-%s" type)))
       (set var (cons article (symbol-value var)))
        (error "No such mark type: %s" type)
       (setq var (intern (format "gnus-newsgroup-%s" type)))
       (set var (cons article (symbol-value var)))
-      (if (memq type '(processable cached replied forwarded saved))
+      (if (memq type '(processable cached replied forwarded recent saved))
          (gnus-summary-update-secondary-mark article)
          (gnus-summary-update-secondary-mark article)
-       ;;; !!! This is bobus.  We should find out what primary
+       ;;; !!! This is bogus.  We should find out what primary
        ;;; !!! mark we want to set.
        (gnus-summary-update-mark gnus-del-mark 'unread)))))
 
        ;;; !!! mark we want to set.
        (gnus-summary-update-mark gnus-del-mark 'unread)))))
 
@@ -8788,7 +9189,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
     (setq mark gnus-del-mark))
   (when (and (not no-expire)
             gnus-newsgroup-auto-expire
     (setq mark gnus-del-mark))
   (when (and (not no-expire)
             gnus-newsgroup-auto-expire
-            (memq mark gnus-auto-expirable-marks))
+            (memq mark gnus-auto-expirable-marks))
     (setq mark gnus-expirable-mark))
   (let ((article (or article (gnus-summary-article-number)))
        (old-mark (gnus-summary-article-mark article)))
     (setq mark gnus-expirable-mark))
   (let ((article (or article (gnus-summary-article-number)))
        (old-mark (gnus-summary-article-mark article)))
@@ -8834,6 +9235,10 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
          gnus-forwarded-mark)
         ((memq article gnus-newsgroup-saved)
          gnus-saved-mark)
          gnus-forwarded-mark)
         ((memq article gnus-newsgroup-saved)
          gnus-saved-mark)
+        ((memq article gnus-newsgroup-recent)
+         gnus-recent-mark)
+        ((memq article gnus-newsgroup-unseen)
+         gnus-unseen-mark)
         (t gnus-no-mark))
    'replied)
   (when (gnus-visual-p 'summary-highlight 'highlight)
         (t gnus-no-mark))
    'replied)
   (when (gnus-visual-p 'summary-highlight 'highlight)
@@ -8842,7 +9247,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
 
 (defun gnus-summary-update-mark (mark type)
   (let ((forward (cdr (assq type gnus-summary-mark-positions)))
 
 (defun gnus-summary-update-mark (mark type)
   (let ((forward (cdr (assq type gnus-summary-mark-positions)))
-        (buffer-read-only nil))
+       (buffer-read-only nil))
     (re-search-backward "[\n\r]" (gnus-point-at-bol) 'move-to-limit)
     (when forward
       (when (looking-at "\r")
     (re-search-backward "[\n\r]" (gnus-point-at-bol) 'move-to-limit)
     (when forward
       (when (looking-at "\r")
@@ -8979,7 +9384,7 @@ The difference between N and the number of marks cleared is returned."
       (gnus-summary-mark-article gnus-current-article gnus-read-mark))))
 
 (defun gnus-summary-mark-unread-as-ticked ()
       (gnus-summary-mark-article gnus-current-article gnus-read-mark))))
 
 (defun gnus-summary-mark-unread-as-ticked ()
-   "Intended to be used by `gnus-summary-mark-article-hook'."
+  "Intended to be used by `gnus-summary-mark-article-hook'."
   (when (memq gnus-current-article gnus-newsgroup-unreads)
     (gnus-summary-mark-article gnus-current-article gnus-ticked-mark)))
 
   (when (memq gnus-current-article gnus-newsgroup-unreads)
     (gnus-summary-mark-article gnus-current-article gnus-ticked-mark)))
 
@@ -9067,7 +9472,7 @@ even ticked and dormant ones."
        (goto-char (point-min))
        (push gnus-newsgroup-limit gnus-newsgroup-limits)
        (setq gnus-newsgroup-limit (copy-sequence gnus-newsgroup-limit))
        (goto-char (point-min))
        (push gnus-newsgroup-limit gnus-newsgroup-limits)
        (setq gnus-newsgroup-limit (copy-sequence gnus-newsgroup-limit))
-       (mapcar (lambda (x) (push (mail-header-number x) 
+       (mapcar (lambda (x) (push (mail-header-number x)
                                  gnus-newsgroup-limit))
                headers)
        (gnus-summary-prepare-unthreaded (nreverse headers))
                                  gnus-newsgroup-limit))
                headers)
        (gnus-summary-prepare-unthreaded (nreverse headers))
@@ -9301,6 +9706,8 @@ is non-nil or the Subject: of both articles are the same."
        (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)
+       (if (gnus-summary-goto-subject (cdr gnus-article-current) nil t)
+           (gnus-summary-update-secondary-mark (cdr gnus-article-current)))
        (gnus-summary-rethread-current)
        (gnus-message 3 "Article %d is now the child of article %d"
                      current-article parent-article)))))
        (gnus-summary-rethread-current)
        (gnus-message 3 "Article %d is now the child of article %d"
                      current-article parent-article)))))
@@ -9342,18 +9749,49 @@ Returns nil if no thread was there to be shown."
       (goto-char orig)
       (gnus-summary-position-point))))
 
       (goto-char orig)
       (gnus-summary-position-point))))
 
-(defun gnus-summary-hide-all-threads ()
-  "Hide all thread subtrees."
+(defun gnus-summary-maybe-hide-threads ()
+  "If requested, hide the threads that should be hidden."
+  (when (and gnus-show-threads
+            gnus-thread-hide-subtree)
+    (gnus-summary-hide-all-threads
+     (if (or (consp gnus-thread-hide-subtree)
+            (gnus-functionp gnus-thread-hide-subtree))
+        (gnus-make-predicate gnus-thread-hide-subtree)
+       nil))))
+
+;;; Hiding predicates.
+
+(defun gnus-article-unread-p (header)
+  (memq (mail-header-number header) gnus-newsgroup-unreads))
+
+(defun gnus-article-unseen-p (header)
+  (memq (mail-header-number header) gnus-newsgroup-unseen))
+
+(defun gnus-map-articles (predicate articles)
+  "Map PREDICATE over ARTICLES and return non-nil if any predicate is non-nil."
+  (apply 'gnus-or (mapcar predicate
+                         (mapcar 'gnus-summary-article-header articles))))
+
+(defun gnus-summary-hide-all-threads (&optional predicate)
+  "Hide all thread subtrees.
+If PREDICATE is supplied, threads that satisfy this predicate
+will not be hidden."
   (interactive)
   (save-excursion
     (goto-char (point-min))
   (interactive)
   (save-excursion
     (goto-char (point-min))
-    (gnus-summary-hide-thread)
-    (while (zerop (gnus-summary-next-thread 1 t))
-      (gnus-summary-hide-thread)))
+    (let ((end nil))
+      (while (not end)
+       (when (or (not predicate)
+                 (gnus-map-articles
+                  predicate (gnus-summary-article-children)))
+           (gnus-summary-hide-thread))
+       (setq end (not (zerop (gnus-summary-next-thread 1 t)))))))
   (gnus-summary-position-point))
 
 (defun gnus-summary-hide-thread ()
   "Hide thread subtrees.
   (gnus-summary-position-point))
 
 (defun gnus-summary-hide-thread ()
   "Hide thread subtrees.
+If PREDICATE is supplied, threads that satisfy this predicate
+will not be hidden.
 Returns nil if no threads were there to be hidden."
   (interactive)
   (let ((buffer-read-only nil)
 Returns nil if no threads were there to be hidden."
   (interactive)
   (let ((buffer-read-only nil)
@@ -9549,8 +9987,7 @@ Argument REVERSE means reverse order."
     ;; We do the sorting by regenerating the threads.
     (gnus-summary-prepare)
     ;; Hide subthreads if needed.
     ;; We do the sorting by regenerating the threads.
     (gnus-summary-prepare)
     ;; Hide subthreads if needed.
-    (when (and gnus-show-threads gnus-thread-hide-subtree)
-      (gnus-summary-hide-all-threads))))
+    (gnus-summary-maybe-hide-threads)))
 
 (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."
@@ -9573,8 +10010,7 @@ Argument REVERSE means reverse order."
     ;; We do the sorting by regenerating the threads.
     (gnus-summary-prepare)
     ;; Hide subthreads if needed.
     ;; We do the sorting by regenerating the threads.
     (gnus-summary-prepare)
     ;; Hide subthreads if needed.
-    (when (and gnus-show-threads gnus-thread-hide-subtree)
-      (gnus-summary-hide-all-threads))))
+    (gnus-summary-maybe-hide-threads)))
 
 ;; Summary saving commands.
 
 
 ;; Summary saving commands.
 
@@ -9600,7 +10036,9 @@ The variable `gnus-default-article-saver' specifies the saver function."
            (gnus-message 1 "Article %d is unsaveable" article))
        ;; This is a real article.
        (save-window-excursion
            (gnus-message 1 "Article %d is unsaveable" article))
        ;; This is a real article.
        (save-window-excursion
-         (gnus-summary-select-article t nil nil article))
+         (let ((gnus-display-mime-function nil)
+               (gnus-article-prepare-hook nil))
+           (gnus-summary-select-article t nil nil article)))
        (save-excursion
          (set-buffer save-buffer)
          (erase-buffer)
        (save-excursion
          (set-buffer save-buffer)
          (erase-buffer)
@@ -9625,9 +10063,9 @@ pipe those articles instead."
   (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe))
     (gnus-summary-save-article arg t))
   (let ((buffer (get-buffer "*Shell Command Output*")))
   (let ((gnus-default-article-saver 'gnus-summary-save-in-pipe))
     (gnus-summary-save-article arg t))
   (let ((buffer (get-buffer "*Shell Command Output*")))
-    (if (and buffer 
-             (with-current-buffer buffer (> (point-max) (point-min))))
-        (gnus-configure-windows 'pipe))))
+    (if (and buffer
+            (with-current-buffer buffer (> (point-max) (point-min))))
+       (gnus-configure-windows 'pipe))))
 
 (defun gnus-summary-save-article-mail (&optional arg)
   "Append the current article to an mail file.
 
 (defun gnus-summary-save-article-mail (&optional arg)
   "Append the current article to an mail file.
@@ -9684,6 +10122,17 @@ save those articles instead."
   (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file))
     (gnus-summary-save-article arg)))
 
   (let ((gnus-default-article-saver 'gnus-summary-save-body-in-file))
     (gnus-summary-save-article arg)))
 
+(defun gnus-summary-muttprint (&optional arg)
+  "Print the current article using Muttprint.
+If N is a positive number, save the N next articles.
+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")
+  (require 'gnus-art)
+  (let ((gnus-default-article-saver 'gnus-summary-pipe-to-muttprint))
+    (gnus-summary-save-article arg t)))
+
 (defun gnus-summary-pipe-message (program)
   "Pipe the current article through PROGRAM."
   (interactive "sProgram: ")
 (defun gnus-summary-pipe-message (program)
   "Pipe the current article through PROGRAM."
   (interactive "sProgram: ")
@@ -9691,11 +10140,11 @@ save those articles instead."
   (let ((mail-header-separator ""))
     (gnus-eval-in-buffer-window gnus-article-buffer
       (save-restriction
   (let ((mail-header-separator ""))
     (gnus-eval-in-buffer-window gnus-article-buffer
       (save-restriction
-        (widen)
-        (let ((start (window-start))
-              buffer-read-only)
-          (message-pipe-buffer-body program)
-          (set-window-start (get-buffer-window (current-buffer)) start))))))
+       (widen)
+       (let ((start (window-start))
+             buffer-read-only)
+         (message-pipe-buffer-body program)
+         (set-window-start (get-buffer-window (current-buffer)) start))))))
 
 (defun gnus-get-split-value (methods)
   "Return a value based on the split METHODS."
 
 (defun gnus-get-split-value (methods)
   "Return a value based on the split METHODS."
@@ -9770,7 +10219,7 @@ save those articles instead."
                                          (nreverse split-name))
                                  nil nil nil
                                  'gnus-group-history))))
                                          (nreverse split-name))
                                  nil nil nil
                                  'gnus-group-history))))
-         (to-method (gnus-server-to-method (gnus-group-method to-newsgroup))))
+        (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))
@@ -10323,7 +10772,7 @@ returned."
              (gnus-set-difference articles
                                   (mapcar (lambda (h) (mail-header-number h))
                                           gnus-newsgroup-headers)))
              (gnus-set-difference articles
                                   (mapcar (lambda (h) (mail-header-number h))
                                           gnus-newsgroup-headers)))
-    (setq gnus-newsgroup-headers 
+    (setq gnus-newsgroup-headers
          (merge 'list
                 gnus-newsgroup-headers
                 (gnus-fetch-headers articles)
          (merge 'list
                 gnus-newsgroup-headers
                 (gnus-fetch-headers articles)
@@ -10331,12 +10780,12 @@ returned."
     ;; Suppress duplicates?
     (when gnus-suppress-duplicates
       (gnus-dup-suppress-articles))
     ;; Suppress duplicates?
     (when gnus-suppress-duplicates
       (gnus-dup-suppress-articles))
-    
+
     ;; We might want to build some more threads first.
     (when (and gnus-fetch-old-headers
               (eq gnus-headers-retrieved-by 'nov))
       (if (eq gnus-fetch-old-headers 'invisible)
     ;; We might want to build some more threads first.
     (when (and gnus-fetch-old-headers
               (eq gnus-headers-retrieved-by 'nov))
       (if (eq gnus-fetch-old-headers 'invisible)
-       (gnus-build-all-threads)
+         (gnus-build-all-threads)
        (gnus-build-old-threads)))
     ;; Let the Gnus agent mark articles as read.
     (when gnus-agent
        (gnus-build-old-threads)))
     ;; Let the Gnus agent mark articles as read.
     (when gnus-agent
@@ -10367,9 +10816,9 @@ If ALL is a number, fetch this number of articles."
          (or (memq i old) (push i older))
          (incf i))
        (setq len (length older))
          (or (memq i old) (push i older))
          (incf i))
        (setq len (length older))
-       (cond 
+       (cond
         ((null older) nil)
         ((null older) nil)
-        ((numberp all) 
+        ((numberp all)
          (if (< all len)
              (setq older (subseq older 0 all))))
         (all nil)
          (if (< all len)
              (setq older (subseq older 0 all))))
         (all nil)
@@ -10380,16 +10829,17 @@ If ALL is a number, fetch this number of articles."
                     (read-string
                      (format
                       "How many articles from %s (default %d): "
                     (read-string
                      (format
                       "How many articles from %s (default %d): "
-                      (gnus-limit-string 
+                      (gnus-limit-string
                        (gnus-group-decoded-name gnus-newsgroup-name) 35)
                       len))))
                        (gnus-group-decoded-name gnus-newsgroup-name) 35)
                       len))))
-               (unless (string-match "^[ \t]*$" input) 
+               (unless (string-match "^[ \t]*$" input)
                  (setq all (string-to-number input))
                  (if (< all len)
                      (setq older (subseq older 0 all))))))))
        (if (not older)
            (message "No old news.")
                  (setq all (string-to-number input))
                  (if (< all len)
                      (setq older (subseq older 0 all))))))))
        (if (not older)
            (message "No old news.")
-         (gnus-summary-insert-articles older)
+         (let ((gnus-fetch-old-headers t))
+           (gnus-summary-insert-articles older))
          (gnus-summary-limit (gnus-union older old))))
     (gnus-summary-position-point)))
 
          (gnus-summary-limit (gnus-union older old))))
     (gnus-summary-position-point)))
 
@@ -10401,7 +10851,7 @@ If ALL is a number, fetch this number of articles."
            (old-active gnus-newsgroup-active)
            (nnmail-fetched-sources (list t))
            i new)
            (old-active gnus-newsgroup-active)
            (nnmail-fetched-sources (list t))
            i new)
-       (setq gnus-newsgroup-active 
+       (setq gnus-newsgroup-active
              (gnus-activate-group gnus-newsgroup-name 'scan))
        (setq i (1+ (cdr old-active)))
        (while (<= i (cdr gnus-newsgroup-active))
              (gnus-activate-group gnus-newsgroup-name 'scan))
        (setq i (1+ (cdr old-active)))
        (while (<= i (cdr gnus-newsgroup-active))
@@ -10409,7 +10859,7 @@ If ALL is a number, fetch this number of articles."
          (incf i))
        (if (not new)
            (message "No gnus is bad news.")
          (incf i))
        (if (not new)
            (message "No gnus is bad news.")
-         (setq new (nreverse new))
+         (setq new (nreverse new))
          (gnus-summary-insert-articles new)
          (setq gnus-newsgroup-unreads
                (append gnus-newsgroup-unreads new))
          (gnus-summary-insert-articles new)
          (setq gnus-newsgroup-unreads
                (append gnus-newsgroup-unreads new))