*** empty log message ***
[gnus] / lisp / gnus.el
index ab9ae3d..787e19c 100644 (file)
@@ -31,8 +31,8 @@
 (require 'mail-utils)
 (require 'timezone)
 (require 'nnheader)
-(require 'message)
 (require 'nnmail)
+(require 'nnoo)
 
 (eval-when-compile (require 'cl))
 
@@ -142,7 +142,32 @@ see the manual for details.")
     (nnfolder-get-new-mail nil)
     (nnfolder-inhibit-expiry t))
   "*Method used for archiving messages you've sent.
-This should be a mail method.")
+This should be a mail method.
+
+It's probably not a very effective to change this variable once you've
+run Gnus once.  After doing that, you must edit this server from the
+server buffer.")
+
+(defvar gnus-message-archive-group nil
+  "*Name of the group in which to save the messages you've written.
+This can either be a string, a list of strings; or an alist
+of regexps/functions/forms to be evaluated to return a string (or a list
+of strings).  The functions are called with the name of the current
+group (or nil) as a parameter.
+
+If you want to save your mail in one group and the news articles you
+write in another group, you could say something like:
+
+ \(setq gnus-message-archive-group 
+        '((if (message-news-p)
+              \"misc-news\" 
+            \"misc-mail\")))
+
+Normally the group names returned by this variable should be
+unprefixed -- which implictly means \"store on the archive server\".
+However, you may wish to store the message on some other server.  In
+that case, just return a fully prefixed name of the group --
+\"nnml+private:mail.misc\", for instance.")
 
 (defvar gnus-refer-article-method nil
   "*Preferred method for fetching an article by Message-ID.
@@ -185,6 +210,7 @@ instead.")
 (defvar gnus-group-faq-directory
   '("/ftp@mirrors.aol.com:/pub/rtfm/usenet/"
     "/ftp@sunsite.auc.dk:/pub/usenet/"
+    "/ftp@sunsite.doc.ic.ac.uk:/pub/usenet/news-faqs/"
     "/ftp@src.doc.ic.ac.uk:/usenet/news-FAQS/"
     "/ftp@ftp.seas.gwu.edu:/pub/rtfm/"
     "/ftp@rtfm.mit.edu:/pub/usenet/"
@@ -198,8 +224,8 @@ This will most commonly be on a remote machine, and the file will be
 fetched by ange-ftp.
 
 This variable can also be a list of directories.  In that case, the
-first element in the list will be used by default, and the others will
-be used as backup sites.
+first element in the list will be used by default.  The others can
+be used when being prompted for a site.
 
 Note that Gnus uses an aol machine as the default directory.  If this
 feels fundamentally unclean, just think of it as a way to finally get
@@ -277,7 +303,11 @@ If this variable is a list, and the list contains the element
 `not-score', long file names will not be used for score files; if it
 contains the element `not-save', long file names will not be used for
 saving; and if it contains the element `not-kill', long file names
-will not be used for kill files.")
+will not be used for kill files.
+
+Note that the default for this variable varies according to what system
+type you're using.  On `usg-unix-v' and `xenix' this variable defaults
+to nil while on all other systems it defaults to t.")
 
 (defvar gnus-article-save-directory gnus-directory
   "*Name of the directory articles will be saved in (default \"~/News\").")
@@ -476,7 +506,7 @@ If this variable is `fuzzy', Gnus will use a fuzzy algorithm when
 comparing subjects.")
 
 (defvar gnus-simplify-ignored-prefixes nil
-  "*Regexp, matches for which are removed from subject lines when simplifying.")
+  "*Regexp, matches for which are removed from subject lines when simplifying fuzzily.")
 
 (defvar gnus-build-sparse-threads nil
   "*If non-nil, fill in the gaps in threads.
@@ -509,15 +539,26 @@ whether it is read or not.")
   "*If non-nil, the \\<gnus-group-mode-map>\\[gnus-group-get-new-news-this-group] command will advance point to the next group.")
 
 (defvar gnus-check-new-newsgroups t
-  "*Non-nil means that Gnus will add new newsgroups at startup.
-If this variable is `ask-server', Gnus will ask the server for new
-groups since the last time it checked. This means that the killed list
-is no longer necessary, so you could set `gnus-save-killed-list' to
-nil.
-
-A variant is to have this variable be a list of select methods.         Gnus
-will then use the `ask-server' method on all these select methods to
-query for new groups from all those servers.
+  "*Non-nil means that Gnus will run gnus-find-new-newsgroups at startup.
+This normally finds new newsgroups by comparing the active groups the
+servers have already reported with those Gnus already knows, either alive
+or killed.
+
+When any of the following are true, gnus-find-new-newsgroups will instead
+ask the servers (primary, secondary, and archive servers) to list new
+groups since the last time it checked:
+  1. This variable is `ask-server'.
+  2. This variable is a list of select methods (see below).
+  3. `gnus-read-active-file' is nil or `some'.
+  4. A prefix argument is given to gnus-find-new-newsgroups interactively.
+
+Thus, if this variable is `ask-server' or a list of select methods or
+`gnus-read-active-file' is nil or `some', then the killed list is no
+longer necessary, so you could safely set `gnus-save-killed-list' to nil.
+
+This variable can be a list of select methods which Gnus will query with
+the `ask-server' method in addition to the primary, secondary, and archive
+servers.
 
 Eg.
   (setq gnus-check-new-newsgroups
@@ -854,7 +895,6 @@ beginning of a line.")
        '(vertical 1.0
                 (summary 0.25 point)
                 (if gnus-carpal '(summary-carpal 4))
-                (if gnus-use-trees '(tree 0.25))
                 (article 1.0)))))
     (server
      (vertical 1.0
@@ -1073,7 +1113,7 @@ list of parameters to that command.")
 (defvar gnus-insert-pseudo-articles t
   "*If non-nil, insert pseudo-articles when decoding articles.")
 
-(defvar gnus-group-line-format "%M%S%p%P%5y: %(%g%)%l\n"
+(defvar gnus-group-line-format "%M\%S\%p\%P\%5y: %(%g%)%l\n"
   "*Format of group lines.
 It works along the same lines as a normal formatting string,
 with some simple extensions.
@@ -1121,7 +1161,7 @@ Also note that if you change the format specification to include any
 of these specs, you must probably re-start Gnus to see them go into
 effect.")
 
-(defvar gnus-summary-line-format "%U%R%z%I%(%[%4L: %-20,20n%]%) %s\n"
+(defvar gnus-summary-line-format "%U\%R\%z\%I\%(%[%4L: %-20,20n%]%) %s\n"
   "*The format specification of the lines in the summary buffer.
 
 It works along the same lines as a normal formatting string,
@@ -1210,7 +1250,7 @@ with some simple extensions:
   "*The format specification for the article mode line.
 See `gnus-summary-mode-line-format' for a closer description.")
 
-(defvar gnus-group-mode-line-format "Gnus: %%b {%M%:%S}"
+(defvar gnus-group-mode-line-format "Gnus: %%b {%M\%:%S}"
   "*The format specification for the group mode line.
 It works along the same lines as a normal formatting string,
 with some simple extensions:
@@ -1230,13 +1270,13 @@ with some simple extensions:
     ("nneething" none address prompt-address)
     ("nndoc" none address prompt-address)
     ("nnbabyl" mail address respool)
-    ("nnkiboze" post address virtual)
+    ("nnkiboze" post virtual)
     ("nnsoup" post-mail address)
     ("nndraft" post-mail)
     ("nnfolder" mail respool address))
   "An alist of valid select methods.
 The first element of each list lists should be a string with the name
-of the select method.  The other elements may be be the category of
+of the select method.  The other elements may be the category of
 this method (ie. `post', `mail', `none' or whatever) or other
 properties that this method has (like being respoolable).
 If you implement a new select method, all you should have to change is
@@ -1304,12 +1344,20 @@ See `gnus-thread-score-function' for en explanation of what a
   "^nnml\\|^nnfolder\\|^nnmbox\\|^nnmh\\|^nnbabyl"
   "*All new groups that match this regexp will be subscribed automatically.
 Note that this variable only deals with new groups.  It has no effect
-whatsoever on old groups.")
+whatsoever on old groups.
+
+New groups that match this regexp will not be handled by
+`gnus-subscribe-newsgroup-method'.  Instead, they will
+be subscribed using `gnus-subscribe-options-newsgroup-method'.")
 
 (defvar gnus-options-subscribe nil
   "*All new groups matching this regexp will be subscribed unconditionally.
 Note that this variable deals only with new newsgroups.         This variable
-does not affect old newsgroups.")
+does not affect old newsgroups.
+
+New groups that match this regexp will not be handled by
+`gnus-subscribe-newsgroup-method'.  Instead, they will
+be subscribed using `gnus-subscribe-options-newsgroup-method'.")
 
 (defvar gnus-options-not-subscribe nil
   "*All new groups matching this regexp will be ignored.
@@ -1359,9 +1407,15 @@ It calls `gnus-summary-expire-articles' by default.")
 (defvar gnus-summary-exit-hook nil
   "*A hook called on exit from the summary buffer.")
 
+(defvar gnus-check-bogus-groups-hook nil
+  "A hook run after removing bogus groups.")
+
 (defvar gnus-group-catchup-group-hook nil
   "*A hook run when catching up a group from the group buffer.")
 
+(defvar gnus-group-update-group-hook nil
+  "*A hook called when updating group lines.")
+
 (defvar gnus-open-server-hook nil
   "*A hook called just before opening connection to the news server.")
 
@@ -1417,12 +1471,6 @@ If you want to run a special decoding program like nkf, use this hook.")
 ;(add-hook 'gnus-article-display-hook 'gnus-article-treat-overstrike)
 ;(add-hook 'gnus-article-display-hook 'gnus-article-maybe-highlight)
 
-(defvar gnus-article-x-face-command
-  "{ echo '/* Width=48, Height=48 */'; uncompface; } | icontopbm | xv -quit -"
-  "String or function to be executed to display an X-Face header.
-If it is a string, the command will be executed in a sub-shell
-asynchronously.         The compressed face will be piped to this command.")
-
 (defvar gnus-article-x-face-too-ugly nil
   "Regexp matching posters whose face shouldn't be shown automatically.")
 
@@ -1698,7 +1746,7 @@ variable (string, integer, character, etc).")
     (?A gnus-tmp-article-number ?d)
     (?Z gnus-tmp-unread-and-unselected ?s)
     (?V gnus-version ?s)
-    (?U gnus-tmp-unread ?d)
+    (?U gnus-tmp-unread-and-unticked ?d)
     (?S gnus-tmp-subject ?s)
     (?e gnus-tmp-unselected ?d)
     (?u gnus-tmp-user-defined ?s)
@@ -1723,7 +1771,7 @@ variable (string, integer, character, etc).")
   "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
   "The mail address of the Gnus maintainers.")
 
-(defconst gnus-version-number "5.2.3"
+(defconst gnus-version-number "5.2.35"
   "Version number for this version of Gnus.")
 
 (defconst gnus-version (format "Gnus v%s" gnus-version-number)
@@ -1732,8 +1780,12 @@ variable (string, integer, character, etc).")
 (defvar gnus-info-nodes
   '((gnus-group-mode "(gnus)The Group Buffer")
     (gnus-summary-mode "(gnus)The Summary Buffer")
-    (gnus-article-mode "(gnus)The Article Buffer"))
-  "Assoc list of major modes and related Info nodes.")
+    (gnus-article-mode "(gnus)The Article Buffer")
+    (gnus-server-mode "(gnus)The Server Buffer")
+    (gnus-browse-mode "(gnus)Browse Foreign Server")
+    (gnus-tree-mode "(gnus)Tree Display")
+    )
+  "Alist of major modes and related Info nodes.")
 
 (defvar gnus-group-buffer "*Group*")
 (defvar gnus-summary-buffer "*Summary*")
@@ -1934,12 +1986,12 @@ gnus-newsrc-hashtb should be kept so that both hold the same information.")
     gnus-newsgroup-scored gnus-newsgroup-kill-headers
     gnus-newsgroup-async gnus-thread-expunge-below
     gnus-score-alist gnus-current-score-file gnus-summary-expunge-below
-    (gnus-summary-mark-below . 0)
+    (gnus-summary-mark-below . global)
     gnus-newsgroup-active gnus-scores-exclude-files
     gnus-newsgroup-history gnus-newsgroup-ancient
     gnus-newsgroup-sparse
     (gnus-newsgroup-adaptive . gnus-use-adaptive-scoring)
-    gnus-newsgroup-adaptive-score-file
+    gnus-newsgroup-adaptive-score-file (gnus-reffed-article-number . -1)
     (gnus-newsgroup-expunged-tally . 0)
     gnus-cache-removable-articles gnus-newsgroup-cached
     gnus-newsgroup-data gnus-newsgroup-data-reverse
@@ -1995,17 +2047,14 @@ Thank you for your help in stamping out bugs.
      ("nnvirtual" nnvirtual-catchup-group)
      ("timezone" timezone-make-date-arpa-standard timezone-fix-time
       timezone-make-sortable-date timezone-make-time-string)
-     ("sendmail" mail-position-on-field mail-setup)
      ("rmailout" rmail-output)
-     ("rnewspost" news-mail-other-window news-reply-yank-original
-      news-caesar-buffer-body)
      ("rmail" rmail-insert-rmail-file-header rmail-count-new-messages
       rmail-show-message)
      ("gnus-soup" :interactive t
       gnus-group-brew-soup gnus-brew-soup gnus-soup-add-article
       gnus-soup-send-replies gnus-soup-save-areas gnus-soup-pack-packet)
      ("nnsoup" nnsoup-pack-replies)
-     ("gnus-scomo" :interactive t gnus-score-mode)
+     ("score-mode" :interactive t gnus-score-mode)
      ("gnus-mh" gnus-mh-mail-setup gnus-summary-save-article-folder
       gnus-Folder-save-name gnus-folder-save-name)
      ("gnus-mh" :interactive t gnus-summary-save-in-folder)
@@ -2078,25 +2127,25 @@ Thank you for your help in stamping out bugs.
       gnus-uu-decode-binhex-view)
      ("gnus-msg" (gnus-summary-send-map keymap)
       gnus-mail-yank-original gnus-mail-send-and-exit
-      gnus-sendmail-setup-mail gnus-article-mail
-      gnus-inews-message-id gnus-new-mail gnus-mail-reply)
+      gnus-article-mail gnus-new-mail gnus-mail-reply
+      gnus-copy-article-buffer)
      ("gnus-msg" :interactive t
       gnus-group-post-news gnus-group-mail gnus-summary-post-news
       gnus-summary-followup gnus-summary-followup-with-original
-      gnus-summary-followup-and-reply
-      gnus-summary-followup-and-reply-with-original
       gnus-summary-cancel-article gnus-summary-supersede-article
-      gnus-post-news gnus-inews-news gnus-cancel-news
+      gnus-post-news gnus-inews-news 
       gnus-summary-reply gnus-summary-reply-with-original
       gnus-summary-mail-forward gnus-summary-mail-other-window
       gnus-bug)
      ("gnus-picon" :interactive t gnus-article-display-picons
-      gnus-group-display-picons gnus-picons-article-display-x-face)
+      gnus-group-display-picons gnus-picons-article-display-x-face
+      gnus-picons-display-x-face)
      ("gnus-gl" bbb-login bbb-logout bbb-grouplens-group-p 
       gnus-grouplens-mode)
+     ("smiley" :interactive t gnus-smiley-display)
      ("gnus-vm" gnus-vm-mail-setup)
      ("gnus-vm" :interactive t gnus-summary-save-in-vm
-      gnus-summary-save-article-vm gnus-yank-article))))
+      gnus-summary-save-article-vm))))
 
 \f
 
@@ -2127,6 +2176,10 @@ Thank you for your help in stamping out bugs.
             ,@forms)
         (select-window ,tempvar)))))
 
+(put 'gnus-eval-in-buffer-window 'lisp-indent-function 1)
+(put 'gnus-eval-in-buffer-window 'lisp-indent-hook 1)
+(put 'gnus-eval-in-buffer-window 'edebug-form-spec '(form body))
+
 (defmacro gnus-gethash (string hashtable)
   "Get hash value of STRING in HASHTABLE."
   `(symbol-value (intern-soft ,string ,hashtable)))
@@ -2218,6 +2271,18 @@ Thank you for your help in stamping out bugs.
   (and gnus-group-buffer
        (get-buffer gnus-group-buffer)))
 
+(defun gnus-delete-first (elt list)
+  "Delete by side effect the first occurrence of ELT as a member of LIST."
+  (if (equal (car list) elt)
+      (cdr list)
+    (let ((total list))
+      (while (and (cdr list)
+                 (not (equal (cadr list) elt)))
+       (setq list (cdr list)))
+      (when (cdr list)
+       (setcdr list (cddr list)))
+      total)))
+
 ;; Delete the current line (and the next N lines.);
 (defmacro gnus-delete-line (&optional n)
   `(delete-region (progn (beginning-of-line) (point))
@@ -2300,6 +2365,16 @@ Thank you for your help in stamping out bugs.
          flist)
       (cons 'progn (cddr fval)))))
 
+;; Find out whether the gnus-visual TYPE is wanted.
+(defun gnus-visual-p (&optional type class)
+  (and gnus-visual                     ; Has to be non-nil, at least.
+       (if (not type)                  ; We don't care about type.
+          gnus-visual
+        (if (listp gnus-visual)        ; It's a list, so we check it.
+            (or (memq type gnus-visual)
+                (memq class gnus-visual))
+          t))))
+
 ;;; Load the compatability functions.
 
 (require 'gnus-cus)
@@ -2901,7 +2976,10 @@ If variable `gnus-use-long-file-name' is non-nil, it is
              (setq prefixes (cons prefix prefixes))
              (message "Descend hierarchy %s? ([y]nsq): "
                       (substring prefix 1 (1- (length prefix))))
-             (setq ans (read-char))
+             (while (not (memq (setq ans (read-char)) '(?y ?\n ?n ?s ?q)))
+               (ding)
+               (message "Descend hierarchy %s? ([y]nsq): "
+                        (substring prefix 1 (1- (length prefix)))))
              (cond ((= ans ?n)
                     (while (and groups
                                 (string-match prefix
@@ -2927,7 +3005,9 @@ If variable `gnus-use-long-file-name' is non-nil, it is
                       (setq groups (cdr groups))))
                    (t nil)))
          (message "Subscribe %s? ([n]yq)" (car groups))
-         (setq ans (read-char))
+         (while (not (memq (setq ans (read-char)) '(?y ?\n ?q ?n)))
+           (ding)
+           (message "Subscribe %s? ([n]yq)" (car groups)))
          (setq group (car groups))
          (cond ((= ans ?y)
                 (gnus-subscribe-alphabetically (car groups))
@@ -2976,7 +3056,8 @@ If variable `gnus-use-long-file-name' is non-nil, it is
        (setq groupkey
              (if (string-match "^\\(.*\\)\\.[^.]+$" groupkey)
                  (substring groupkey (match-beginning 1) (match-end 1)))))
-      (gnus-subscribe-newsgroup newgroup before))))
+      (gnus-subscribe-newsgroup newgroup before))
+    (kill-buffer (current-buffer))))
 
 (defun gnus-subscribe-interactively (group)
   "Subscribe the new GROUP interactively.
@@ -3081,49 +3162,50 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
 ;; all whitespace.
 ;; Written by Stainless Steel Rat <ratinox@ccs.neu.edu>.
 (defun gnus-simplify-buffer-fuzzy ()
-  (goto-char (point-min))
-  (while (search-forward "\t" nil t)
-    (replace-match " " t t))
-  (goto-char (point-min))
-  (re-search-forward "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *" nil t)
-  (goto-char (match-beginning 0))
-  (while (or
-         (looking-at "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *")
-         (looking-at "^[[].*: .*[]]$"))
+  (let ((case-fold-search t))
+    (goto-char (point-min))
+    (while (search-forward "\t" nil t)
+      (replace-match " " t t))
     (goto-char (point-min))
-    (while (re-search-forward "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *"
-                             nil t)
+    (re-search-forward "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *" nil t)
+    (goto-char (match-beginning 0))
+    (while (or
+           (looking-at "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *")
+           (looking-at "^[[].*: .*[]]$"))
+      (goto-char (point-min))
+      (while (re-search-forward "^ *\\(re\\|fwd\\)[[{(^0-9]*[])}]?[:;] *"
+                               nil t)
+       (replace-match "" t t))
+      (goto-char (point-min))
+      (while (re-search-forward "^[[].*: .*[]]$" nil t)
+       (goto-char (match-end 0))
+       (delete-char -1)
+       (delete-region
+        (progn (goto-char (match-beginning 0)))
+        (re-search-forward ":"))))
+    (goto-char (point-min))
+    (while (re-search-forward " *[[{(][^()\n]*[]})] *$" nil t)
       (replace-match "" t t))
     (goto-char (point-min))
-    (while (re-search-forward "^[[].*: .*[]]$" nil t)
-      (goto-char (match-end 0))
-      (delete-char -1)
-      (delete-region
-       (progn (goto-char (match-beginning 0)))
-       (re-search-forward ":"))))
-  (goto-char (point-min))
-  (while (re-search-forward " *[[{(][^()\n]*[]})] *$" nil t)
-    (replace-match "" t t))
-  (goto-char (point-min))
-  (while (re-search-forward "  +" nil t)
-    (replace-match " " t t))
-  (goto-char (point-min))
-  (while (re-search-forward " $" nil t)
-    (replace-match "" t t))
-  (goto-char (point-min))
-  (while (re-search-forward "^ +" nil t)
-    (replace-match "" t t))
-  (goto-char (point-min))
-  (when gnus-simplify-subject-fuzzy-regexp
-    (if (listp gnus-simplify-subject-fuzzy-regexp)
-       (let ((list gnus-simplify-subject-fuzzy-regexp))
-         (while list
-           (goto-char (point-min))
-           (while (re-search-forward (car list) nil t)
-             (replace-match "" t t))
-           (setq list (cdr list))))
-      (while (re-search-forward gnus-simplify-subject-fuzzy-regexp nil t)
-       (replace-match "" t t)))))
+    (while (re-search-forward "  +" nil t)
+      (replace-match " " t t))
+    (goto-char (point-min))
+    (while (re-search-forward " $" nil t)
+      (replace-match "" t t))
+    (goto-char (point-min))
+    (while (re-search-forward "^ +" nil t)
+      (replace-match "" t t))
+    (goto-char (point-min))
+    (when gnus-simplify-subject-fuzzy-regexp
+      (if (listp gnus-simplify-subject-fuzzy-regexp)
+         (let ((list gnus-simplify-subject-fuzzy-regexp))
+           (while list
+             (goto-char (point-min))
+             (while (re-search-forward (car list) nil t)
+               (replace-match "" t t))
+             (setq list (cdr list))))
+       (while (re-search-forward gnus-simplify-subject-fuzzy-regexp nil t)
+         (replace-match "" t t))))))
 
 (defun gnus-simplify-subject-fuzzy (subject)
   "Siplify a subject string fuzzily."
@@ -3174,6 +3256,10 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
        gnus-server-alist nil
        gnus-group-list-mode nil
        gnus-opened-servers nil
+       gnus-group-mark-positions nil
+       gnus-newsgroup-data nil
+       gnus-newsgroup-unreads nil
+       nnoo-state-alist nil
        gnus-current-select-method nil)
   (gnus-shutdown 'gnus)
   ;; Kill the startup file.
@@ -3190,10 +3276,14 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
   (while gnus-buffer-list
     (gnus-kill-buffer (pop gnus-buffer-list)))
   ;; Remove Gnus frames.
+  (gnus-kill-gnus-frames))
+
+(defun gnus-kill-gnus-frames ()
+  "Kill all frames Gnus has created."
   (while gnus-created-frames
     (when (frame-live-p (car gnus-created-frames))
       ;; We slap a condition-case around this `delete-frame' to ensure 
-      ;; agains errors if we try do delete the single frame that's left.
+      ;; against errors if we try do delete the single frame that's left.
       (condition-case ()
          (delete-frame (car gnus-created-frames))
        (error nil)))
@@ -3227,13 +3317,15 @@ If RE-ONLY is non-nil, strip leading `Re:'s only."
        (or (not (numberp (nth i elem)))
            (zerop (nth i elem))
            (progn
-             (setq perc  (/ (float (nth 0 elem)) total))
+             (setq perc (if (= i 2)
+                            1.0
+                          (/ (float (nth 0 elem)) total)))
              (setq out (cons (if (eq pbuf (nth i types))
-                                 (vector (nth i types) perc 'point)
-                               (vector (nth i types) perc))
+                                 (list (nth i types) perc 'point)
+                               (list (nth i types) perc))
                              out))))
        (setq i (1+ i)))
-      (list (nreverse out)))))
+      `(vertical 1.0 ,@(nreverse out)))))
 
 ;;;###autoload
 (defun gnus-add-configuration (conf)
@@ -3507,9 +3599,10 @@ should have point."
             (delete-windows-on (car bufs)))
        (setq bufs (cdr bufs))))))
 
-(defun gnus-version ()
-  "Version numbers of this version of Gnus."
-  (interactive)
+(defun gnus-version (&optional arg)
+  "Version number of this version of Gnus.
+If ARG, insert string at point."
+  (interactive "P")
   (let ((methods gnus-valid-select-methods)
        (mess gnus-version)
        meth)
@@ -3523,7 +3616,9 @@ should have point."
           (stringp (symbol-value meth))
           (setq mess (concat mess "; " (symbol-value meth))))
       (setq methods (cdr methods)))
-    (gnus-message 2 mess)))
+    (if arg
+       (insert (message mess))
+      (message mess))))
 
 (defun gnus-info-find-node ()
   "Find Info documentation of Gnus."
@@ -3754,7 +3849,7 @@ simple-first is t, first argument is already simplified."
     (apply 'format args)))
 
 (defun gnus-error (level &rest args)
-  "Beep an error if `gnus-verbose' is on LEVEL or less."
+  "Beep an error if LEVEL is equal to or less than `gnus-verbose'."
   (when (<= (floor level) gnus-verbose)
     (apply 'message args)
     (ding)
@@ -3784,22 +3879,12 @@ simple-first is t, first argument is already simplified."
   (remove-text-properties b e gnus-hidden-properties)
   (when (memq 'intangible gnus-hidden-properties)
     (gnus-put-text-property (max (1- b) (point-min))
-                      b 'intangible nil)))
+                           b 'intangible nil)))
 
 (defun gnus-hide-text-type (b e type)
   "Hide text of TYPE between B and E."
   (gnus-hide-text b e (cons 'gnus-type (cons type gnus-hidden-properties))))
 
-;; Find out whether the gnus-visual TYPE is wanted.
-(defun gnus-visual-p (&optional type class)
-  (and gnus-visual                     ; Has to be non-nil, at least.
-       (if (not type)                  ; We don't care about type.
-          gnus-visual
-        (if (listp gnus-visual)        ; It's a list, so we check it.
-            (or (memq type gnus-visual)
-                (memq class gnus-visual))
-          t))))
-
 (defun gnus-parent-headers (headers &optional generation)
   "Return the headers of the GENERATIONeth parent of HEADERS."
   (unless generation 
@@ -4150,7 +4235,7 @@ Note: LIST has to be sorted over `<'."
     "V" gnus-version
     "s" gnus-group-save-newsrc
     "z" gnus-group-suspend
-    "Z" gnus-group-clear-dribble
+;    "Z" gnus-group-clear-dribble
     "q" gnus-group-exit
     "Q" gnus-group-quit
     "?" gnus-group-describe-briefly
@@ -4428,7 +4513,8 @@ prompt the user for the name of an NNTP server to use."
            (setcar (cddr entry) (gnus-byte-code 'gnus-tmp-func)))))
 
       (push (cons 'version emacs-version) gnus-format-specs)
-
+      ;; Mark the .newsrc.eld file as "dirty".
+      (gnus-dribble-enter " ")
       (gnus-message 7 "Compiling user specs...done"))))
 
 (defun gnus-indent-rigidly (start end arg)
@@ -4714,6 +4800,20 @@ If REGEXP, only list groups matching REGEXP."
       (pop opened))
     out))
 
+(defun gnus-archive-server-wanted-p ()
+  "Say whether the user wants to use the archive server."
+  (cond 
+   ((or (not gnus-message-archive-method)
+       (not gnus-message-archive-group))
+    nil)
+   ((and gnus-message-archive-method gnus-message-archive-group)
+    t)
+   (t
+    (let ((active (cadr (assq 'nnfolder-active-file
+                             gnus-message-archive-method))))
+      (and active
+          (file-exists-p active))))))
+
 (defun gnus-group-prefixed-name (group method)
   "Return the whole name from GROUP and METHOD."
   (and (stringp method) (setq method (gnus-server-to-method method)))
@@ -4896,16 +4996,17 @@ increase the score of each group you read."
         (group (gnus-group-group-name))
         (entry (and group (gnus-gethash group gnus-newsrc-hashtb)))
         gnus-group-indentation)
-    (and entry
-        (not (gnus-ephemeral-group-p group))
-        (gnus-dribble-enter
-         (concat "(gnus-group-set-info '"
-                 (prin1-to-string (nth 2 entry)) ")")))
-    (setq gnus-group-indentation (gnus-group-group-indentation))
-    (gnus-delete-line)
-    (gnus-group-insert-group-line-info group)
-    (forward-line -1)
-    (gnus-group-position-point)))
+    (when group
+      (and entry
+          (not (gnus-ephemeral-group-p group))
+          (gnus-dribble-enter
+           (concat "(gnus-group-set-info '"
+                   (prin1-to-string (nth 2 entry)) ")")))
+      (setq gnus-group-indentation (gnus-group-group-indentation))
+      (gnus-delete-line)
+      (gnus-group-insert-group-line-info group)
+      (forward-line -1)
+      (gnus-group-position-point))))
 
 (defun gnus-group-insert-group-line-info (group)
   "Insert GROUP on the current line."
@@ -5025,7 +5126,10 @@ already."
          (goto-char loc)
          (let ((gnus-group-indentation (gnus-group-group-indentation)))
            (gnus-delete-line)
-           (gnus-group-insert-group-line-info group))
+           (gnus-group-insert-group-line-info group)
+           (save-excursion
+             (forward-line -1)
+             (run-hooks 'gnus-group-update-group-hook)))
          (setq loc (1+ loc)))
        (unless (or found visible-only)
          ;; No such line in the buffer, find out where it's supposed to
@@ -5044,7 +5148,10 @@ already."
              (or entry (goto-char (point-max)))))
          ;; Finally insert the line.
          (let ((gnus-group-indentation (gnus-group-group-indentation)))
-           (gnus-group-insert-group-line-info group)))
+           (gnus-group-insert-group-line-info group)
+           (save-excursion
+             (forward-line -1)
+             (run-hooks 'gnus-group-update-group-hook))))
        (gnus-group-set-mode-line)))))
 
 (defun gnus-group-set-mode-line ()
@@ -5064,23 +5171,25 @@ already."
             (max-len 60)
             gnus-tmp-header            ;Dummy binding for user-defined formats
             ;; Get the resulting string.
+            (modified 
+             (and gnus-dribble-buffer
+                  (buffer-name gnus-dribble-buffer)
+                  (buffer-modified-p gnus-dribble-buffer)
+                  (save-excursion
+                    (set-buffer gnus-dribble-buffer)
+                    (not (zerop (buffer-size))))))
             (mode-string (eval gformat)))
        ;; Say whether the dribble buffer has been modified.
        (setq mode-line-modified
-             (if (and gnus-dribble-buffer
-                      (buffer-name gnus-dribble-buffer)
-                      (buffer-modified-p gnus-dribble-buffer)
-                      (save-excursion
-                        (set-buffer gnus-dribble-buffer)
-                        (not (zerop (buffer-size)))))
-                 "---*- " "----- "))
+             (if modified "---*- " "----- "))
        ;; If the line is too long, we chop it off.
        (when (> (length mode-string) max-len)
          (setq mode-string (substring mode-string 0 (- max-len 4))))
        (prog1
            (setq mode-line-buffer-identification 
-                 (list mode-string))
-         (set-buffer-modified-p t))))))
+                 (gnus-mode-line-buffer-identification
+                  (list mode-string)))
+         (set-buffer-modified-p modified))))))
 
 (defun gnus-group-group-name ()
   "Get the name of the newsgroup on the current line."
@@ -5416,15 +5525,15 @@ Returns whether the fetching was successful or not."
                                             group gnus-active-hashtb))))
       (and b (goto-char b)))))
 
-(defun gnus-group-next-group (n)
+(defun gnus-group-next-group (n &optional silent)
   "Go to next N'th newsgroup.
 If N is negative, search backward instead.
 Returns the difference between N and the number of skips actually
 done."
   (interactive "p")
-  (gnus-group-next-unread-group n t))
+  (gnus-group-next-unread-group n t nil silent))
 
-(defun gnus-group-next-unread-group (n &optional all level)
+(defun gnus-group-next-unread-group (n &optional all level silent)
   "Go to next N'th unread newsgroup.
 If N is negative, search backward instead.
 If ALL is non-nil, choose any newsgroup, unread or not.
@@ -5440,8 +5549,10 @@ made."
                (gnus-group-search-forward
                 backward (or (not gnus-group-goto-unread) all) level))
       (setq n (1- n)))
-    (if (/= 0 n) (gnus-message 7 "No more%s newsgroups%s" (if all "" " unread")
-                              (if level " on this level or higher" "")))
+    (when (and (/= 0 n)
+              (not silent))
+      (gnus-message 7 "No more%s newsgroups%s" (if all "" " unread")
+                   (if level " on this level or higher" "")))
     n))
 
 (defun gnus-group-prev-group (n)
@@ -5577,10 +5688,11 @@ ADDRESS."
     t))
 
 (defun gnus-group-delete-group (group &optional force)
-  "Delete the current group.
+  "Delete the current group.  Only meaningful with mail groups.
 If FORCE (the prefix) is non-nil, all the articles in the group will
 be deleted.  This is \"deleted\" as in \"removed forever from the face
-of the Earth\".         There is no undo."
+of the Earth\".         There is no undo.  The user will be prompted before
+doing the deletion."
   (interactive
    (list (gnus-group-group-name)
         current-prefix-arg))
@@ -6029,6 +6141,8 @@ read.  Cross references (Xref: header) of articles are ignored.
 The difference between N and actual number of newsgroups that were
 caught up is returned."
   (interactive "P")
+  (unless (gnus-group-group-name)
+    (error "No group on the current line"))
   (if (not (or (not gnus-interactive-catchup) ;Without confirmation?
               gnus-expert-user
               (gnus-y-or-n-p
@@ -6120,7 +6234,8 @@ or nil if no action could be taken."
                     (gnus-uncompress-sequence (cdr expirable)) group))
                ;; Just expire using the normal expiry values.
                (gnus-request-expire-articles
-                (gnus-uncompress-sequence (cdr expirable)) group)))))
+                (gnus-uncompress-sequence (cdr expirable)) group))))
+           (gnus-close-group group))
          (gnus-message 6 "Expiring articles in %s...done" group)))
       (gnus-group-position-point))))
 
@@ -6291,6 +6406,12 @@ of groups killed."
        (while groups
          (gnus-group-remove-mark (setq group (pop groups)))
          (gnus-delete-line)
+         (push group gnus-killed-list)
+         (setq gnus-newsrc-alist
+               (delq (assoc group gnus-newsrc-alist)
+                     gnus-newsrc-alist))
+         (when gnus-group-change-level-function
+           (funcall gnus-group-change-level-function group 9 3))
          (cond
           ((setq entry (gnus-gethash group gnus-newsrc-hashtb))
            (push (cons (car entry) (nth 2 entry))
@@ -6348,8 +6469,10 @@ is returned."
     (let* ((prev gnus-newsrc-alist)
           (alist (cdr prev)))
       (while alist
-       (if (= (gnus-info-level level) level)
-           (setcdr prev (cdr alist))
+       (if (= (gnus-info-level (car alist)) level)
+           (progn
+             (push (gnus-info-group (car alist)) gnus-killed-list)
+             (setcdr prev (cdr alist)))
          (setq prev alist))
        (setq alist (cdr alist)))
       (gnus-make-hashtable-from-newsrc-alist)
@@ -6470,7 +6593,10 @@ If N is negative, this group and the N-1 previous groups will be checked."
            (unless (gnus-virtual-group-p group)
              (gnus-close-group group))
            (gnus-group-update-group group))
-       (gnus-error 3 "%s error: %s" group (gnus-status-message group))))
+       (if (eq (gnus-server-status (gnus-find-method-for-group group))
+               'denied)
+           (gnus-error "Server denied access")
+         (gnus-error 3 "%s error: %s" group (gnus-status-message group)))))
     (when beg (goto-char beg))
     (when gnus-goto-next-group-when-activating
       (gnus-group-next-unread-group 1 t))
@@ -6481,11 +6607,13 @@ If N is negative, this group and the N-1 previous groups will be checked."
   "Fetch the FAQ for the current group."
   (interactive
    (list
-    (gnus-group-real-name (gnus-group-group-name))
+    (and (gnus-group-group-name)
+        (gnus-group-real-name (gnus-group-group-name)))
     (cond (current-prefix-arg
           (completing-read
            "Faq dir: " (and (listp gnus-group-faq-directory)
-                            gnus-group-faq-directory))))))
+                            (mapcar (lambda (file) (list file))
+                                    gnus-group-faq-directory)))))))
   (or faq-dir
       (setq faq-dir (if (listp gnus-group-faq-directory)
                        (car gnus-group-faq-directory)
@@ -6500,16 +6628,17 @@ If N is negative, this group and the N-1 previous groups will be checked."
 (defun gnus-group-describe-group (force &optional group)
   "Display a description of the current newsgroup."
   (interactive (list current-prefix-arg (gnus-group-group-name)))
-  (and force (setq gnus-description-hashtb nil))
-  (let ((method (gnus-find-method-for-group group))
-       desc)
+  (let* ((method (gnus-find-method-for-group group))
+        (mname (gnus-group-prefixed-name "" method))
+        desc)
+    (when (and force
+              gnus-description-hashtb)
+      (gnus-sethash mname nil gnus-description-hashtb))
     (or group (error "No group name given"))
     (and (or (and gnus-description-hashtb
                  ;; We check whether this group's method has been
                  ;; queried for a description file.
-                 (gnus-gethash
-                  (gnus-group-prefixed-name "" method)
-                  gnus-description-hashtb))
+                 (gnus-gethash mname gnus-description-hashtb))
             (setq desc (gnus-group-get-description group))
             (gnus-read-descriptions-file method))
         (gnus-message 1
@@ -6540,7 +6669,7 @@ If N is negative, this group and the N-1 previous groups will be checked."
     (goto-char (point-min))
     (gnus-group-position-point)))
 
-;; Suggested by by Daniel Quinlan <quinlan@best.com>.
+;; Suggested by Daniel Quinlan <quinlan@best.com>.
 (defun gnus-group-apropos (regexp &optional search-description)
   "List all newsgroups that have names that match a regexp."
   (interactive "sGnus apropos (regexp): ")
@@ -6603,7 +6732,7 @@ This command may read the active file."
   (interactive "P\nsList newsgroups matching: ")
   ;; First make sure active file has been read.
   (when (and level
-            (>= (prefix-numeric-value level) gnus-level-killed))
+            (> (prefix-numeric-value level) gnus-level-killed))
     (gnus-get-killed-groups))
   (gnus-group-prepare-flat (or level gnus-level-subscribed)
                           all (or lowest 1) regexp)
@@ -6677,19 +6806,18 @@ The hook gnus-suspend-gnus-hook is called before actually suspending."
   (interactive)
   (run-hooks 'gnus-suspend-gnus-hook)
   ;; Kill Gnus buffers except for group mode buffer.
-  (let ((group-buf (get-buffer gnus-group-buffer)))
-    ;; Do this on a separate list in case the user does a ^G before we finish
-    (let ((gnus-buffer-list
-          (delq group-buf (delq gnus-dribble-buffer
-                                (append gnus-buffer-list nil)))))
-      (while gnus-buffer-list
-       (gnus-kill-buffer (car gnus-buffer-list))
-       (setq gnus-buffer-list (cdr gnus-buffer-list))))
-    (if group-buf
-       (progn
-         (setq gnus-buffer-list (list group-buf))
-         (bury-buffer group-buf)
-         (delete-windows-on group-buf t)))))
+  (let* ((group-buf (get-buffer gnus-group-buffer))
+        ;; Do this on a separate list in case the user does a ^G before we finish
+        (gnus-buffer-list
+         (delete group-buf (delete gnus-dribble-buffer
+                                   (append gnus-buffer-list nil)))))
+    (while gnus-buffer-list
+      (gnus-kill-buffer (pop gnus-buffer-list)))
+    (gnus-kill-gnus-frames)
+    (when group-buf
+      (setq gnus-buffer-list (list group-buf))
+      (bury-buffer group-buf)
+      (delete-windows-on group-buf t))))
 
 (defun gnus-group-clear-dribble ()
   "Clear all information from the dribble buffer."
@@ -7049,6 +7177,7 @@ and the second element is the address."
     "s" gnus-article-hide-signature
     "c" gnus-article-hide-citation
     "p" gnus-article-hide-pgp
+    "P" gnus-article-hide-pem
     "\C-c" gnus-article-hide-citation-maybe)
 
   (gnus-define-keys (gnus-summary-wash-highlight-map "H" gnus-summary-wash-map)
@@ -7123,15 +7252,7 @@ The following commands are available:
             (gnus-visual-p 'summary-menu 'menu))
     (gnus-summary-make-menu-bar))
   (kill-all-local-variables)
-  (let ((locals gnus-summary-local-variables))
-    (while locals
-      (if (consp (car locals))
-         (progn
-           (make-local-variable (caar locals))
-           (set (caar locals) (eval (cdar locals))))
-       (make-local-variable (car locals))
-       (set (car locals) nil))
-      (setq locals (cdr locals))))
+  (gnus-summary-make-local-variables)
   (gnus-make-thread-indent-array)
   (gnus-simplify-mode-line)
   (setq major-mode 'gnus-summary-mode)
@@ -7148,8 +7269,28 @@ The following commands are available:
   (make-local-variable 'gnus-summary-line-format)
   (make-local-variable 'gnus-summary-line-format-spec)
   (make-local-variable 'gnus-summary-mark-positions)
+  (gnus-make-local-hook 'post-command-hook)
+  (gnus-add-hook 'post-command-hook 'gnus-clear-inboxes-moved nil t)
   (run-hooks 'gnus-summary-mode-hook))
 
+(defun gnus-summary-make-local-variables ()
+  "Make all the local summary buffer variables."
+  (let ((locals gnus-summary-local-variables)
+       global local)
+    (while (setq local (pop locals))
+      (if (consp local)
+         (progn
+           (if (eq (cdr local) 'global)
+               ;; Copy the global value of the variable.
+               (setq global (symbol-value (car local)))
+             ;; Use the value from the list.
+             (setq global (eval (cdr local))))
+           (make-local-variable (car local))
+           (set (car local) global))
+       ;; Simple nil-valued local variable.
+       (make-local-variable local)
+       (set local nil)))))
+
 (defun gnus-summary-make-display-table ()
   ;; Change the display table. Odd characters have a tendency to mess
   ;; up nicely formatted displays - we make all possible glyphs
@@ -7483,6 +7624,7 @@ This is all marks except unread, ticked, dormant, and expirable."
          (article-buffer gnus-article-buffer)
          (original gnus-original-article-buffer)
          (gac gnus-article-current)
+         (reffed gnus-reffed-article-number)
          (score-file gnus-current-score-file))
       (save-excursion
        (set-buffer gnus-group-buffer)
@@ -7495,6 +7637,7 @@ This is all marks except unread, ticked, dormant, and expirable."
        (setq gnus-summary-buffer summary)
        (setq gnus-article-buffer article-buffer)
        (setq gnus-original-article-buffer original)
+       (setq gnus-reffed-article-number reffed)
        (setq gnus-current-score-file score-file)))))
 
 (defun gnus-summary-last-article-p (&optional article)
@@ -7746,7 +7889,7 @@ If NO-DISPLAY, don't generate a summary buffer."
        (cond (gnus-newsgroup-dormant
               (gnus-summary-limit-include-dormant))
              ((and gnus-newsgroup-scored show-all)
-              (gnus-summary-limit-include-expunged))))
+              (gnus-summary-limit-include-expunged t))))
       ;; Function `gnus-apply-kill-file' must be called in this hook.
       (run-hooks 'gnus-apply-kill-hook)
       (if (and (zerop (buffer-size))
@@ -8042,26 +8185,32 @@ If NO-DISPLAY, don't generate a summary buffer."
                      (delq number gnus-newsgroup-unselected)))
            (push number gnus-newsgroup-ancient)))))))
 
-(defun gnus-summary-update-article (article &optional header)
+(defun gnus-summary-update-article (article &optional iheader)
   "Update ARTICLE in the summary buffer."
   (set-buffer gnus-summary-buffer)
-  (let* ((header (or header (gnus-summary-article-header article)))
+  (let* ((header (or iheader (gnus-summary-article-header article)))
         (id (mail-header-id header))
         (data (gnus-data-find article))
         (thread (gnus-id-to-thread id))
+        (references (mail-header-references header))
         (parent
-         (gnus-id-to-thread (or (gnus-parent-id 
-                                 (mail-header-references header))
-                                "tull")))
+         (gnus-id-to-thread
+          (or (gnus-parent-id 
+               (if (and references
+                        (not (equal "" references)))
+                   references))
+              "none")))
         (buffer-read-only nil)
         (old (car thread))
         (number (mail-header-number header))
         pos)
     (when thread
-      (setcar thread nil)
+      ;; !!! Should this be in or not?
+      (unless iheader
+       (setcar thread nil))
       (when parent
        (delq thread parent))
-      (if (gnus-summary-insert-subject id header)
+      (if (gnus-summary-insert-subject id header iheader)
          ;; Set the (possibly) new article number in the data structure.
          (gnus-data-set-number data (gnus-id-to-article id))
        (setcar thread old)
@@ -8106,6 +8255,15 @@ If NO-DISPLAY, don't generate a summary buffer."
       (gnus-data-compute-positions)
       (setq gnus-newsgroup-threads (nconc threads gnus-newsgroup-threads)))))
 
+(defun gnus-number-to-header (number)
+  "Return the header for article NUMBER."
+  (let ((headers gnus-newsgroup-headers))
+    (while (and headers
+               (not (= number (mail-header-number (car headers)))))
+      (pop headers))
+    (when headers
+      (car headers))))
+
 (defun gnus-id-to-thread (id)
   "Return the (sub-)thread where ID appears."
   (gnus-gethash id gnus-newsgroup-dependencies))
@@ -8161,8 +8319,8 @@ If NO-DISPLAY, don't generate a summary buffer."
       (while threads
        (setq sub (car threads))
        (if (stringp (car sub))
-           ;; This is a gathered threads, so we look at the roots
-           ;; below it to find whether this article in in this
+           ;; This is a gathered thread, so we look at the roots
+           ;; below it to find whether this article is in this
            ;; gathered root.
            (progn
              (setq sub (cdr sub))
@@ -8328,22 +8486,30 @@ Unscored articles will be counted as having a score of zero."
 
 (defun gnus-thread-total-score (thread)
   ;;  This function find the total score of THREAD.
-  (if (consp thread)
-      (if (stringp (car thread))
-         (apply gnus-thread-score-function 0
-                (mapcar 'gnus-thread-total-score-1 (cdr thread)))
-       (gnus-thread-total-score-1 thread))
-    (gnus-thread-total-score-1 (list thread))))
+  (cond ((null thread)
+        0)
+       ((consp thread)
+        (if (stringp (car thread))
+            (apply gnus-thread-score-function 0
+                   (mapcar 'gnus-thread-total-score-1 (cdr thread)))
+          (gnus-thread-total-score-1 thread)))
+       (t
+        (gnus-thread-total-score-1 (list thread)))))
 
 (defun gnus-thread-total-score-1 (root)
   ;; This function find the total score of the thread below ROOT.
   (setq root (car root))
   (apply gnus-thread-score-function
-        (or (cdr (assq (mail-header-number root) gnus-newsgroup-scored))
-            gnus-summary-default-score 0)
-        (mapcar 'gnus-thread-total-score
-                (cdr (gnus-gethash (mail-header-id root)
-                                   gnus-newsgroup-dependencies)))))
+        (or (append
+             (mapcar 'gnus-thread-total-score
+                     (cdr (gnus-gethash (mail-header-id root)
+                                        gnus-newsgroup-dependencies)))
+                (if (> (mail-header-number root) 0)
+                    (list (or (cdr (assq (mail-header-number root) 
+                                         gnus-newsgroup-scored))
+                              gnus-summary-default-score 0))))
+            (list gnus-summary-default-score)
+            '(0))))
 
 ;; Added by Per Abrahamsen <amanda@iesd.auc.dk>.
 (defvar gnus-tmp-prev-subject nil)
@@ -8564,6 +8730,8 @@ or a straight list of headers."
                    gnus-cached-mark)
                   ((memq number gnus-newsgroup-replied)
                    gnus-replied-mark)
+                  ((memq number gnus-newsgroup-saved)
+                   gnus-saved-mark)
                   (t gnus-unread-mark))
             gnus-tmp-from (mail-header-from gnus-tmp-header)
             gnus-tmp-name
@@ -8746,13 +8914,12 @@ If READ-ALL is non-nil, all articles in the group are selected."
       (unless gnus-single-article-buffer
        (gnus-article-setup-buffer))
       ;; First and last article in this newsgroup.
-      (and gnus-newsgroup-headers
-          (setq gnus-newsgroup-begin
-                (mail-header-number (car gnus-newsgroup-headers)))
-          (setq gnus-newsgroup-end
-                (mail-header-number
-                 (gnus-last-element gnus-newsgroup-headers))))
-      (setq gnus-reffed-article-number -1)
+      (when gnus-newsgroup-headers
+       (setq gnus-newsgroup-begin
+             (mail-header-number (car gnus-newsgroup-headers))
+             gnus-newsgroup-end
+             (mail-header-number
+              (gnus-last-element gnus-newsgroup-headers))))
       ;; GROUP is successfully selected.
       (or gnus-newsgroup-headers t)))))
 
@@ -8789,7 +8956,8 @@ If READ-ALL is non-nil, all articles in the group are selected."
                           "How many articles from %s (default %d): "
                           gnus-newsgroup-name number))))
                    (if (string-match "^[ \t]*$" input) number input)))
-                ((and (> scored marked) (< scored number))
+                ((and (> scored marked) (< scored number)
+                      (> (- scored number) 20))
                  (let ((input
                         (read-string
                          (format "%s %s (%d scored, %d total): "
@@ -8846,7 +9014,7 @@ If READ-ALL is non-nil, all articles in the group are selected."
         (min (car active))
         (max (cdr active))
         (types gnus-article-mark-lists)
-        (uncompressed '(score bookmark))
+        (uncompressed '(score bookmark killed))
         marks var articles article mark)
 
     (while marked-lists
@@ -8862,14 +9030,15 @@ If READ-ALL is non-nil, all articles in the group are selected."
       ;; All articles have to be subsets of the active articles.
       (cond
        ;; Adjust "simple" lists.
-       ((memq mark '(tick dormant expirable reply killed save))
+       ((memq mark '(tick dormant expirable reply save))
        (while articles
          (when (or (< (setq article (pop articles)) min) (> article max))
            (set var (delq article (symbol-value var))))))
        ;; Adjust assocs.
-       ((memq mark '(score bookmark))
+       ((memq mark uncompressed)
        (while articles
-         (when (or (< (car (setq article (pop articles))) min)
+         (when (or (not (consp (setq article (pop articles))))
+                   (< (car article) min)
                    (> (car article) max))
            (set var (delq article (symbol-value var))))))))))
 
@@ -8904,7 +9073,8 @@ If READ-ALL is non-nil, all articles in the group are selected."
                                                (car type))))))
          (push (cons (cdr type)
                      (if (memq (cdr type) uncompressed) list
-                       (gnus-compress-sequence (set symbol (sort list '<)) t)))
+                       (gnus-compress-sequence 
+                        (set symbol (sort list '<)) t)))
                newmarked)))
 
       ;; Enter these new marks into the info of the group.
@@ -8996,7 +9166,9 @@ If WHERE is `summary', the summary mode line format will be used."
          ;; Pad the mode string a bit.
          (setq mode-string (format (format "%%-%ds" max-len) mode-string))))
       ;; Update the mode line.
-      (setq mode-line-buffer-identification (list mode-string))
+      (setq mode-line-buffer-identification 
+           (gnus-mode-line-buffer-identification
+            (list mode-string)))
       (set-buffer-modified-p t))))
 
 (defun gnus-create-xref-hashtb (from-newsgroup headers unreads)
@@ -9203,10 +9375,10 @@ The resulting hash table is returned, or nil if no Xrefs were found."
            (progn
              (goto-char p)
              (if (search-forward "\nreferences: " nil t)
-                 (prog1
-                     (gnus-header-value)
-                   (setq end (match-end 0))
-                   (save-excursion
+                 (progn
+                   (setq end (point))
+                   (prog1
+                       (gnus-header-value)
                      (setq ref
                            (buffer-substring
                             (progn
@@ -9385,13 +9557,12 @@ list of headers that match SEQUENCE (see `nntp-retrieve-headers')."
                (setq header nil))
            (setcar (symbol-value id-dep) header))
        (set id-dep (list header))))
-    (if header
-       (progn
-         (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 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))
 
 (defun gnus-article-get-xrefs ()
@@ -9417,15 +9588,17 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
                                               (progn (end-of-line) (point))))
                  (mail-header-set-xref headers xref))))))))
 
-(defun gnus-summary-insert-subject (id &optional old-header)
+(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 (or old-header (gnus-read-header id)))
+  (let ((header (if (and old-header use-old-header)
+                   old-header (gnus-read-header id)))
        (number (and (numberp id) id))
        pos)
     (when header
       ;; Rebuild the thread that this article is part of and go to the
       ;; article we have fetched.
-      (when old-header
+      (when (and (not gnus-show-threads)
+                old-header)
        (when (setq pos (text-property-any
                         (point-min) (point-max) 'gnus-number 
                         (mail-header-number old-header)))
@@ -9460,10 +9633,10 @@ This is meant to be called in `gnus-article-internal-prepare-hook'."
 the list of process marked articles, and the current article will be
 taken into consideration."
   (cond
-   ((and n (numberp n))
+   (n
     ;; A numerical prefix has been given.
     (let ((backward (< n 0))
-         (n (abs n))
+         (n (abs (prefix-numeric-value n)))
          articles article)
       (save-excursion
        (while
@@ -9789,6 +9962,8 @@ With arg, turn line truncation on iff arg is positive."
 The prefix argument ALL means to select all articles."
   (interactive "P")
   (gnus-set-global-variables)
+  (when (gnus-ephemeral-group-p gnus-newsgroup-name)
+    (error "Ephemeral groups can't be reselected"))
   (let ((current-subject (gnus-summary-article-number))
        (group gnus-newsgroup-name))
     (setq gnus-newsgroup-begin nil)
@@ -9801,7 +9976,7 @@ The prefix argument ALL means to select all articles."
       (save-excursion
        (gnus-group-get-new-news-this-group 1)))
     (gnus-group-read-group all t)
-    (gnus-summary-goto-subject current-subject)))
+    (gnus-summary-goto-subject current-subject nil t)))
 
 (defun gnus-summary-rescan-group (&optional all)
   "Exit the newsgroup, ask for new articles, and select the newsgroup."
@@ -10200,7 +10375,7 @@ If FORCE, also allow jumping to articles not currently shown."
     ;; We read in the article if we have to.
     (and (not data)
         force
-        (gnus-summary-insert-subject article (and (vectorp force) force))
+        (gnus-summary-insert-subject article (and (vectorp force) force) t)
         (setq data (gnus-data-find article)))
     (goto-char b)
     (if (not data)
@@ -10303,8 +10478,7 @@ If BACKWARD, the previous article is selected instead of the next."
    ;; If not, we try the first unread, if that is wanted.
    ((and subject
         gnus-auto-select-same
-        (or (gnus-summary-first-unread-article)
-            (eq (gnus-summary-article-mark) gnus-canceled-mark)))
+        (gnus-summary-first-unread-article))
     (gnus-summary-position-point)
     (gnus-message 6 "Wrapped"))
    ;; Try to get next/previous article not displayed in this group.
@@ -10327,7 +10501,8 @@ If BACKWARD, the previous article is selected instead of the next."
       (select-window (get-buffer-window (current-buffer)))
       ;; Select next unread newsgroup automagically.
       (cond
-       ((not gnus-auto-select-next)
+       ((or (not gnus-auto-select-next)
+           (not cmd))
        (gnus-message 7 "No more%s articles" (if unread " unread" "")))
        ((or (eq gnus-auto-select-next 'quietly)
            (and (eq gnus-auto-select-next 'slightly-quietly)
@@ -10437,9 +10612,8 @@ article."
              (not (equal (car gnus-article-current) gnus-newsgroup-name)))
          ;; Selected subject is different from current article's.
          (gnus-summary-display-article article)
-       (gnus-eval-in-buffer-window
-        gnus-article-buffer
-        (setq endp (gnus-article-next-page lines)))
+       (gnus-eval-in-buffer-window gnus-article-buffer
+         (setq endp (gnus-article-next-page lines)))
        (if endp
            (cond (circular
                   (gnus-summary-beginning-of-article))
@@ -10468,7 +10642,7 @@ Argument LINES specifies lines to be scrolled down."
        (gnus-summary-display-article article)
       (gnus-summary-recenter)
       (gnus-eval-in-buffer-window gnus-article-buffer
-                                 (gnus-article-prev-page lines))))
+       (gnus-article-prev-page lines))))
   (gnus-summary-position-point))
 
 (defun gnus-summary-scroll-up (lines)
@@ -10479,13 +10653,12 @@ Argument LINES specifies lines to be scrolled up (or down if negative)."
   (gnus-configure-windows 'article)
   (gnus-summary-show-thread)
   (when (eq (gnus-summary-select-article nil nil 'pseudo) 'old)
-    (gnus-eval-in-buffer-window
-     gnus-article-buffer
-     (cond ((> lines 0)
-           (if (gnus-article-next-page lines)
-               (gnus-message 3 "End of message")))
-          ((< lines 0)
-           (gnus-article-prev-page (- lines))))))
+    (gnus-eval-in-buffer-window gnus-article-buffer
+      (cond ((> lines 0)
+            (if (gnus-article-next-page lines)
+                (gnus-message 3 "End of message")))
+           ((< lines 0)
+            (gnus-article-prev-page (- lines))))))
   (gnus-summary-recenter)
   (gnus-summary-position-point))
 
@@ -10776,6 +10949,7 @@ If ALL, mark even excluded ticked and dormants as read."
   (setq gnus-newsgroup-limit articles)
   (let ((total (length gnus-newsgroup-data))
        (data (gnus-data-find-list (gnus-summary-article-number)))
+       (gnus-summary-mark-below nil)   ; Inhibit this.
        found)
     ;; This will do all the work of generating the new summary buffer
     ;; according to the new limit.
@@ -11020,10 +11194,17 @@ Return how many articles were fetched."
       (setq message-id (concat "<" message-id)))
     (unless (string-match ">$" message-id)
       (setq message-id (concat message-id ">")))
-    (let ((header (gnus-id-to-header message-id)))
+    (let* ((header (gnus-id-to-header message-id))
+          (sparse (and header
+                       (memq (mail-header-number header)
+                             gnus-newsgroup-sparse))))
       (if header
-         ;; The article is present in the buffer, to we just go to it.
-         (gnus-summary-goto-article (mail-header-number header) nil header)
+         (prog1
+             ;; The article is present in the buffer, to we just go to it.
+             (gnus-summary-goto-article 
+              (mail-header-number header) nil header)
+           (when sparse
+             (gnus-summary-update-article (mail-header-number header))))
        ;; We fetch the article
        (let ((gnus-override-method 
               (and (gnus-news-group-p gnus-newsgroup-name)
@@ -11082,10 +11263,9 @@ If REGEXP-P (the prefix) is non-nil, do regexp isearch."
   (gnus-set-global-variables)
   (gnus-summary-select-article)
   (gnus-configure-windows 'article)
-  (gnus-eval-in-buffer-window
-   gnus-article-buffer
-   (goto-char (point-min))
-   (isearch-forward regexp-p)))
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    ;;(goto-char (point-min))
+    (isearch-forward regexp-p)))
 
 (defun gnus-summary-search-article-forward (regexp &optional backward)
   "Search for an article containing REGEXP forward.
@@ -11130,6 +11310,8 @@ Optional argument BACKWARD means do search for backward.
     (gnus-save-hidden-threads
       (gnus-summary-select-article)
       (set-buffer gnus-article-buffer)
+      (when backward
+       (forward-line -1))
       (while (not found)
        (gnus-message 7 "Searching article: %d..." (cdr gnus-article-current))
        (if (if backward
@@ -11225,11 +11407,10 @@ article.  If BACKWARD (the prefix) is non-nil, search backward instead."
   (gnus-set-global-variables)
   (gnus-summary-select-article)
   (gnus-configure-windows 'article)
-  (gnus-eval-in-buffer-window
-   gnus-article-buffer
-   (widen)
-   (goto-char (point-min))
-   (and gnus-break-pages (gnus-narrow-to-page))))
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (widen)
+    (goto-char (point-min))
+    (and gnus-break-pages (gnus-narrow-to-page))))
 
 (defun gnus-summary-end-of-article ()
   "Scroll to the end of the article."
@@ -11237,12 +11418,11 @@ article.  If BACKWARD (the prefix) is non-nil, search backward instead."
   (gnus-set-global-variables)
   (gnus-summary-select-article)
   (gnus-configure-windows 'article)
-  (gnus-eval-in-buffer-window
-   gnus-article-buffer
-   (widen)
-   (goto-char (point-max))
-   (recenter -3)
-   (and gnus-break-pages (gnus-narrow-to-page))))
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (widen)
+    (goto-char (point-max))
+    (recenter -3)
+    (and gnus-break-pages (gnus-narrow-to-page))))
 
 (defun gnus-summary-show-article (&optional arg)
   "Force re-fetching of the current article.
@@ -11330,20 +11510,21 @@ forward."
   (gnus-set-global-variables)
   (gnus-summary-select-article)
   (let ((mail-header-separator ""))
-    (gnus-eval-in-buffer-window
-     gnus-article-buffer
-     (save-restriction
-       (widen)
-       (let ((start (window-start)))
-        (news-caesar-buffer-body arg)
-        (set-window-start (get-buffer-window (current-buffer)) start))))))
+    (gnus-eval-in-buffer-window gnus-article-buffer
+      (save-restriction
+       (widen)
+       (let ((start (window-start))
+             buffer-read-only)
+         (message-caesar-buffer-body arg)
+         (set-window-start (get-buffer-window (current-buffer)) start))))))
 
 (defun gnus-summary-stop-page-breaking ()
   "Stop page breaking in the current article."
   (interactive)
   (gnus-set-global-variables)
   (gnus-summary-select-article)
-  (gnus-eval-in-buffer-window gnus-article-buffer (widen)))
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (widen)))
 
 (defun gnus-summary-move-article (&optional n to-newsgroup select-method action)
   "Move the current article to a different newsgroup.
@@ -11390,7 +11571,7 @@ and `request-accept' functions."
             articles prefix))
       (set (intern (format "gnus-current-%s-group" action)) to-newsgroup))
     (setq to-method (or select-method 
-                       (gnus-find-method-for-group to-newsgroup)))
+                       (gnus-group-name-to-method to-newsgroup)))
     ;; Check the method we are to move this article to...
     (or (gnus-check-backend-function 'request-accept-article (car to-method))
        (error "%s does not support article copying" (car to-method)))
@@ -11561,7 +11742,7 @@ latter case, they will be copied into the relevant groups."
                                        gnus-newsgroup-name)))))
                (method
                 (gnus-completing-read 
-                 methname "What backend do you want to use when"
+                 methname "What backend do you want to use when respooling?"
                  methods nil t nil 'gnus-method-history))
                ms)
           (cond
@@ -11610,7 +11791,7 @@ latter case, they will be copied into the relevant groups."
                          (current-time-string (nth 5 atts))
                          (current-time-zone now)
                          (current-time-zone now)) "\n"
-               "Message-ID: " (gnus-inews-message-id) "\n"
+               "Message-ID: " (message-make-message-id) "\n"
                "Lines: " (int-to-string lines) "\n"
                "Chars: " (int-to-string (nth 7 atts)) "\n\n"))
       (gnus-request-accept-article group nil t)
@@ -11737,9 +11918,11 @@ groups."
   (interactive)
   (if (gnus-group-read-only-p)
       (progn
-       (gnus-summary-edit-article-postpone)
-       (gnus-error
-        1 "The current newsgroup does not support article editing."))
+       (let ((beep (not (eq major-mode 'text-mode))))
+         (gnus-summary-edit-article-postpone)
+         (when beep
+           (gnus-error
+            3 "The current newsgroup does not support article editing."))))
     (let ((buf (format "%s" (buffer-string))))
       (erase-buffer)
       (insert buf)
@@ -11754,8 +11937,8 @@ groups."
        (gnus-configure-windows 'summary)
        (gnus-summary-update-article (cdr gnus-article-current))
        (when gnus-use-cache
-         (gnus-cache-update-article 
-          (cdr gnus-article-current) (car gnus-article-current)))
+         (gnus-cache-update-article    
+          (car gnus-article-current) (cdr gnus-article-current)))
        (when gnus-keep-backlog
          (gnus-backlog-remove-article 
           (car gnus-article-current) (cdr gnus-article-current))))
@@ -11995,9 +12178,7 @@ the actual number of articles marked is returned."
 
 (defun gnus-summary-mark-forward (n &optional mark no-expire)
   "Mark N articles as read forwards.
-If N is negative, mark backwards instead.
-Mark with MARK.         If MARK is ? , ?! or ??, articles will be
-marked as unread.
+If N is negative, mark backwards instead.  Mark with MARK, ?r by default.
 The difference between N and the actual number of articles marked is
 returned."
   (interactive "p")
@@ -12051,32 +12232,34 @@ returned."
 (defun gnus-summary-mark-article-as-unread (mark)
   "Mark the current article quickly as unread with MARK."
   (let ((article (gnus-summary-article-number)))
-    (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
-    (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
-    (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
-    (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
-    (cond ((= mark gnus-ticked-mark)
-          (push article gnus-newsgroup-marked))
-         ((= mark gnus-dormant-mark)
-          (push article gnus-newsgroup-dormant))
-         (t
-          (push article gnus-newsgroup-unreads)))
-    (setq gnus-newsgroup-reads
-         (delq (assq article gnus-newsgroup-reads)
-               gnus-newsgroup-reads))
-
-    ;; See whether the article is to be put in the cache.
-    (and gnus-use-cache
-        (vectorp (gnus-summary-article-header article))
-        (save-excursion
-          (gnus-cache-possibly-enter-article
-           gnus-newsgroup-name article
-           (gnus-summary-article-header article)
-           (= mark gnus-ticked-mark)
-           (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
-
-    ;; Fix the mark.
-    (gnus-summary-update-mark mark 'unread)
+    (if (< article 0)
+       (gnus-error 1 "Unmarkable article")
+      (setq gnus-newsgroup-marked (delq article gnus-newsgroup-marked))
+      (setq gnus-newsgroup-dormant (delq article gnus-newsgroup-dormant))
+      (setq gnus-newsgroup-expirable (delq article gnus-newsgroup-expirable))
+      (setq gnus-newsgroup-reads (delq article gnus-newsgroup-reads))
+      (cond ((= mark gnus-ticked-mark)
+            (push article gnus-newsgroup-marked))
+           ((= mark gnus-dormant-mark)
+            (push article gnus-newsgroup-dormant))
+           (t
+            (push article gnus-newsgroup-unreads)))
+      (setq gnus-newsgroup-reads
+           (delq (assq article gnus-newsgroup-reads)
+                 gnus-newsgroup-reads))
+
+      ;; See whether the article is to be put in the cache.
+      (and gnus-use-cache
+          (vectorp (gnus-summary-article-header article))
+          (save-excursion
+            (gnus-cache-possibly-enter-article
+             gnus-newsgroup-name article
+             (gnus-summary-article-header article)
+             (= mark gnus-ticked-mark)
+             (= mark gnus-dormant-mark) (= mark gnus-unread-mark))))
+
+      ;; Fix the mark.
+      (gnus-summary-update-mark mark 'unread))
     t))
 
 (defun gnus-summary-mark-article (&optional article mark no-expire)
@@ -12339,7 +12522,7 @@ even ticked and dormant ones."
 
 ;; Suggested by Daniel Quinlan <quinlan@best.com>.
 (defalias 'gnus-summary-show-all-expunged 'gnus-summary-limit-include-expunged)
-(defun gnus-summary-limit-include-expunged ()
+(defun gnus-summary-limit-include-expunged (&optional no-error)
   "Display all the hidden articles that were expunged for low scores."
   (interactive)
   (gnus-set-global-variables)
@@ -12352,11 +12535,14 @@ even ticked and dormant ones."
                 (< (cdar scored) gnus-summary-expunge-below)
                 (setq headers (cons h headers))))
        (setq scored (cdr scored)))
-      (or headers (error "No expunged articles hidden."))
-      (goto-char (point-min))
-      (gnus-summary-prepare-unthreaded (nreverse headers)))
-    (goto-char (point-min))
-    (gnus-summary-position-point)))
+      (if (not headers)
+         (when (not no-error)
+           (error "No expunged articles hidden."))
+       (goto-char (point-min))
+       (gnus-summary-prepare-unthreaded (nreverse headers))
+       (goto-char (point-min))
+       (gnus-summary-position-point)
+       t))))
 
 (defun gnus-summary-catchup (&optional all quietly to-here not-mark)
   "Mark all articles not marked as unread in this newsgroup as read.
@@ -12556,6 +12742,7 @@ If ARG is positive number, turn showing conversation threads on."
            (> (prefix-numeric-value arg) 0)))
     (gnus-summary-prepare)
     (gnus-summary-goto-subject current)
+    (gnus-message 6 "Threading is now %s" (if gnus-show-threads "on" "off"))
     (gnus-summary-position-point)))
 
 (defun gnus-summary-show-all-threads ()
@@ -12748,8 +12935,8 @@ If the prefix argument is positive, remove any kinds of marks.
 If the prefix argument is negative, tick articles instead."
   (interactive "P")
   (gnus-set-global-variables)
-  (if unmark
-      (setq unmark (prefix-numeric-value unmark)))
+  (when unmark
+    (setq unmark (prefix-numeric-value unmark)))
   (let ((articles (gnus-summary-articles-in-thread)))
     (save-excursion
       ;; Expand the thread.
@@ -12865,6 +13052,8 @@ The variable `gnus-default-article-saver' specifies the saver function."
   (interactive "P")
   (gnus-set-global-variables)
   (let ((articles (gnus-summary-work-articles n))
+       (save-buffer (save-excursion 
+                      (nnheader-set-temp-buffer " *Gnus Save*")))
        file header article)
     (while articles
       (setq header (gnus-summary-article-header
@@ -12877,33 +13066,37 @@ The variable `gnus-default-article-saver' specifies the saver function."
        ;; This is a real article.
        (save-window-excursion
          (gnus-summary-select-article t nil nil article))
+       (save-excursion
+         (set-buffer save-buffer)
+         (erase-buffer)
+         (insert-buffer-substring gnus-original-article-buffer))
        (unless gnus-save-all-headers
          ;; Remove headers accoring to `gnus-saved-headers'.
          (let ((gnus-visible-headers
-                (or gnus-saved-headers gnus-visible-headers)))
-           (gnus-article-hide-headers nil t)))
-       ;; Remove any X-Gnus lines.
-       (save-excursion
-         (set-buffer gnus-article-buffer)
-         (save-restriction
-           (let ((buffer-read-only nil))
-             (nnheader-narrow-to-headers)
-             (while (re-search-forward "^X-Gnus" nil t)
-               (gnus-delete-line)))))
+                (or gnus-saved-headers gnus-visible-headers))
+               (gnus-article-buffer save-buffer))
+           (gnus-article-hide-headers 1 t)))
        (save-window-excursion
          (if (not gnus-default-article-saver)
              (error "No default saver is defined.")
-           (setq file (funcall
-                       gnus-default-article-saver
-                       (cond
-                        ((not gnus-prompt-before-saving)
-                         'default)
-                        ((eq gnus-prompt-before-saving 'always)
-                         nil)
-                        (t file))))))
+           ;; !!! Magic!  The saving functions all save
+           ;; `gnus-original-article-buffer' (or so they think),
+           ;; but we bind that variable to our save-buffer.
+           (set-buffer gnus-article-buffer)
+           (let ((gnus-original-article-buffer save-buffer))
+             (set-buffer gnus-summary-buffer)
+             (setq file (funcall
+                         gnus-default-article-saver
+                         (cond
+                          ((not gnus-prompt-before-saving)
+                           'default)
+                          ((eq gnus-prompt-before-saving 'always)
+                           nil)
+                          (t file)))))))
        (gnus-summary-remove-process-mark article)
        (unless not-saved
          (gnus-summary-set-saved-mark article))))
+    (gnus-kill-buffer save-buffer)
     (gnus-summary-position-point)
     n))
 
@@ -13042,6 +13235,14 @@ save those articles instead."
          (setq to-newsgroup (or default "")))
       (or (gnus-active to-newsgroup)
          (gnus-activate-group to-newsgroup)
+         (if (gnus-y-or-n-p (format "No such group: %s.  Create it? "
+                                    to-newsgroup))
+             (or (and (gnus-request-create-group 
+                       to-newsgroup (gnus-group-name-to-method to-newsgroup))
+                      (gnus-activate-group to-newsgroup nil nil
+                                           (gnus-group-name-to-method
+                                            to-newsgroup)))
+                 (error "Couldn't create group %s" to-newsgroup)))
          (error "No such group: %s" to-newsgroup)))
     to-newsgroup))
 
@@ -13059,10 +13260,14 @@ save those articles instead."
             default-name))
           ;; A single split name was found
           ((= 1 (length split-name))
-           (read-file-name
-            (concat prompt " (default " (car split-name) ") ")
-            gnus-article-save-directory
-            (concat gnus-article-save-directory (car split-name))))
+           (let* ((name (car split-name))
+                  (dir (cond ((file-directory-p name)
+                              (file-name-as-directory name))
+                             ((file-exists-p name) name)
+                             (t gnus-article-save-directory))))
+             (read-file-name
+              (concat prompt " (default " name ") ")
+              dir name)))
           ;; A list of splits was found.
           (t
            (setq split-name (nreverse split-name))
@@ -13103,12 +13308,11 @@ Directory to save to is default to `gnus-article-save-directory'."
                (t (gnus-read-save-file-name
                    "Save in rmail file:" default-name))))
     (gnus-make-directory (file-name-directory filename))
-    (gnus-eval-in-buffer-window
-     gnus-original-article-buffer
-     (save-excursion
-       (save-restriction
-        (widen)
-        (gnus-output-to-rmail filename))))
+    (gnus-eval-in-buffer-window gnus-original-article-buffer
+      (save-excursion
+       (save-restriction
+         (widen)
+         (gnus-output-to-rmail filename))))
     ;; Remember the directory name to save articles
     (setq gnus-newsgroup-last-rmail filename)))
 
@@ -13132,15 +13336,14 @@ Directory to save to is default to `gnus-article-save-directory'."
                            (and default-name
                                 (file-name-directory default-name))))
     (gnus-make-directory (file-name-directory filename))
-    (gnus-eval-in-buffer-window
-     gnus-original-article-buffer
-     (save-excursion
-       (save-restriction
-        (widen)
-        (if (and (file-readable-p filename) (mail-file-babyl-p filename))
-            (gnus-output-to-rmail filename)
-          (let ((mail-use-rfc822 t))
-            (rmail-output filename 1 t t))))))
+    (gnus-eval-in-buffer-window gnus-original-article-buffer
+      (save-excursion
+       (save-restriction
+         (widen)
+         (if (and (file-readable-p filename) (mail-file-babyl-p filename))
+             (gnus-output-to-rmail filename)
+           (let ((mail-use-rfc822 t))
+             (rmail-output filename 1 t t))))))
     ;; Remember the directory name to save articles.
     (setq gnus-newsgroup-last-mail filename)))
 
@@ -13160,12 +13363,11 @@ Directory to save to is default to `gnus-article-save-directory'."
                (t (gnus-read-save-file-name
                    "Save in file:" default-name))))
     (gnus-make-directory (file-name-directory filename))
-    (gnus-eval-in-buffer-window
-     gnus-original-article-buffer
-     (save-excursion
-       (save-restriction
-        (widen)
-        (gnus-output-to-file filename))))
+    (gnus-eval-in-buffer-window gnus-original-article-buffer
+      (save-excursion
+       (save-restriction
+         (widen)
+         (gnus-output-to-file filename))))
     ;; Remember the directory name to save articles.
     (setq gnus-newsgroup-last-file filename)))
 
@@ -13185,15 +13387,14 @@ The directory to save in defaults to `gnus-article-save-directory'."
                (t (gnus-read-save-file-name
                    "Save body in file:" default-name))))
     (gnus-make-directory (file-name-directory filename))
-    (gnus-eval-in-buffer-window
-     gnus-article-buffer
-     (save-excursion
-       (save-restriction
-        (widen)
-        (goto-char (point-min))
-        (and (search-forward "\n\n" nil t)
-             (narrow-to-region (point) (point-max)))
-        (gnus-output-to-file filename))))
+    (gnus-eval-in-buffer-window gnus-original-article-buffer
+      (save-excursion
+       (save-restriction
+         (widen)
+         (goto-char (point-min))
+         (and (search-forward "\n\n" nil t)
+              (narrow-to-region (point) (point-max)))
+         (gnus-output-to-file filename))))
     ;; Remember the directory name to save articles.
     (setq gnus-newsgroup-last-file filename)))
 
@@ -13209,11 +13410,10 @@ The directory to save in defaults to `gnus-article-save-directory'."
                              gnus-last-shell-command))))
   (if (string-equal command "")
       (setq command gnus-last-shell-command))
-  (gnus-eval-in-buffer-window
-   gnus-article-buffer
-   (save-restriction
-     (widen)
-     (shell-command-on-region (point-min) (point-max) command nil)))
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (save-restriction
+      (widen)
+      (shell-command-on-region (point-min) (point-max) command nil)))
   (setq gnus-last-shell-command command))
 
 ;; Summary extract commands
@@ -13304,8 +13504,10 @@ The directory to save in defaults to `gnus-article-save-directory'."
       (erase-buffer)
       (insert "$ " command "\n\n")
       (if gnus-view-pseudo-asynchronously
-         (start-process "gnus-execute" nil "sh" "-c" command)
-       (call-process "sh" nil t nil "-c" command)))))
+         (start-process "gnus-execute" nil shell-file-name
+                        shell-command-switch command)
+       (call-process shell-file-name nil t nil
+                     shell-command-switch command)))))
 
 (defun gnus-copy-file (file &optional to)
   "Copy FILE to TO."
@@ -13361,6 +13563,9 @@ The directory to save in defaults to `gnus-article-save-directory'."
     "\r" gnus-article-press-button
     "\t" gnus-article-next-button
     "\M-\t" gnus-article-prev-button
+    "<" beginning-of-buffer
+    ">" end-of-buffer
+    "\C-c\C-i" gnus-info-find-node
     "\C-c\C-b" gnus-bug)
 
   (substitute-key-definition
@@ -13423,6 +13628,7 @@ The following commands are available:
       (set-buffer (get-buffer-create gnus-original-article-buffer))
       (buffer-disable-undo (current-buffer))
       (setq major-mode 'gnus-original-article-mode)
+      (gnus-add-current-to-buffer-list)
       (make-local-variable 'gnus-original-article))
     (if (get-buffer name)
        (save-excursion
@@ -13620,14 +13826,9 @@ The following commands are available:
        ;; We have found the header.
        header
       ;; We have to really fetch the header to this article.
-      (when (setq where
-                 (if (gnus-check-backend-function 'request-head group)
-                     (gnus-request-head id group)
-                   (gnus-request-article id group)))
+      (when (setq where (gnus-request-head id group))
        (save-excursion
          (set-buffer nntp-server-buffer)
-         (and (search-forward "\n\n" nil t)
-              (delete-region (1- (point)) (point-max)))
          (goto-char (point-max))
          (insert ".\n")
          (goto-char (point-min))
@@ -13653,11 +13854,24 @@ The following commands are available:
                ;; numbers for this article.
                (mail-header-set-number header gnus-reffed-article-number))
            (decf gnus-reffed-article-number)
+           (gnus-remove-header (mail-header-number header))
            (push header gnus-newsgroup-headers)
            (setq gnus-current-headers header)
            (push (mail-header-number header) gnus-newsgroup-limit))
          header)))))
 
+(defun gnus-remove-header (number)
+  "Remove header NUMBER from `gnus-newsgroup-headers'."
+  (if (and gnus-newsgroup-headers
+          (= number (mail-header-number (car gnus-newsgroup-headers))))
+      (pop gnus-newsgroup-headers)
+    (let ((headers gnus-newsgroup-headers))
+      (while (and (cdr headers)
+                 (not (= number (mail-header-number (cadr headers)))))
+       (pop headers))
+      (when (cdr headers)
+       (setcdr headers (cddr headers))))))
+
 (defun gnus-article-prepare (article &optional all-headers header)
   "Prepare ARTICLE in article mode buffer.
 ARTICLE should either be an article number or a Message-ID.
@@ -13806,7 +14020,7 @@ Provided for backwards compatibility."
   "Toggle whether to hide unwanted headers and possibly sort them as well.
 If given a negative prefix, always show; if given a positive prefix,
 always hide."
-  (interactive "P")
+  (interactive (gnus-hidden-arg))
   (if (gnus-article-check-hidden-text 'headers arg)
       ;; Show boring headers as well.
       (gnus-article-show-hidden-text 'boring-headers)
@@ -13831,6 +14045,7 @@ always hide."
                       ((and gnus-visible-headers
                             (listp gnus-visible-headers))
                        (mapconcat 'identity gnus-visible-headers "\\|"))))
+               (inhibit-point-motion-hooks t)
                want-list beg)
            ;; First we narrow to just the headers.
            (widen)
@@ -13839,7 +14054,9 @@ always hide."
            (while (looking-at "From ")
              (forward-line 1))
            (unless (bobp)
-             (gnus-hide-text (point-min) (point) props))
+             (if delete
+                 (delete-region (point-min) (point))
+               (gnus-hide-text (point-min) (point) props)))
            ;; Then treat the rest of the header lines.
            (narrow-to-region
             (point)
@@ -13876,7 +14093,7 @@ always hide."
   "Toggle hiding of headers that aren't very interesting.
 If given a negative prefix, always show; if given a positive prefix,
 always hide."
-  (interactive "P")
+  (interactive (gnus-hidden-arg))
   (unless (gnus-article-check-hidden-text 'boring-headers arg)
     (save-excursion
       (set-buffer gnus-article-buffer)
@@ -13951,17 +14168,18 @@ always hide."
       (while (search-forward "\b" nil t)
        (let ((next (following-char))
              (previous (char-after (- (point) 2))))
-         (cond ((eq next previous)
-                (gnus-put-text-property (- (point) 2) (point) 'invisible t)
-                (gnus-put-text-property (point) (1+ (point)) 'face 'bold))
-               ((eq next ?_)
-                (gnus-put-text-property (1- (point)) (1+ (point)) 'invisible t)
-                (gnus-put-text-property
-                 (- (point) 2) (1- (point)) 'face 'underline))
-               ((eq previous ?_)
-                (gnus-put-text-property (- (point) 2) (point) 'invisible t)
-                (gnus-put-text-property
-                 (point) (1+ (point))  'face 'underline))))))))
+         (cond 
+          ((eq next previous)
+           (gnus-put-text-property (- (point) 2) (point) 'invisible t)
+           (gnus-put-text-property (point) (1+ (point)) 'face 'bold))
+          ((eq next ?_)
+           (gnus-put-text-property (1- (point)) (1+ (point)) 'invisible t)
+           (gnus-put-text-property
+            (- (point) 2) (1- (point)) 'face 'underline))
+          ((eq previous ?_)
+           (gnus-put-text-property (- (point) 2) (point) 'invisible t)
+           (gnus-put-text-property
+            (point) (1+ (point))       'face 'underline))))))))
 
 (defun gnus-article-word-wrap ()
   "Format too long lines."
@@ -14045,7 +14263,8 @@ always hide."
              (let ((process-connection-type nil))
                (process-kill-without-query
                 (start-process
-                 "gnus-x-face" nil "sh" "-c" gnus-article-x-face-command))
+                 "gnus-x-face" nil shell-file-name shell-command-switch
+                 gnus-article-x-face-command))
                (process-send-region "gnus-x-face" beg end)
                (process-send-eof "gnus-x-face")))))))))
 
@@ -14061,6 +14280,7 @@ always hide."
        (goto-char (point-min))
        (or (search-forward "\n\n" nil t) (point-max)))
 
+      (goto-char (point-min))
       (while (re-search-forward 
              "=\\?iso-8859-1\\?q\\?\\([^?\t\n]*\\)\\?=" nil t)
        (setq string (match-string 1))
@@ -14114,7 +14334,7 @@ or not."
   "Toggle hiding of any PGP headers and signatures in the current article.
 If given a negative prefix, always show; if given a positive prefix,
 always hide."
-  (interactive "P")
+  (interactive (gnus-hidden-arg))
   (unless (gnus-article-check-hidden-text 'pgp arg)
     (save-excursion
       (set-buffer gnus-article-buffer)
@@ -14145,11 +14365,40 @@ always hide."
            (gnus-hide-text (match-beginning 0) (match-end 0) props))
          (widen))))))
 
+(defun gnus-article-hide-pem (&optional arg)
+  "Toggle hiding of any PEM headers and signatures in the current article.
+If given a negative prefix, always show; if given a positive prefix,
+always hide."
+  (interactive (gnus-hidden-arg))
+  (unless (gnus-article-check-hidden-text 'pem arg)
+    (save-excursion
+      (set-buffer gnus-article-buffer)
+      (let ((props (nconc (list 'gnus-type 'pem) gnus-hidden-properties))
+           buffer-read-only end)
+       (widen)
+       (goto-char (point-min))
+       ;; hide the horrendously ugly "header".
+       (and (search-forward "\n-----BEGIN PRIVACY-ENHANCED MESSAGE-----\n"
+                            nil
+                            t)
+            (setq end (1+ (match-beginning 0)))
+            (gnus-hide-text
+             end
+             (if (search-forward "\n\n" nil t)
+                 (match-end 0)
+               (point-max))
+             props))
+       ;; hide the trailer as well
+       (and (search-forward "\n-----END PRIVACY-ENHANCED MESSAGE-----\n"
+                            nil
+                            t)
+            (gnus-hide-text (match-beginning 0) (match-end 0) props))))))
+
 (defun gnus-article-hide-signature (&optional arg)
   "Hide the signature in the current article.
 If given a negative prefix, always show; if given a positive prefix,
 always hide."
-  (interactive "P")
+  (interactive (gnus-hidden-arg))
   (unless (gnus-article-check-hidden-text 'signature arg)
     (save-excursion
       (set-buffer gnus-article-buffer)
@@ -14177,10 +14426,11 @@ always hide."
   (if (and (boundp 'mime::preview/content-list)
           mime::preview/content-list)
       (let ((pcinfo (car (last mime::preview/content-list))))
-       (narrow-to-region
-        (funcall (intern "mime::preview-content-info/point-min") pcinfo)
-        (point-max))
-       t))
+       (condition-case ()
+           (narrow-to-region
+            (funcall (intern "mime::preview-content-info/point-min") pcinfo)
+            (point-max))
+         (error nil))))
   (goto-char (point-max))
   (when (re-search-backward gnus-signature-separator nil t)
     (forward-line 1)
@@ -14194,17 +14444,29 @@ always hide."
       (narrow-to-region (point) (point-max))
       t)))
 
+(defun gnus-hidden-arg ()
+  "Return the current prefix arg as a number, or 0 if no prefix."
+  (list (if current-prefix-arg
+           (prefix-numeric-value current-prefix-arg)
+         0)))
+
 (defun gnus-article-check-hidden-text (type arg)
-  "Return nil if hiding is necessary."
+  "Return nil if hiding is necessary.
+Arg can be nil or a number.  Nil and positive means hide, negative
+means show, 0 means toggle."
   (save-excursion
     (set-buffer gnus-article-buffer)
     (let ((hide (gnus-article-hidden-text-p type)))
-      (cond ((or (and (null arg) (eq hide 'hidden))
-                (and arg (< 0 (prefix-numeric-value arg))))
-            (gnus-article-show-hidden-text type))
-           ((eq hide 'shown)
-            (gnus-article-show-hidden-text type t))
-           (t nil)))))
+      (cond
+       ((or (null arg)
+           (> arg 0))
+       nil)
+       ((< arg 0)
+       (gnus-article-show-hidden-text type))
+       (t
+       (if (eq hide 'hidden)
+           (gnus-article-show-hidden-text type)
+         nil))))))
 
 (defun gnus-article-hidden-text-p (type)
   "Say whether the current buffer contains hidden text of type TYPE."
@@ -14355,7 +14617,7 @@ how much time has lapsed since DATE."
              (prog1
                  (concat (if prev ", " "") (int-to-string
                                             (floor num))
-                         " " (symbol-name (car unit))
+                         " " (symbol-name (car unit)) 
                          (if (> num 1) "s" ""))
                (setq prev t))))
          gnus-article-time-units "")
@@ -14389,7 +14651,7 @@ function and want to see what the date was before converting."
   (if (gnus-visual-p 'article-highlight 'highlight)
       (gnus-article-highlight-some)))
 
-;; Article savers.
+;;; Article savers.
 
 (defun gnus-output-to-rmail (file-name)
   "Append the current article to an Rmail file named FILE-NAME."
@@ -14444,20 +14706,14 @@ function and want to see what the date was before converting."
 
 (defun gnus-output-to-file (file-name)
   "Append the current article to a file named FILE-NAME."
-  (setq file-name (expand-file-name file-name))
-  (let ((artbuf (current-buffer))
-       (tmpbuf (get-buffer-create " *Gnus-output*")))
-    (save-excursion
-      (set-buffer tmpbuf)
-      (buffer-disable-undo (current-buffer))
-      (erase-buffer)
+  (let ((artbuf (current-buffer)))
+    (nnheader-temp-write nil
       (insert-buffer-substring artbuf)
       ;; Append newline at end of the buffer as separator, and then
       ;; save it to file.
       (goto-char (point-max))
       (insert "\n")
-      (append-to-file (point-min) (point-max) file-name))
-    (kill-buffer tmpbuf)))
+      (append-to-file (point-min) (point-max) file-name))))
 
 (defun gnus-convert-article-to-rmail ()
   "Convert article in current buffer to Rmail message format."
@@ -14589,7 +14845,7 @@ Argument LINES specifies lines to be scrolled down."
   "Describe article mode commands briefly."
   (interactive)
   (gnus-message 6
-               (substitute-command-keys "\\<gnus-article-mode-map>\\[gnus-article-next-page]:Next page  \\[gnus-article-prev-page]:Prev page  \\[gnus-article-show-summary]:Show summary  \\[gnus-info-find-node]:Run Info  \\[gnus-article-describe-briefly]:This help")))
+               (substitute-command-keys "\\<gnus-article-mode-map>\\[gnus-article-goto-next-page]:Next page     \\[gnus-article-goto-prev-page]:Prev page  \\[gnus-article-show-summary]:Show summary  \\[gnus-info-find-node]:Run Info  \\[gnus-article-describe-briefly]:This help")))
 
 (defun gnus-article-summary-command ()
   "Execute the last keystroke in the summary buffer."
@@ -14618,7 +14874,9 @@ Argument LINES specifies lines to be scrolled down."
   (let ((nosaves
         '("q" "Q"  "c" "r" "R" "\C-c\C-f" "m"  "a" "f" "F"
           "Zc" "ZC" "ZE" "ZQ" "ZZ" "Zn" "ZR" "ZG" "ZN" "ZP"
-          "=" "^" "\M-^"))
+          "=" "^" "\M-^" "|"))
+       (nosave-but-article
+        '("A\r"))
        keys)
     (save-excursion
       (set-buffer gnus-summary-buffer)
@@ -14626,12 +14884,18 @@ Argument LINES specifies lines to be scrolled down."
       (setq keys (read-key-sequence nil)))
     (message "")
 
