This commit was generated by cvs2svn to compensate for changes in r2665,
[elisp/gnus.git-] / lisp / gnus-sum.el
index 52b5d1e..c78156c 100644 (file)
@@ -1,7 +1,7 @@
 ;;; gnus-sum.el --- summary mode commands for Semi-gnus
 ;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
 ;;; gnus-sum.el --- summary mode commands for Semi-gnus
 ;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
-;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Keywords: mail, news, MIME
 
 ;;         MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Keywords: mail, news, MIME
 
@@ -34,7 +34,6 @@
 (require 'gnus-range)
 (require 'gnus-int)
 (require 'gnus-undo)
 (require 'gnus-range)
 (require 'gnus-int)
 (require 'gnus-undo)
-(require 'std11)
 (require 'mime-view)
 
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
 (require 'mime-view)
 
 (autoload 'gnus-summary-limit-include-cached "gnus-cache" nil t)
@@ -222,10 +221,10 @@ to expose hidden threads."
   :group 'gnus-thread
   :type 'boolean)
 
   :group 'gnus-thread
   :type 'boolean)
 
-(defcustom gnus-thread-ignore-subject nil
-  "*If non-nil, ignore subjects and do all threading based on the Reference header.
-If nil, which is the default, articles that have different subjects
-from their parents will start separate threads."
+(defcustom gnus-thread-ignore-subject t
+  "*If non-nil, which is the default, ignore subjects and do all threading based on the Reference header.
+If nil, articles that have different subjects from their parents will
+start separate threads."
   :group 'gnus-thread
   :type 'boolean)
 
   :group 'gnus-thread
   :type 'boolean)
 
@@ -286,7 +285,9 @@ will go to the next group without confirmation."
                 (sexp :menu-tag "on" t)))
 
 (defcustom gnus-auto-select-same nil
                 (sexp :menu-tag "on" t)))
 
 (defcustom gnus-auto-select-same nil
-  "*If non-nil, select the next article with the same subject."
+  "*If non-nil, select the next article with the same subject.
+If there are no more articles with the same subject, go to
+the first unread article."
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
   :group 'gnus-summary-maneuvering
   :type 'boolean)
 
@@ -514,6 +515,7 @@ with some simple extensions:
 %G  Group name
 %p  Unprefixed group name
 %A  Current article number
 %G  Group name
 %p  Unprefixed group name
 %A  Current article number
+%z  Current article score
 %V  Gnus version
 %U  Number of unread articles in the group
 %e  Number of unselected articles in the group
 %V  Gnus version
 %U  Number of unread articles in the group
 %e  Number of unselected articles in the group
@@ -665,7 +667,7 @@ is not run if `gnus-visual' is nil."
   :type 'hook)
 
 (defcustom gnus-structured-field-decoder
   :type 'hook)
 
 (defcustom gnus-structured-field-decoder
-  #'eword-decode-and-unfold-structured-field
+  #'eword-decode-and-unfold-structured-field-body
   "Function to decode non-ASCII characters in structured field for summary."
   :group 'gnus-various
   :type 'function)
   "Function to decode non-ASCII characters in structured field for summary."
   :group 'gnus-various
   :type 'function)
@@ -674,7 +676,7 @@ is not run if `gnus-visual' is nil."
   (function
    (lambda (string)
      (eword-decode-unstructured-field-body
   (function
    (lambda (string)
      (eword-decode-unstructured-field-body
-      (std11-unfold-string string) 'must-unfold)
+      (std11-unfold-string string))
      ))
   "Function to decode non-ASCII characters in unstructured field for summary."
   :group 'gnus-various
      ))
   "Function to decode non-ASCII characters in unstructured field for summary."
   :group 'gnus-various
@@ -875,6 +877,7 @@ variable (string, integer, character, etc).")
     (?d (length gnus-newsgroup-dormant) ?d)
     (?t (length gnus-newsgroup-marked) ?d)
     (?r (length gnus-newsgroup-reads) ?d)
     (?d (length gnus-newsgroup-dormant) ?d)
     (?t (length gnus-newsgroup-marked) ?d)
     (?r (length gnus-newsgroup-reads) ?d)
+    (?z (gnus-summary-article-score gnus-tmp-article-number) ?d)
     (?E gnus-newsgroup-expunged-tally ?d)
     (?s (gnus-current-score-file-nondirectory) ?s)))
 
     (?E gnus-newsgroup-expunged-tally ?d)
     (?s (gnus-current-score-file-nondirectory) ?s)))
 
@@ -1148,7 +1151,7 @@ increase the score of each group you read."
     [delete] gnus-summary-prev-page
     [backspace] gnus-summary-prev-page
     "\r" gnus-summary-scroll-up
     [delete] gnus-summary-prev-page
     [backspace] gnus-summary-prev-page
     "\r" gnus-summary-scroll-up
-    "\e\r" gnus-summary-scroll-down
+    "\M-\r" gnus-summary-scroll-down
     "n" gnus-summary-next-unread-article
     "p" gnus-summary-prev-unread-article
     "N" gnus-summary-next-article
     "n" gnus-summary-next-unread-article
     "p" gnus-summary-prev-unread-article
     "N" gnus-summary-next-article
@@ -1355,6 +1358,7 @@ increase the score of each group you read."
     [delete] gnus-summary-prev-page
     "p" gnus-summary-prev-page
     "\r" gnus-summary-scroll-up
     [delete] gnus-summary-prev-page
     "p" gnus-summary-prev-page
     "\r" gnus-summary-scroll-up
+    "\M-\r" gnus-summary-scroll-down
     "<" gnus-summary-beginning-of-article
     ">" gnus-summary-end-of-article
     "b" gnus-summary-beginning-of-article
     "<" gnus-summary-beginning-of-article
     ">" gnus-summary-end-of-article
     "b" gnus-summary-beginning-of-article
@@ -1389,6 +1393,7 @@ increase the score of each group you read."
     "b" gnus-article-hide-boring-headers
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
     "b" gnus-article-hide-boring-headers
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
+    "C" gnus-article-hide-citation-in-followups
     "p" gnus-article-hide-pgp
     "P" gnus-article-hide-pem
     "\C-c" gnus-article-hide-citation-maybe)
     "p" gnus-article-hide-pgp
     "P" gnus-article-hide-pem
     "\C-c" gnus-article-hide-citation-maybe)
@@ -1434,6 +1439,7 @@ increase the score of each group you read."
     "c" gnus-summary-copy-article
     "B" gnus-summary-crosspost-article
     "q" gnus-summary-respool-query
     "c" gnus-summary-copy-article
     "B" gnus-summary-crosspost-article
     "q" gnus-summary-respool-query
+    "t" gnus-summary-respool-trace
     "i" gnus-summary-import-article
     "p" gnus-summary-article-posted-p)
 
     "i" gnus-summary-import-article
     "p" gnus-summary-article-posted-p)
 
@@ -1482,211 +1488,111 @@ increase the score of each group you read."
         ["Increase score..." gnus-summary-increase-score t]
         ["Lower score..." gnus-summary-lower-score t]))))
 
         ["Increase score..." gnus-summary-increase-score t]
         ["Lower score..." gnus-summary-lower-score t]))))
 
