Synch with Oort Gnus.
[elisp/gnus.git-] / lisp / gnus-sum.el
index 7960b8d..0c8ba57 100644 (file)
@@ -1,9 +1,11 @@
-;;; gnus-sum.el --- summary mode commands for Gnus
-;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001
+;;; gnus-sum.el --- summary mode commands for Semi-gnus
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002
 ;;        Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
-;; Keywords: news
+;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;;         Katsumi Yamaoka  <yamaoka@jpl.org>
+;; Keywords: mail, news, MIME
 
 ;; This file is part of GNU Emacs.
 
@@ -27,6 +29,7 @@
 ;;; Code:
 
 (eval-when-compile (require 'cl))
+(eval-when-compile (require 'gnus-clfns))
 
 (require 'gnus)
 (require 'gnus-group)
 (require 'gnus-int)
 (require 'gnus-undo)
 (require 'gnus-util)
-(require 'mm-decode)
 (require 'nnoo)
+(require 'mime-view)
+
+(eval-when-compile
+  (require 'mime-play)
+  (require 'static))
+
+(eval-and-compile
+  (autoload 'pgg-decrypt-region "pgg" nil t)
+  (autoload 'pgg-verify-region "pgg" nil t))
 
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (autoload 'gnus-cache-write-active "gnus-cache")
+(autoload 'gnus-set-summary-default-charset "gnus-i18n" nil t)
 (autoload 'gnus-mailing-list-insinuate "gnus-ml" nil t)
 (autoload 'turn-on-gnus-mailing-list-mode "gnus-ml" nil t)
 (autoload 'mm-uu-dissect "mm-uu")
+(autoload 'gnus-article-outlook-deuglify-article "deuglify" 
+  "Deuglify broken Outlook (Express) articles and redisplay."
+  t)
 
 (defcustom gnus-kill-summary-on-exit t
   "*If non-nil, kill the summary buffer when you exit from it.
@@ -234,6 +249,7 @@ simplification is selected."
 
 (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."
@@ -294,13 +310,24 @@ 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.."
+the first unseen article), 'unseen-or-unread' (place point on the subject
+line of the first unseen article or, if all article have been seen, on the
+subject line of the first unread 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)))
+                (const unseen)
+                (const unseen-or-unread)))
+
+(defcustom gnus-dont-select-after-jump-to-other-group nil
+  "If non-nil, don't select the first unread article after entering the
+other group by the command `gnus-summary-jump-to-other-group'.  If nil,
+it is depend on the value of `gnus-auto-select-first' whether to select
+or not."
+  :group 'gnus-group-select
+  :type 'boolean)
 
 (defcustom gnus-auto-select-next t
   "*If non-nil, offer to go to the next group from the end of the previous.
@@ -368,6 +395,13 @@ variable."
   :group 'gnus-article-various
   :type 'boolean)
 
+(defcustom gnus-show-mime t
+  "*If non-nil, do mime processing of articles.
+The articles will simply be fed to the function given by
+`gnus-article-display-method-for-mime'."
+  :group 'gnus-article-mime
+  :type 'boolean)
+
 (defcustom gnus-move-split-methods nil
   "*Variable used to suggest where articles are to be moved to.
 It uses the same syntax as the `gnus-split-methods' variable.
@@ -378,7 +412,7 @@ this variable specifies group names."
                         (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)
@@ -463,7 +497,7 @@ this variable specifies group names."
   :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)
@@ -513,7 +547,7 @@ this variable specifies group names."
   :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)
@@ -570,7 +604,11 @@ list of parameters to that command."
 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)
 
@@ -655,7 +693,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',
-`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
@@ -747,15 +787,14 @@ If you'd like to simplify subjects like the
 `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)
 
@@ -772,7 +811,7 @@ is not run if `gnus-visual' is nil."
   :group 'gnus-summary-visual
   :type 'hook)
 
-(defcustom gnus-parse-headers-hook nil
+(defcustom gnus-parse-headers-hook '(gnus-set-summary-default-charset)
   "*A hook called before parsing the headers."
   :group 'gnus-various
   :type 'hook)
@@ -891,10 +930,11 @@ mark:         The articles mark."
 The function is called with one parameter, the article header vector,
 which it may alter in any way.")
 
-(defvar gnus-decode-encoded-word-function 'mail-decode-encoded-word-string
+(defvar gnus-decode-encoded-word-function
+  (mime-find-field-decoder 'From 'nov)
   "Variable that says which function should be used to decode a string with encoded words.")
 
-(defcustom gnus-extra-headers nil
+(defcustom gnus-extra-headers '(To Newsgroups)
   "*Extra headers to parse."
   :version "21.1"
   :group 'gnus-summary
@@ -951,6 +991,25 @@ This variable uses the same syntax as `gnus-emphasis-alist'."
                                             gnus-emphasis-highlight-words)))))
   :group 'gnus-summary-visual)
 
+(defcustom gnus-use-wheel nil
+  "Use Intelli-mouse on summary movement"
+  :type 'boolean
+  :group 'gnus-summary-maneuvering)
+
+(defcustom gnus-wheel-scroll-amount '(5 . 1)
+  "Amount to scroll messages by spinning the mouse wheel.
+This is actually a cons cell, where the first item is the amount to scroll
+on a normal wheel event, and the second is the amount to scroll when the
+wheel is moved with the shift key depressed."
+  :type '(cons (integer :tag "Shift") integer)
+  :group 'gnus-summary-maneuvering)
+
+(defcustom gnus-wheel-edge-resistance 2
+  "How hard it should be to change the current article
+by moving the mouse over the edge of the article window."
+  :type 'integer
+  :group 'gnus-summary-maneuvering)
+
 (defcustom gnus-summary-show-article-charset-alist
   nil
   "Alist of number and charset.
@@ -1004,9 +1063,20 @@ that were fetched.  Say, for nnultimate groups."
 
 (defcustom gnus-summary-muttprint-program "muttprint"
   "Command (and optional arguments) used to run Muttprint."
+  :version "21.3"
   :group 'gnus-summary
   :type 'string)
 
+(defcustom gnus-article-loose-mime nil
+  "If non-nil, don't require MIME-Version header.
+Some brain-damaged MUA/MTA, e.g. Lotus Domino 5.0.6 clients, does not
+supply the MIME-Version header or deliberately strip it From the mail.
+Set it to non-nil, Gnus will treat some articles as MIME even if
+the MIME-Version header is missed."
+  :version "21.3"
+  :type 'boolean
+  :group 'gnus-article)
+
 ;;; Internal variables
 
 (defvar gnus-summary-display-cache nil)
@@ -1055,9 +1125,10 @@ that were fetched.  Say, for nnultimate groups."
     (?S ,(macroexpand '(mail-header-subject gnus-tmp-header)) ?s)
     (?s gnus-tmp-subject-or-nil ?s)
     (?n gnus-tmp-name ?s)
-    (?A (car (cdr (funcall gnus-extract-address-components gnus-tmp-from)))
-       ?s)
-    (?a (or (car (funcall gnus-extract-address-components gnus-tmp-from))
+    (?A (std11-address-string
+        (car (mime-entity-read-field gnus-tmp-header 'From))) ?s)
+    (?a (or (std11-full-name-string
+            (car (mime-entity-read-field gnus-tmp-header 'From)))
            gnus-tmp-from) ?s)
     (?F gnus-tmp-from ?s)
     (?x ,(macroexpand '(mail-header-xref gnus-tmp-header)) ?s)
@@ -1123,6 +1194,11 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-last-search-regexp nil
   "Default regexp for article search command.")
 
+(defvar gnus-summary-search-article-matched-data nil
+  "Last matched data of article search command.  It is the local variable
+in `gnus-article-buffer' which consists of the list of start position,
+end position and text.")
+
 (defvar gnus-last-shell-command nil
   "Default shell command on article.")
 
@@ -1141,10 +1217,10 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-limits nil)
 
 (defvar gnus-newsgroup-unreads nil
-  "List of unread articles in the current newsgroup.")
+  "Sorted list of unread articles in the current newsgroup.")
 
 (defvar gnus-newsgroup-unselected nil
-  "List of unselected unread articles in the current newsgroup.")
+  "Sorted list of unselected unread articles in the current newsgroup.")
 
 (defvar gnus-newsgroup-reads nil
   "Alist of read articles and article marks in the current newsgroup.")
@@ -1152,13 +1228,13 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-expunged-tally nil)
 
 (defvar gnus-newsgroup-marked nil
-  "List of ticked articles in the current newsgroup (a subset of unread art).")
+  "Sorted list of ticked articles in the current newsgroup (a subset of unread art).")
 
 (defvar gnus-newsgroup-killed nil
   "List of ranges of articles that have been through the scoring process.")
 
 (defvar gnus-newsgroup-cached nil
-  "List of articles that come from the article cache.")
+  "Sorted list of articles that come from the article cache.")
 
 (defvar gnus-newsgroup-saved nil
   "List of articles that have been saved.")
@@ -1175,13 +1251,13 @@ the type of the variable (string, integer, character, etc).")
   "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.")
+  "Sorted list of articles in the current newsgroup that can be expired.")
 
 (defvar gnus-newsgroup-processable nil
   "List of articles in the current newsgroup that can be processed.")
 
 (defvar gnus-newsgroup-downloadable nil
-  "List of articles in the current newsgroup that can be processed.")
+  "Sorted list of articles in the current newsgroup that can be processed.")
 
 (defvar gnus-newsgroup-undownloaded nil
   "List of articles in the current newsgroup that haven't been downloaded..")
@@ -1193,7 +1269,7 @@ the type of the variable (string, integer, character, etc).")
   "List of articles in the current newsgroup that have bookmarks.")
 
 (defvar gnus-newsgroup-dormant nil
-  "List of dormant articles in the current newsgroup.")
+  "Sorted list of dormant articles in the current newsgroup.")
 
 (defvar gnus-newsgroup-unseen nil
   "List of unseen articles in the current newsgroup.")
@@ -1207,6 +1283,9 @@ the type of the variable (string, integer, character, etc).")
 (defvar gnus-newsgroup-scored nil
   "List of scored articles in the current newsgroup.")
 
+(defvar gnus-newsgroup-incorporated nil
+  "List of incorporated articles in the current newsgroup.")
+
 (defvar gnus-newsgroup-headers nil
   "List of article headers in the current newsgroup.")
 
@@ -1268,7 +1347,8 @@ 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-newsgroup-charset gnus-newsgroup-display)
+    gnus-newsgroup-charset gnus-newsgroup-display
+    gnus-newsgroup-incorporated)
   "Variables that are buffer-local to the summary buffers.")
 
 (defvar gnus-newsgroup-variables nil
@@ -1289,44 +1369,6 @@ buffers. For example:
 ;; Byte-compiler warning.
 (eval-when-compile (defvar gnus-article-mode-map))
 
-;; MIME stuff.
-
-(defvar gnus-decode-encoded-word-methods
-  '(mail-decode-encoded-word-string)
-  "List of methods used to decode encoded words.
-
-This variable is a list of FUNCTION or (REGEXP . FUNCTION).  If item
-is FUNCTION, FUNCTION will be apply to all newsgroups.  If item is a
-\(REGEXP . FUNCTION), FUNCTION will be only apply to thes newsgroups
-whose names match REGEXP.
-
-For example:
-\((\"chinese\" . gnus-decode-encoded-word-string-by-guess)
- mail-decode-encoded-word-string
- (\"chinese\" . rfc1843-decode-string))")
-
-(defvar gnus-decode-encoded-word-methods-cache nil)
-
-(defun gnus-multi-decode-encoded-word-string (string)
-  "Apply the functions from `gnus-encoded-word-methods' that match."
-  (unless (and gnus-decode-encoded-word-methods-cache
-              (eq gnus-newsgroup-name
-                  (car gnus-decode-encoded-word-methods-cache)))
-    (setq gnus-decode-encoded-word-methods-cache (list gnus-newsgroup-name))
-    (mapcar (lambda (x)
-             (if (symbolp x)
-                 (nconc gnus-decode-encoded-word-methods-cache (list x))
-               (if (and gnus-newsgroup-name
-                        (string-match (car x) gnus-newsgroup-name))
-                   (nconc gnus-decode-encoded-word-methods-cache
-                          (list (cdr x))))))
-           gnus-decode-encoded-word-methods))
-  (let ((xlist gnus-decode-encoded-word-methods-cache))
-    (pop xlist)
-    (while xlist
-      (setq string (funcall (pop xlist) string))))
-  string)
-
 ;; Subject simplification.
 
 (defun gnus-simplify-whitespace (str)
@@ -1532,6 +1574,7 @@ increase the score of each group you read."
     "\M-g" gnus-summary-rescan-group
     "w" gnus-summary-stop-page-breaking
     "\C-c\C-r" gnus-summary-caesar-message
+    "\M-t" gnus-summary-toggle-mime
     "f" gnus-summary-followup
     "F" gnus-summary-followup-with-original
     "C" gnus-summary-cancel-article
@@ -1554,15 +1597,17 @@ increase the score of each group you read."
     "i" gnus-summary-news-other-window
     "x" gnus-summary-limit-to-unread
     "s" gnus-summary-isearch-article
-    "t" gnus-summary-toggle-header
+    "t" gnus-article-toggle-headers
     "g" gnus-summary-show-article
     "l" gnus-summary-goto-last-article
+    "v" gnus-summary-preview-mime-message
     "\C-c\C-v\C-v" gnus-uu-decode-uu-view
     "\C-d" gnus-summary-enter-digest-group
     "\M-\C-d" gnus-summary-read-document
     "\M-\C-e" gnus-summary-edit-parameters
     "\M-\C-a" gnus-summary-customize-parameters
     "\C-c\C-b" gnus-bug
+    "\C-c\C-n" gnus-namazu-search
     "*" gnus-cache-enter-article
     "\M-*" gnus-cache-remove-article
     "\M-&" gnus-summary-universal-argument
@@ -1572,9 +1617,6 @@ increase the score of each group you read."
     "\M-i" gnus-symbolic-argument
     "h" gnus-summary-select-article-buffer
 
-    "b" gnus-article-view-part
-    "\M-t" gnus-summary-toggle-display-buttonized
-
     "V" gnus-summary-score-map
     "X" gnus-uu-extract-map
     "S" gnus-summary-send-map)
@@ -1675,6 +1717,7 @@ increase the score of each group you read."
     "c" gnus-summary-catchup-and-exit
     "C" gnus-summary-catchup-all-and-exit
     "E" gnus-summary-exit-no-update
+    "J" gnus-summary-jump-to-other-group
     "Q" gnus-summary-exit
     "Z" gnus-summary-exit
     "n" gnus-summary-catchup-and-goto-next-group
@@ -1716,26 +1759,24 @@ increase the score of each group you read."
     "Q" gnus-article-fill-long-lines
     "C" gnus-article-capitalize-sentences
     "c" gnus-article-remove-cr
-    "q" gnus-article-de-quoted-unreadable
-    "6" gnus-article-de-base64-unreadable
     "Z" gnus-article-decode-HZ
     "h" gnus-article-wash-html
-    "s" gnus-summary-force-verify-and-decrypt
+    "u" gnus-article-unsplit-urls
     "f" gnus-article-display-x-face
     "l" gnus-summary-stop-page-breaking
     "r" gnus-summary-caesar-message
-    "t" gnus-summary-toggle-header
-    "g" gnus-summary-toggle-smiley
-    "u" gnus-article-treat-unfold-headers
-    "n" gnus-article-treat-fold-newsgroups
+    "t" gnus-article-toggle-headers
+    "g" gnus-treat-smiley
     "v" gnus-summary-verbose-headers
+    "m" gnus-summary-toggle-mime
     "a" gnus-article-strip-headers-in-body ;; mnemonic: wash archive
     "p" gnus-article-verify-x-pgp-sig
-    "d" gnus-article-treat-dumbquotes)
+    "d" gnus-article-treat-dumbquotes
+    "k" gnus-article-outlook-deuglify-article)
 
   (gnus-define-keys (gnus-summary-wash-hide-map "W" gnus-summary-wash-map)
     "a" gnus-article-hide
-    "h" gnus-article-hide-headers
+    "h" gnus-article-toggle-headers
     "b" gnus-article-hide-boring-headers
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
@@ -1752,19 +1793,19 @@ increase the score of each group you read."
     "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-summary-toggle-smiley
+    "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
-    "v" gnus-mime-view-all-parts
-    "b" gnus-article-view-part)
-
   (gnus-define-keys (gnus-summary-wash-time-map "T" gnus-summary-wash-map)
     "z" gnus-article-date-ut
     "u" gnus-article-date-ut
@@ -1829,10 +1870,57 @@ increase the score of each group you read."
     "o" gnus-article-save-part
     "c" gnus-article-copy-part
     "C" gnus-article-view-part-as-charset
-    "e" gnus-article-externalize-part
+    "e" gnus-article-view-part-externally
     "E" gnus-article-encrypt-body
     "i" gnus-article-inline-part
-    "|" gnus-article-pipe-part))
+    "|" gnus-article-pipe-part)
+
+  (gnus-define-keys (gnus-uu-mark-map "P" gnus-summary-mark-map)
+    "p" gnus-summary-mark-as-processable
+    "u" gnus-summary-unmark-as-processable
+    "U" gnus-summary-unmark-all-processable
+    "v" gnus-uu-mark-over
+    "s" gnus-uu-mark-series
+    "r" gnus-uu-mark-region
+    "g" gnus-uu-unmark-region
+    "R" gnus-uu-mark-by-regexp
+    "G" gnus-uu-unmark-by-regexp
+    "t" gnus-uu-mark-thread
+    "T" gnus-uu-unmark-thread
+    "a" gnus-uu-mark-all
+    "b" gnus-uu-mark-buffer
+    "S" gnus-uu-mark-sparse
+    "k" gnus-summary-kill-process-mark
+    "y" gnus-summary-yank-process-mark
+    "w" gnus-summary-save-process-mark
+    "i" gnus-uu-invert-processable)
+
+  (gnus-define-keys (gnus-uu-extract-map "X" gnus-summary-mode-map)
+    ;;"x" gnus-uu-extract-any
+    "m" gnus-summary-save-parts
+    "u" gnus-uu-decode-uu
+    "U" gnus-uu-decode-uu-and-save
+    "s" gnus-uu-decode-unshar
+    "S" gnus-uu-decode-unshar-and-save
+    "o" gnus-uu-decode-save
+    "O" gnus-uu-decode-save
+    "b" gnus-uu-decode-binhex
+    "B" gnus-uu-decode-binhex
+    "p" gnus-uu-decode-postscript
+    "P" gnus-uu-decode-postscript-and-save)
+
+  (gnus-define-keys
+      (gnus-uu-extract-view-map "v" gnus-uu-extract-map)
+    "u" gnus-uu-decode-uu-view
+    "U" gnus-uu-decode-uu-and-save-view
+    "s" gnus-uu-decode-unshar-view
+    "S" gnus-uu-decode-unshar-and-save-view
+    "o" gnus-uu-decode-save-view
+    "O" gnus-uu-decode-save-view
+    "b" gnus-uu-decode-binhex-view
+    "B" gnus-uu-decode-binhex-view
+    "p" gnus-uu-decode-postscript-view
+    "P" gnus-uu-decode-postscript-and-save-view))
 
 (defvar gnus-article-post-menu nil)
 
@@ -1842,31 +1930,31 @@ increase the score of each group you read."
   (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]))))
+     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
@@ -1874,7 +1962,7 @@ increase the score of each group you read."
     (let ((innards
           `(("Hide"
              ["All" gnus-article-hide t]
-             ["Headers" gnus-article-hide-headers t]
+             ["Headers" gnus-article-toggle-headers t]
              ["Signature" gnus-article-hide-signature t]
              ["Citation" gnus-article-hide-citation t]
              ["List identifiers" gnus-article-hide-list-identifiers t]
@@ -1886,14 +1974,6 @@ increase the score of each group you read."
              ["Headers" gnus-article-highlight-headers t]
              ["Signature" gnus-article-highlight-signature t]
              ["Citation" gnus-article-highlight-citation t])
-            ("MIME"
-             ["Words" gnus-article-decode-mime-words t]
-             ["Charset" gnus-article-decode-charset t]
-             ["QP" gnus-article-de-quoted-unreadable t]
-             ["Base64" gnus-article-de-base64-unreadable t]
-             ["View all" gnus-mime-view-all-parts t]
-             ["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]
@@ -1902,7 +1982,8 @@ increase the score of each group you read."
              ["Lapsed" gnus-article-date-lapsed t]
              ["User-defined" gnus-article-date-user t])
             ("Display"
-             ["Toggle smiley" gnus-summary-toggle-smiley t]
+             ["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]
@@ -1925,8 +2006,6 @@ increase the score of each group you read."
              ["Fill long lines" gnus-article-fill-long-lines t]
              ["Capitalize sentences" gnus-article-capitalize-sentences t]
              ["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"))]
@@ -1934,13 +2013,17 @@ increase the score of each group you read."
              ["Add buttons" gnus-article-add-buttons t]
              ["Add buttons to head" gnus-article-add-buttons-to-head t]
              ["Stop page breaking" gnus-summary-stop-page-breaking t]
+             ["Toggle MIME" gnus-summary-toggle-mime t]
              ["Verbose header" gnus-summary-verbose-headers t]
              ["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]
+             ["URLs" gnus-article-unsplit-urls t]
              ["Verify X-PGP-Sig" gnus-article-verify-x-pgp-sig t]
-             ["HZ" gnus-article-decode-HZ t])
+             ["HZ" gnus-article-decode-HZ t]
+             ["OutlooK deuglify" gnus-article-outlook-deuglify-article t]
+             )
             ("Output"
              ["Save in default format" gnus-summary-save-article
               ,@(if (featurep 'xemacs) '(t)
@@ -2004,15 +2087,15 @@ increase the score of each group you read."
             ["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])))
+            ["Raw article" gnus-summary-show-raw-article :keys "C-u g"])))
       (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))
+          gnus-article-commands-menu gnus-article-mode-map ""
+          (cons "Commands" innards))
        ;; in Emacs, don't share menu.
        (setq gnus-article-commands-menu
              (copy-keymap gnus-summary-article-menu))
@@ -2020,63 +2103,67 @@ increase the score of each group you read."
          (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
-      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"))]
-       ["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])
-       ))
+     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-summary-digest-mail-forward t]
+       ["Digest and post" gnus-summary-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))
@@ -2089,140 +2176,140 @@ increase the score of each group you read."
       (cons "Post" gnus-article-post-menu))
 
     (easy-menu-define
-      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-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)))
 
@@ -2399,6 +2486,9 @@ The following commands are available:
   (gnus-summary-set-display-table)
   (gnus-set-default-directory)
   (setq gnus-newsgroup-name group)
+  (unless (gnus-news-group-p group)
+    (setq gnus-newsgroup-incorporated
+         (nnmail-new-mail-numbers (gnus-group-real-name group))))
   (make-local-variable 'gnus-summary-line-format)
   (make-local-variable 'gnus-summary-line-format-spec)
   (make-local-variable 'gnus-summary-dummy-line-format)
@@ -2408,7 +2498,6 @@ 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)
-  (mm-enable-multibyte-mule4)
   (gnus-update-format-specifications nil 'summary 'summary-mode 'summary-dummy)
   (gnus-update-summary-mark-positions))
 
@@ -2461,7 +2550,7 @@ The following commands are available:
   `(nth 3 ,data))
 
 (defmacro gnus-data-set-header (data header)
-  `(setf (nth 3 ,data) ,header))
+  `(setcar (nthcdr 3 ,data) ,header))
 
 (defmacro gnus-data-level (data)
   `(nth 4 ,data))
@@ -2505,7 +2594,7 @@ The following commands are available:
            (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)))
@@ -2567,7 +2656,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)))
-    (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))))))
 
@@ -2772,7 +2861,7 @@ display only a single character."
     ;; 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)
@@ -2807,7 +2896,12 @@ display only a single character."
 
 (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)
@@ -2922,7 +3016,9 @@ buffer that was in action when the last article was fetched."
        (let ((gnus-summary-line-format-spec spec)
              (gnus-newsgroup-downloadable '((0 . t))))
          (gnus-summary-insert-line
-          [0 "" "" "05 Apr 2001 23:33:09 +0400" "" "" 0 0 "" nil]
+          (make-full-mail-header 0 "" "nobody"
+                                 "05 Apr 2001 23:33:09 +0400"
+                                 "" "" 0 0 "" nil)
           0 nil 128 t nil "" nil 1)
          (goto-char (point-min))
          (setq pos (list (cons 'unread (and (search-forward "\200" nil t)
@@ -2952,12 +3048,10 @@ buffer that was in action when the last article was fetched."
       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)))
+  (let ((default-mime-charset (with-current-buffer gnus-summary-buffer
+                               default-mime-charset)))
+    ;; Is it really necessary to do this next part for each summary line?
+    ;; Luckily, doesn't seem to slow things down much.
     (or
      (and gnus-ignored-from-addresses
          (string-match gnus-ignored-from-addresses gnus-tmp-from)
@@ -2967,11 +3061,12 @@ buffer that was in action when the last article was fetched."
            (cond
             ((setq to (cdr (assq 'To extra-headers)))
              (concat "-> "
-                     (gnus-summary-extract-address-component
-                      (funcall gnus-decode-encoded-word-function to))))
+                     (inline
+                       (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))))
+     (inline (gnus-summary-extract-address-component gnus-tmp-from)))))
 
 (defun gnus-summary-insert-line (gnus-tmp-header
                                 gnus-tmp-level gnus-tmp-current
@@ -2986,7 +3081,7 @@ 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))
-             ?                         ;Whitespace
+             ?\ ;;;Whitespace
            (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))
@@ -3027,7 +3122,7 @@ buffer that was in action when the last article was fetched."
     (if (= gnus-tmp-lines -1)
        (setq gnus-tmp-lines "?")
       (setq gnus-tmp-lines (number-to-string gnus-tmp-lines)))
-    (gnus-put-text-property
+    (gnus-put-text-property-excluding-characters-with-faces
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
      'gnus-number gnus-tmp-number)
@@ -3059,7 +3154,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))
-            ?                          ;Whitespace
+            ?\ ;;;Whitespace
           (if (< score gnus-summary-default-score)
               gnus-score-below-mark gnus-score-over-mark))
         'score))
@@ -3074,7 +3169,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
-        ;; 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)
@@ -3100,7 +3195,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))
-       (vars '(quit-config))           ; Ignore quit-config.
+       (vars '(quit-config))           ; Ignore quit-config.
        elem)
     (while params
       (setq elem (car params)
@@ -3143,6 +3238,26 @@ If NO-DISPLAY, don't generate a summary buffer."
        (setq group nil)))
     result))
 
+(defun gnus-summary-jump-to-other-group (group &optional show-all)
+  "Directly jump to the other GROUP from summary buffer.
+If SHOW-ALL is non-nil, already read articles are also listed."
+  (interactive
+   (if (eq gnus-summary-buffer (current-buffer))
+       (list (completing-read
+             "Group: " gnus-active-hashtb nil t
+             (when (and gnus-newsgroup-name
+                        (string-match "[.:][^.:]+$" gnus-newsgroup-name))
+               (substring gnus-newsgroup-name 0 (1+ (match-beginning 0))))
+             'gnus-group-history)
+            current-prefix-arg)
+     (error "%s must be invoked from a gnus summary buffer." this-command)))
+  (unless (or (zerop (length group))
+             (and gnus-newsgroup-name
+                  (string-equal gnus-newsgroup-name group)))
+    (gnus-summary-exit)
+    (gnus-summary-read-group group show-all
+                            gnus-dont-select-after-jump-to-other-group)))
+
 (defun gnus-summary-read-group-1 (group show-all no-article
                                        kill-buffer no-display
                                        &optional select-articles)
@@ -3264,9 +3379,7 @@ 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.
-       (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))
        (gnus-summary-auto-select-subject)
@@ -3277,7 +3390,10 @@ If NO-DISPLAY, don't generate a summary buffer."
                 gnus-auto-select-first)
            (progn
              (gnus-configure-windows 'summary)
-             (gnus-summary-goto-article (gnus-summary-article-number)))
+             (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)
@@ -3305,6 +3421,8 @@ If NO-DISPLAY, don't generate a summary buffer."
     (gnus-summary-first-unread-subject))
    ((eq gnus-auto-select-subject 'unseen)
     (gnus-summary-first-unseen-subject))
+   ((eq gnus-auto-select-subject 'unseen-or-unread)
+    (gnus-summary-first-unseen-or-unread-subject))
    ((eq gnus-auto-select-subject 'first)
     ;; Do nothing.
     )
@@ -3355,14 +3473,15 @@ If NO-DISPLAY, don't generate a summary buffer."
 
   (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 ()
   "Query where the respool algorithm would put this article."
   (interactive)
   (gnus-summary-select-article)
-  (message (gnus-general-simplify-subject (gnus-summary-article-subject))))
+  (message "%s"
+          (gnus-general-simplify-subject (gnus-summary-article-subject))))
 
 (defun gnus-gather-threads-by-subject (threads)
   "Gather threads by looking at Subject headers."
@@ -3406,7 +3525,7 @@ If NO-DISPLAY, don't generate a summary buffer."
     (while threads
       (when (setq references (mail-header-references (caar threads)))
        (setq id (mail-header-id (caar threads))
-             ids (gnus-split-references references)
+             ids (inline (gnus-split-references references))
              entered nil)
        (while (setq ref (pop ids))
          (setq ids (delete ref ids))
@@ -3490,7 +3609,7 @@ If NO-DISPLAY, don't generate a summary buffer."
                  (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)))
@@ -3505,13 +3624,13 @@ if it was already present.
 
 If `gnus-summary-ignore-duplicates' is nil then duplicate Message-IDs
 will not be entered in the DEPENDENCIES table.  Otherwise duplicate
-Message-IDs will be renamed be renamed to a unique Message-ID before
-being entered.
+Message-IDs will be renamed to a unique Message-ID before being
+entered.
 
 Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
   (let* ((id (mail-header-id header))
         (id-dep (and id (intern id dependencies)))
-        ref ref-dep ref-header)
+        ref ref-dep ref-header replaced)
     ;; Enter this `header' in the `dependencies' table.
     (cond
      ((not id-dep)
@@ -3528,7 +3647,8 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
      (force-new
       ;; Overrides an existing entry;
       ;; just set the header part of the entry.
-      (setcar (symbol-value id-dep) header))
+      (setcar (symbol-value id-dep) header)
+      (setq replaced t))
 
      ;; Renames the existing `header' to a unique Message-ID.
      ((not gnus-summary-ignore-duplicates)
@@ -3551,8 +3671,8 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
               (or (mail-header-xref header) "")))
       (setq header nil)))
 
-    (when header
-      ;; First check if that we are not creating a References loop.
+    (when (and header (not replaced))
+      ;; First check that we are not creating a References loop.
       (setq ref (gnus-parent-id (mail-header-references header)))
       (while (and ref
                  (setq ref-dep (intern-soft ref dependencies))
@@ -3574,6 +3694,11 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
        (set ref-dep (list nil (symbol-value id-dep)))))
     header))
 
+(defun gnus-extract-message-id-from-in-reply-to (string)
+  (if (string-match "<[^>]+>" string)
+      (substring string (match-beginning 0) (match-end 0))
+    nil))
+
 (defun gnus-build-sparse-threads ()
   (let ((headers gnus-newsgroup-headers)
        (mail-parse-charset gnus-newsgroup-charset)
@@ -3610,7 +3735,7 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
     (mapcar
      (lambda (relation)
        (when (gnus-dependencies-add-header
-             (make-full-mail-header
+             (make-full-mail-header-from-decoded-header
               gnus-reffed-article-number
               (nth 3 relation) "" (or (nth 4 relation) "")
               (nth 1 relation)
@@ -3650,7 +3775,7 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
 (defsubst gnus-nov-parse-line (number dependencies &optional force-new)
   (let ((eol (gnus-point-at-eol))
        (buffer (current-buffer))
-       header)
+       header references in-reply-to)
 
     ;; overview: [num subject from date id refs chars lines misc]
     (unwind-protect
@@ -3661,24 +3786,28 @@ Returns HEADER if it was entered in the DEPENDENCIES.  Returns nil otherwise."
 
          (setq header
                (make-full-mail-header
-                number                 ; number
-                (funcall gnus-decode-encoded-word-function
-                         (nnheader-nov-field)) ; subject
-                (funcall gnus-decode-encoded-word-function
-                         (nnheader-nov-field)) ; from
-                (nnheader-nov-field)   ; date
+                number                         ; number
+                (nnheader-nov-field)           ; subject
+                (nnheader-nov-field)           ; from
+                (nnheader-nov-field)           ; date
                 (nnheader-nov-read-message-id) ; id
-                (nnheader-nov-field)   ; refs
-                (nnheader-nov-read-integer) ; chars
-                (nnheader-nov-read-integer) ; lines
+                (nnheader-nov-field)           ; refs
+                (nnheader-nov-read-integer)    ; chars
+                (nnheader-nov-read-integer)    ; lines
                 (unless (eobp)
                   (if (looking-at "Xref: ")
                       (goto-char (match-end 0)))
-                  (nnheader-nov-field)) ; Xref
-                (nnheader-nov-parse-extra)))) ; extra
+                  (nnheader-nov-field))        ; Xref
+                (nnheader-nov-parse-extra))))  ; extra
 
       (widen))
 
+    (when (and (string= references "")
+              (setq in-reply-to (mail-header-extra header))
+              (setq in-reply-to (cdr (assq 'In-Reply-To in-reply-to))))
+      (mail-header-set-references
+       header (gnus-extract-message-id-from-in-reply-to in-reply-to)))
+
     (when gnus-alter-header-function
       (funcall gnus-alter-header-function header))
     (gnus-dependencies-add-header header dependencies force-new)))
@@ -3713,7 +3842,9 @@ the id of the parent article (if any)."
          (push header gnus-newsgroup-headers)
          (if (memq number gnus-newsgroup-unselected)
              (progn
-               (push number gnus-newsgroup-unreads)
+               (setq gnus-newsgroup-unreads
+                     (gnus-add-to-sorted-list gnus-newsgroup-unreads
+                                              number))
                (setq gnus-newsgroup-unselected
                      (delq number gnus-newsgroup-unselected)))
            (push number gnus-newsgroup-ancient)))))))
@@ -3739,7 +3870,9 @@ the id of the parent article (if any)."
              (if (memq (setq article (mail-header-number header))
                        gnus-newsgroup-unselected)
                  (progn
-                   (push article gnus-newsgroup-unreads)
+                   (setq gnus-newsgroup-unreads
+                         (gnus-add-to-sorted-list
+                          gnus-newsgroup-unreads article))
                    (setq gnus-newsgroup-unselected
                          (delq article gnus-newsgroup-unselected)))
                (push article gnus-newsgroup-ancient)))
@@ -3812,7 +3945,7 @@ the id of the parent article (if any)."
        (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))))
@@ -4084,14 +4217,15 @@ using some other form will lead to serious barfage."
 (defsubst gnus-article-sort-by-author (h1 h2)
   "Sort articles by root author."
   (string-lessp
-   (let ((extract (funcall
-                  gnus-extract-address-components
-                  (mail-header-from h1))))
-     (or (car extract) (cadr extract) ""))
-   (let ((extract (funcall
-                  gnus-extract-address-components
-                  (mail-header-from h2))))
-     (or (car extract) (cadr extract) ""))))
+   (let ((addr (car (mime-entity-read-field h1 'From))))
+     (or (std11-full-name-string addr)
+        (std11-address-string addr)
+        ""))
+   (let ((addr (car (mime-entity-read-field h2 'From))))
+     (or (std11-full-name-string addr)
+        (std11-address-string addr)
+        ""))
+   ))
 
 (defun gnus-thread-sort-by-author (h1 h2)
   "Sort threads by root author."
@@ -4142,15 +4276,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.
-  (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.
@@ -4337,7 +4503,9 @@ or a straight list of headers."
            (setq gnus-newsgroup-unreads
                  (delq number gnus-newsgroup-unreads))
            (if gnus-newsgroup-auto-expire
-               (push number gnus-newsgroup-expirable)
+               (setq gnus-newsgroup-expirable
+                     (gnus-add-to-sorted-list
+                      gnus-newsgroup-expirable number))
              (push (cons number gnus-low-score-mark)
                    gnus-newsgroup-reads))))
 
@@ -4394,7 +4562,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))
-                ?                      ;Whitespace
+                ?\ ;;;Whitespace
               (if (< gnus-tmp-score gnus-summary-default-score)
                   gnus-score-below-mark gnus-score-over-mark))
             gnus-tmp-replied
@@ -4629,8 +4797,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       (setq cached gnus-newsgroup-cached))
 
     (setq gnus-newsgroup-unreads
-         (gnus-set-difference
-          (gnus-set-difference gnus-newsgroup-unreads gnus-newsgroup-marked)
+         (gnus-sorted-ndifference
+          (gnus-sorted-ndifference gnus-newsgroup-unreads
+                                   gnus-newsgroup-marked)
           gnus-newsgroup-dormant))
 
     (setq gnus-newsgroup-processable nil)
@@ -4643,9 +4812,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
 
     (if (setq articles select-articles)
        (setq gnus-newsgroup-unselected
-             (gnus-sorted-intersection
-              gnus-newsgroup-unreads
-              (gnus-sorted-complement gnus-newsgroup-unreads articles)))
+             (gnus-sorted-difference gnus-newsgroup-unreads articles))
       (setq articles (gnus-articles-to-read group read-all)))
 
     (cond
@@ -4677,20 +4844,13 @@ If SELECT-ARTICLES, only select those articles from GROUP."
                    gnus-newsgroup-headers))
       (setq gnus-newsgroup-articles fetched-articles)
       (setq gnus-newsgroup-unreads
-           (gnus-set-sorted-intersection
+           (gnus-sorted-nintersection
             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)))
+      (gnus-compute-unseen-list)
 
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
-       (gnus-sorted-complement fetched-articles articles))
+       (gnus-sorted-difference articles fetched-articles))
       ;; We might want to build some more threads first.
       (when (and gnus-fetch-old-headers
                 (eq gnus-headers-retrieved-by 'nov))
@@ -4719,19 +4879,29 @@ If SELECT-ARTICLES, only select those articles from GROUP."
       ;; GROUP is successfully selected.
       (or gnus-newsgroup-headers t)))))
 
+(defun gnus-compute-unseen-list ()
+  ;; The `seen' marks are treated specially.
+  (if (not gnus-newsgroup-seen)
+      (setq gnus-newsgroup-unseen gnus-newsgroup-articles)
+    (setq gnus-newsgroup-unseen
+         (gnus-inverse-list-range-intersection
+          gnus-newsgroup-articles gnus-newsgroup-seen))))
+
 (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))
+    (dolist (elem (append '((unread . unread)
+                           (read . read)
+                           (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))
+  (let ((gnus-category-predicate-alist gnus-summary-display-cache)
+       (gnus-category-predicate-cache gnus-summary-display-cache))
     (gnus-get-predicate display)))
 
 ;; Uses the dynamically bound `number' variable.
@@ -4783,7 +4953,8 @@ If SELECT-ARTICLES, only select those articles from GROUP."
          (if (or read-all
                  (and (zerop (length gnus-newsgroup-marked))
                       (zerop (length gnus-newsgroup-unreads)))
-                 (eq gnus-newsgroup-display 'gnus-not-ignore))
+                 ;; Fetch all if the predicate is non-nil.
+                 gnus-newsgroup-display)
              ;; 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
@@ -4792,9 +4963,9 @@ If SELECT-ARTICLES, only select those articles from GROUP."
               (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))
-                 '<)))
+           (gnus-sorted-nunion
+            (gnus-sorted-union gnus-newsgroup-dormant gnus-newsgroup-marked)
+            gnus-newsgroup-unreads)))
         (scored-list (gnus-killed-articles gnus-newsgroup-killed articles))
         (scored (length scored-list))
         (number (length articles))
@@ -4804,20 +4975,29 @@ If SELECT-ARTICLES, only select those articles from GROUP."
          (cond
           ((numberp read-all)
            read-all)
+          ((numberp gnus-newsgroup-display)
+           gnus-newsgroup-display)
           (t
            (condition-case ()
                (cond
                 ((and (or (<= scored marked) (= scored number))
                       (numberp gnus-large-newsgroup)
                       (> number gnus-large-newsgroup))
-                 (let ((input
-                        (read-string
-                         (format
-                          "How many articles from %s (default %d): "
-                          (gnus-limit-string
-                           (gnus-group-decoded-name gnus-newsgroup-name)
-                           35)
-                          number))))
+                 (let* ((cursor-in-echo-area nil)
+                        (initial (gnus-parameter-large-newsgroup-initial
+                                  gnus-newsgroup-name))
+                        (input
+                         (read-string
+                          (format
+                           "How many articles from %s (%s %d): "
+                           (gnus-limit-string
+                            (gnus-group-decoded-name gnus-newsgroup-name)
+                            35)
+                           (if initial "max" "default")
+                           number)
+                          (if initial
+                              (cons (number-to-string initial)
+                                    0)))))
                    (if (string-match "^[ \t]*$" input) number input)))
                 ((and (> scored marked) (< scored number)
                       (> (- scored number) 20))
@@ -4849,9 +5029,7 @@ If SELECT-ARTICLES, only select those articles from GROUP."
          ;; Select the N most recent articles.
          (setq articles (nthcdr (- number select) articles))))
       (setq gnus-newsgroup-unselected
-           (gnus-sorted-intersection
-            gnus-newsgroup-unreads
-            (gnus-sorted-complement gnus-newsgroup-unreads articles)))
+           (gnus-sorted-difference gnus-newsgroup-unreads articles))
       (when gnus-alter-articles-to-read-function
        (setq gnus-newsgroup-unreads
              (sort
@@ -4928,6 +5106,10 @@ If SELECT-ARTICLES, only select those articles from GROUP."
        ((eq mark-type 'range)
        (cond
         ((eq mark 'seen)
+         ;; Fix the record for `seen' if it looks like (seen NUM1 . NUM2).
+         ;; It should be (seen (NUM1 . NUM2)).
+         (when (numberp (cddr marks))
+           (setcdr marks (list (cdr marks))))
          (setq articles (cdr marks))
          (while (and articles
                      (or (and (consp (car articles))
@@ -5033,7 +5215,7 @@ 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 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
@@ -5060,7 +5242,7 @@ If WHERE is `summary', the summary mode line format will be used."
                     (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
@@ -5078,7 +5260,7 @@ If WHERE is `summary', the summary mode line format will be used."
          ;; We might have to chop a bit of the string off...
          (when (> (length mode-string) max-len)
            (setq mode-string
-                 (concat (truncate-string-to-width mode-string (- max-len 3))
+                 (concat (gnus-truncate-string mode-string (- max-len 3))
                          "...")))
          ;; Pad the mode string a bit.
          (setq mode-string (format (format "%%-%ds" max-len) mode-string))))
@@ -5249,7 +5431,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
       (subst-char-in-region (point-min) (point-max) ?\r ?  t)
       (gnus-run-hooks 'gnus-parse-headers-hook)
       (let ((case-fold-search t)
-           in-reply-to header p lines chars)
+           in-reply-to header p lines chars ctype)
        (goto-char (point-min))
        ;; Search to the beginning of the next header.  Error messages
        ;; do not begin with 2 or 3.
@@ -5264,7 +5446,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
          ;; doesn't always go hand in hand.
          (setq
           header
-          (vector
+          (make-full-mail-header
            ;; Number.
            (prog1
                (read cur)
@@ -5278,15 +5460,13 @@ The resulting hash table is returned, or nil if no Xrefs were found."
            (progn
              (goto-char p)
              (if (search-forward "\nsubject:" nil t)
-                 (funcall gnus-decode-encoded-word-function
-                          (nnheader-header-value))
+                 (nnheader-header-value)
                "(none)"))
            ;; From.
            (progn
              (goto-char p)
              (if (search-forward "\nfrom:" nil t)
-                 (funcall gnus-decode-encoded-word-function
-                          (nnheader-header-value))
+                 (nnheader-header-value)
                "(nobody)"))
            ;; Date.
            (progn
@@ -5316,7 +5496,7 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                      (setq ref
                            (buffer-substring
                             (progn
-                              (end-of-line)
+                              ;; (end-of-line)
                               (search-backward ">" end t)
                               (1+ (point)))
                             (progn
@@ -5365,10 +5545,14 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                  (goto-char p)
                  (when (search-forward
                         (concat "\n" (symbol-name (car extra)) ":") nil t)
-                   (push (cons (car extra) (nnheader-header-value))
-                         out))
+                   (push (cons (car extra) (nnheader-header-value)) out))
                  (pop extra))
                out))))
+         (goto-char p)
+         (if (and (search-forward "\ncontent-type: " nil t)
+                  (setq ctype (nnheader-header-value)))
+             (mime-entity-set-content-type-internal
+              header (mime-parse-Content-Type ctype)))
          (when (equal id ref)
            (setq ref nil))
 
@@ -5413,29 +5597,24 @@ Return a list of headers that match SEQUENCE (see
       ;; Allow the user to mangle the headers before parsing them.
       (gnus-run-hooks 'gnus-parse-headers-hook)
       (goto-char (point-min))
-      (while (not (eobp))
-       (condition-case ()
-           (while (and (or sequence allp)
-                       (not (eobp)))
-             (setq number (read cur))
-             (when (not allp)
-               (while (and sequence
-                           (< (car sequence) number))
-                 (setq sequence (cdr sequence))))
-             (when (and (or allp
-                            (and sequence
-                                 (eq number (car sequence))))
-                        (progn
-                          (setq sequence (cdr sequence))
-                          (setq header (inline
-                                         (gnus-nov-parse-line
-                                          number dependencies force-new)))))
-               (push header headers))
-             (forward-line 1))
-         (error
-          (gnus-error 4 "Strange nov line (%d)"
-                      (count-lines (point-min) (point)))))
-       (forward-line 1))
+      (gnus-parse-without-error
+       (while (and (or sequence allp)
+                   (not (eobp)))
+         (setq number (read cur))
+         (when (not allp)
+           (while (and sequence
+                       (< (car sequence) number))
+             (setq sequence (cdr sequence))))
+         (when (and (or allp
+                        (and sequence
+                             (eq number (car sequence))))
+                    (progn
+                      (setq sequence (cdr sequence))
+                      (setq header (inline
+                                     (gnus-nov-parse-line
+                                      number dependencies force-new)))))
+           (push header headers))
+         (forward-line 1)))
       ;; A common bug in inn is that if you have posted an article and
       ;; then retrieves the active file, it will answer correctly --
       ;; the new article is included.  However, a NOV entry for the
@@ -5559,7 +5738,7 @@ current article will be taken into consideration."
       (let ((max (max (point) (mark)))
            articles article)
        (save-excursion
-         (goto-char (min (min (point) (mark))))
+         (goto-char (min (point) (mark)))
          (while
              (and
               (push (setq article (gnus-summary-article-number)) articles)
@@ -5729,7 +5908,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).
-;; 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)
@@ -5745,7 +5924,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,
-      ;; 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))))
@@ -5834,13 +6013,13 @@ displayed, no centering will be performed."
         (marked (gnus-info-marks info))
         (active (gnus-active group)))
     (and info active
-        (gnus-set-difference
-         (gnus-sorted-complement
-          (gnus-uncompress-range active)
-          (gnus-list-of-unread-articles group))
-         (append
-          (gnus-uncompress-range (cdr (assq 'dormant marked)))
-          (gnus-uncompress-range (cdr (assq 'tick marked))))))))
+        (gnus-list-range-difference
+         (gnus-list-range-difference
+          (gnus-sorted-complement
+           (gnus-uncompress-range active)
+           (gnus-list-of-unread-articles group))
+          (cdr (assq 'dormant marked)))
+         (cdr (assq 'tick marked))))))
 
 ;; Various summary commands
 
@@ -5898,7 +6077,10 @@ The prefix argument ALL means to select all articles."
     (gnus-summary-jump-to-group group)
     (when rescan
       (save-excursion
-       (gnus-group-get-new-news-this-group 1)))
+       (save-window-excursion
+         ;; Don't show group contents.
+         (set-window-start (selected-window) (point-max))
+         (gnus-group-get-new-news-this-group 1))))
     (gnus-group-read-group all t)
     (gnus-summary-goto-subject current-subject nil t)))
 
@@ -5914,13 +6096,10 @@ The prefix argument ALL means to select all articles."
        (when gnus-newsgroup-kill-headers
          (setq gnus-newsgroup-killed
                (gnus-compress-sequence
-                (nconc
-                 (gnus-set-sorted-intersection
-                  (gnus-uncompress-range gnus-newsgroup-killed)
-                  (setq gnus-newsgroup-unselected
-                        (sort gnus-newsgroup-unselected '<)))
-                 (setq gnus-newsgroup-unreads
-                       (sort gnus-newsgroup-unreads '<)))
+                (gnus-sorted-union
+                 (gnus-list-range-intersection
+                  gnus-newsgroup-unselected gnus-newsgroup-killed)
+                 gnus-newsgroup-unreads)
                 t)))
        (unless (listp (cdr gnus-newsgroup-killed))
          (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
@@ -5930,7 +6109,8 @@ The prefix argument ALL means to select all articles."
            (set-buffer gnus-group-buffer)
            (gnus-undo-force-boundary))
          (gnus-update-read-articles
-          group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
+          group (gnus-sorted-union
+                 gnus-newsgroup-unreads gnus-newsgroup-unselected))
          ;; Set the current article marks.
          (let ((gnus-newsgroup-scored
                 (if (and (not gnus-save-score)
@@ -5962,13 +6142,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
 `gnus-exit-group-hook' is called with no arguments if that value is non-nil."
   (interactive)
   (gnus-set-global-variables)
-  (when (gnus-buffer-live-p gnus-article-buffer)
-    (save-excursion
-      (set-buffer gnus-article-buffer)
-      (mm-destroy-parts gnus-article-mime-handles)
-      ;; Set it to nil for safety reason.
-      (setq gnus-article-mime-handle-alist nil)
-      (setq gnus-article-mime-handles nil)))
   (gnus-kill-save-kill-buffer)
   (gnus-async-halt-prefetch)
   (let* ((group gnus-newsgroup-name)
@@ -6027,7 +6200,7 @@ If FORCE (the prefix), also save the .newsrc file(s)."
          (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.
@@ -6047,7 +6220,14 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (if (not quit-config)
          (progn
            (goto-char group-point)
-           (gnus-configure-windows 'group 'force))
+           (gnus-configure-windows 'group 'force)
+           (unless (pos-visible-in-window-p)
+             (forward-line (/ (static-if (featurep 'xemacs)
+                                  (window-displayed-height)
+                                (1- (window-height)))
+                              -2))
+             (set-window-start (selected-window) (point))
+             (goto-char group-point)))
        (gnus-handle-ephemeral-exit quit-config))
       ;; Return to group mode buffer.
       (when (eq mode 'gnus-summary-mode)
@@ -6069,13 +6249,6 @@ If FORCE (the prefix), also save the .newsrc file(s)."
       (mapcar 'funcall
              (delq 'gnus-summary-expire-articles
                    (copy-sequence gnus-summary-prepare-exit-hook)))
-      (when (gnus-buffer-live-p gnus-article-buffer)
-       (save-excursion
-         (set-buffer gnus-article-buffer)
-         (mm-destroy-parts gnus-article-mime-handles)
-         ;; Set it to nil for safety reason.
-         (setq gnus-article-mime-handle-alist nil)
-         (setq gnus-article-mime-handles nil)))
       ;; If we have several article buffers, we kill them at exit.
       (unless gnus-single-article-buffer
        (gnus-kill-buffer gnus-article-buffer)
@@ -6141,6 +6314,16 @@ The state which existed when entering the ephemeral is reset."
       (gnus-summary-recenter)
       (gnus-summary-position-point))))
 
+(defun gnus-summary-preview-mime-message ()
+  "MIME decode and play this message."
+  (interactive)
+  (let ((gnus-break-pages nil)
+       (gnus-show-mime t))
+    (gnus-summary-select-article gnus-show-all-headers t))
+  (let ((w (get-buffer-window gnus-article-buffer)))
+    (when w
+      (select-window (get-buffer-window gnus-article-buffer)))))
+
 ;;; Dead summaries.
 
 (defvar gnus-dead-summary-mode-map nil)
@@ -6150,10 +6333,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)
-  (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.")
@@ -6199,17 +6383,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)))
-    (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."
@@ -6264,7 +6451,7 @@ previous group instead."
   (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...
@@ -6335,9 +6522,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)))))
-                          (not (and unseen
-                                    (memq (car data) gnus-newsgroup-unseen)))
-                          (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)))
@@ -6387,6 +6577,8 @@ If optional argument UNREAD is non-nil, only unread article is selected."
   "Go the subject line of ARTICLE.
 If FORCE, also allow jumping to articles not currently shown."
   (interactive "nArticle number: ")
+  (unless (numberp article)
+    (error "Article %s is not a number" article))
   (let ((b (point))
        (data (gnus-data-find article)))
     ;; We read in the article if we have to.
@@ -6423,19 +6615,22 @@ 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
-      (mm-enable-multibyte-mule4)))
+      (set-buffer-multibyte t)))
   (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)))
+      (set-buffer-multibyte t)))
   (if (null article)
       nil
     (prog1
        (if gnus-summary-display-article-function
            (funcall gnus-summary-display-article-function article all-header)
          (gnus-article-prepare article all-header))
+      (with-current-buffer gnus-article-buffer
+       (set (make-local-variable 'gnus-summary-search-article-matched-data)
+            nil))
       (gnus-run-hooks 'gnus-select-article-hook)
       (when (and gnus-current-article
                 (not (zerop gnus-current-article)))
@@ -6458,7 +6653,7 @@ be displayed."
   (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)
@@ -6476,20 +6671,12 @@ be displayed."
                   (or (null gnus-current-article)
                       (not (eq gnus-current-article article))))
              force)
-       ;; The requested article is different from the current article.
+         ;; The requested article is different from the current article.
          (progn
            (gnus-summary-display-article article all-headers)
-           (when (gnus-buffer-live-p gnus-article-buffer)
-             (with-current-buffer gnus-article-buffer
-               (if (not gnus-article-decoded-p) ;; a local variable
-                   (mm-disable-multibyte-mule4))))
-           (when (or all-headers gnus-show-all-headers)
-             (gnus-article-show-all-headers))
            (gnus-article-set-window-start
             (cdr (assq article gnus-newsgroup-bookmarks)))
            article)
-       (when (or all-headers gnus-show-all-headers)
-         (gnus-article-show-all-headers))
        'old))))
 
 (defun gnus-summary-force-verify-and-decrypt ()
@@ -6788,6 +6975,19 @@ Return nil if there are no unseen articles."
        (gnus-summary-first-subject t t t))
     (gnus-summary-position-point)))
 
+(defun gnus-summary-first-unseen-or-unread-subject ()
+  "Place the point on the subject line of the first unseen article.
+Return nil if there are no unseen articles."
+  (interactive)
+  (prog1
+      (unless (when (gnus-summary-first-subject t t t)
+               (gnus-summary-show-thread)
+               (gnus-summary-first-subject t t t))
+       (when (gnus-summary-first-subject t)
+         (gnus-summary-show-thread)
+         (gnus-summary-first-subject t)))
+    (gnus-summary-position-point)))
+
 (defun gnus-summary-first-article ()
   "Select the first article.
 Return nil if there are no articles."
@@ -6966,10 +7166,10 @@ articles that are younger than AGE days."
        (when (> (length days) 0)
         (setq days (read days)))
        (if (numberp days)
-          (progn 
+          (progn
             (setq days-got t)
             (if (< days 0)
-                (progn 
+                (progn
                   (setq younger (not younger))
                   (setq days (* days -1)))))
         (message "Please enter a number.")
@@ -6999,7 +7199,7 @@ articles that are younger than AGE days."
   (interactive
    (let ((header
          (intern
-          (gnus-completing-read
+          (gnus-completing-read-with-default
            (symbol-name (car gnus-extra-headers))
            (if current-prefix-arg
                "Exclude extra header:"
@@ -7172,15 +7372,17 @@ fetched for this group."
   "Mark all unread excluded articles as read.
 If ALL, mark even excluded ticked and dormants as read."
   (interactive "P")
-  (let ((articles (gnus-sorted-complement
+  (setq gnus-newsgroup-limit (sort gnus-newsgroup-limit '<))
+  (let ((articles (gnus-sorted-ndifference
                   (sort
                    (mapcar (lambda (h) (mail-header-number h))
                            gnus-newsgroup-headers)
                    '<)
-                  (sort gnus-newsgroup-limit '<)))
+                  gnus-newsgroup-limit))
        article)
     (setq gnus-newsgroup-unreads
-         (gnus-intersection gnus-newsgroup-unreads gnus-newsgroup-limit))
+         (gnus-sorted-intersection gnus-newsgroup-unreads
+                                   gnus-newsgroup-limit))
     (if all
        (setq gnus-newsgroup-dormant nil
              gnus-newsgroup-marked nil
@@ -7210,9 +7412,7 @@ If ALL, mark even excluded ticked and dormants as read."
     ;; 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
@@ -7625,8 +7825,11 @@ to guess what the document format is."
                (gnus-group-read-ephemeral-group
                 name `(nndoc ,name (nndoc-address ,(get-buffer dig))
                              (nndoc-article-type
-                              ,(if force 'mbox 'guess))) t))
-           ;; Make all postings to this group go to the parent group.
+                              ,(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.
              (nconc (gnus-info-params (gnus-get-info name))
                     params)
            ;; Couldn't select this doc group.
@@ -7666,7 +7869,7 @@ Obeys the standard process/prefix convention."
                                     (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))
@@ -7690,12 +7893,16 @@ Obeys the standard process/prefix convention."
   "Do incremental search forward on the current article.
 If REGEXP-P (the prefix) is non-nil, do regexp isearch."
   (interactive "P")
-  (gnus-summary-select-article)
-  (gnus-configure-windows 'article)
-  (gnus-eval-in-buffer-window gnus-article-buffer
-    (save-restriction
-      (widen)
-      (isearch-forward regexp-p))))
+  (let* ((gnus-inhibit-treatment t)
+        (old (gnus-summary-select-article)))
+    (gnus-configure-windows 'article)
+    (gnus-eval-in-buffer-window gnus-article-buffer
+      (save-restriction
+       (widen)
+       (when (eq 'old old)
+         (gnus-article-show-all-headers))
+       (goto-char (point-min))
+       (isearch-forward regexp-p)))))
 
 (defun gnus-summary-search-article-forward (regexp &optional backward)
   "Search for an article containing REGEXP forward.
@@ -7729,6 +7936,84 @@ If BACKWARD, search backward instead."
                    "")))))
   (gnus-summary-search-article-forward regexp 'backward))
 
+(eval-when-compile
+  (defmacro gnus-summary-search-article-position-point (regexp backward)
+    "Dehighlight the last matched text and goto the beginning position."
+    (` (if (and gnus-summary-search-article-matched-data
+               (let ((text (caddr gnus-summary-search-article-matched-data))
+                     (inhibit-read-only t)
+                     buffer-read-only)
+                 (delete-region
+                  (goto-char (car gnus-summary-search-article-matched-data))
+                  (cadr gnus-summary-search-article-matched-data))
+                 (insert text)
+                 (string-match (, regexp) text)))
+          (if (, backward) (beginning-of-line) (end-of-line))
+        (goto-char (if (, backward) (point-max) (point-min))))))
+
+  (defmacro gnus-summary-search-article-highlight-goto-x-face (opoint)
+    "Place point where X-Face image is displayed."
+    (if (featurep 'xemacs)
+       (` (let ((end (if (search-forward "\n\n" nil t)
+                         (goto-char (1- (point)))
+                       (point-min)))
+                extent)
+            (or (search-backward "\n\n" nil t) (goto-char (point-min)))
+            (unless (and (re-search-forward "^From:" end t)
+                         (setq extent (extent-at (point)))
+                         (extent-begin-glyph extent))
+              (goto-char (, opoint)))))
+      (` (let ((end (if (search-forward "\n\n" nil t)
+                       (goto-char (1- (point)))
+                     (point-min)))
+              (start (or (search-backward "\n\n" nil t) (point-min))))
+          (goto-char
+           (or (text-property-any start end 'x-face-image t);; x-face-e21
+               (text-property-any start end 'x-face-mule-bitmap-image t)
+               (, opoint)))))))
+
+  (defmacro gnus-summary-search-article-highlight-matched-text
+    (backward treated x-face)
+    "Highlight matched text in the function `gnus-summary-search-article'."
+    (` (let ((start (set-marker (make-marker) (match-beginning 0)))
+            (end (set-marker (make-marker) (match-end 0)))
+            (inhibit-read-only t)
+            buffer-read-only)
+        (unless treated
+          (let ((,@
+                 (let ((items (mapcar 'car gnus-treatment-function-alist)))
+                   (mapcar
+                    (lambda (item) (setq items (delq item items)))
+                    '(gnus-treat-buttonize
+                      gnus-treat-fill-article
+                      gnus-treat-fill-long-lines
+                      gnus-treat-emphasize
+                      gnus-treat-highlight-headers
+                      gnus-treat-highlight-citation
+                      gnus-treat-highlight-signature
+                      gnus-treat-overstrike
+                      gnus-treat-display-xface
+                      gnus-treat-buttonize-head
+                      gnus-treat-decode-article-as-default-mime-charset))
+                   (static-if (featurep 'xemacs)
+                       items
+                     (cons '(x-face-mule-delete-x-face-field
+                             (quote never))
+                           items))))
+                (gnus-treat-display-xface
+                 (when (, x-face) gnus-treat-display-xface)))
+            (gnus-article-prepare-mime-display)))
+        (goto-char (if (, backward) start end))
+        (when (, x-face)
+          (gnus-summary-search-article-highlight-goto-x-face (point)))
+        (setq gnus-summary-search-article-matched-data
+              (list start end (buffer-substring start end)))
+        (unless (eq start end);; matched text has been deleted. :-<
+          (put-text-property start end 'face
+                             (or (find-face 'isearch)
+                                 'secondary-selection))))))
+  )
+
 (defun gnus-summary-search-article (regexp &optional backward)
   "Search for an article containing REGEXP.
 Optional argument BACKWARD means do search for backward.
@@ -7744,15 +8029,38 @@ Optional argument BACKWARD means do search for backward.
        (gnus-xmas-force-redisplay nil) ;Inhibit XEmacs redisplay.
        (gnus-use-trees nil)            ;Inhibit updating tree buffer.
        (sum (current-buffer))
-       (gnus-display-mime-function nil)
        (found nil)
-       point)
+       point treated)
     (gnus-save-hidden-threads
-      (gnus-summary-select-article)
+      (static-if (featurep 'xemacs)
+         (let ((gnus-inhibit-treatment t))
+           (setq treated (eq 'old (gnus-summary-select-article)))
+           (when (and treated
+                      (not (and (gnus-buffer-live-p gnus-article-buffer)
+                                (window-live-p (get-buffer-window
+                                                gnus-article-buffer t)))))
+             (gnus-summary-select-article nil t)
+             (setq treated nil)))
+       (let ((gnus-inhibit-treatment t)
+             (x-face-mule-delete-x-face-field 'never))
+         (setq treated (eq 'old (gnus-summary-select-article)))
+         (when (and treated
+                    (not
+                     (and (gnus-buffer-live-p gnus-article-buffer)
+                          (window-live-p (get-buffer-window
+                                          gnus-article-buffer t))
+                          (or (not (string-match "^\\^X-Face:" regexp))
+                              (with-current-buffer gnus-article-buffer
+                                gnus-summary-search-article-matched-data)))))
+           (gnus-summary-select-article nil t)
+           (setq treated nil))))
       (set-buffer gnus-article-buffer)
-      (goto-char (window-point (get-buffer-window (current-buffer))))
-      (when backward
-       (forward-line -1))
+      (widen)
+      (if treated
+         (progn
+           (gnus-article-show-all-headers)
+           (gnus-summary-search-article-position-point regexp backward))
+       (goto-char (if backward (point-max) (point-min))))
       (while (not found)
        (gnus-message 7 "Searching article: %d..." (cdr gnus-article-current))
        (if (if backward
@@ -7760,15 +8068,16 @@ Optional argument BACKWARD means do search for backward.
              (re-search-forward regexp nil t))
            ;; We found the regexp.
            (progn
+             (gnus-summary-search-article-highlight-matched-text
+              backward treated (string-match "^\\^X-Face:" regexp))
              (setq found 'found)
-             (beginning-of-line)
+             (forward-line
+              (/ (- 2 (window-height
+                       (get-buffer-window gnus-article-buffer t)))
+                 2))
              (set-window-start
               (get-buffer-window (current-buffer))
               (point))
-             (forward-line 1)
-             (set-window-point
-              (get-buffer-window (current-buffer))
-              (point))
              (set-buffer sum)
              (setq point (point)))
          ;; We didn't find it, so we go to the next article.
@@ -7783,7 +8092,9 @@ Optional argument BACKWARD means do search for backward.
              (unless (gnus-summary-article-sparse-p
                       (gnus-summary-article-number))
                (setq found nil)
-               (gnus-summary-select-article)
+               (let ((gnus-inhibit-treatment t))
+                 (gnus-summary-select-article))
+               (setq treated nil)
                (set-buffer gnus-article-buffer)
                (widen)
                (goto-char (if backward (point-max) (point-min))))))))
@@ -7871,7 +8182,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))
-;; 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)
@@ -7966,23 +8277,21 @@ If ARG (the prefix) is a number, show the article with the charset
 defined in `gnus-summary-show-article-charset-alist', or the charset
 input.
 If ARG (the prefix) is non-nil and not a number, show the raw article
-without any article massaging functions being run.  Normally, the key strokes 
+without any article massaging functions being run.  Normally, the key strokes
 are `C-u g'."
   (interactive "P")
   (cond
    ((numberp arg)
     (gnus-summary-show-article t)
-    (let ((gnus-newsgroup-charset
-          (or (cdr (assq arg gnus-summary-show-article-charset-alist))
-              (mm-read-coding-system
-               "View as charset: "
-               (save-excursion
-                 (set-buffer gnus-article-buffer)
-                 (let ((coding-systems
-                        (detect-coding-region (point) (point-max))))
-                   (or (car-safe coding-systems)
-                       coding-systems))))))
-         (gnus-newsgroup-ignored-charsets 'gnus-all))
+    (let* ((gnus-newsgroup-charset
+           (or (cdr (assq arg gnus-summary-show-article-charset-alist))
+               (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))))))
+          (default-mime-charset gnus-newsgroup-charset)
+          (gnus-newsgroup-ignored-charsets 'gnus-all))
       (gnus-summary-select-article nil 'force)
       (let ((deps gnus-newsgroup-dependencies)
            head header lines)
@@ -8023,16 +8332,9 @@ are `C-u g'."
     (let ((gnus-have-all-headers t)
          gnus-article-prepare-hook
          gnus-article-decode-hook
-         gnus-display-mime-function
-         gnus-break-pages)
-      ;; Destroy any MIME parts.
-      (when (gnus-buffer-live-p gnus-article-buffer)
-       (save-excursion
-         (set-buffer gnus-article-buffer)
-         (mm-destroy-parts gnus-article-mime-handles)
-         ;; Set it to nil for safety reason.
-         (setq gnus-article-mime-handle-alist nil)
-         (setq gnus-article-mime-handles nil)))
+         gnus-break-pages
+         gnus-show-mime
+         (gnus-inhibit-treatment t))
       (gnus-summary-select-article nil 'force))))
   (gnus-summary-goto-subject gnus-current-article)
   (gnus-summary-position-point))
@@ -8066,20 +8368,19 @@ If ARG is a negative number, hide the unwanted header lines."
       (let* ((buffer-read-only nil)
             (inhibit-point-motion-hooks t)
             hidden e)
-       (setq hidden
-             (if (numberp arg)
-                 (>= arg 0)
-               (save-restriction
-                 (article-narrow-to-head)
-                 (gnus-article-hidden-text-p 'headers))))
-       (goto-char (point-min))
-       (when (search-forward "\n\n" nil t)
-         (delete-region (point-min) (1- (point))))
+       (save-restriction
+         (article-narrow-to-head)
+         (setq e (point-max)
+               hidden (if (numberp arg)
+                          (>= arg 0)
+                        (gnus-article-hidden-text-p 'headers))))
+       (delete-region (point-min) e)
        (goto-char (point-min))
        (save-excursion
          (set-buffer gnus-original-article-buffer)
          (goto-char (point-min))
-         (setq e (1- (or (search-forward "\n\n" nil t) (point-max)))))
+         (setq e (search-forward "\n\n" nil t)
+               e (if e (1- e) (point-max))))
        (insert-buffer-substring gnus-original-article-buffer 1 e)
        (save-restriction
          (narrow-to-region (point-min) (point))
@@ -8097,6 +8398,16 @@ If ARG is a negative number, hide the unwanted header lines."
   (interactive)
   (gnus-summary-toggle-header 1))
 
+(defun gnus-summary-toggle-mime (&optional arg)
+  "Toggle MIME processing.
+If ARG is a positive number, turn MIME processing on."
+  (interactive "P")
+  (setq gnus-show-mime
+       (if (null arg)
+           (not gnus-show-mime)
+         (> (prefix-numeric-value arg) 0)))
+  (gnus-summary-select-article t 'force))
+
 (defun gnus-summary-caesar-message (&optional arg)
   "Caesar rotate the current article by 13.
 The numerical prefix specifies how many places to rotate each letter
@@ -8162,17 +8473,27 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                 (crosspost "Crosspost" "Crossposting")))
        (copy-buf (save-excursion
                    (nnheader-set-temp-buffer " *copy article*")))
+       (default-marks gnus-article-mark-lists)
+       (no-expire-marks (delete '(expirable . expire)
+                                (copy-sequence gnus-article-mark-lists)))
        art-group to-method new-xref article to-groups)
     (unless (assq action names)
       (error "Unknown action %s" action))
-    ;; 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)
-      (gnus-summary-select-article nil nil nil (car articles)))
     ;; Read the newsgroup name.
     (when (and (not to-newsgroup)
               (not select-method))
+      (if (and gnus-move-split-methods
+              (not
+               (and (memq gnus-current-article articles)
+                    (gnus-buffer-live-p gnus-original-article-buffer))))
+         ;; When `gnus-move-split-methods' is non-nil, we have to
+         ;; select an article to give `gnus-read-move-group-name' an
+         ;; opportunity to suggest an appropriate default.  However,
+         ;; we needn't render or mark the article.
+         (let ((gnus-display-mime-function nil)
+               (gnus-article-prepare-hook nil)
+               (gnus-mark-article-hook nil))
+           (gnus-summary-select-article nil nil nil (car articles))))
       (setq to-newsgroup
            (gnus-read-move-group-name
             (cadr (assq action names))
@@ -8277,7 +8598,9 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
                                       (list (cdr art-group)))))
 
            ;; See whether the article is to be put in the cache.
-           (let ((marks gnus-article-mark-lists)
+           (let ((marks (if (gnus-group-auto-expirable-p to-group)
+                            default-marks
+                          no-expire-marks))
                  (to-article (cdr art-group)))
 
              ;; Enter the article into the cache in the new group,
@@ -8285,6 +8608,10 @@ ACTION can be either `move' (the default), `crosspost' or `copy'."
              (when gnus-use-cache
                (gnus-cache-possibly-enter-article
                 to-group to-article
+                (let ((header (copy-sequence
+                               (gnus-summary-article-header article))))
+                  (mail-header-set-number header to-article)
+                  header)
                 (memq article gnus-newsgroup-marked)
                 (memq article gnus-newsgroup-dormant)
                 (memq article gnus-newsgroup-unreads)))
@@ -8394,7 +8721,7 @@ latter case, they will be copied into the relevant groups."
                                  (car (gnus-find-method-for-group
                                        gnus-newsgroup-name)))))
                (method
-                (gnus-completing-read
+                (gnus-completing-read-with-default
                  methname "What backend do you want to use when respooling?"
                  methods nil t nil 'gnus-mail-method-history))
                ms)
@@ -8441,7 +8768,7 @@ latter case, they will be copied into the relevant groups."
            (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.
+       ;; 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"
@@ -8538,14 +8865,12 @@ 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.
-         (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)
-                 (when (gnus-data-find (car expirable))
-                   (gnus-summary-mark-article
-                    (car expirable) gnus-canceled-mark)))
-               (setq expirable (cdr expirable))))))
+             (dolist (article expirable)
+               (when (and (not (memq article es))
+                          (gnus-data-find article))
+                 (gnus-summary-mark-article article gnus-canceled-mark))))))
        (gnus-message 6 "Expiring articles...done")))))
 
 (defun gnus-summary-expire-articles-now ()
@@ -8600,72 +8925,32 @@ delete these instead."
     (gnus-set-mode-line 'summary)
     not-deleted))
 
-(defun gnus-summary-edit-article (&optional arg)
+(defun gnus-summary-edit-article (&optional force)
   "Edit the current article.
 This will have permanent effect only in mail groups.
-If ARG is nil, edit the decoded articles.
-If ARG is 1, edit the raw articles.
-If ARG is 2, edit the raw articles even in read-only groups.
-If ARG is 3, edit the articles with the current handles.
-Otherwise, allow editing of articles even in read-only
+If FORCE is non-nil, allow editing of articles even in read-only
 groups."
   (interactive "P")
-  (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"))
-    (save-excursion
-      (set-buffer gnus-summary-buffer)
-      (let ((mail-parse-charset gnus-newsgroup-charset)
-           (mail-parse-ignored-charsets gnus-newsgroup-ignored-charsets))
-       (gnus-set-global-variables)
-       (when (and (not force)
-                  (gnus-group-read-only-p))
-         (error "The current newsgroup does not support article editing"))
-       (gnus-summary-show-article t)
-       (when (and (not raw) (gnus-buffer-live-p gnus-article-buffer))
-         (with-current-buffer gnus-article-buffer
-           (mm-enable-multibyte-mule4)))
-       (if (equal gnus-newsgroup-name "nndraft:drafts")
-           (setq raw t))
-       (gnus-article-edit-article
-        (if raw 'ignore
-          `(lambda ()
-             (let ((mbl mml-buffer-list))
-               (setq mml-buffer-list nil)
-               (mime-to-mml ,'current-handles)
-               (let ((mbl1 mml-buffer-list))
-                 (setq mml-buffer-list mbl)
-                 (set (make-local-variable 'mml-buffer-list) mbl1))
-               (make-local-hook 'kill-buffer-hook)
-               (add-hook 'kill-buffer-hook 'mml-destroy-buffers t t))))
-        `(lambda (no-highlight)
-           (let ((mail-parse-charset ',gnus-newsgroup-charset)
-                 (message-options message-options)
-                 (message-options-set-recipient)
-                 (mail-parse-ignored-charsets
-                  ',gnus-newsgroup-ignored-charsets))
-             ,(if (not raw) '(progn
-                               (mml-to-mime)
-                               (mml-destroy-buffers)
-                               (remove-hook 'kill-buffer-hook
-                                            'mml-destroy-buffers t)
-                               (kill-local-variable 'mml-buffer-list)))
-             (gnus-summary-edit-article-done
-              ,(or (mail-header-references gnus-current-headers) "")
-              ,(gnus-group-read-only-p)
-              ,gnus-summary-buffer no-highlight))))))))
+  (save-excursion
+    (set-buffer gnus-summary-buffer)
+    (let ((mail-parse-charset gnus-newsgroup-charset)
+         (mail-parse-ignored-charsets gnus-newsgroup-ignored-charsets))
+      (gnus-set-global-variables)
+      (when (and (not force)
+                (gnus-group-read-only-p))
+       (error "The current newsgroup does not support article editing"))
+      (gnus-summary-show-article t)
+      (gnus-article-edit-article
+       'ignore
+       `(lambda (no-highlight)
+         (let ((mail-parse-charset ',gnus-newsgroup-charset)
+               (message-options message-options)
+               (message-options-set-recipient)
+               (mail-parse-ignored-charsets
+                ',gnus-newsgroup-ignored-charsets))
+           (gnus-summary-edit-article-done
+            ,(or (mail-header-references gnus-current-headers) "")
+            ,(gnus-group-read-only-p) ,gnus-summary-buffer no-highlight)))))))
 
 (defalias 'gnus-summary-edit-article-postpone 'gnus-article-edit-exit)
 
@@ -8674,7 +8959,7 @@ groups."
   "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)))
@@ -8721,10 +9006,7 @@ groups."
                    (insert ".\n")
                    (let ((nntp-server-buffer (current-buffer)))
                      (setq header (car (gnus-get-newsgroup-headers
-                                        (save-excursion
-                                          (set-buffer gnus-summary-buffer)
-                                          gnus-newsgroup-dependencies)
-                                        t))))
+                                        nil t))))
                    (save-excursion
                      (set-buffer gnus-summary-buffer)
                      (gnus-data-set-header
@@ -8768,14 +9050,6 @@ groups."
   (execute-kbd-macro (concat (this-command-keys) key))
   (gnus-article-edit-done))
 
-
-(defun gnus-summary-toggle-smiley (&optional arg)
-  "Toggle the display of smilies as small graphical icons."
-  (interactive "P")
-  (save-excursion
-    (set-buffer gnus-article-buffer)
-    (gnus-smiley-display arg)))
-
 ;;; Respooling
 
 (defun gnus-summary-respool-query (&optional silent trace)
@@ -9096,11 +9370,17 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
        (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
        (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
        (cond ((= mark gnus-ticked-mark)
-              (push article gnus-newsgroup-marked))
+              (setq gnus-newsgroup-marked
+                    (gnus-add-to-sorted-list gnus-newsgroup-marked
+                                             article)))
              ((= mark gnus-dormant-mark)
-              (push article gnus-newsgroup-dormant))
+              (setq gnus-newsgroup-dormant
+                    (gnus-add-to-sorted-list gnus-newsgroup-dormant
+                                             article)))
              (t
-              (push article gnus-newsgroup-unreads)))
+              (setq gnus-newsgroup-unreads
+                    (gnus-add-to-sorted-list gnus-newsgroup-unreads
+                                             article))))
        (gnus-pull article gnus-newsgroup-reads)
 
        ;; See whether the article is to be put in the cache.
@@ -9109,6 +9389,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
             (save-excursion
               (gnus-cache-possibly-enter-article
                gnus-newsgroup-name article
+               (gnus-summary-article-header article)
                (= mark gnus-ticked-mark)
                (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
 
@@ -9155,6 +9436,7 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
             (save-excursion
               (gnus-cache-possibly-enter-article
                gnus-newsgroup-name article
+               (gnus-summary-article-header article)
                (= mark gnus-ticked-mark)
                (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
 
@@ -9210,9 +9492,10 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
   "Enter ARTICLE in the pertinent lists and remove it from others."
   ;; Make the article expirable.
   (let ((mark (or mark gnus-del-mark)))
-    (if (= mark gnus-expirable-mark)
-       (push article gnus-newsgroup-expirable)
-      (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable)))
+    (setq gnus-newsgroup-expirable
+         (if (= mark gnus-expirable-mark)
+             (gnus-add-to-sorted-list gnus-newsgroup-expirable article)
+           (delq article gnus-newsgroup-expirable)))
     ;; Remove from unread and marked lists.
     (setq gnus-newsgroup-unreads (delq article gnus-newsgroup-unreads))
     (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
@@ -9240,11 +9523,14 @@ Iff NO-EXPIRE, auto-expiry will be inhibited."
        (gnus-dup-unsuppress-article article))
 
       (cond ((= mark gnus-ticked-mark)
-            (push article gnus-newsgroup-marked))
+            (setq gnus-newsgroup-marked
+                  (gnus-add-to-sorted-list gnus-newsgroup-marked article)))
            ((= mark gnus-dormant-mark)
-            (push article gnus-newsgroup-dormant))
+            (setq gnus-newsgroup-dormant
+                  (gnus-add-to-sorted-list gnus-newsgroup-dormant article)))
            (t
-            (push article gnus-newsgroup-unreads)))
+            (setq gnus-newsgroup-unreads
+                  (gnus-add-to-sorted-list gnus-newsgroup-unreads article))))
       (gnus-pull article gnus-newsgroup-reads)
       t)))
 
@@ -9494,8 +9780,8 @@ If ALL is non-nil, also mark ticked and dormant articles as read."
        ;; We check that there are unread articles.
        (when (or all (gnus-summary-find-next))
          (gnus-summary-catchup all t beg nil t)))))
-
   (gnus-summary-position-point))
+
 (defun gnus-summary-catchup-all (&optional quietly)
   "Mark all articles in this newsgroup as read."
   (interactive "P")
@@ -9692,18 +9978,49 @@ Returns nil if no thread was there to be shown."
       (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))
-    (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.
+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)
@@ -9899,8 +10216,7 @@ Argument REVERSE means reverse order."
     ;; 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."
@@ -9923,8 +10239,7 @@ Argument REVERSE means reverse order."
     ;; 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.
 
@@ -10116,23 +10431,26 @@ save those articles instead."
         (to-newsgroup
          (cond
           ((null split-name)
-           (gnus-completing-read default prom
-                                 gnus-active-hashtb
-                                 'gnus-valid-move-group-p
-                                 nil prefix
-                                 'gnus-group-history))
+           (gnus-completing-read-with-default
+            default prom
+            gnus-active-hashtb
+            'gnus-valid-move-group-p
+            nil prefix
+            'gnus-group-history))
           ((= 1 (length split-name))
-           (gnus-completing-read (car split-name) prom
-                                 gnus-active-hashtb
-                                 'gnus-valid-move-group-p
-                                 nil nil
-                                 'gnus-group-history))
+           (gnus-completing-read-with-default
+            (car split-name) prom
+            gnus-active-hashtb
+            'gnus-valid-move-group-p
+            nil nil
+            'gnus-group-history))
           (t
-           (gnus-completing-read nil prom
-                                 (mapcar (lambda (el) (list el))
-                                         (nreverse split-name))
-                                 nil nil nil
-                                 'gnus-group-history))))
+           (gnus-completing-read-with-default
+            nil prom
+            (mapcar (lambda (el) (list el))
+                    (nreverse split-name))
+            nil nil nil
+            'gnus-group-history))))
         (to-method (gnus-server-to-method (gnus-group-method to-newsgroup))))
     (when to-newsgroup
       (if (or (string= to-newsgroup "")
@@ -10172,7 +10490,8 @@ If REVERSE, save parts that do not match TYPE."
     (save-excursion
       (set-buffer gnus-article-buffer)
       (let ((handles (or gnus-article-mime-handles
-                        (mm-dissect-buffer) (mm-uu-dissect))))
+                        (mm-dissect-buffer nil gnus-article-loose-mime)
+                        (mm-uu-dissect))))
        (when handles
          (gnus-summary-save-parts-1 type dir handles reverse)
          (unless gnus-article-mime-handles ;; Don't destroy this case.
@@ -10232,7 +10551,7 @@ If REVERSE, save parts that do not match TYPE."
                                (lambda (f)
                                  (if (equal f " ")
                                      f
-                                   (mm-quote-arg f)))
+                                   (gnus-quote-arg-for-sh-or-csh f)))
                                files " ")))))
          (setq ps (cdr ps)))))
     (if (and gnus-view-pseudos (not not-view))
@@ -10259,7 +10578,9 @@ If REVERSE, save parts that do not match TYPE."
          (gnus-data-enter
           after-article gnus-reffed-article-number
           gnus-unread-mark b (car pslist) 0 (- e b))
-         (push gnus-reffed-article-number gnus-newsgroup-unreads)
+         (setq gnus-newsgroup-unreads
+               (gnus-add-to-sorted-list gnus-newsgroup-unreads
+                                        gnus-reffed-article-number))
          (setq gnus-reffed-article-number (1- gnus-reffed-article-number))
          (setq pslist (cdr pslist)))))))
 
@@ -10449,12 +10770,12 @@ If REVERSE, save parts that do not match TYPE."
     (goto-char p)))
 
 (defun gnus-update-read-articles (group unread &optional compute)
-  "Update the list of read articles in GROUP."
+  "Update the list of read articles in GROUP.
+UNREAD is a sorted list."
   (let* ((active (or gnus-newsgroup-active (gnus-active group)))
         (entry (gnus-gethash group gnus-newsrc-hashtb))
         (info (nth 2 entry))
         (prev 1)
-        (unread (sort (copy-sequence unread) '<))
         read)
     (if (or (not info) (not active))
        ;; There is no info on this group if it was, in fact,
@@ -10543,6 +10864,102 @@ If REVERSE, save parts that do not match TYPE."
           (gnus-summary-exit))
         buffers)))))
 
+
+;;; @ for mime-partial
+;;;
+
+(defun gnus-request-partial-message ()
+  (save-excursion
+    (let ((number (gnus-summary-article-number))
+         (group gnus-newsgroup-name)
+         (mother gnus-article-buffer))
+      (set-buffer (get-buffer-create " *Partial Article*"))
+      (erase-buffer)
+      (setq mime-preview-buffer mother)
+      (gnus-request-article-this-buffer number group)
+      (mime-parse-buffer)
+      )))
+
+(autoload 'mime-combine-message/partial-pieces-automatically
+  "mime-partial"
+  "Internal method to combine message/partial messages automatically.")
+
+(mime-add-condition
+ 'action '((type . message)(subtype . partial)
+          (major-mode . gnus-original-article-mode)
+          (method . mime-combine-message/partial-pieces-automatically)
+          (summary-buffer-exp . gnus-summary-buffer)
+          (request-partial-message-method . gnus-request-partial-message)
+          ))
+
+
+;;; @ for message/rfc822
+;;;
+
+(defun gnus-mime-extract-message/rfc822 (entity situation)
+  "Burst a forwarded article."
+  (save-excursion
+    (set-buffer gnus-summary-buffer)
+    (let* ((group (completing-read "Group: " gnus-active-hashtb nil t
+                                  gnus-newsgroup-name 'gnus-group-history))
+          (gnus-group-marked (list group))
+          article info)
+      (with-temp-buffer
+       (mime-insert-entity-content entity)
+       (setq article (gnus-request-accept-article group)))
+      (when (and (consp article)
+                (numberp (setq article (cdr article))))
+       (setq info (gnus-get-info group))
+       (gnus-info-set-read info
+                           (gnus-remove-from-range (gnus-info-read info)
+                                                   (list article)))
+       (when (string-equal group gnus-newsgroup-name)
+         (forward-line 1)
+         (let (gnus-show-threads)
+           (gnus-summary-goto-subject article t))
+         (gnus-summary-clear-mark-forward 1))
+       (set-buffer gnus-group-buffer)
+       (gnus-group-get-new-news-this-group nil t)))))
+
+(mime-add-condition
+ 'action '((type . message)(subtype . rfc822)
+          (major-mode . gnus-original-article-mode)
+          (method . gnus-mime-extract-message/rfc822)
+          (mode . "extract")
+          ))
+
+(mime-add-condition
+ 'action '((type . message)(subtype . news)
+          (major-mode . gnus-original-article-mode)
+          (method . gnus-mime-extract-message/rfc822)
+          (mode . "extract")
+          ))
+
+(defun gnus-mime-extract-multipart (entity situation)
+  (let ((children (mime-entity-children entity))
+       mime-acting-situation-to-override
+       f)
+    (while children
+      (mime-play-entity (car children)
+                       (cons (assq 'mode situation)
+                             mime-acting-situation-to-override))
+      (setq children (cdr children)))
+    (if (setq f (cdr (assq 'after-method
+                          mime-acting-situation-to-override)))
+       (eval f)
+      )))
+
+(mime-add-condition
+ 'action '((type . multipart)
+          (method . gnus-mime-extract-multipart)
+          (mode . "extract")
+          )
+ 'with-default)
+
+
+;;; @ end
+;;;
+
 (defun gnus-summary-setup-default-charset ()
   "Setup newsgroup default charset."
   (if (equal gnus-newsgroup-name "nndraft:drafts")
@@ -10606,6 +11023,104 @@ treated as multipart/mixed."
     (gnus-summary-show-article)))
 
 ;;;
+;;; Intelli-mouse commmands
+;;;
+
+(defun gnus-wheel-summary-scroll (event)
+  (interactive "e")
+  (let ((amount (if (memq 'shift (event-modifiers event))
+                   (car gnus-wheel-scroll-amount)
+                 (cdr gnus-wheel-scroll-amount)))
+       (direction (- (* (static-if (featurep 'xemacs)
+                            (event-button event)
+                          (cond ((eq 'mouse-4 (event-basic-type event))
+                                 4)
+                                ((eq 'mouse-5 (event-basic-type event))
+                                 5)))
+                        2) 9))
+       edge)
+    (gnus-summary-scroll-up (* amount direction))
+    (when (gnus-eval-in-buffer-window gnus-article-buffer
+           (save-restriction
+             (widen)
+             (and (if (< 0 direction)
+                      (gnus-article-next-page 0)
+                    (gnus-article-prev-page 0)
+                    (bobp))
+                  (if (setq edge (get-text-property
+                                  (point-min) 'gnus-wheel-edge))
+                      (setq edge (* edge direction))
+                    (setq edge -1))
+                  (or (plusp edge)
+                      (let ((buffer-read-only nil)
+                            (inhibit-read-only t))
+                        (put-text-property (point-min) (point-max)
+                                           'gnus-wheel-edge direction)
+                        nil))
+                  (or (> edge gnus-wheel-edge-resistance)
+                      (let ((buffer-read-only nil)
+                            (inhibit-read-only t))
+                        (put-text-property (point-min) (point-max)
+                                           'gnus-wheel-edge
+                                           (* (1+ edge) direction))
+                        nil))
+                  (eq last-command 'gnus-wheel-summary-scroll))))
+      (gnus-summary-next-article nil nil (minusp direction)))))
+
+(defun gnus-wheel-install ()
+  "Enable mouse wheel support on summary window."
+  (when gnus-use-wheel
+    (let ((keys
+          '([(mouse-4)] [(shift mouse-4)] [(mouse-5)] [(shift mouse-5)])))
+      (dolist (key keys)
+       (define-key gnus-summary-mode-map key
+         'gnus-wheel-summary-scroll)))))
+
+(add-hook 'gnus-summary-mode-hook 'gnus-wheel-install)
+
+;;;
+;;; Traditional PGP commmands
+;;;
+
+(defun gnus-summary-decrypt-article (&optional force)
+  "Decrypt the current article in traditional PGP way.
+This will have permanent effect only in mail groups.
+If FORCE is non-nil, allow editing of articles even in read-only
+groups."
+  (interactive "P")
+  (gnus-summary-select-article t)
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (save-excursion
+      (save-restriction
+       (widen)
+       (goto-char (point-min))
+       (unless (re-search-forward (car pgg-armor-header-lines) nil t)
+         (error "Not a traditional PGP message!"))
+       (let ((armor-start (match-beginning 0)))
+         (if (and (pgg-decrypt-region armor-start (point-max))
+                  (or force (not (gnus-group-read-only-p))))
+             (let ((inhibit-read-only t)
+                   buffer-read-only)
+               (delete-region armor-start
+                              (progn
+                                (re-search-forward "^-+END PGP" nil t)
+                                (beginning-of-line 2)
+                                (point)))
+               (insert-buffer-substring pgg-output-buffer))))))))
+
+(defun gnus-summary-verify-article ()
+  "Verify the current article in traditional PGP way."
+  (interactive)
+  (save-excursion
+    (set-buffer gnus-original-article-buffer)
+    (goto-char (point-min))
+    (unless (re-search-forward "^-+BEGIN PGP SIGNED MESSAGE" nil t)
+      (error "Not a traditional PGP message!"))
+    (re-search-forward "^-+END PGP" nil t)
+    (beginning-of-line 2)
+    (call-interactively (function pgg-verify-region))))
+
+;;;
 ;;; Generic summary marking commands
 ;;;
 
@@ -10651,7 +11166,7 @@ If N, the prefix, then repeat N times.
 If N is negative, move in reverse order.
 The difference between N and the actual number of articles marked is
 returned."
-       name (cadr lway))
+       name (car (cdr lway)))
      (interactive "p")
      (gnus-summary-generic-mark n ,mark ',(nth 2 lway) ,(nth 3 lway))))
 
@@ -10683,9 +11198,10 @@ returned."
 
 (defun gnus-summary-insert-articles (articles)
   (when (setq articles
-             (gnus-set-difference articles
-                                  (mapcar (lambda (h) (mail-header-number h))
-                                          gnus-newsgroup-headers)))
+             (gnus-sorted-difference articles
+                                     (mapcar (lambda (h)
+                                               (mail-header-number h))
+                                             gnus-newsgroup-headers)))
     (setq gnus-newsgroup-headers
          (merge 'list
                 gnus-newsgroup-headers
@@ -10723,44 +11239,51 @@ If ALL is non-nil, already read articles become readable.
 If ALL is a number, fetch this number of articles."
   (interactive "P")
   (prog1
-      (let ((old (mapcar 'car gnus-newsgroup-data))
-           (i (car gnus-newsgroup-active))
+      (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
            older len)
-       (while (<= i (cdr gnus-newsgroup-active))
-         (or (memq i old) (push i older))
-         (incf i))
+       (setq older
+             (gnus-sorted-difference
+              (gnus-uncompress-range (list gnus-newsgroup-active))
+              old))
        (setq len (length older))
        (cond
         ((null older) nil)
         ((numberp all)
          (if (< all len)
-             (setq older (subseq older 0 all))))
+             (setq older (last older all))))
         (all nil)
         (t
          (if (and (numberp gnus-large-newsgroup)
                   (> len gnus-large-newsgroup))
-             (let ((input
-                    (read-string
-                     (format
-                      "How many articles from %s (default %d): "
-                      (gnus-limit-string
-                       (gnus-group-decoded-name gnus-newsgroup-name) 35)
-                      len))))
+             (let* ((cursor-in-echo-area nil)
+                    (initial (gnus-parameter-large-newsgroup-initial 
+                              gnus-newsgroup-name))
+                    (input
+                     (read-string
+                      (format
+                       "How many articles from %s (%s %d): "
+                       (gnus-limit-string
+                        (gnus-group-decoded-name gnus-newsgroup-name) 35)
+                       (if initial "max" "default")
+                       len)
+                      (if initial
+                          (cons (number-to-string initial)
+                                0)))))
                (unless (string-match "^[ \t]*$" input)
                  (setq all (string-to-number input))
                  (if (< all len)
-                     (setq older (subseq older 0 all))))))))
+                     (setq older (last older all))))))))
        (if (not older)
            (message "No old news.")
          (gnus-summary-insert-articles older)
-         (gnus-summary-limit (gnus-union older old))))
+         (gnus-summary-limit (gnus-sorted-nunion old older))))
     (gnus-summary-position-point)))
 
 (defun gnus-summary-insert-new-articles ()
   "Insert all new articles in this group."
   (interactive)
   (prog1
-      (let ((old (mapcar 'car gnus-newsgroup-data))
+      (let ((old (sort (mapcar 'car gnus-newsgroup-data) '<))
            (old-active gnus-newsgroup-active)
            (nnmail-fetched-sources (list t))
            i new)
@@ -10775,8 +11298,8 @@ If ALL is a number, fetch this number of articles."
          (setq new (nreverse new))
          (gnus-summary-insert-articles new)
          (setq gnus-newsgroup-unreads
-               (append gnus-newsgroup-unreads new))
-         (gnus-summary-limit (gnus-union old new))))
+               (gnus-sorted-nunion gnus-newsgroup-unreads new))
+         (gnus-summary-limit (gnus-sorted-nunion old new))))
     (gnus-summary-position-point)))
 
 (gnus-summary-make-all-marking-commands)