-    (if (member keys nosaves)
+    (if (or (member keys nosaves)
+           (member keys nosave-but-article))
        (let (func)
-         (pop-to-buffer gnus-summary-buffer 'norecord)
-         (if (setq func (lookup-key (current-local-map) keys))
-             (call-interactively func)
-           (ding)))
+         (save-window-excursion
+           (pop-to-buffer gnus-summary-buffer 'norecord)
+           (setq func (lookup-key (current-local-map) keys)))
+         (if (not func)
+             (ding)
+           (set-buffer gnus-summary-buffer)
+           (call-interactively func))
+         (when (member keys nosave-but-article)
+           (pop-to-buffer gnus-article-buffer 'norecord)))
       (let ((obuf (current-buffer))
            (owin (current-window-configuration))
            (opoint (point))
@@ -14766,6 +15030,7 @@ If NEWSGROUP is nil, return the global kill file name instead."
        (set-buffer gnus-dribble-buffer)
        (insert string "\n")
        (set-window-point (get-buffer-window (current-buffer)) (point-max))
+       (bury-buffer gnus-dribble-buffer)
        (set-buffer obuf))))
 
 (defun gnus-dribble-read-file ()
@@ -14931,7 +15196,7 @@ If it is down, start it up (again)."
        (unless silent
          (message ""))))))
 
-(defun gnus-get-function (method function)
+(defun gnus-get-function (method function &optional noerror)
   "Return a function symbol based on METHOD and FUNCTION."
   ;; Translate server names into methods.
   (unless method
@@ -14943,7 +15208,8 @@ If it is down, start it up (again)."
     ;; question.
     (unless (fboundp func)
       (require (car method))
-      (unless (fboundp func)
+      (when (and (not (fboundp func))
+                (not noerror))
        ;; This backend doesn't implement this function.
        (error "No such function: %s" func)))
     func))
@@ -15094,9 +15360,19 @@ If BUFFER, insert the article in that group."
 
 (defun gnus-request-head (article group)
   "Request the head of ARTICLE in GROUP."
-  (let ((method (gnus-find-method-for-group group)))
-    (funcall (gnus-get-function method 'request-head)
-            article (gnus-group-real-name group) (nth 1 method))))
+  (let* ((method (gnus-find-method-for-group group))
+        (head (gnus-get-function method 'request-head t)))
+    (if (fboundp head)
+       (funcall head article (gnus-group-real-name group) (nth 1 method))
+      (let ((res (gnus-request-article article group)))
+       (when res
+         (save-excursion
+           (set-buffer nntp-server-buffer)
+           (goto-char (point-min))
+           (when (search-forward "\n\n" nil t)
+             (delete-region (1- (point)) (point-max)))
+           (nnheader-fold-continuation-lines)))
+       res))))
 
 (defun gnus-request-body (article group)
   "Request the body of ARTICLE in GROUP."
@@ -15145,7 +15421,7 @@ If GROUP is nil, all groups on METHOD are scanned."
     (setq method (gnus-server-to-method method)))
   (when (and (not method)
             (stringp group))
-    (setq method (gnus-find-method-for-group group)))
+    (setq method (gnus-group-name-to-method group)))
   (goto-char (point-max))
   (unless (bolp)
     (insert "\n"))
@@ -15214,6 +15490,20 @@ If GROUP is nil, all groups on METHOD are scanned."
     (setcar (cdr entry) (concat (nth 1 entry) "+" group))
     (nconc entry (cdr method))))
 
+(defun gnus-server-status (method)
+  "Return the status of METHOD."
+  (nth 1 (assoc method gnus-opened-servers)))
+
+(defun gnus-group-name-to-method (group)
+  "Return a select method suitable for GROUP."
+  (if (string-match ":" group)
+      (let ((server (substring group 0 (match-beginning 0))))
+       (if (string-match "\\+" server)
+           (list (intern (substring server 0 (match-beginning 0)))
+                 (substring server (match-end 0)))
+         (list (intern server) "")))
+    gnus-select-method))
+
 (defun gnus-find-method-for-group (group &optional info)
   "Find the select method that GROUP uses."
   (or gnus-override-method
@@ -15274,7 +15564,7 @@ If LEVEL is non-nil, the news will be set up at level LEVEL."
       (gnus-read-newsrc-file rawfile))
 
     (when (and (not (assoc "archive" gnus-server-alist))
-              gnus-message-archive-method)
+              (gnus-archive-server-wanted-p))
       (push (cons "archive" gnus-message-archive-method)
            gnus-server-alist))
 
@@ -15424,7 +15714,7 @@ the server for new groups."
   (let* ((date (or gnus-newsrc-last-checked-date (current-time-string)))
         (methods (cons gnus-select-method
                        (nconc
-                        (when gnus-message-archive-method
+                        (when (gnus-archive-server-wanted-p)
                           (list "archive"))
                         (append
                          (and (consp gnus-check-new-newsgroups)
@@ -15687,7 +15977,7 @@ newsgroup."
          (gnus-group-change-level entry gnus-level-killed)
          (setq gnus-killed-list (delete group gnus-killed-list))))
       ;; Then we remove all bogus groups from the list of killed and
-      ;; zombie groups.  They are are removed without confirmation.
+      ;; zombie groups.  They are removed without confirmation.
       (let ((dead-lists '(gnus-killed-list gnus-zombie-list))
            killed)
        (while dead-lists
@@ -15699,6 +15989,7 @@ newsgroup."
              (set (car dead-lists)
                   (delete group (symbol-value (car dead-lists))))))
          (setq dead-lists (cdr dead-lists))))
+      (run-hooks 'gnus-check-bogus-groups-hook)
       (gnus-message 5 "Checking bogus newsgroups...done"))))
 
 (defun gnus-check-duplicate-killed-groups ()
@@ -15713,6 +16004,7 @@ newsgroup."
 ;; We want to inline a function from gnus-cache, so we cheat here:
 (eval-when-compile
   (provide 'gnus)
+  (setq gnus-directory (or (getenv "SAVEDIR") "~/News/"))
   (require 'gnus-cache))
 
 (defun gnus-get-unread-articles-in-group (info active &optional update)
@@ -15886,10 +16178,10 @@ newsgroup."
       (while list
        (gnus-sethash (car list) (pop list) gnus-killed-hashtb)))))
 
-(defun gnus-activate-group (group &optional scan dont-check)
+(defun gnus-activate-group (group &optional scan dont-check method)
   ;; Check whether a group has been activated or not.
   ;; If SCAN, request a scan of that group as well.
-  (let ((method (gnus-find-method-for-group group))
+  (let ((method (or method (gnus-find-method-for-group group)))
        active)
     (and (gnus-check-server method)
         ;; We escape all bugs and quit here to make it possible to
@@ -15901,7 +16193,7 @@ newsgroup."
                (gnus-request-scan group method))
           t)
         (condition-case ()
-            (gnus-request-group group dont-check)
+            (gnus-request-group group dont-check method)
        ;   (error nil)
           (quit nil))
         (save-excursion
@@ -15987,7 +16279,7 @@ Returns whether the updating was successful."
       (setq lists (cdr lists)))))
 
 (defun gnus-get-killed-groups ()
-  "Go through the active hashtb and all all unknown groups as killed."
+  "Go through the active hashtb and mark all unknown groups as killed."
   ;; First make sure active file has been read.
   (unless (gnus-read-active-file-p)
     (let ((gnus-read-active-file t))
@@ -16023,7 +16315,7 @@ Returns whether the updating was successful."
            ;; secondary ones.
            gnus-secondary-select-methods)
          ;; Also read from the archive server.
-         (when gnus-message-archive-method
+         (when (gnus-archive-server-wanted-p)
            (list "archive"))))
        list-type)
     (setq gnus-have-read-active-file nil)
@@ -16278,7 +16570,8 @@ If FORCE is non-nil, the .newsrc file is read."
 
 (defun gnus-continuum-version (version)
   "Return VERSION as a floating point number."
-  (when (string-match "^\\([^ ]+\\)? ?Gnus v?\\([0-9.]+\\)$" version)
+  (when (or (string-match "^\\([^ ]+\\)? ?Gnus v?\\([0-9.]+\\)$" version)
+           (string-match "^\\(.?\\)gnus-\\([0-9.]+\\)$" version))
     (let* ((alpha (and (match-beginning 1) (match-string 1 version)))
           (number (match-string 2 version))
           major minor least)
@@ -16292,9 +16585,9 @@ If FORCE is non-nil, the .newsrc file is read."
        (if (zerop major)
           (format "%s00%02d%02d"
                   (cond 
-                   ((string= alpha "(ding)") "4.99")
-                   ((string= alpha "September") "5.01")
-                   ((string= alpha "Red") "5.03"))
+                   ((member alpha '("(ding)" "d")) "4.99")
+                   ((member alpha '("September" "s")) "5.01")
+                   ((member alpha '("Red" "r")) "5.03"))
                   minor least)
         (format "%d.%02d%02d" major minor least))))))
 
@@ -16357,8 +16650,8 @@ If FORCE is non-nil, the .newsrc file is read."
                  killed gnus-killed-assoc
                  marked gnus-marked-assoc)))
       (setq gnus-newsrc-alist nil)
-      (while (setq info (gnus-get-info (setq group (pop newsrc))))
-       (if info
+      (while (setq group (pop newsrc))
+       (if (setq info (gnus-get-info (car group)))
            (progn
              (gnus-info-set-read info (cddr group))
              (gnus-info-set-level
@@ -16834,7 +17127,7 @@ If FORCE is non-nil, the .newsrc file is read."
 (defun gnus-read-all-descriptions-files ()
   (let ((methods (cons gnus-select-method 
                       (nconc
-                       (when gnus-message-archive-method
+                       (when (gnus-archive-server-wanted-p)
                          (list "archive"))
                        gnus-secondary-select-methods))))
     (while methods
@@ -16843,7 +17136,8 @@ If FORCE is non-nil, the .newsrc file is read."
     t))
 
 (defun gnus-read-descriptions-file (&optional method)
-  (let ((method (or method gnus-select-method)))
+  (let ((method (or method gnus-select-method))
+       group)
     (when (stringp method)
       (setq method (gnus-server-to-method method)))
     ;; We create the hashtable whether we manage to read the desc file
@@ -16864,35 +17158,43 @@ If FORCE is non-nil, the .newsrc file is read."
       (gnus-message 1 "Couldn't read newsgroups descriptions")
       nil)
      (t
-      (let (group)
-       (save-excursion
-         (save-restriction
-           (set-buffer nntp-server-buffer)
-           (goto-char (point-min))
-           (if (or (search-forward "\n.\n" nil t)
+      (save-excursion
+       (save-restriction
+         (set-buffer nntp-server-buffer)
+         (goto-char (point-min))
+         (when (or (search-forward "\n.\n" nil t)
                    (goto-char (point-max)))
-               (progn
-                 (beginning-of-line)
-                 (narrow-to-region (point-min) (point))))
-           (goto-char (point-min))
-           (while (not (eobp))
-             ;; If we get an error, we set group to 0, which is not a
-             ;; symbol...
-             (setq group
-                   (condition-case ()
-                       (let ((obarray gnus-description-hashtb))
-                         ;; Group is set to a symbol interned in this
-                         ;; hash table.
-                         (read nntp-server-buffer))
-                     (error 0)))
-             (skip-chars-forward " \t")
-             ;; ...  which leads to this line being effectively ignored.
-             (and (symbolp group)
-                  (set group (buffer-substring
-                              (point) (progn (end-of-line) (point)))))
-             (forward-line 1))))
-       (gnus-message 5 "Reading descriptions file...done")
-       t)))))
+           (beginning-of-line)
+           (narrow-to-region (point-min) (point)))
+         ;; If these are groups from a foreign select method, we insert the
+         ;; group prefix in front of the group names.
+         (and method (not (gnus-server-equal
+                           (gnus-server-get-method nil method)
+                           (gnus-server-get-method nil gnus-select-method)))
+              (let ((prefix (gnus-group-prefixed-name "" method)))
+                (goto-char (point-min))
+                (while (and (not (eobp))
+                            (progn (insert prefix)
+                                   (zerop (forward-line 1)))))))
+         (goto-char (point-min))
+         (while (not (eobp))
+           ;; If we get an error, we set group to 0, which is not a
+           ;; symbol...
+           (setq group
+                 (condition-case ()
+                     (let ((obarray gnus-description-hashtb))
+                       ;; Group is set to a symbol interned in this
+                       ;; hash table.
+                       (read nntp-server-buffer))
+                   (error 0)))
+           (skip-chars-forward " \t")
+           ;; ...  which leads to this line being effectively ignored.
+           (and (symbolp group)
+                (set group (buffer-substring
+                            (point) (progn (end-of-line) (point)))))
+           (forward-line 1))))
+      (gnus-message 5 "Reading descriptions file...done")
+      t))))
 
 (defun gnus-group-get-description (group)
   "Get the description of a group by sending XGTITLE to the server."