-    '(("Default header"
-       ["Ask" (gnus-score-set-default 'gnus-score-default-header nil)
-       :style radio
-       :selected (null gnus-score-default-header)]
-       ["From" (gnus-score-set-default 'gnus-score-default-header 'a)
-       :style radio
-       :selected (eq gnus-score-default-header 'a)]
-       ["Subject" (gnus-score-set-default 'gnus-score-default-header 's)
-       :style radio
-       :selected (eq gnus-score-default-header 's)]
-       ["Article body"
-       (gnus-score-set-default 'gnus-score-default-header 'b)
-       :style radio
-       :selected (eq gnus-score-default-header 'b )]
-       ["All headers"
-       (gnus-score-set-default 'gnus-score-default-header 'h)
-       :style radio
-       :selected (eq gnus-score-default-header 'h )]
-       ["Message-ID" (gnus-score-set-default 'gnus-score-default-header 'i)
-       :style radio
-       :selected (eq gnus-score-default-header 'i )]
-       ["Thread" (gnus-score-set-default 'gnus-score-default-header 't)
-       :style radio
-       :selected (eq gnus-score-default-header 't )]
-       ["Crossposting"
-       (gnus-score-set-default 'gnus-score-default-header 'x)
-       :style radio
-       :selected (eq gnus-score-default-header 'x )]
-       ["Lines" (gnus-score-set-default 'gnus-score-default-header 'l)
-       :style radio
-       :selected (eq gnus-score-default-header 'l )]
-       ["Date" (gnus-score-set-default 'gnus-score-default-header 'd)
-       :style radio
-       :selected (eq gnus-score-default-header 'd )]
-       ["Followups to author"
-       (gnus-score-set-default 'gnus-score-default-header 'f)
-       :style radio
-       :selected (eq gnus-score-default-header 'f )])
-      ("Default type"
-       ["Ask" (gnus-score-set-default 'gnus-score-default-type nil)
-       :style radio
-       :selected (null gnus-score-default-type)]
-       ;; The `:active' key is commented out in the following,
-       ;; because the GNU Emacs hack to support radio buttons use
-       ;; active to indicate which button is selected.
-       ["Substring" (gnus-score-set-default 'gnus-score-default-type 's)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 's)]
-       ["Regexp" (gnus-score-set-default 'gnus-score-default-type 'r)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 'r)]
-       ["Exact" (gnus-score-set-default 'gnus-score-default-type 'e)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 'e)]
-       ["Fuzzy" (gnus-score-set-default 'gnus-score-default-type 'f)
-       :style radio
-       ;; :active (not (memq gnus-score-default-header '(l d)))
-       :selected (eq gnus-score-default-type 'f)]
-       ["Before date" (gnus-score-set-default 'gnus-score-default-type 'b)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'd))
-       :selected (eq gnus-score-default-type 'b)]
-       ["At date" (gnus-score-set-default 'gnus-score-default-type 'n)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'd))
-       :selected (eq gnus-score-default-type 'n)]
-       ["After date" (gnus-score-set-default 'gnus-score-default-type 'a)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'd))
-       :selected (eq gnus-score-default-type 'a)]
-       ["Less than number"
-       (gnus-score-set-default 'gnus-score-default-type '<)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'l))
-       :selected (eq gnus-score-default-type '<)]
-       ["Equal to number"
-       (gnus-score-set-default 'gnus-score-default-type '=)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'l))
-       :selected (eq gnus-score-default-type '=)]
-       ["Greater than number"
-       (gnus-score-set-default 'gnus-score-default-type '>)
-       :style radio
-       ;; :active (eq (gnus-score-default-header 'l))
-       :selected (eq gnus-score-default-type '>)])
-      ["Default fold" gnus-score-default-fold-toggle
-       :style toggle
-       :selected gnus-score-default-fold]
-      ("Default duration"
-       ["Ask" (gnus-score-set-default 'gnus-score-default-duration nil)
-       :style radio
-       :selected (null gnus-score-default-duration)]
-       ["Permanent"
-       (gnus-score-set-default 'gnus-score-default-duration 'p)
-       :style radio
-       :selected (eq gnus-score-default-duration 'p)]
-       ["Temporary"
-       (gnus-score-set-default 'gnus-score-default-duration 't)
-       :style radio
-       :selected (eq gnus-score-default-duration 't)]
-       ["Immediate"
-       (gnus-score-set-default 'gnus-score-default-duration 'i)
-       :style radio
-       :selected (eq gnus-score-default-duration 'i)]))
-
-    (easy-menu-define
-     gnus-summary-article-menu gnus-summary-mode-map ""
-     '("Article"
-       ("Hide"
-       ["All" gnus-article-hide t]
-       ["Headers" gnus-article-hide-headers t]
-       ["Signature" gnus-article-hide-signature t]
-       ["Citation" gnus-article-hide-citation t]
-       ["PGP" gnus-article-hide-pgp t]
-       ["Boring headers" gnus-article-hide-boring-headers t])
-       ("Highlight"
-       ["All" gnus-article-highlight t]
-       ["Headers" gnus-article-highlight-headers t]
-       ["Signature" gnus-article-highlight-signature t]
-       ["Citation" gnus-article-highlight-citation t])
-       ("Date"
-       ["Local" gnus-article-date-local t]
-       ["ISO8601" gnus-article-date-iso8601 t]
-       ["UT" gnus-article-date-ut t]
-       ["Original" gnus-article-date-original t]
-       ["Lapsed" gnus-article-date-lapsed t]
-       ["User-defined" gnus-article-date-user t])
-       ("Washing"
-       ("Remove Blanks"
-        ["Leading" gnus-article-strip-leading-blank-lines t]
-        ["Multiple" gnus-article-strip-multiple-blank-lines t]
-        ["Trailing" gnus-article-remove-trailing-blank-lines t]
-        ["All of the above" gnus-article-strip-blank-lines t]
-        ["All" gnus-article-strip-all-blank-lines t]
-        ["Leading space" gnus-article-strip-leading-space t])
-       ["Overstrike" gnus-article-treat-overstrike t]
-       ["Dumb quotes" gnus-article-treat-dumbquotes t]
-       ["Emphasis" gnus-article-emphasize t]
-       ["Word wrap" gnus-article-fill-cited-article t]
-       ["CR" gnus-article-remove-cr t]
-       ["Show X-Face" gnus-article-display-x-face t]
-       ["UnHTMLize" gnus-article-treat-html t]
-       ["Rot 13" gnus-summary-caesar-message t]
-       ["Unix pipe" gnus-summary-pipe-message t]
-       ["Add buttons" gnus-article-add-buttons t]
-       ["Add buttons to head" gnus-article-add-buttons-to-head t]
-       ["Stop page breaking" gnus-summary-stop-page-breaking t]
-       ["Toggle MIME" gnus-summary-toggle-mime t]
-       ["Verbose header" gnus-summary-verbose-headers t]
-       ["Toggle header" gnus-summary-toggle-header t])
-       ("Output"
-       ["Save in default format" gnus-summary-save-article t]
-       ["Save in file" gnus-summary-save-article-file t]
-       ["Save in Unix mail format" gnus-summary-save-article-mail t]
-       ["Save in MH folder" gnus-summary-save-article-folder t]
-       ["Save in VM folder" gnus-summary-save-article-vm t]
-       ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
-       ["Save body in file" gnus-summary-save-article-body-file t]
-       ["Pipe through a filter" gnus-summary-pipe-output t]
-       ["Add to SOUP packet" gnus-soup-add-article t]
-       ["Print" gnus-summary-print-article t])
-       ("Backend"
-       ["Respool article..." gnus-summary-respool-article t]
-       ["Move article..." gnus-summary-move-article
-        (gnus-check-backend-function
-         'request-move-article gnus-newsgroup-name)]
-       ["Copy article..." gnus-summary-copy-article t]
-       ["Crosspost article..." gnus-summary-crosspost-article
-        (gnus-check-backend-function
-         'request-replace-article gnus-newsgroup-name)]
-       ["Import file..." gnus-summary-import-article t]
-       ["Check if posted" gnus-summary-article-posted-p t]
-       ["Edit article" gnus-summary-edit-article
-        (not (gnus-group-read-only-p))]
-       ["Delete article" gnus-summary-delete-article
-        (gnus-check-backend-function
-         'request-expire-articles gnus-newsgroup-name)]
-       ["Query respool" gnus-summary-respool-query t]
-       ["Delete expirable articles" gnus-summary-expire-articles-now
-        (gnus-check-backend-function
-         'request-expire-articles gnus-newsgroup-name)])
-       ("Extract"
-       ["Uudecode" gnus-uu-decode-uu t]
-       ["Uudecode and save" gnus-uu-decode-uu-and-save t]
-       ["Unshar" gnus-uu-decode-unshar t]
-       ["Unshar and save" gnus-uu-decode-unshar-and-save t]
-       ["Save" gnus-uu-decode-save t]
-       ["Binhex" gnus-uu-decode-binhex t]
-       ["Postscript" gnus-uu-decode-postscript t])
-       ("Cache"
-       ["Enter article" gnus-cache-enter-article t]
-       ["Remove article" gnus-cache-remove-article t])
-       ["Select article buffer" gnus-summary-select-article-buffer t]
-       ["Enter digest buffer" gnus-summary-enter-digest-group t]
-       ["Isearch article..." gnus-summary-isearch-article t]
-       ["Beginning of the article" gnus-summary-beginning-of-article t]
-       ["End of the article" gnus-summary-end-of-article t]
-       ["Fetch parent of article" gnus-summary-refer-parent-article t]
-       ["Fetch referenced articles" gnus-summary-refer-references t]
-       ["Fetch current thread" gnus-summary-refer-thread t]
-       ["Fetch article with id..." gnus-summary-refer-article t]
-       ["Redisplay" gnus-summary-show-article t]))
+    ;; Define both the Article menu in the summary buffer and the equivalent
+    ;; Commands menu in the article buffer here for consistency.
+    (let ((innards
+           '(("Hide"
+              ["All" gnus-article-hide t]
+              ["Headers" gnus-article-hide-headers t]
+              ["Signature" gnus-article-hide-signature t]
+              ["Citation" gnus-article-hide-citation t]
+              ["PGP" gnus-article-hide-pgp t]
+              ["Boring headers" gnus-article-hide-boring-headers t])
+             ("Highlight"
+              ["All" gnus-article-highlight t]
+              ["Headers" gnus-article-highlight-headers t]
+              ["Signature" gnus-article-highlight-signature t]
+              ["Citation" gnus-article-highlight-citation t])
+             ("Date"
+              ["Local" gnus-article-date-local t]
+              ["ISO8601" gnus-article-date-iso8601 t]
+              ["UT" gnus-article-date-ut t]
+              ["Original" gnus-article-date-original t]
+              ["Lapsed" gnus-article-date-lapsed t]
+              ["User-defined" gnus-article-date-user t])
+             ("Washing"
+              ("Remove Blanks"
+               ["Leading" gnus-article-strip-leading-blank-lines t]
+               ["Multiple" gnus-article-strip-multiple-blank-lines t]
+               ["Trailing" gnus-article-remove-trailing-blank-lines t]
+               ["All of the above" gnus-article-strip-blank-lines t]
+               ["All" gnus-article-strip-all-blank-lines t]
+               ["Leading space" gnus-article-strip-leading-space t])
+              ["Overstrike" gnus-article-treat-overstrike t]
+              ["Dumb quotes" gnus-article-treat-dumbquotes t]
+              ["Emphasis" gnus-article-emphasize t]
+              ["Word wrap" gnus-article-fill-cited-article t]
+              ["CR" gnus-article-remove-cr t]
+              ["Show X-Face" gnus-article-display-x-face t]
+              ["UnHTMLize" gnus-article-treat-html t]
+              ["Rot 13" gnus-summary-caesar-message t]
+              ["Unix pipe" gnus-summary-pipe-message t]
+              ["Add buttons" gnus-article-add-buttons t]
+              ["Add buttons to head" gnus-article-add-buttons-to-head t]
+              ["Stop page breaking" gnus-summary-stop-page-breaking t]
+              ["Toggle MIME" gnus-summary-toggle-mime t]
+              ["Verbose header" gnus-summary-verbose-headers t]
+              ["Toggle header" gnus-summary-toggle-header t])
+             ("Output"
+              ["Save in default format" gnus-summary-save-article t]
+              ["Save in file" gnus-summary-save-article-file t]
+              ["Save in Unix mail format" gnus-summary-save-article-mail t]
+              ["Save in MH folder" gnus-summary-save-article-folder t]
+              ["Save in VM folder" gnus-summary-save-article-vm t]
+              ["Save in RMAIL mbox" gnus-summary-save-article-rmail t]
+              ["Save body in file" gnus-summary-save-article-body-file t]
+              ["Pipe through a filter" gnus-summary-pipe-output t]
+              ["Add to SOUP packet" gnus-soup-add-article t]
+              ["Print" gnus-summary-print-article t])
+             ("Backend"
+              ["Respool article..." gnus-summary-respool-article t]
+              ["Move article..." gnus-summary-move-article
+               (gnus-check-backend-function
+                'request-move-article gnus-newsgroup-name)]
+              ["Copy article..." gnus-summary-copy-article t]
+              ["Crosspost article..." gnus-summary-crosspost-article
+               (gnus-check-backend-function
+                'request-replace-article gnus-newsgroup-name)]
+              ["Import file..." gnus-summary-import-article t]
+              ["Check if posted" gnus-summary-article-posted-p t]
+              ["Edit article" gnus-summary-edit-article
+               (not (gnus-group-read-only-p))]
+              ["Delete article" gnus-summary-delete-article
+               (gnus-check-backend-function
+                'request-expire-articles gnus-newsgroup-name)]
+              ["Query respool" gnus-summary-respool-query t]
+             ["Trace respool" gnus-summary-respool-trace t]
+              ["Delete expirable articles" gnus-summary-expire-articles-now
+               (gnus-check-backend-function
+                'request-expire-articles gnus-newsgroup-name)])
+             ("Extract"
+              ["Uudecode" gnus-uu-decode-uu t]
+              ["Uudecode and save" gnus-uu-decode-uu-and-save t]
+              ["Unshar" gnus-uu-decode-unshar t]
+              ["Unshar and save" gnus-uu-decode-unshar-and-save t]
+              ["Save" gnus-uu-decode-save t]
+              ["Binhex" gnus-uu-decode-binhex t]
+              ["Postscript" gnus-uu-decode-postscript t])
+             ("Cache"
+              ["Enter article" gnus-cache-enter-article t]
+              ["Remove article" gnus-cache-remove-article t])
+             ["Select article buffer" gnus-summary-select-article-buffer t]
+             ["Enter digest buffer" gnus-summary-enter-digest-group t]
+             ["Isearch article..." gnus-summary-isearch-article t]
+             ["Beginning of the article" gnus-summary-beginning-of-article t]
+             ["End of the article" gnus-summary-end-of-article t]
+             ["Fetch parent of article" gnus-summary-refer-parent-article t]
+             ["Fetch referenced articles" gnus-summary-refer-references t]
+             ["Fetch current thread" gnus-summary-refer-thread t]
+             ["Fetch article with id..." gnus-summary-refer-article t]
+             ["Redisplay" gnus-summary-show-article t])))
+      (easy-menu-define
+       gnus-summary-article-menu gnus-summary-mode-map ""
+       (cons "Article" innards))
+
+      (easy-menu-define
+       gnus-article-commands-menu gnus-article-mode-map ""
+       (cons "Commands" innards)))
 
     (easy-menu-define
      gnus-summary-thread-menu gnus-summary-mode-map ""
 
     (easy-menu-define
      gnus-summary-thread-menu gnus-summary-mode-map ""
@@ -1721,8 +1627,8 @@ increase the score of each group you read."
        ["Wide reply and yank" gnus-summary-wide-reply-with-original t]
        ["Mail forward" gnus-summary-mail-forward t]
        ["Post forward" gnus-summary-post-forward t]
        ["Wide reply and yank" gnus-summary-wide-reply-with-original t]
        ["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]
+       ["Digest and mail" gnus-summary-mail-digest t]
+       ["Digest and post" gnus-summary-post-digest 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]
        ["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]
@@ -1777,7 +1683,9 @@ increase the score of each group you read."
        ["Mark above" gnus-uu-mark-over t]
        ["Mark series" gnus-uu-mark-series t]
        ["Mark region" gnus-uu-mark-region 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]
        ["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 all" gnus-uu-mark-all t]
        ["Mark buffer" gnus-uu-mark-buffer t]
        ["Mark sparse" gnus-uu-mark-sparse t]
@@ -1837,9 +1745,10 @@ increase the score of each group you read."
        ["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]
        ["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]
+       ["Send a bug report" gnus-bug t]
        ("Exit"
        ["Catchup and exit" gnus-summary-catchup-and-exit t]
        ("Exit"
        ["Catchup and exit" gnus-summary-catchup-and-exit t]
-       ["Catchup all and exit" gnus-summary-catchup-and-exit t]
+       ["Catchup all and exit" gnus-summary-catchup-all-and-exit t]
        ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
        ["Exit group" gnus-summary-exit t]
        ["Exit group without updating" gnus-summary-exit-no-update t]
        ["Catchup and goto next" gnus-summary-catchup-and-goto-next-group t]
        ["Exit group" gnus-summary-exit t]
        ["Exit group without updating" gnus-summary-exit-no-update t]
@@ -2078,21 +1987,26 @@ The following commands are available:
   (when list
     (let ((data (and after-article (gnus-data-find-list after-article)))
          (ilist list))
   (when list
     (let ((data (and after-article (gnus-data-find-list after-article)))
          (ilist list))
-      (or data (not after-article) (error "No such article: %d" after-article))
-      ;; Find the last element in the list to be spliced into the main
-      ;; list.
-      (while (cdr list)
-       (setq list (cdr list)))
-      (if (not data)
-         (progn
-           (setcdr list gnus-newsgroup-data)
-           (setq gnus-newsgroup-data ilist)
+      (if (not (or data
+                  after-article))
+         (let ((odata gnus-newsgroup-data))
+           (setq gnus-newsgroup-data (nconc list gnus-newsgroup-data))
            (when offset
            (when offset
-             (gnus-data-update-list (cdr list) offset)))
-       (setcdr list (cdr data))
-       (setcdr data ilist)
-       (when offset
-         (gnus-data-update-list (cdr list) offset)))
+             (gnus-data-update-list odata offset)))
+       ;; Find the last element in the list to be spliced into the main
+       ;; list.
+       (while (cdr list)
+         (setq list (cdr list)))
+       (if (not data)
+           (progn
+             (setcdr list gnus-newsgroup-data)
+             (setq gnus-newsgroup-data ilist)
+             (when offset
+               (gnus-data-update-list (cdr list) offset)))
+         (setcdr list (cdr data))
+         (setcdr data ilist)
+         (when offset
+           (gnus-data-update-list (cdr list) offset))))
       (setq gnus-newsgroup-data-reverse nil))))
 
 (defun gnus-data-remove (article &optional offset)
       (setq gnus-newsgroup-data-reverse nil))))
 
 (defun gnus-data-remove (article &optional offset)
@@ -2121,20 +2035,25 @@ The following commands are available:
 
 (defun gnus-data-update-list (data offset)
   "Add OFFSET to the POS of all data entries in DATA."
 
 (defun gnus-data-update-list (data offset)
   "Add OFFSET to the POS of all data entries in DATA."
+  (setq gnus-newsgroup-data-reverse nil)
   (while data
     (setcar (nthcdr 2 (car data)) (+ offset (nth 2 (car data))))
     (setq data (cdr data))))
 
 (defun gnus-data-compute-positions ()
   "Compute the positions of all articles."
   (while data
     (setcar (nthcdr 2 (car data)) (+ offset (nth 2 (car data))))
     (setq data (cdr data))))
 
 (defun gnus-data-compute-positions ()
   "Compute the positions of all articles."
-  (let ((data gnus-newsgroup-data)
-       pos)
-    (while data
-      (when (setq pos (text-property-any
-                      (point-min) (point-max)
-                      'gnus-number (gnus-data-number (car data))))
-       (gnus-data-set-pos (car data) (+ pos 3)))
-      (setq data (cdr data)))))
+  (setq gnus-newsgroup-data-reverse nil)
+  (let ((data gnus-newsgroup-data))
+    (save-excursion
+      (gnus-save-hidden-threads
+       (gnus-summary-show-all-threads)
+       (goto-char (point-min))
+       (while data
+         (while (get-text-property (point) 'gnus-intangible)
+           (forward-line 1))
+         (gnus-data-set-pos (car data) (+ (point) 3))
+         (setq data (cdr data))
+         (forward-line 1))))))
 
 (defun gnus-summary-article-pseudo-p (article)
   "Say whether this article is a pseudo article or not."
 
 (defun gnus-summary-article-pseudo-p (article)
   "Say whether this article is a pseudo article or not."
@@ -2363,8 +2282,7 @@ marks of articles."
          (setq gnus-summary-buffer (current-buffer))
          (not gnus-newsgroup-prepared))
       ;; Fix by Sudish Joseph <joseph@cis.ohio-state.edu>
          (setq gnus-summary-buffer (current-buffer))
          (not gnus-newsgroup-prepared))
       ;; Fix by Sudish Joseph <joseph@cis.ohio-state.edu>
-      (setq gnus-summary-buffer (set-buffer (get-buffer-create buffer)))
-      (gnus-add-current-to-buffer-list)
+      (setq gnus-summary-buffer (set-buffer (gnus-get-buffer-create buffer)))
       (gnus-summary-mode group)
       (when gnus-carpal
        (gnus-carpal-setup-buffer 'summary))
       (gnus-summary-mode group)
       (when gnus-carpal
        (gnus-carpal-setup-buffer 'summary))
@@ -2447,7 +2365,7 @@ marks of articles."
          (gnus-score-over-mark 130)
          (gnus-download-mark 131)
          (spec gnus-summary-line-format-spec)
          (gnus-score-over-mark 130)
          (gnus-download-mark 131)
          (spec gnus-summary-line-format-spec)
-         thread gnus-visual pos)
+         gnus-visual pos)
       (save-excursion
        (gnus-set-work-buffer)
        (let ((gnus-summary-line-format-spec spec)
       (save-excursion
        (gnus-set-work-buffer)
        (let ((gnus-summary-line-format-spec spec)
@@ -2523,7 +2441,7 @@ marks of articles."
       (setq gnus-tmp-name gnus-tmp-from))
     (unless (numberp gnus-tmp-lines)
       (setq gnus-tmp-lines 0))
       (setq gnus-tmp-name gnus-tmp-from))
     (unless (numberp gnus-tmp-lines)
       (setq gnus-tmp-lines 0))
-    (gnus-put-text-property
+    (gnus-put-text-property-excluding-characters-with-faces
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
      'gnus-number gnus-tmp-number)
      (point)
      (progn (eval gnus-summary-line-format-spec) (point))
      'gnus-number gnus-tmp-number)
@@ -2603,12 +2521,14 @@ the thread are to be displayed."
       (and (consp elem)                        ; Has to be a cons.
           (consp (cdr elem))           ; The cdr has to be a list.
           (symbolp (car elem))         ; Has to be a symbol in there.
       (and (consp elem)                        ; Has to be a cons.
           (consp (cdr elem))           ; The cdr has to be a list.
           (symbolp (car elem))         ; Has to be a symbol in there.
+          (not (memq (car elem) '(quit-config))) ; Ignore quit-config.
           (ignore-errors               ; So we set it.
             (make-local-variable (car elem))
             (set (car elem) (eval (nth 1 elem))))))))
 
 (defun gnus-summary-read-group (group &optional show-all no-article
           (ignore-errors               ; So we set it.
             (make-local-variable (car elem))
             (set (car elem) (eval (nth 1 elem))))))))
 
 (defun gnus-summary-read-group (group &optional show-all no-article
-                                     kill-buffer no-display backward)
+                                     kill-buffer no-display backward
+                                     select-articles)
   "Start reading news in newsgroup GROUP.
 If SHOW-ALL is non-nil, already read articles are also listed.
 If NO-ARTICLE is non-nil, no article is selected initially.
   "Start reading news in newsgroup GROUP.
 If SHOW-ALL is non-nil, already read articles are also listed.
 If NO-ARTICLE is non-nil, no article is selected initially.
@@ -2619,8 +2539,10 @@ If NO-DISPLAY, don't generate a summary buffer."
                            (let ((gnus-auto-select-next nil))
                              (or (gnus-summary-read-group-1
                                   group show-all no-article
                            (let ((gnus-auto-select-next nil))
                              (or (gnus-summary-read-group-1
                                   group show-all no-article
-                                  kill-buffer no-display)
-                                 (setq show-all nil)))))
+                                  kill-buffer no-display
+                                  select-articles)
+                                 (setq show-all nil
+                                  select-articles nil)))))
                (eq gnus-auto-select-next 'quietly))
       (set-buffer gnus-group-buffer)
       ;; The entry function called above goes to the next
                (eq gnus-auto-select-next 'quietly))
       (set-buffer gnus-group-buffer)
       ;; The entry function called above goes to the next
@@ -2634,7 +2556,8 @@ If NO-DISPLAY, don't generate a summary buffer."
     result))
 
 (defun gnus-summary-read-group-1 (group show-all no-article
     result))
 
 (defun gnus-summary-read-group-1 (group show-all no-article
-                                       kill-buffer no-display)
+                                       kill-buffer no-display
+                                       &optional select-articles)
   ;; Killed foreign groups can't be entered.
   (when (and (not (gnus-group-native-p group))
             (not (gnus-gethash group gnus-newsrc-hashtb)))
   ;; Killed foreign groups can't be entered.
   (when (and (not (gnus-group-native-p group))
             (not (gnus-gethash group gnus-newsrc-hashtb)))
@@ -2642,7 +2565,8 @@ If NO-DISPLAY, don't generate a summary buffer."
   (gnus-message 5 "Retrieving newsgroup: %s..." group)
   (let* ((new-group (gnus-summary-setup-buffer group))
         (quit-config (gnus-group-quit-config group))
   (gnus-message 5 "Retrieving newsgroup: %s..." group)
   (let* ((new-group (gnus-summary-setup-buffer group))
         (quit-config (gnus-group-quit-config group))
-        (did-select (and new-group (gnus-select-newsgroup group show-all))))
+        (did-select (and new-group (gnus-select-newsgroup
+                                    group show-all select-articles))))
     (cond
      ;; This summary buffer exists already, so we just select it.
      ((not new-group)
     (cond
      ;; This summary buffer exists already, so we just select it.
      ((not new-group)
@@ -2965,11 +2889,89 @@ If NO-DISPLAY, don't generate a summary buffer."
              gnus-newsgroup-dependencies)))
     threads))
 
              gnus-newsgroup-dependencies)))
     threads))
 
+;; Build the thread tree.
+(defun gnus-dependencies-add-header (header dependencies force-new)
+  "Enter HEADER into the DEPENDENCIES table if it is not already there.
+
+If FORCE-NEW is not nil, enter HEADER into the DEPENDENCIES table even
+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.
+
+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)
+    ;; Enter this `header' in the `dependencies' table.
+    (cond
+     ((not id-dep)
+      (setq header nil))
+     ;; The first two cases do the normal part: enter a new `header'
+     ;; in the `dependencies' table.
+     ((not (boundp id-dep))
+      (set id-dep (list header)))
+     ((null (car (symbol-value id-dep)))
+      (setcar (symbol-value id-dep) header))
+
+     ;; From here the `header' was already present in the
+     ;; `dependencies' table.
+     (force-new
+      ;; Overrides an existing entry;
+      ;; just set the header part of the entry.
+      (setcar (symbol-value id-dep) header))
+
+     ;; Renames the existing `header' to a unique Message-ID.
+     ((not gnus-summary-ignore-duplicates)
+      ;; An article with this Message-ID has already been seen.
+      ;; We rename the Message-ID.
+      (set (setq id-dep (intern (setq id (nnmail-message-id)) dependencies))
+          (list header))
+      (mail-header-set-id header id))
+
+     ;; The last case ignores an existing entry, except it adds any
+     ;; additional Xrefs (in case the two articles came from different
+     ;; servers.
+     ;; Also sets `header' to `nil' meaning that the `dependencies'
+     ;; table was *not* modified.
+     (t
+      (mail-header-set-xref
+       (car (symbol-value id-dep))
+       (concat (or (mail-header-xref (car (symbol-value id-dep)))
+                  "")
+              (or (mail-header-xref header) "")))
+      (setq header nil)))
+
+    (when header
+      ;; First check if 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))
+                 (boundp ref-dep)
+                 (setq ref-header (car (symbol-value ref-dep))))
+       (if (string= id ref)
+           ;; Yuk!  This is a reference loop.  Make the article be a
+           ;; root article.
+           (progn
+             (mail-header-set-references (car (symbol-value id-dep)) "none")
+             (setq ref nil))
+         (setq ref (gnus-parent-id (mail-header-references ref-header)))))
+      (setq ref (gnus-parent-id (mail-header-references header)))
+      (setq ref-dep (intern (or ref "none") dependencies))
+      (if (boundp ref-dep)
+         (setcdr (symbol-value ref-dep)
+                 (nconc (cdr (symbol-value ref-dep))
+                        (list (symbol-value id-dep))))
+       (set ref-dep (list nil (symbol-value id-dep)))))
+    header))
+
 (defun gnus-build-sparse-threads ()
   (let ((headers gnus-newsgroup-headers)
 (defun gnus-build-sparse-threads ()
   (let ((headers gnus-newsgroup-headers)
-       (deps gnus-newsgroup-dependencies)
+       (gnus-summary-ignore-duplicates t)
        header references generation relations
        header references generation relations
-       cthread subject child end pthread relation new-child children)
+       subject child end new-child date)
     ;; First we create an alist of generations/relations, where
     ;; generations is how much we trust the relation, and the relation
     ;; is parent/child.
     ;; First we create an alist of generations/relations, where
     ;; generations is how much we trust the relation, and the relation
     ;; is parent/child.
@@ -2981,55 +2983,37 @@ If NO-DISPLAY, don't generate a summary buffer."
                   (not (string= references "")))
          (insert references)
          (setq child (mail-header-id header)
                   (not (string= references "")))
          (insert references)
          (setq child (mail-header-id header)
-               subject (mail-header-subject header))
-         (setq generation 0)
+               subject (mail-header-subject header)
+               date (mail-header-date header)
+               generation 0)
          (while (search-backward ">" nil t)
            (setq end (1+ (point)))
            (when (search-backward "<" nil t)
          (while (search-backward ">" nil t)
            (setq end (1+ (point)))
            (when (search-backward "<" nil t)
-             ;; This is a rather weak for of loop-checking, but if
-             ;; an article contains the same Message-ID twice in
-             ;; the References header, this will catch it.  I haven't
-             ;; considered other forms of thread loop preventions,
-             ;; though -- I think one should probably go through
-             ;; the entire thread after building it and break
-             ;; any loops that are found.
-             (unless (member (setq new-child (buffer-substring (point) end))
-                              children)
-               (push (list (incf generation)
-                           child (setq child new-child)
-                           subject)
-                     relations)
-               (push child children))))
-         (push (list (1+ generation) child nil subject) relations)
+             (setq new-child (buffer-substring (point) end))
+             (push (list (incf generation)
+                         child (setq child new-child)
+                         subject date)
+                   relations)))
+         (when child
+           (push (list (1+ generation) child nil subject) relations))
          (erase-buffer)))
       (kill-buffer (current-buffer)))
     ;; Sort over trustworthiness.
          (erase-buffer)))
       (kill-buffer (current-buffer)))
     ;; Sort over trustworthiness.
-    (setq relations (sort relations 'car-less-than-car))
-    (while (setq relation (pop relations))
-      (when (if (boundp (setq cthread (intern (cadr relation) deps)))
-               (unless (car (symbol-value cthread))
-                 ;; Make this article the parent of these threads.
-                 (setcar (symbol-value cthread)
-                         (vector gnus-reffed-article-number
-                                 (cadddr relation)
-                                 "" ""
-                                 (cadr relation)
-                                 (or (caddr relation) "") 0 0 "")))
-             (set cthread (list (vector gnus-reffed-article-number
-                                        (cadddr relation)
-                                        "" "" (cadr relation)
-                                        (or (caddr relation) "") 0 0 ""))))
-       (push gnus-reffed-article-number gnus-newsgroup-limit)
-       (push gnus-reffed-article-number gnus-newsgroup-sparse)
-       (push (cons gnus-reffed-article-number gnus-sparse-mark)
-             gnus-newsgroup-reads)
-       (decf gnus-reffed-article-number)
-       ;; Make this new thread the child of its parent.
-       (if (boundp (setq pthread (intern (or (caddr relation) "none") deps)))
-           (setcdr (symbol-value pthread)
-                   (nconc (cdr (symbol-value pthread))
-                          (list (symbol-value cthread))))
-         (set pthread (list nil (symbol-value cthread))))))
+    (mapcar
+     (lambda (relation)
+       (when (gnus-dependencies-add-header
+             (make-full-mail-header
+              gnus-reffed-article-number
+              (nth 3 relation) "" (or (nth 4 relation) "")
+              (nth 1 relation)
+              (or (nth 2 relation) "") 0 0 "")
+             gnus-newsgroup-dependencies nil)
+        (push gnus-reffed-article-number gnus-newsgroup-limit)
+        (push gnus-reffed-article-number gnus-newsgroup-sparse)
+        (push (cons gnus-reffed-article-number gnus-sparse-mark)
+              gnus-newsgroup-reads)
+        (decf gnus-reffed-article-number)))
+     (sort relations 'car-less-than-car))
     (gnus-message 7 "Making sparse threads...done")))
 
 (defun gnus-build-old-threads ()
     (gnus-message 7 "Making sparse threads...done")))
 
 (defun gnus-build-old-threads ()
@@ -3048,11 +3032,64 @@ If NO-DISPLAY, don't generate a summary buffer."
               (setq heads (cdr heads))
             (setq id (symbol-name refs))
             (while (and (setq id (gnus-build-get-header id))
               (setq heads (cdr heads))
             (setq id (symbol-name refs))
             (while (and (setq id (gnus-build-get-header id))
-                        (not (car (gnus-gethash
-                                   id gnus-newsgroup-dependencies)))))
+                        (not (car (gnus-id-to-thread id)))))
             (setq heads nil)))))
      gnus-newsgroup-dependencies)))
 
             (setq heads nil)))))
      gnus-newsgroup-dependencies)))
 
+;; The following macros and functions were written by Felix Lee
+;; <flee@cse.psu.edu>.
+
+(defmacro gnus-nov-read-integer ()
+  '(prog1
+       (if (= (following-char) ?\t)
+          0
+        (let ((num (ignore-errors (read buffer))))
+          (if (numberp num) num 0)))
+     (unless (eobp)
+       (search-forward "\t" eol 'move))))
+
+(defmacro gnus-nov-skip-field ()
+  '(search-forward "\t" eol 'move))
+
+(defmacro gnus-nov-field ()
+  '(buffer-substring (point) (if (gnus-nov-skip-field) (1- (point)) eol)))
+
+;; This function has to be called with point after the article number
+;; on the beginning of the line.
+(defsubst gnus-nov-parse-line (number dependencies &optional force-new)
+  (let ((eol (gnus-point-at-eol))
+       (buffer (current-buffer))
+       header)
+
+    ;; overview: [num subject from date id refs chars lines misc]
+    (unwind-protect
+       (progn
+         (narrow-to-region (point) eol)
+         (unless (eobp)
+           (forward-char))
+
+         (setq header
+               (make-full-mail-header
+                number                 ; number
+                (funcall
+                 gnus-unstructured-field-decoder (gnus-nov-field)) ; subject
+                (funcall
+                 gnus-structured-field-decoder (gnus-nov-field)) ; from
+                (gnus-nov-field)       ; date
+                (or (gnus-nov-field)
+                    (nnheader-generate-fake-message-id)) ; id
+                (gnus-nov-field)       ; refs
+                (gnus-nov-read-integer) ; chars
+                (gnus-nov-read-integer) ; lines
+                (unless (= (following-char) ?\n)
+                  (gnus-nov-field))))) ; misc
+
+      (widen))
+
+    (when gnus-alter-header-function
+      (funcall gnus-alter-header-function header))
+    (gnus-dependencies-add-header header dependencies force-new)))
+
 (defun gnus-build-get-header (id)
   ;; Look through the buffer of NOV lines and find the header to
   ;; ID.  Enter this line into the dependencies hash table, and return
 (defun gnus-build-get-header (id)
   ;; Look through the buffer of NOV lines and find the header to
   ;; ID.  Enter this line into the dependencies hash table, and return
@@ -3090,26 +3127,29 @@ If NO-DISPLAY, don't generate a summary buffer."
 
 (defun gnus-build-all-threads ()
   "Read all the headers."
 
 (defun gnus-build-all-threads ()
   "Read all the headers."
-  (let ((deps gnus-newsgroup-dependencies)
-       (gnus-summary-ignore-duplicates t)
-       found header article)
+  (let ((gnus-summary-ignore-duplicates t)
+       (dependencies gnus-newsgroup-dependencies)
+       header article)
     (save-excursion
       (set-buffer nntp-server-buffer)
       (let ((case-fold-search nil))
        (goto-char (point-min))
        (while (not (eobp))
          (ignore-errors
     (save-excursion
       (set-buffer nntp-server-buffer)
       (let ((case-fold-search nil))
        (goto-char (point-min))
        (while (not (eobp))
          (ignore-errors
-           (setq article (read (current-buffer)))
-           (setq header (gnus-nov-parse-line article deps)))
+           (setq article (read (current-buffer))
+                 header (gnus-nov-parse-line
+                         article dependencies)))
          (when header
          (when header
-           (push header gnus-newsgroup-headers)
-           (if (memq (setq article (mail-header-number header))
-                     gnus-newsgroup-unselected)
-               (progn
-                 (push article gnus-newsgroup-unreads)
-                 (setq gnus-newsgroup-unselected
-                       (delq article gnus-newsgroup-unselected)))
-             (push article gnus-newsgroup-ancient))
+           (save-excursion
+             (set-buffer gnus-summary-buffer)
+             (push header gnus-newsgroup-headers)
+             (if (memq (setq article (mail-header-number header))
+                       gnus-newsgroup-unselected)
+                 (progn
+                   (push article gnus-newsgroup-unreads)
+                   (setq gnus-newsgroup-unselected
+                         (delq article gnus-newsgroup-unselected)))
+               (push article gnus-newsgroup-ancient)))
            (forward-line 1)))))))
 
 (defun gnus-summary-update-article-line (article header)
            (forward-line 1)))))))
 
 (defun gnus-summary-update-article-line (article header)
@@ -3157,7 +3197,7 @@ If NO-DISPLAY, don't generate a summary buffer."
 (defun gnus-summary-update-article (article &optional iheader)
   "Update ARTICLE in the summary buffer."
   (set-buffer gnus-summary-buffer)
 (defun gnus-summary-update-article (article &optional iheader)
   "Update ARTICLE in the summary buffer."
   (set-buffer gnus-summary-buffer)
-  (let* ((header (or iheader (gnus-summary-article-header article)))
+  (let* ((header (gnus-summary-article-header article))
         (id (mail-header-id header))
         (data (gnus-data-find article))
         (thread (gnus-id-to-thread id))
         (id (mail-header-id header))
         (data (gnus-data-find article))
         (thread (gnus-id-to-thread id))
@@ -3170,23 +3210,21 @@ If NO-DISPLAY, don't generate a summary buffer."
                  references))
               "none")))
         (buffer-read-only nil)
                  references))
               "none")))
         (buffer-read-only nil)
-        (old (car thread))
-        (number (mail-header-number header))
-        pos)
+        (old (car thread)))
     (when thread
     (when thread
-      ;; !!! Should this be in or not?
       (unless iheader
       (unless iheader
-       (setcar thread nil))
-      (when parent
-       (delq thread parent))
-      (if (gnus-summary-insert-subject id header iheader)
+       (setcar thread nil)
+       (when parent
+         (delq thread parent)))
+      (if (gnus-summary-insert-subject id header)
          ;; Set the (possibly) new article number in the data structure.
          (gnus-data-set-number data (gnus-id-to-article id))
        (setcar thread old)
        nil))))
 
          ;; Set the (possibly) new article number in the data structure.
          (gnus-data-set-number data (gnus-id-to-article id))
        (setcar thread old)
        nil))))
 
-(defun gnus-rebuild-thread (id)
-  "Rebuild the thread containing ID."
+(defun gnus-rebuild-thread (id &optional line)
+  "Rebuild the thread containing ID.
+If LINE, insert the rebuilt thread starting on line LINE."
   (let ((buffer-read-only nil)
        old-pos current thread data)
     (if (not gnus-show-threads)
   (let ((buffer-read-only nil)
        old-pos current thread data)
     (if (not gnus-show-threads)
@@ -3216,6 +3254,9 @@ If NO-DISPLAY, don't generate a summary buffer."
          (setq thread (cons subject (gnus-sort-threads roots))))))
     (let (threads)
       ;; We then insert this thread into the summary buffer.
          (setq thread (cons subject (gnus-sort-threads roots))))))
     (let (threads)
       ;; We then insert this thread into the summary buffer.
+      (when line
+       (goto-char (point-min))
+       (forward-line (1- line)))
       (let (gnus-newsgroup-data gnus-newsgroup-threads)
        (if gnus-show-threads
            (gnus-summary-prepare-threads (gnus-cut-threads (list thread)))
       (let (gnus-newsgroup-data gnus-newsgroup-threads)
        (if gnus-show-threads
            (gnus-summary-prepare-threads (gnus-cut-threads (list thread)))
@@ -3223,8 +3264,15 @@ If NO-DISPLAY, don't generate a summary buffer."
        (setq data (nreverse gnus-newsgroup-data))
        (setq threads gnus-newsgroup-threads))
       ;; We splice the new data into the data structure.
        (setq data (nreverse gnus-newsgroup-data))
        (setq threads gnus-newsgroup-threads))
       ;; We splice the new data into the data structure.
-      (gnus-data-enter-list current data (- (point) old-pos))
-      (setq gnus-newsgroup-threads (nconc threads gnus-newsgroup-threads)))))
+      ;;!!! This is kinda bogus.  We assume that in LINE is non-nil,
+      ;;!!! then we want to insert at the beginning of the buffer.
+      ;;!!! That happens to be true with Gnus now, but that may
+      ;;!!! change in the future.  Perhaps.
+      (gnus-data-enter-list
+       (if line nil current) data (- (point) old-pos))
+      (setq gnus-newsgroup-threads
+           (nconc threads gnus-newsgroup-threads))
+      (gnus-data-compute-positions))))
 
 (defun gnus-number-to-header (number)
   "Return the header for article NUMBER."
 
 (defun gnus-number-to-header (number)
   "Return the header for article NUMBER."
@@ -3235,19 +3283,23 @@ If NO-DISPLAY, don't generate a summary buffer."
     (when headers
       (car headers))))
 
     (when headers
       (car headers))))
 
-(defun gnus-parent-headers (headers &optional generation)
+(defun gnus-parent-headers (in-headers &optional generation)
   "Return the headers of the GENERATIONeth parent of HEADERS."
   (unless generation
     (setq generation 1))
   (let ((parent t)
   "Return the headers of the GENERATIONeth parent of HEADERS."
   (unless generation
     (setq generation 1))
   (let ((parent t)
+       (headers in-headers)
        references)
        references)
-    (while (and parent headers (not (zerop generation)))
-      (setq references (mail-header-references headers))
-      (when (and references
-                (setq parent (gnus-parent-id references))
-                (setq headers (car (gnus-id-to-thread parent))))
-       (decf generation)))
-    headers))
+    (while (and parent
+               (not (zerop generation))
+               (setq references (mail-header-references headers)))
+      (setq headers (if (and references
+                            (setq parent (gnus-parent-id references)))
+                       (car (gnus-id-to-thread parent))
+                     nil))
+      (decf generation))
+    (and (not (eq headers in-headers))
+        headers)))
 
 (defun gnus-id-to-thread (id)
   "Return the (sub-)thread where ID appears."
 
 (defun gnus-id-to-thread (id)
   "Return the (sub-)thread where ID appears."
@@ -3282,8 +3334,7 @@ If NO-DISPLAY, don't generate a summary buffer."
 (defun gnus-root-id (id)
   "Return the id of the root of the thread where ID appears."
   (let (last-id prev)
 (defun gnus-root-id (id)
   "Return the id of the root of the thread where ID appears."
   (let (last-id prev)
-    (while (and id (setq prev (car (gnus-gethash
-                                   id gnus-newsgroup-dependencies))))
+    (while (and id (setq prev (car (gnus-id-to-thread id))))
       (setq last-id id
            id (gnus-parent-id (mail-header-references prev))))
     last-id))
       (setq last-id id
            id (gnus-parent-id (mail-header-references prev))))
     last-id))
@@ -3295,12 +3346,10 @@ If NO-DISPLAY, don't generate a summary buffer."
 
 (defun gnus-remove-thread (id &optional dont-remove)
   "Remove the thread that has ID in it."
 
 (defun gnus-remove-thread (id &optional dont-remove)
   "Remove the thread that has ID in it."
-  (let ((dep gnus-newsgroup-dependencies)
-       headers thread last-id)
+  (let (headers thread last-id)
     ;; First go up in this thread until we find the root.
     ;; First go up in this thread until we find the root.
-    (setq last-id (gnus-root-id id))
-    (setq headers (list (car (gnus-id-to-thread last-id))
-                       (caadr (gnus-id-to-thread last-id))))
+    (setq last-id (gnus-root-id id)
+         headers (message-flatten-list (gnus-id-to-thread last-id)))
     ;; We have now found the real root of this thread. It might have
     ;; been gathered into some loose thread, so we have to search
     ;; through the threads to find the thread we wanted.
     ;; We have now found the real root of this thread. It might have
     ;; been gathered into some loose thread, so we have to search
     ;; through the threads to find the thread we wanted.
@@ -3329,7 +3378,7 @@ If NO-DISPLAY, don't generate a summary buffer."
       (if thread
          (unless dont-remove
            (setq gnus-newsgroup-threads (delq thread gnus-newsgroup-threads)))
       (if thread
          (unless dont-remove
            (setq gnus-newsgroup-threads (delq thread gnus-newsgroup-threads)))
-       (setq thread (gnus-gethash last-id dep)))
+       (setq thread (gnus-id-to-thread last-id)))
       (when thread
        (prog1
            thread                      ; We return this thread.
       (when thread
        (prog1
            thread                      ; We return this thread.
@@ -3339,12 +3388,18 @@ If NO-DISPLAY, don't generate a summary buffer."
                  ;; If we use dummy roots, then we have to remove the
                  ;; dummy root as well.
                  (when (eq gnus-summary-make-false-root 'dummy)
                  ;; If we use dummy roots, then we have to remove the
                  ;; dummy root as well.
                  (when (eq gnus-summary-make-false-root 'dummy)
+                   ;; We go to the dummy root by going to
+                   ;; the first sub-"thread", and then one line up.
+                   (gnus-summary-goto-article
+                    (mail-header-number (caadr thread)))
+                   (forward-line -1)
                    (gnus-delete-line)
                    (gnus-data-compute-positions))
                  (setq thread (cdr thread))
                  (while thread
                    (gnus-remove-thread-1 (car thread))
                    (setq thread (cdr thread))))
                    (gnus-delete-line)
                    (gnus-data-compute-positions))
                  (setq thread (cdr thread))
                  (while thread
                    (gnus-remove-thread-1 (car thread))
                    (setq thread (cdr thread))))
+             (gnus-summary-show-all-threads)
              (gnus-remove-thread-1 thread))))))))
 
 (defun gnus-remove-thread-1 (thread)
              (gnus-remove-thread-1 thread))))))))
 
 (defun gnus-remove-thread-1 (thread)
@@ -3367,10 +3422,10 @@ If NO-DISPLAY, don't generate a summary buffer."
   "Sort THREADS."
   (if (not gnus-thread-sort-functions)
       threads
   "Sort THREADS."
   (if (not gnus-thread-sort-functions)
       threads
-    (gnus-message 7 "Sorting threads...")
+    (gnus-message 8 "Sorting threads...")
     (prog1
        (sort threads (gnus-make-sort-function gnus-thread-sort-functions))
     (prog1
        (sort threads (gnus-make-sort-function gnus-thread-sort-functions))
-      (gnus-message 7 "Sorting threads...done"))))
+      (gnus-message 8 "Sorting threads...done"))))
 
 (defun gnus-sort-articles (articles)
   "Sort ARTICLES."
 
 (defun gnus-sort-articles (articles)
   "Sort ARTICLES."
@@ -3489,8 +3544,7 @@ Unscored articles will be counted as having a score of zero."
   (apply gnus-thread-score-function
         (or (append
              (mapcar 'gnus-thread-total-score
   (apply gnus-thread-score-function
         (or (append
              (mapcar 'gnus-thread-total-score
-                     (cdr (gnus-gethash (mail-header-id root)
-                                        gnus-newsgroup-dependencies)))
+                     (cdr (gnus-id-to-thread (mail-header-id root))))
              (when (> (mail-header-number root) 0)
                (list (or (cdr (assq (mail-header-number root)
                                     gnus-newsgroup-scored))
              (when (> (mail-header-number root) 0)
                (list (or (cdr (assq (mail-header-number root)
                                     gnus-newsgroup-scored))
@@ -3651,7 +3705,10 @@ or a straight list of headers."
          (when gnus-tmp-header
            ;; We may have an old dummy line to output before this
            ;; article.
          (when gnus-tmp-header
            ;; We may have an old dummy line to output before this
            ;; article.
-           (when gnus-tmp-dummy-line
+           (when (and gnus-tmp-dummy-line
+                      (gnus-subject-equal
+                       gnus-tmp-dummy-line
+                       (mail-header-subject gnus-tmp-header)))
              (gnus-summary-insert-dummy-line
               gnus-tmp-dummy-line (mail-header-number gnus-tmp-header))
              (setq gnus-tmp-dummy-line nil))
              (gnus-summary-insert-dummy-line
               gnus-tmp-dummy-line (mail-header-number gnus-tmp-header))
              (setq gnus-tmp-dummy-line nil))
@@ -3728,7 +3785,7 @@ or a straight list of headers."
              (setq gnus-tmp-name gnus-tmp-from))
            (unless (numberp gnus-tmp-lines)
              (setq gnus-tmp-lines 0))
              (setq gnus-tmp-name gnus-tmp-from))
            (unless (numberp gnus-tmp-lines)
              (setq gnus-tmp-lines 0))
-           (gnus-put-text-property
+           (gnus-put-text-property-excluding-characters-with-faces
             (point)
             (progn (eval gnus-summary-line-format-spec) (point))
             'gnus-number number)
             (point)
             (progn (eval gnus-summary-line-format-spec) (point))
             'gnus-number number)
@@ -3782,13 +3839,14 @@ or a straight list of headers."
         (cdr (assq number gnus-newsgroup-scored))
         (memq number gnus-newsgroup-processable))))))
 
         (cdr (assq number gnus-newsgroup-scored))
         (memq number gnus-newsgroup-processable))))))
 
-(defun gnus-select-newsgroup (group &optional read-all)
+(defun gnus-select-newsgroup (group &optional read-all select-articles)
   "Select newsgroup GROUP.
   "Select newsgroup GROUP.
-If READ-ALL is non-nil, all articles in the group are selected."
+If READ-ALL is non-nil, all articles in the group are selected.
+If SELECT-ARTICLES, only select those articles from GROUP."
   (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
         ;;!!! Dirty hack; should be removed.
         (gnus-summary-ignore-duplicates
   (let* ((entry (gnus-gethash group gnus-newsrc-hashtb))
         ;;!!! Dirty hack; should be removed.
         (gnus-summary-ignore-duplicates
-         (if (eq (car (gnus-find-method-for-group group)) 'nnvirtual)
+         (if (eq (car (gnus-find-method-for-group group)) 'nnvirtual)
              t
            gnus-summary-ignore-duplicates))
         (info (nth 2 entry))
              t
            gnus-summary-ignore-duplicates))
         (info (nth 2 entry))
@@ -3833,10 +3891,13 @@ If READ-ALL is non-nil, all articles in the group are selected."
     (setq gnus-newsgroup-processable nil)
 
     (gnus-update-read-articles group gnus-newsgroup-unreads)
     (setq gnus-newsgroup-processable nil)
 
     (gnus-update-read-articles group gnus-newsgroup-unreads)
-    (unless (gnus-ephemeral-group-p gnus-newsgroup-name)
-      (gnus-group-update-group group))
 
 
-    (setq articles (gnus-articles-to-read group read-all))
+    (if (setq articles select-articles)
+       (setq gnus-newsgroup-unselected
+             (gnus-sorted-intersection
+              gnus-newsgroup-unreads
+              (gnus-sorted-complement gnus-newsgroup-unreads articles)))
+      (setq articles (gnus-articles-to-read group read-all)))
 
     (cond
      ((null articles)
 
     (cond
      ((null articles)
@@ -3856,11 +3917,11 @@ If READ-ALL is non-nil, all articles in the group are selected."
                           articles gnus-newsgroup-name
                           ;; We might want to fetch old headers, but
                           ;; not if there is only 1 article.
                           articles gnus-newsgroup-name
                           ;; We might want to fetch old headers, but
                           ;; not if there is only 1 article.
-                          (and gnus-fetch-old-headers
-                               (or (and
+                          (and (or (and
                                     (not (eq gnus-fetch-old-headers 'some))
                                     (not (numberp gnus-fetch-old-headers)))
                                     (not (eq gnus-fetch-old-headers 'some))
                                     (not (numberp gnus-fetch-old-headers)))
-                                   (> (length articles) 1))))))
+                                   (> (length articles) 1))
+                               gnus-fetch-old-headers))))
                (gnus-get-newsgroup-headers-xover
                 articles nil nil gnus-newsgroup-name t)
              (gnus-get-newsgroup-headers)))
                (gnus-get-newsgroup-headers-xover
                 articles nil nil gnus-newsgroup-name t)
              (gnus-get-newsgroup-headers)))
@@ -3886,15 +3947,15 @@ If READ-ALL is non-nil, all articles in the group are selected."
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
       ;; Removed marked articles that do not exist.
       (gnus-update-missing-marks
        (gnus-sorted-complement fetched-articles articles))
-      ;; Let the Gnus agent mark articles as read.
-      (when gnus-agent
-       (gnus-agent-get-undownloaded-list))
       ;; We might want to build some more threads first.
       (when (and gnus-fetch-old-headers
                 (eq gnus-headers-retrieved-by 'nov))
        (if (eq gnus-fetch-old-headers 'invisible)
            (gnus-build-all-threads)
          (gnus-build-old-threads)))
       ;; We might want to build some more threads first.
       (when (and gnus-fetch-old-headers
                 (eq gnus-headers-retrieved-by 'nov))
        (if (eq gnus-fetch-old-headers 'invisible)
            (gnus-build-all-threads)
          (gnus-build-old-threads)))
+      ;; Let the Gnus agent mark articles as read.
+      (when gnus-agent
+       (gnus-agent-get-undownloaded-list))
       ;; Check whether auto-expire is to be done in this group.
       (setq gnus-newsgroup-auto-expire
            (gnus-group-auto-expirable-p group))
       ;; Check whether auto-expire is to be done in this group.
       (setq gnus-newsgroup-auto-expire
            (gnus-group-auto-expirable-p group))
@@ -4320,14 +4381,14 @@ The resulting hash table is returned, or nil if no Xrefs were found."
         (or dependencies
             (save-excursion (set-buffer gnus-summary-buffer)
                             gnus-newsgroup-dependencies)))
         (or dependencies
             (save-excursion (set-buffer gnus-summary-buffer)
                             gnus-newsgroup-dependencies)))
-       headers id id-dep ref-dep end ref)
+       headers id end ref)
     (save-excursion
       (set-buffer nntp-server-buffer)
       ;; Translate all TAB characters into SPACE characters.
       (subst-char-in-region (point-min) (point-max) ?\t ?  t)
       (gnus-run-hooks 'gnus-parse-headers-hook)
       (let ((case-fold-search t)
     (save-excursion
       (set-buffer nntp-server-buffer)
       ;; Translate all TAB characters into SPACE characters.
       (subst-char-in-region (point-min) (point-max) ?\t ?  t)
       (gnus-run-hooks 'gnus-parse-headers-hook)
       (let ((case-fold-search t)
-           in-reply-to header p lines)
+           in-reply-to header p lines chars)
        (goto-char (point-min))
        ;; Search to the beginning of the next header.  Error messages
        ;; do not begin with 2 or 3.
        (goto-char (point-min))
        ;; Search to the beginning of the next header.  Error messages
        ;; do not begin with 2 or 3.
@@ -4413,10 +4474,16 @@ The resulting hash table is returned, or nil if no Xrefs were found."
                        (setq ref2 (substring in-reply-to (match-beginning 0)
                                              (match-end 0)))
                        (when (> (length ref2) (length ref))
                        (setq ref2 (substring in-reply-to (match-beginning 0)
                                              (match-end 0)))
                        (when (> (length ref2) (length ref))
-                         (setq ref ref2))))
+                         (setq ref ref2)))
+                     ref)
                  (setq ref nil))))
            ;; Chars.
                  (setq ref nil))))
            ;; Chars.
-           0
+           (progn
+             (goto-char p)
+             (if (search-forward "\nchars: " nil t)
+                 (if (numberp (setq chars (ignore-errors (read cur))))
+                     chars 0)
+               0))
            ;; Lines.
            (progn
              (goto-char p)
            ;; Lines.
            (progn
              (goto-char p)
@@ -4436,151 +4503,15 @@ The resulting hash table is returned, or nil if no Xrefs were found."
            (funcall gnus-alter-header-function header)
            (setq id (mail-header-id header)
                  ref (gnus-parent-id (mail-header-references header))))
            (funcall gnus-alter-header-function header)
            (setq id (mail-header-id header)
                  ref (gnus-parent-id (mail-header-references header))))
-    
-         ;; We do the threading while we read the headers.  The
-         ;; message-id and the last reference are both entered into
-         ;; the same hash table.  Some tippy-toeing around has to be
-         ;; done in case an article has arrived before the article
-         ;; which it refers to.
-         (if (boundp (setq id-dep (intern id dependencies)))
-             (if (and (car (symbol-value id-dep))
-                      (not force-new))
-                 ;; An article with this Message-ID has already been seen.
-                 (if gnus-summary-ignore-duplicates
-                     ;; We ignore this one, except we add
-                     ;; any additional Xrefs (in case the two articles
-                     ;; came from different servers).
-                     (progn
-                       (mail-header-set-xref
-                        (car (symbol-value id-dep))
-                        (concat (or (mail-header-xref
-                                     (car (symbol-value id-dep)))
-                                    "")
-                                (or (mail-header-xref header) "")))
-                       (setq header nil))
-                   ;; We rename the Message-ID.
-                   (set
-                    (setq id-dep (intern (setq id (nnmail-message-id))
-                                         dependencies))
-                    (list header))
-                   (mail-header-set-id header id))
-               (setcar (symbol-value id-dep) header))
-           (set id-dep (list header)))
-         (when header
-           (if (boundp (setq ref-dep (intern (or ref "none") dependencies)))
-               (setcdr (symbol-value ref-dep)
-                       (nconc (cdr (symbol-value ref-dep))
-                              (list (symbol-value id-dep))))
-             (set ref-dep (list nil (symbol-value id-dep))))
+
+         (when (setq header
+                     (gnus-dependencies-add-header
+                      header dependencies force-new))
            (push header headers))
          (goto-char (point-max))
          (widen))
        (nreverse headers)))))
 
            (push header headers))
          (goto-char (point-max))
          (widen))
        (nreverse headers)))))
 
-;; The following macros and functions were written by Felix Lee
-;; <flee@cse.psu.edu>.
-
-(defmacro gnus-nov-read-integer ()
-  '(prog1
-       (if (= (following-char) ?\t)
-          0
-        (let ((num (ignore-errors (read buffer))))
-          (if (numberp num) num 0)))
-     (unless (eobp)
-       (search-forward "\t" eol 'move))))
-
-(defmacro gnus-nov-skip-field ()
-  '(search-forward "\t" eol 'move))
-
-(defmacro gnus-nov-field ()
-  '(buffer-substring (point) (if (gnus-nov-skip-field) (1- (point)) eol)))
-
-;; (defvar gnus-nov-none-counter 0)
-
-;; This function has to be called with point after the article number
-;; on the beginning of the line.
-(defun gnus-nov-parse-line (number dependencies &optional force-new)
-  (let ((eol (gnus-point-at-eol))
-       (buffer (current-buffer))
-       header ref id id-dep ref-dep)
-
-    ;; overview: [num subject from date id refs chars lines misc]
-    (unwind-protect
-       (progn
-         (narrow-to-region (point) eol)
-         (unless (eobp)
-           (forward-char))
-
-         (setq header
-               (vector
-                number                 ; number
-                (funcall
-                 gnus-unstructured-field-decoder (gnus-nov-field)) ; subject
-                (funcall
-                 gnus-structured-field-decoder (gnus-nov-field)) ; from
-                (gnus-nov-field)       ; date
-                (setq id (or (gnus-nov-field)
-                             (nnheader-generate-fake-message-id))) ; id
-                (progn
-                  (let ((beg (point)))
-                    (search-forward "\t" eol)
-                    (if (search-backward ">" beg t)
-                        (setq ref
-                              (buffer-substring
-                               (1+ (point))
-                               (or (search-backward "<" beg t) beg)))
-                      (setq ref nil))
-                    (goto-char beg))
-                  (gnus-nov-field))    ; refs
-                (gnus-nov-read-integer) ; chars
-                (gnus-nov-read-integer) ; lines
-                (if (= (following-char) ?\n)
-                    nil
-                  (gnus-nov-field))))) ; misc
-
-      (widen))
-
-    (when gnus-alter-header-function
-      (funcall gnus-alter-header-function header)
-      (setq id (mail-header-id header)
-           ref (gnus-parent-id (mail-header-references header))))
-    
-    ;; We build the thread tree.
-    (when (equal id ref)
-      ;; This article refers back to itself.  Naughty, naughty.
-      (setq ref nil))
-    (if (boundp (setq id-dep (intern id dependencies)))
-       (if (and (car (symbol-value id-dep))
-                (not force-new))
-           ;; An article with this Message-ID has already been seen.
-           (if gnus-summary-ignore-duplicates
-               ;; We ignore this one, except we add any additional
-               ;; Xrefs (in case the two articles came from different
-               ;; servers.
-               (progn
-                 (mail-header-set-xref
-                  (car (symbol-value id-dep))
-                  (concat (or (mail-header-xref
-                               (car (symbol-value id-dep)))
-                              "")
-                          (or (mail-header-xref header) "")))
-                 (setq header nil))
-             ;; We rename the Message-ID.
-             (set
-              (setq id-dep (intern (setq id (nnmail-message-id))
-                                   dependencies))
-              (list header))
-             (mail-header-set-id header id))
-         (setcar (symbol-value id-dep) header))
-      (set id-dep (list header)))
-    (when header
-      (if (boundp (setq ref-dep (intern (or ref "none") dependencies)))
-         (setcdr (symbol-value ref-dep)
-                 (nconc (cdr (symbol-value ref-dep))
-                        (list (symbol-value id-dep))))
-       (set ref-dep (list nil (symbol-value id-dep)))))
-    header))
-
 ;; Goes through the xover lines and returns a list of vectors
 (defun gnus-get-newsgroup-headers-xover (sequence &optional
                                                  force-new dependencies
 ;; Goes through the xover lines and returns a list of vectors
 (defun gnus-get-newsgroup-headers-xover (sequence &optional
                                                  force-new dependencies
@@ -4657,8 +4588,12 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
              (mail-header-set-xref headers xref)))))))
 
 (defun gnus-summary-insert-subject (id &optional old-header use-old-header)
              (mail-header-set-xref headers xref)))))))
 
 (defun gnus-summary-insert-subject (id &optional old-header use-old-header)
-  "Find article ID and insert the summary line for that article."
-  (let ((header (cond ((and old-header use-old-header)
+  "Find article ID and insert the summary line for that article.
+OLD-HEADER can either be a header or a line number to insert
+the subject line on."
+  (let* ((line (and (numberp old-header) old-header))
+        (old-header (and (vectorp old-header) old-header))
+        (header (cond ((and old-header use-old-header)
                       old-header)
                      ((and (numberp id)
                            (gnus-number-to-header id))
                       old-header)
                      ((and (numberp id)
                            (gnus-number-to-header id))
@@ -4666,7 +4601,7 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
                      (t
                       (gnus-read-header id))))
        (number (and (numberp id) id))
                      (t
                       (gnus-read-header id))))
        (number (and (numberp id) id))
-       pos d)
+       d)
     (when header
       ;; Rebuild the thread that this article is part of and go to the
       ;; article we have fetched.
     (when header
       ;; Rebuild the thread that this article is part of and go to the
       ;; article we have fetched.
@@ -4688,7 +4623,7 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
                  gnus-newsgroup-sparse))
       (setq gnus-newsgroup-ancient (delq number gnus-newsgroup-ancient))
       (push number gnus-newsgroup-limit)
                  gnus-newsgroup-sparse))
       (setq gnus-newsgroup-ancient (delq number gnus-newsgroup-ancient))
       (push number gnus-newsgroup-limit)
-      (gnus-rebuild-thread (mail-header-id header))
+      (gnus-rebuild-thread (mail-header-id header) line)
       (gnus-summary-goto-subject number nil t))
     (when (and (numberp number)
               (> number 0))
       (gnus-summary-goto-subject number nil t))
     (when (and (numberp number)
               (> number 0))
@@ -4708,9 +4643,9 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
 ;;; Process/prefix in the summary buffer
 
 (defun gnus-summary-work-articles (n)
 ;;; Process/prefix in the summary buffer
 
 (defun gnus-summary-work-articles (n)
-  "Return a list of articles to be worked upon.         The prefix argument,
-the list of process marked articles, and the current article will be
-taken into consideration."
+  "Return a list of articles to be worked upon.
+The prefix argument, the list of process marked articles, and the
+current article will be taken into consideration."
   (save-excursion
     (set-buffer gnus-summary-buffer)
     (cond
   (save-excursion
     (set-buffer gnus-summary-buffer)
     (cond
@@ -4753,6 +4688,19 @@ taken into consideration."
       ;; Just return the current article.
       (list (gnus-summary-article-number))))))
 
       ;; Just return the current article.
       (list (gnus-summary-article-number))))))
 
+(defmacro gnus-summary-iterate (arg &rest forms)
+  "Iterate over the process/prefixed articles and do FORMS.
+ARG is the interactive prefix given to the command.  FORMS will be
+executed with point over the summary line of the articles."
+  (let ((articles (make-symbol "gnus-summary-iterate-articles")))
+    `(let ((,articles (gnus-summary-work-articles ,arg)))
+       (while ,articles
+        (gnus-summary-goto-subject (car ,articles))
+        ,@forms))))
+
+(put 'gnus-summary-iterate 'lisp-indent-function 1)
+(put 'gnus-summary-iterate 'edebug-form-spec '(form body))
+
 (defun gnus-summary-save-process-mark ()
   "Push the current set of process marked articles on the stack."
   (interactive)
 (defun gnus-summary-save-process-mark ()
   "Push the current set of process marked articles on the stack."
   (interactive)
@@ -4951,12 +4899,12 @@ displayed, no centering will be performed."
       ;; first unread article is the article after the last read
       ;; article.  Sounds logical, doesn't it?
       (if (not (listp (cdr read)))
       ;; first unread article is the article after the last read
       ;; article.  Sounds logical, doesn't it?
       (if (not (listp (cdr read)))
-         (setq first (1+ (cdr read)))
+         (setq first (max (car active) (1+ (cdr read))))
        ;; `read' is a list of ranges.
        (when (/= (setq nlast (or (and (numberp (car read)) (car read))
                                  (caar read)))
                  1)
        ;; `read' is a list of ranges.
        (when (/= (setq nlast (or (and (numberp (car read)) (car read))
                                  (caar read)))
                  1)
-         (setq first 1))
+         (setq first (car active)))
        (while read
          (when first
            (while (< first nlast)
        (while read
          (when first
            (while (< first nlast)
@@ -5069,12 +5017,7 @@ The prefix argument ALL means to select all articles."
                 t)))
        (unless (listp (cdr gnus-newsgroup-killed))
          (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
                 t)))
        (unless (listp (cdr gnus-newsgroup-killed))
          (setq gnus-newsgroup-killed (list gnus-newsgroup-killed)))
-       (let ((headers gnus-newsgroup-headers)
-             (gnus-newsgroup-scored 
-              (if (and (not gnus-save-score)
-                       (not non-destructive))
-                  nil
-                gnus-newsgroup-scored)))
+       (let ((headers gnus-newsgroup-headers))
          ;; Set the new ranges of read articles.
          (save-excursion
            (set-buffer gnus-group-buffer)
          ;; Set the new ranges of read articles.
          (save-excursion
            (set-buffer gnus-group-buffer)
@@ -5082,7 +5025,13 @@ The prefix argument ALL means to select all articles."
          (gnus-update-read-articles
           group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
          ;; Set the current article marks.
          (gnus-update-read-articles
           group (append gnus-newsgroup-unreads gnus-newsgroup-unselected))
          ;; Set the current article marks.
-         (gnus-update-marks)
+         (let ((gnus-newsgroup-scored 
+                (if (and (not gnus-save-score)
+                         (not non-destructive))
+                    nil
+                  gnus-newsgroup-scored)))
+           (save-excursion
+             (gnus-update-marks)))
          ;; Do the cross-ref thing.
          (when gnus-use-cross-reference
            (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
          ;; Do the cross-ref thing.
          (when gnus-use-cross-reference
            (gnus-mark-xrefs-as-read group headers gnus-newsgroup-unreads))
@@ -5225,8 +5174,8 @@ gnus-exit-group-hook is called with no arguments if that value is non-nil."
         (gnus-handle-ephemeral-exit quit-config)))))
 
 (defun gnus-handle-ephemeral-exit (quit-config)
         (gnus-handle-ephemeral-exit quit-config)))))
 
 (defun gnus-handle-ephemeral-exit (quit-config)
-  "Handle movement when leaving an ephemeral group.  The state
-which existed when entering the ephemeral is reset."
+  "Handle movement when leaving an ephemeral group.
+The state which existed when entering the ephemeral is reset."
   (if (not (buffer-name (car quit-config)))
       (gnus-configure-windows 'group 'force)
     (set-buffer (car quit-config))
   (if (not (buffer-name (car quit-config)))
       (gnus-configure-windows 'group 'force)
     (set-buffer (car quit-config))
@@ -5259,23 +5208,12 @@ which existed when entering the ephemeral is reset."
 (defun gnus-summary-preview-mime-message (arg)
   "MIME decode and play this message."
   (interactive "P")
 (defun gnus-summary-preview-mime-message (arg)
   "MIME decode and play this message."
   (interactive "P")
-  (let ((gnus-break-pages nil))
-    (gnus-summary-select-article t t)
-    )
-  (pop-to-buffer gnus-original-article-buffer t)
-  (let (buffer-read-only)
-    (if (text-property-any (point-min) (point-max) 'invisible t)
-       (remove-text-properties (point-min) (point-max)
-                               gnus-hidden-properties)
-      ))
-  (mime-view-mode nil nil nil gnus-original-article-buffer
-                 gnus-article-buffer)
-  )
-
-(defun gnus-summary-scroll-down ()
-  "Scroll down one line current article."
-  (interactive)
-  (gnus-summary-scroll-up -1)
+  (or gnus-show-mime
+      (let ((gnus-break-pages nil)
+           (gnus-show-mime t))
+       (gnus-summary-select-article t t)
+       ))
+  (select-window (get-buffer-window gnus-article-buffer))
   )
 
 ;;; Dead summaries.
   )
 
 ;;; Dead summaries.
@@ -5527,7 +5465,10 @@ If FORCE, also allow jumping to articles not currently shown."
     ;; We read in the article if we have to.
     (and (not data)
         force
     ;; We read in the article if we have to.
     (and (not data)
         force
-        (gnus-summary-insert-subject article (and (vectorp force) force) t)
+        (gnus-summary-insert-subject
+         article
+         (if (or (numberp force) (vectorp force)) force)
+         t)
         (setq data (gnus-data-find article)))
     (goto-char b)
     (if (not data)
         (setq data (gnus-data-find article)))
     (goto-char b)
     (if (not data)
@@ -5536,6 +5477,7 @@ If FORCE, also allow jumping to articles not currently shown."
            (gnus-message 3 "Can't find article %d" article))
          nil)
       (goto-char (gnus-data-pos data))
            (gnus-message 3 "Can't find article %d" article))
          nil)
       (goto-char (gnus-data-pos data))
+      (gnus-summary-position-point)
       article)))
 
 ;; Walking around summary lines with displaying articles.
       article)))
 
 ;; Walking around summary lines with displaying articles.
@@ -5637,7 +5579,7 @@ If BACKWARD, the previous article is selected instead of the next."
         (not unread) (not subject))
     (gnus-summary-goto-article
      (if backward (1- gnus-newsgroup-begin) (1+ gnus-newsgroup-end))
         (not unread) (not subject))
     (gnus-summary-goto-article
      (if backward (1- gnus-newsgroup-begin) (1+ gnus-newsgroup-end))
-     nil t))
+     nil (count-lines (point-min) (point))))
    ;; Go to next/previous group.
    (t
     (unless (gnus-ephemeral-group-p gnus-newsgroup-name)
    ;; Go to next/previous group.
    (t
     (unless (gnus-ephemeral-group-p gnus-newsgroup-name)
@@ -5843,6 +5785,12 @@ Argument LINES specifies lines to be scrolled up (or down if negative)."
   (gnus-summary-recenter)
   (gnus-summary-position-point))
 
   (gnus-summary-recenter)
   (gnus-summary-position-point))
 
+(defun gnus-summary-scroll-down (lines)
+  "Scroll down (or up) one line current article.
+Argument LINES specifies lines to be scrolled down (or up if negative)."
+  (interactive "p")
+  (gnus-summary-scroll-up (- lines)))
+
 (defun gnus-summary-next-same-subject ()
   "Select next article which has the same subject as current one."
   (interactive)
 (defun gnus-summary-next-same-subject ()
   "Select next article which has the same subject as current one."
   (interactive)
@@ -5913,7 +5861,9 @@ Return nil if there are no articles."
 
 (defun gnus-summary-goto-article (article &optional all-headers force)
   "Fetch ARTICLE (article number or Message-ID) and display it if it exists.
 
 (defun gnus-summary-goto-article (article &optional all-headers force)
   "Fetch ARTICLE (article number or Message-ID) and display it if it exists.
-If ALL-HEADERS is non-nil, no header lines are hidden."
+If ALL-HEADERS is non-nil, no header lines are hidden.
+If FORCE, go to the article even if it isn't displayed.  If FORCE
+is a number, it is the line the article is to be displayed on."
   (interactive
    (list
     (completing-read
   (interactive
    (list
     (completing-read
@@ -6013,7 +5963,9 @@ articles that are younger than AGE days."
            (setq is-younger (nnmail-time-less
                              (nnmail-time-since (nnmail-date-to-time date))
                              cutoff))
            (setq is-younger (nnmail-time-less
                              (nnmail-time-since (nnmail-date-to-time date))
                              cutoff))
-           (when (if younger-p is-younger (not is-younger))
+           (when (if younger-p
+                     is-younger
+                   (not is-younger))
              (push (gnus-data-number d) articles))))
        (gnus-summary-limit (nreverse articles)))
     (gnus-summary-position-point)))
              (push (gnus-data-number d) articles))))
        (gnus-summary-limit (nreverse articles)))
     (gnus-summary-position-point)))
@@ -6149,7 +6101,8 @@ If ALL, mark even excluded ticked and dormants as read."
                    '<)
                   (sort gnus-newsgroup-limit '<)))
        article)
                    '<)
                   (sort gnus-newsgroup-limit '<)))
        article)
-    (setq gnus-newsgroup-unreads gnus-newsgroup-limit)
+    (setq gnus-newsgroup-unreads
+         (gnus-intersection gnus-newsgroup-unreads gnus-newsgroup-limit))
     (if all
        (setq gnus-newsgroup-dormant nil
              gnus-newsgroup-marked nil
     (if all
        (setq gnus-newsgroup-dormant nil
              gnus-newsgroup-marked nil
@@ -6197,6 +6150,7 @@ If ALL, mark even excluded ticked and dormants as read."
       ;; after the current one.
       (goto-char (point-max))
       (gnus-summary-find-prev))
       ;; after the current one.
       (goto-char (point-max))
       (gnus-summary-find-prev))
+    (gnus-set-mode-line 'summary)
     ;; We return how many articles were removed from the summary
     ;; buffer as a result of the new limit.
     (- total (length gnus-newsgroup-data))))
     ;; We return how many articles were removed from the summary
     ;; buffer as a result of the new limit.
     (- total (length gnus-newsgroup-data))))
@@ -6446,8 +6400,7 @@ of what's specified by the `gnus-refer-thread-limit' variable."
   (interactive "P")
   (let ((id (mail-header-id (gnus-summary-article-header)))
        (limit (if limit (prefix-numeric-value limit)
   (interactive "P")
   (let ((id (mail-header-id (gnus-summary-article-header)))
        (limit (if limit (prefix-numeric-value limit)
-                gnus-refer-thread-limit))
-       fmethod root)
+                gnus-refer-thread-limit)))
     ;; We want to fetch LIMIT *old* headers, but we also have to
     ;; re-fetch all the headers in the current buffer, because many of
     ;; them may be undisplayed.  So we adjust LIMIT.
     ;; We want to fetch LIMIT *old* headers, but we also have to
     ;; re-fetch all the headers in the current buffer, because many of
     ;; them may be undisplayed.  So we adjust LIMIT.
@@ -6482,8 +6435,7 @@ or `gnus-select-method', no matter what backend the article comes from."
                        (gnus-summary-article-sparse-p
                         (mail-header-number header))
                        (memq (mail-header-number header)
                        (gnus-summary-article-sparse-p
                         (mail-header-number header))
                        (memq (mail-header-number header)
-                             gnus-newsgroup-limit)))
-          h)
+                             gnus-newsgroup-limit))))
       (cond
        ;; If the article is present in the buffer we just go to it.
        ((and header
       (cond
        ;; If the article is present in the buffer we just go to it.
        ((and header
@@ -7055,15 +7007,10 @@ and `request-accept' functions."
        (gnus-summary-mark-article article gnus-canceled-mark)
        (gnus-message 4 "Deleted article %s" article))
        (t
        (gnus-summary-mark-article article gnus-canceled-mark)
        (gnus-message 4 "Deleted article %s" article))
        (t
-       (let* ((entry
-               (or
-                (gnus-gethash (car art-group) gnus-newsrc-hashtb)
-                (gnus-gethash
-                 (gnus-group-prefixed-name
-                  (car art-group)
-                  (or select-method
-                      (gnus-find-method-for-group to-newsgroup)))
-                 gnus-newsrc-hashtb)))
+       (let* ((pto-group (gnus-group-prefixed-name
+                          (car art-group) to-method))
+              (entry
+               (gnus-gethash pto-group gnus-newsrc-hashtb))
               (info (nth 2 entry))
               (to-group (gnus-info-group info)))
          ;; Update the group that has been moved to.
               (info (nth 2 entry))
               (to-group (gnus-info-group info)))
          ;; Update the group that has been moved to.
@@ -7167,7 +7114,7 @@ re-spool using this method."
 (defcustom gnus-summary-respool-default-method nil
   "Default method for respooling an article.
 If nil, use to the current newsgroup method."
 (defcustom gnus-summary-respool-default-method nil
   "Default method for respooling an article.
 If nil, use to the current newsgroup method."
-  :type `(choice (gnus-select-method :value (nnml ""))
+  :type '(choice (gnus-select-method :value (nnml ""))
                 (const nil))
   :group 'gnus-summary-mail)
 
                 (const nil))
   :group 'gnus-summary-mail)
 
@@ -7227,7 +7174,7 @@ latter case, they will be copied into the relevant groups."
        (not (file-regular-p file))
        (error "Can't read %s" file))
     (save-excursion
        (not (file-regular-p file))
        (error "Can't read %s" file))
     (save-excursion
-      (set-buffer (get-buffer-create " *import file*"))
+      (set-buffer (gnus-get-buffer-create " *import file*"))
       (buffer-disable-undo (current-buffer))
       (erase-buffer)
       (nnheader-insert-file-contents file)
       (buffer-disable-undo (current-buffer))
       (erase-buffer)
       (nnheader-insert-file-contents file)
@@ -7336,7 +7283,7 @@ delete these instead."
                                       gnus-newsgroup-name)
     (error "The current newsgroup does not support article deletion"))
   ;; Compute the list of articles to delete.
                                       gnus-newsgroup-name)
     (error "The current newsgroup does not support article deletion"))
   ;; Compute the list of articles to delete.
-  (let ((articles (gnus-summary-work-articles n))
+  (let ((articles (sort (copy-sequence (gnus-summary-work-articles n)) '<))
        not-deleted)
     (if (and gnus-novice-user
             (not (gnus-yes-or-no-p
        not-deleted)
     (if (and gnus-novice-user
             (not (gnus-yes-or-no-p
@@ -7391,55 +7338,58 @@ groups."
   "Make edits to the current article permanent."
   (interactive)
   ;; Replace the article.
   "Make edits to the current article permanent."
   (interactive)
   ;; Replace the article.
-  (if (and (not read-only)
-          (not (gnus-request-replace-article
-                (cdr gnus-article-current) (car gnus-article-current)
-                (current-buffer))))
-      (error "Couldn't replace article")
-    ;; Update the summary buffer.
-    (if (and references
-            (equal (message-tokenize-header references " ")
-                   (message-tokenize-header
-                    (or (message-fetch-field "references") "") " ")))
-       ;; We only have to update this line.
-       (save-excursion
-         (save-restriction
-           (message-narrow-to-head)
-           (let ((head (buffer-string))
-                 header)
-             (nnheader-temp-write nil
-               (insert (format "211 %d Article retrieved.\n"
-                               (cdr gnus-article-current)))
-               (insert head)
-               (insert ".\n")
-               (let ((nntp-server-buffer (current-buffer)))
-                 (setq header (car (gnus-get-newsgroup-headers
-                                    (save-excursion
-                                      (set-buffer gnus-summary-buffer)
-                                      gnus-newsgroup-dependencies)
-                                    t))))
-               (save-excursion
-                 (set-buffer gnus-summary-buffer)
-                 (gnus-data-set-header
-                  (gnus-data-find (cdr gnus-article-current))
-                  header)
-                 (gnus-summary-update-article-line
-                  (cdr gnus-article-current) header))))))
-      ;; Update threads.
-      (set-buffer (or buffer gnus-summary-buffer))
-      (gnus-summary-update-article (cdr gnus-article-current)))
-    ;; Prettify the article buffer again.
-    (unless no-highlight
-      (save-excursion
-       (set-buffer gnus-article-buffer)
-       (gnus-run-hooks 'gnus-article-display-hook)
-       (set-buffer gnus-original-article-buffer)
-       (gnus-request-article
-        (cdr gnus-article-current)
-        (car gnus-article-current) (current-buffer))))
-    ;; Prettify the summary buffer line.
-    (when (gnus-visual-p 'summary-highlight 'highlight)
-      (gnus-run-hooks 'gnus-visual-mark-article-hook))))
+  (let ((buf (current-buffer)))
+    (nnheader-temp-write nil
+      (insert-buffer buf)
+      (if (and (not read-only)
+              (not (gnus-request-replace-article
+                    (cdr gnus-article-current) (car gnus-article-current)
+                    (current-buffer))))
+         (error "Couldn't replace article")
+       ;; Update the summary buffer.
+       (if (and references
+                (equal (message-tokenize-header references " ")
+                       (message-tokenize-header
+                        (or (message-fetch-field "references") "") " ")))
+           ;; We only have to update this line.
+           (save-excursion
+             (save-restriction
+               (message-narrow-to-head)
+               (let ((head (buffer-string))
+                     header)
+                 (nnheader-temp-write nil
+                   (insert (format "211 %d Article retrieved.\n"
+                                   (cdr gnus-article-current)))
+                   (insert head)
+                   (insert ".\n")
+                   (let ((nntp-server-buffer (current-buffer)))
+                     (setq header (car (gnus-get-newsgroup-headers
+                                        (save-excursion
+                                          (set-buffer gnus-summary-buffer)
+                                          gnus-newsgroup-dependencies)
+                                        t))))
+                   (save-excursion
+                     (set-buffer gnus-summary-buffer)
+                     (gnus-data-set-header
+                      (gnus-data-find (cdr gnus-article-current))
+                      header)
+                     (gnus-summary-update-article-line
+                      (cdr gnus-article-current) header))))))
+         ;; Update threads.
+         (set-buffer (or buffer gnus-summary-buffer))
+         (gnus-summary-update-article (cdr gnus-article-current)))
+       ;; Prettify the article buffer again.
+       (unless no-highlight
+         (save-excursion
+           (set-buffer gnus-article-buffer)
+           (gnus-run-hooks 'gnus-article-display-hook)
+           (set-buffer gnus-original-article-buffer)
+           (gnus-request-article
+            (cdr gnus-article-current)
+            (car gnus-article-current) (current-buffer))))
+       ;; Prettify the summary buffer line.
+       (when (gnus-visual-p 'summary-highlight 'highlight)
+         (gnus-run-hooks 'gnus-visual-mark-article-hook))))))
 
 (defun gnus-summary-edit-wash (key)
   "Perform editing command KEY in the article buffer."
 
 (defun gnus-summary-edit-wash (key)
   "Perform editing command KEY in the article buffer."
@@ -7455,7 +7405,7 @@ groups."
 
 ;;; Respooling
 
 
 ;;; Respooling
 
-(defun gnus-summary-respool-query (&optional silent)
+(defun gnus-summary-respool-query (&optional silent trace)
   "Query where the respool algorithm would put this article."
   (interactive)
   (let (gnus-mark-article-hook)
   "Query where the respool algorithm would put this article."
   (interactive)
   (let (gnus-mark-article-hook)
@@ -7464,7 +7414,7 @@ groups."
       (set-buffer gnus-original-article-buffer)
       (save-restriction
        (message-narrow-to-head)
       (set-buffer gnus-original-article-buffer)
       (save-restriction
        (message-narrow-to-head)
-       (let ((groups (nnmail-article-group 'identity)))
+       (let ((groups (nnmail-article-group 'identity trace)))
          (unless silent
            (if groups
                (message "This message would go to %s"
          (unless silent
            (if groups
                (message "This message would go to %s"
@@ -7472,6 +7422,12 @@ groups."
              (message "This message would go to no groups"))
            groups))))))
 
              (message "This message would go to no groups"))
            groups))))))
 
+(defun gnus-summary-respool-trace ()
+  "Trace where the respool algorithm would put this article.
+Display a buffer showing all fancy splitting patterns which matched."
+  (interactive)
+  (gnus-summary-respool-query nil t))
+
 ;; Summary marking commands.
 
 (defun gnus-summary-kill-same-subject-and-select (&optional unmark)
 ;; Summary marking commands.
 
 (defun gnus-summary-kill-same-subject-and-select (&optional unmark)
@@ -7648,6 +7604,7 @@ the actual number of articles marked is returned."
              (delq article gnus-newsgroup-processable)))
   (when (gnus-summary-goto-subject article)
     (gnus-summary-show-thread)
              (delq article gnus-newsgroup-processable)))
   (when (gnus-summary-goto-subject article)
     (gnus-summary-show-thread)
+    (gnus-summary-goto-subject article)
     (gnus-summary-update-secondary-mark article)))
 
 (defun gnus-summary-remove-process-mark (article)
     (gnus-summary-update-secondary-mark article)))
 
 (defun gnus-summary-remove-process-mark (article)
@@ -7655,6 +7612,7 @@ the actual number of articles marked is returned."
   (setq gnus-newsgroup-processable (delq article gnus-newsgroup-processable))
   (when (gnus-summary-goto-subject article)
     (gnus-summary-show-thread)
   (setq gnus-newsgroup-processable (delq article gnus-newsgroup-processable))
   (when (gnus-summary-goto-subject article)
     (gnus-summary-show-thread)
+    (gnus-summary-goto-subject article)
     (gnus-summary-update-secondary-mark article)))
 
 (defun gnus-summary-set-saved-mark (article)
     (gnus-summary-update-secondary-mark article)))
 
 (defun gnus-summary-set-saved-mark (article)
@@ -7712,6 +7670,8 @@ returned."
                   (= mark gnus-read-mark) (= mark gnus-souped-mark)
                   (= mark gnus-duplicate-mark)))
       (setq mark gnus-expirable-mark)
                   (= mark gnus-read-mark) (= mark gnus-souped-mark)
                   (= mark gnus-duplicate-mark)))
       (setq mark gnus-expirable-mark)
+      ;; Let the backend know about the mark change.
+      (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark))
       (push article gnus-newsgroup-expirable))
     ;; Set the mark in the buffer.
     (gnus-summary-update-mark mark 'unread)
       (push article gnus-newsgroup-expirable))
     ;; Set the mark in the buffer.
     (gnus-summary-update-mark mark 'unread)
@@ -7721,6 +7681,8 @@ returned."
   "Mark the current article quickly as unread with MARK."
   (let* ((article (gnus-summary-article-number))
         (old-mark (gnus-summary-article-mark article)))
   "Mark the current article quickly as unread with MARK."
   (let* ((article (gnus-summary-article-number))
         (old-mark (gnus-summary-article-mark article)))
+      ;; Let the backend know about the mark change.
+      (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark))
     (if (eq mark old-mark)
        t
       (if (<= article 0)
     (if (eq mark old-mark)
        t
       (if (<= article 0)
@@ -7737,9 +7699,7 @@ returned."
               (push article gnus-newsgroup-dormant))
              (t
               (push article gnus-newsgroup-unreads)))
               (push article gnus-newsgroup-dormant))
              (t
               (push article gnus-newsgroup-unreads)))
-       (setq gnus-newsgroup-reads
-             (delq (assq article gnus-newsgroup-reads)
-                   gnus-newsgroup-reads))
+       (gnus-pull article gnus-newsgroup-reads)
 
        ;; See whether the article is to be put in the cache.
        (and gnus-use-cache
 
        ;; See whether the article is to be put in the cache.
        (and gnus-use-cache
@@ -7778,6 +7738,8 @@ marked."
   (let* ((mark (or mark gnus-del-mark))
         (article (or article (gnus-summary-article-number)))
         (old-mark (gnus-summary-article-mark article)))
   (let* ((mark (or mark gnus-del-mark))
         (article (or article (gnus-summary-article-number)))
         (old-mark (gnus-summary-article-mark article)))
+      ;; Let the backend know about the mark change.
+      (setq mark (gnus-request-update-mark gnus-newsgroup-name article mark))
     (if (eq mark old-mark)
        t
       (unless article
     (if (eq mark old-mark)
        t
       (unless article
@@ -7880,9 +7842,7 @@ marked."
             (push article gnus-newsgroup-dormant))
            (t
             (push article gnus-newsgroup-unreads)))
             (push article gnus-newsgroup-dormant))
            (t
             (push article gnus-newsgroup-unreads)))
-      (setq gnus-newsgroup-reads
-           (delq (assq article gnus-newsgroup-reads)
-                 gnus-newsgroup-reads))
+      (gnus-pull article gnus-newsgroup-reads)
       t)))
 
 (defalias 'gnus-summary-mark-as-unread-forward
       t)))
 
 (defalias 'gnus-summary-mark-as-unread-forward
@@ -8597,8 +8557,7 @@ save those articles instead."
   "Pipe the current article through PROGRAM."
   (interactive "sProgram: ")
   (gnus-summary-select-article)
   "Pipe the current article through PROGRAM."
   (interactive "sProgram: ")
   (gnus-summary-select-article)
-  (let ((mail-header-separator "")
-        (art-buf (get-buffer gnus-article-buffer)))
+  (let ((mail-header-separator ""))
     (gnus-eval-in-buffer-window gnus-article-buffer
       (save-restriction
         (widen)
     (gnus-eval-in-buffer-window gnus-article-buffer
       (save-restriction
         (widen)
@@ -8832,9 +8791,7 @@ save those articles instead."
       (when (and header
                 (gnus-summary-article-sparse-p (mail-header-number header)))
        (let* ((parent (gnus-parent-id (mail-header-references header)))
       (when (and header
                 (gnus-summary-article-sparse-p (mail-header-number header)))
        (let* ((parent (gnus-parent-id (mail-header-references header)))
-              (thread
-               (and parent
-                    (gnus-gethash parent gnus-newsgroup-dependencies))))
+              (thread (and parent (gnus-id-to-thread parent))))
          (when thread
            (delq (assq header thread) thread))))
       ;; We have to really fetch the header to this article.
          (when thread
            (delq (assq header thread) thread))))
       ;; We have to really fetch the header to this article.
@@ -8943,7 +8900,7 @@ save those articles instead."
        (setq list (cdr list))))
     (let ((face (cdar list)))
       (unless (eq face (get-text-property beg 'face))
        (setq list (cdr list))))
     (let ((face (cdar list)))
       (unless (eq face (get-text-property beg 'face))
-       (gnus-put-text-property
+       (gnus-put-text-property-excluding-characters-with-faces
         beg end 'face
         (setq face (if (boundp face) (symbol-value face) face)))
        (when gnus-summary-highlight-line-function
         beg end 'face
         (setq face (if (boundp face) (symbol-value face) face)))
        (when gnus-summary-highlight-line-function
@@ -9031,25 +8988,29 @@ save those articles instead."
 ;;; @ for mime-partial
 ;;;
 
 ;;; @ for mime-partial
 ;;;
 
-(defun gnus-mime-partial-preview-function ()
-  (gnus-summary-preview-mime-message (gnus-summary-article-number))
-  )
+(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-method-to-combine-message/partial-pieces
+(autoload 'mime-combine-message/partial-pieces-automatically
   "mime-partial"
   "Internal method to combine message/partial messages automatically.")
 
   "mime-partial"
   "Internal method to combine message/partial messages automatically.")
 
-(ctree-set-calist-strictly
- 'mime-acting-condition
- '((type . message)(subtype . partial)
-   (method . mime-method-to-combine-message/partial-pieces)
-   (major-mode . gnus-original-article-mode)
-   (summary-buffer-exp . gnus-summary-buffer)
-   ))
-
-(set-alist 'mime-view-partial-message-method-alist
-          'gnus-original-article-mode
-          'gnus-mime-partial-preview-function)
+(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)
+          ))
 
 
 ;;; @ end
 
 
 ;;; @ end