*** empty log message ***
[gnus] / lisp / gnus.el
index 8b27916..10cf215 100644 (file)
@@ -1,9 +1,9 @@
 ;;; gnus.el --- a newsreader for GNU Emacs
 ;;; gnus.el --- a newsreader for GNU Emacs
-;; Copyright (C) 1987,88,89,90,93,94,95,96 Free Software Foundation, Inc.
+;; Copyright (C) 1987,88,89,90,93,94,95,96,97 Free Software Foundation, Inc.
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;     Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
 
 ;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
 ;;     Lars Magne Ingebrigtsen <larsi@ifi.uio.no>
-;; Keywords: news
+;; Keywords: news, mail
 
 ;; This file is part of GNU Emacs.
 
 
 ;; This file is part of GNU Emacs.
 
 (eval '(run-hooks 'gnus-load-hook))
 
 (require 'custom)
 (eval '(run-hooks 'gnus-load-hook))
 
 (require 'custom)
+(require 'gnus-load)
+(require 'message)
 
 (defgroup gnus nil
   "The coffee-brewing, all singing, all dancing, kitchen sink newsreader."
 
 (defgroup gnus nil
   "The coffee-brewing, all singing, all dancing, kitchen sink newsreader."
-  :group 'emacs)
+  :group 'news
+  :group 'mail)
 
 (defgroup gnus-start nil
   "Starting your favorite newsreader."
   :group 'gnus)
 
 
 (defgroup gnus-start nil
   "Starting your favorite newsreader."
   :group 'gnus)
 
+(defgroup gnus-start-server nil
+  "Server options at startup."
+  :group 'gnus-start)
+
+;; These belong to gnus-group.el.
+(defgroup gnus-group nil
+  "Group buffers."
+  :link '(custom-manual "(gnus)The Group Buffer")
+  :group 'gnus)
+
+(defgroup gnus-group-foreign nil
+  "Foreign groups."
+  :link '(custom-manual "(gnus)Foreign Groups")
+  :group 'gnus-group)
+
+(defgroup gnus-group-new nil
+  "Automatic subscription of new groups."
+  :group 'gnus-group)
+
+(defgroup gnus-group-levels nil
+  "Group levels."
+  :link '(custom-manual "(gnus)Group Levels")
+  :group 'gnus-group)
+
+(defgroup gnus-group-select nil
+  "Selecting a Group."
+  :link '(custom-manual "(gnus)Selecting a Group")
+  :group 'gnus-group)
+
+(defgroup gnus-group-listing nil
+  "Showing slices of the group list."
+  :link '(custom-manual "(gnus)Listing Groups")
+  :group 'gnus-group)
+
+(defgroup gnus-group-visual nil
+  "Sorting the group buffer."
+  :link '(custom-manual "(gnus)Group Buffer Format")
+  :group 'gnus-group
+  :group 'gnus-visual)
+
+(defgroup gnus-group-various nil
+  "Various group options."
+  :link '(custom-manual "(gnus)Scanning New Messages")
+  :group 'gnus-group)
+
+;; These belong to gnus-sum.el.
+(defgroup gnus-summary nil
+  "Summary buffers."
+  :link '(custom-manual "(gnus)The Summary Buffer")
+  :group 'gnus)
+
+(defgroup gnus-summary-exit nil
+  "Leaving summary buffers."
+  :link '(custom-manual "(gnus)Exiting the Summary Buffer")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-marks nil
+  "Marks used in summary buffers."
+  :link '(custom-manual "(gnus)Marking Articles")
+  :group 'gnus-summary)
+
+(defgroup gnus-thread nil
+  "Ordering articles according to replies."
+  :link '(custom-manual "(gnus)Threading")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-format nil
+  "Formatting of the summary buffer."
+  :link '(custom-manual "(gnus)Summary Buffer Format")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-choose nil
+  "Choosing Articles."
+  :link '(custom-manual "(gnus)Choosing Articles")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-maneuvering nil
+  "Summary movement commands."
+  :link '(custom-manual "(gnus)Summary Maneuvering")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-mail nil
+  "Mail group commands."
+  :link '(custom-manual "(gnus)Mail Group Commands")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-sort nil
+  "Sorting the summary buffer."
+  :link '(custom-manual "(gnus)Sorting")
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-visual nil
+  "Highlighting and menus in the summary buffer."
+  :link '(custom-manual "(gnus)Summary Highlighting")
+  :group 'gnus-visual
+  :group 'gnus-summary)
+
+(defgroup gnus-summary-various nil
+  "Various summary buffer options."
+  :link '(custom-manual "(gnus)Various Summary Stuff")
+  :group 'gnus-summary)
+
+;; Belongs to gnus-uu.el
+(defgroup gnus-extract-view nil
+  "Viewing extracted files."
+  :link '(custom-manual "(gnus)Viewing Files")
+  :group 'gnus-extract)
+
+;; Belongs to gnus-score.el
 (defgroup gnus-score nil
   "Score and kill file handling."
 (defgroup gnus-score nil
   "Score and kill file handling."
-  :group 'gnus )
+  :group 'gnus)
+
+(defgroup gnus-score-kill nil
+  "Kill files."
+  :group 'gnus-score)
+
+(defgroup gnus-score-adapt nil
+  "Adaptive score files."
+  :group 'gnus-score)
+
+(defgroup gnus-score-default nil
+  "Default values for score files."
+  :group 'gnus-score)
+
+(defgroup gnus-score-expire nil
+  "Expiring score rules."
+  :group 'gnus-score)
+
+(defgroup gnus-score-decay nil
+  "Decaying score rules."
+  :group 'gnus-score)
+
+(defgroup gnus-score-files nil
+  "Score and kill file names."
+  :group 'gnus-score
+  :group 'gnus-files)
+
+(defgroup gnus-score-various nil
+  "Various scoring and killing options."
+  :group 'gnus-score)
+
+;; Other
+(defgroup gnus-visual nil
+  "Options controling the visual fluff."
+  :group 'gnus
+  :group 'faces)
+
+(defgroup gnus-files nil
+  "Files used by Gnus."
+  :group 'gnus)
+
+(defgroup gnus-dribble-file nil
+  "Auto save file."
+  :link '(custom-manual "(gnus)Auto Save")
+  :group 'gnus-files)
+
+(defgroup gnus-newsrc nil
+  "Storing Gnus state."
+  :group 'gnus-files)
+
+(defgroup gnus-server nil
+  "Options related to newsservers and other servers used by Gnus."
+  :group 'gnus)
+
+(defgroup gnus-message '((message custom-group))
+  "Composing replies and followups in Gnus."
+  :group 'gnus)
+
+(defgroup gnus-meta nil
+  "Meta variables controling major portions of Gnus.
+In general, modifying these variables does not take affect until Gnus
+is restarted, and sometimes reloaded."
+  :group 'gnus)
 
 
-(defconst gnus-version-number "0.44"
+(defgroup gnus-various nil
+  "Other Gnus options."
+  :link '(custom-manual "(gnus)Various Various")
+  :group 'gnus)
+
+(defgroup gnus-exit nil
+  "Exiting gnus."
+  :link '(custom-manual "(gnus)Exiting Gnus")
+  :group 'gnus)
+
+(defconst gnus-version-number "5.4.29"
   "Version number for this version of Gnus.")
 
   "Version number for this version of Gnus.")
 
-(defconst gnus-version (format "Red Gnus v%s" gnus-version-number)
+(defconst gnus-version (format "Gnus v%s" gnus-version-number)
   "Version string for this version of Gnus.")
 
 (defcustom gnus-inhibit-startup-message nil
   "Version string for this version of Gnus.")
 
 (defcustom gnus-inhibit-startup-message nil
-  "*If non-nil, the startup message will not be displayed."
+  "If non-nil, the startup message will not be displayed.
+This variable is used before `.gnus.el' is loaded, so it should
+be set in `.emacs' instead."
   :group 'gnus-start
   :type 'boolean)
 
   :group 'gnus-start
   :type 'boolean)
 
 
 ;;; Kludges to help the transition from the old `custom.el'.
 
 
 ;;; Kludges to help the transition from the old `custom.el'.
 
-;; XEmacs and Emacs 19.29 facep does different things.
-(defalias 'custom-facep
-  (cond ((fboundp 'find-face)
-        'find-face)
-       ((fboundp 'facep)
-        'facep)
-       (t
-        'ignore)))
+(unless (featurep 'gnus-xmas)
+  (defalias 'gnus-make-overlay 'make-overlay)
+  (defalias 'gnus-overlay-put 'overlay-put)
+  (defalias 'gnus-move-overlay 'move-overlay)
+  (defalias 'gnus-overlay-end 'overlay-end)
+  (defalias 'gnus-extent-detached-p 'ignore)
+  (defalias 'gnus-extent-start-open 'ignore)
+  (defalias 'gnus-set-text-properties 'set-text-properties)
+  (defalias 'gnus-group-remove-excess-properties 'ignore)
+  (defalias 'gnus-topic-remove-excess-properties 'ignore)
+  (defalias 'gnus-appt-select-lowest-window 'appt-select-lowest-window)
+  (defalias 'gnus-mail-strip-quoted-names 'mail-strip-quoted-names)
+  (defalias 'gnus-add-hook 'add-hook)
+  (defalias 'gnus-character-to-event 'identity)
+  (defalias 'gnus-add-text-properties 'add-text-properties)
+  (defalias 'gnus-put-text-property 'put-text-property)
+  (defalias 'gnus-mode-line-buffer-identification 'identity)
+  (defalias 'gnus-characterp 'numberp)
+  (defalias 'gnus-key-press-event-p 'numberp))
 
 ;; The XEmacs people think this is evil, so it must go.
 (defun custom-face-lookup (&optional fg bg stipple bold italic underline)
 
 ;; The XEmacs people think this is evil, so it must go.
 (defun custom-face-lookup (&optional fg bg stipple bold italic underline)
       (copy-face 'default name)
       (when (and fg
                 (not (string-equal fg "default")))
       (copy-face 'default name)
       (when (and fg
                 (not (string-equal fg "default")))
-       (condition-case ()
-           (set-face-foreground name fg)
-         (error nil)))
+       (ignore-errors
+         (set-face-foreground name fg)))
       (when (and bg
                 (not (string-equal bg "default")))
       (when (and bg
                 (not (string-equal bg "default")))
-       (condition-case ()
-           (set-face-background name bg)
-         (error nil)))
+       (ignore-errors
+         (set-face-background name bg)))
       (when (and stipple
                 (not (string-equal stipple "default"))
                 (not (eq stipple 'custom:asis))
       (when (and stipple
                 (not (string-equal stipple "default"))
                 (not (eq stipple 'custom:asis))
        (set-face-stipple name stipple))
       (when (and bold
                 (not (eq bold 'custom:asis)))
        (set-face-stipple name stipple))
       (when (and bold
                 (not (eq bold 'custom:asis)))
-       (condition-case ()
-           (make-face-bold name)
-         (error nil)))
+       (ignore-errors
+         (make-face-bold name)))
       (when (and italic
                 (not (eq italic 'custom:asis)))
       (when (and italic
                 (not (eq italic 'custom:asis)))
-       (condition-case ()
-           (make-face-italic name)
-         (error nil)))
+       (ignore-errors
+         (make-face-italic name)))
       (when (and underline
                 (not (eq underline 'custom:asis)))
       (when (and underline
                 (not (eq underline 'custom:asis)))
-       (condition-case ()
-           (set-face-underline-p name t)
-         (error nil))))
+       (ignore-errors
+         (set-face-underline-p name t))))
     name))
 
     name))
 
-;;; Internal variables
+;; We define these group faces here to avoid the display
+;; update forced when creating new faces.
+
+(defface gnus-group-news-1-face
+  '((((class color)
+      (background dark))
+     (:foreground "PaleTurquoise" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "ForestGreen" :bold t))
+    (t
+     ()))
+  "Level 1 newsgroup face.")
+
+(defface gnus-group-news-1-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "PaleTurquoise"))
+    (((class color)
+      (background light))
+     (:foreground "ForestGreen"))
+    (t
+     ()))
+  "Level 1 empty newsgroup face.")
+
+(defface gnus-group-news-2-face
+  '((((class color)
+      (background dark))
+     (:foreground "turquoise" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "CadetBlue4" :bold t))
+    (t
+     ()))
+  "Level 2 newsgroup face.")
+
+(defface gnus-group-news-2-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "turquoise"))
+    (((class color)
+      (background light))
+     (:foreground "CadetBlue4"))
+    (t
+     ()))
+  "Level 2 empty newsgroup face.")
+
+(defface gnus-group-news-3-face
+  '((((class color)
+      (background dark))
+     (:bold t))
+    (((class color)
+      (background light))
+     (:bold t))
+    (t
+     ()))
+  "Level 3 newsgroup face.")
+
+(defface gnus-group-news-3-empty-face
+  '((((class color)
+      (background dark))
+     ())
+    (((class color)
+      (background light))
+     ())
+    (t
+     ()))
+  "Level 3 empty newsgroup face.")
+
+(defface gnus-group-news-low-face
+  '((((class color)
+      (background dark))
+     (:foreground "DarkTurquoise" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "DarkGreen" :bold t))
+    (t
+     ()))
+  "Low level newsgroup face.")
+
+(defface gnus-group-news-low-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "DarkTurquoise"))
+    (((class color)
+      (background light))
+     (:foreground "DarkGreen"))
+    (t
+     ()))
+  "Low level empty newsgroup face.")
+
+(defface gnus-group-mail-1-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine1" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "DeepPink3" :bold t))
+    (t
+     (:bold t)))
+  "Level 1 mailgroup face.")
+
+(defface gnus-group-mail-1-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine1"))
+    (((class color)
+      (background light))
+     (:foreground "DeepPink3"))
+    (t
+     (:italic t :bold t)))
+  "Level 1 empty mailgroup face.")
+
+(defface gnus-group-mail-2-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine2" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "HotPink3" :bold t))
+    (t
+     (:bold t)))
+  "Level 2 mailgroup face.")
+
+(defface gnus-group-mail-2-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine2"))
+    (((class color)
+      (background light))
+     (:foreground "HotPink3"))
+    (t
+     (:bold t)))
+  "Level 2 empty mailgroup face.")
+
+(defface gnus-group-mail-3-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine3" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "magenta4" :bold t))
+    (t
+     (:bold t)))
+  "Level 3 mailgroup face.")
+
+(defface gnus-group-mail-3-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine3"))
+    (((class color)
+      (background light))
+     (:foreground "magenta4"))
+    (t
+     ()))
+  "Level 3 empty mailgroup face.")
+
+(defface gnus-group-mail-low-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine4" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "DeepPink4" :bold t))
+    (t
+     (:bold t)))
+  "Low level mailgroup face.")
+
+(defface gnus-group-mail-low-empty-face
+  '((((class color)
+      (background dark))
+     (:foreground "aquamarine4"))
+    (((class color)
+      (background light))
+     (:foreground "DeepPink4"))
+    (t
+     (:bold t)))
+  "Low level empty mailgroup face.")
+
+;; Summary mode faces.
+
+(defface gnus-summary-selected-face '((t
+                                      (:underline t)))
+  "Face used for selected articles.")
+
+(defface gnus-summary-cancelled-face
+  '((((class color))
+     (:foreground "yellow" :background "black")))
+  "Face used for cancelled articles.")
+
+(defface gnus-summary-high-ticked-face
+  '((((class color)
+      (background dark))
+     (:foreground "pink" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "firebrick" :bold t))
+    (t
+     (:bold t)))
+  "Face used for high interest ticked articles.")
+
+(defface gnus-summary-low-ticked-face
+  '((((class color)
+      (background dark))
+     (:foreground "pink" :italic t))
+    (((class color)
+      (background light))
+     (:foreground "firebrick" :italic t))
+    (t
+     (:italic t)))
+  "Face used for low interest ticked articles.")
+
+(defface gnus-summary-normal-ticked-face
+  '((((class color)
+      (background dark))
+     (:foreground "pink"))
+    (((class color)
+      (background light))
+     (:foreground "firebrick"))
+    (t
+     ()))
+  "Face used for normal interest ticked articles.")
+
+(defface gnus-summary-high-ancient-face
+  '((((class color)
+      (background dark))
+     (:foreground "SkyBlue" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "RoyalBlue" :bold t))
+    (t
+     (:bold t)))
+  "Face used for high interest ancient articles.")
+
+(defface gnus-summary-low-ancient-face
+  '((((class color)
+      (background dark))
+     (:foreground "SkyBlue" :italic t))
+    (((class color)
+      (background light))
+     (:foreground "RoyalBlue" :italic t))
+    (t
+     (:italic t)))
+  "Face used for low interest ancient articles.")
+
+(defface gnus-summary-normal-ancient-face
+  '((((class color)
+      (background dark))
+     (:foreground "SkyBlue"))
+    (((class color)
+      (background light))
+     (:foreground "RoyalBlue"))
+    (t
+     ()))
+  "Face used for normal interest ancient articles.")
+
+(defface gnus-summary-high-unread-face
+  '((t
+     (:bold t)))
+  "Face used for high interest unread articles.")
+
+(defface gnus-summary-low-unread-face
+  '((t
+     (:italic t)))
+  "Face used for low interest unread articles.")
+
+(defface gnus-summary-normal-unread-face
+  '((t
+     ()))
+  "Face used for normal interest unread articles.")
+
+(defface gnus-summary-high-read-face
+  '((((class color)
+      (background dark))
+     (:foreground "PaleGreen"
+                 :bold t))
+    (((class color)
+      (background light))
+     (:foreground "DarkGreen"
+                 :bold t))
+    (t
+     (:bold t)))
+  "Face used for high interest read articles.")
+
+(defface gnus-summary-low-read-face
+  '((((class color)
+      (background dark))
+     (:foreground "PaleGreen"
+                 :italic t))
+    (((class color)
+      (background light))
+     (:foreground "DarkGreen"
+                 :italic t))
+    (t
+     (:italic t)))
+  "Face used for low interest read articles.")
+
+(defface gnus-summary-normal-read-face
+  '((((class color)
+      (background dark))
+     (:foreground "PaleGreen"))
+    (((class color)
+      (background light))
+     (:foreground "DarkGreen"))
+    (t
+     ()))
+  "Face used for normal interest read articles.")
+
+
+;;; Splash screen.
 
 (defvar gnus-group-buffer "*Group*")
 
 (eval-and-compile
   (autoload 'gnus-play-jingle "gnus-audio"))
 
 
 (defvar gnus-group-buffer "*Group*")
 
 (eval-and-compile
   (autoload 'gnus-play-jingle "gnus-audio"))
 
-;;; Splash screen.
+(defface gnus-splash-face
+  '((((class color)
+      (background dark))
+     (:foreground "red"))
+    (((class color)
+      (background light))
+     (:foreground "red"))
+    (t
+     ()))
+  "Level 1 newsgroup face.")
 
 (defun gnus-splash ()
   (save-excursion
 
 (defun gnus-splash ()
   (save-excursion
       (while (search-forward "\t" nil t)
        (replace-match "        " t t)))))
 
       (while (search-forward "\t" nil t)
        (replace-match "        " t t)))))
 
+(defvar gnus-simple-splash nil)
+
 (defun gnus-group-startup-message (&optional x y)
   "Insert startup message in current buffer."
   ;; Insert the message.
 (defun gnus-group-startup-message (&optional x y)
   "Insert startup message in current buffer."
   ;; Insert the message.
         (rest (- wheight pheight)))
     (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n)))
   ;; Fontify some.
         (rest (- wheight pheight)))
     (insert (make-string (max 0 (* 2 (/ rest 3))) ?\n)))
   ;; Fontify some.
+  (put-text-property (point-min) (point-max) 'face 'gnus-splash-face)
   (goto-char (point-min))
   (goto-char (point-min))
-  (and (search-forward "Praxis" nil t)
-       (put-text-property (match-beginning 0) (match-end 0) 'face 'bold))
-  (goto-char (point-min))
-  (setq mode-line-buffer-identification gnus-version)
+  (setq mode-line-buffer-identification (concat " " gnus-version))
+  (setq gnus-simple-splash t)
   (set-buffer-modified-p t))
 
 (eval-when (load)
   (set-buffer-modified-p t))
 
 (eval-when (load)
 
 ;;; Do the rest.
 
 
 ;;; Do the rest.
 
-(require 'gnus-load)
+(require 'custom)
+(require 'gnus-util)
+(require 'nnheader)
+
+(defcustom gnus-home-directory "~/"
+  "Directory variable that specifies the \"home\" directory.
+All other Gnus path variables are initialized from this variable."
+  :group 'gnus-files
+  :type 'directory)
+
+(defcustom gnus-directory (or (getenv "SAVEDIR")
+                             (nnheader-concat gnus-home-directory "News/"))
+  "Directory variable from which all other Gnus file variables are derived."
+  :group 'gnus-files
+  :type 'directory)
+
+(defcustom gnus-default-directory nil
+  "*Default directory for all Gnus buffers."
+  :group 'gnus-files
+  :type '(choice (const :tag "current" nil)
+                directory))
+
+;; Site dependent variables.  These variables should be defined in
+;; paths.el.
+
+(defvar gnus-default-nntp-server nil
+  "Specify a default NNTP server.
+This variable should be defined in paths.el, and should never be set
+by the user.
+If you want to change servers, you should use `gnus-select-method'.
+See the documentation to that variable.")
+
+;; Don't touch this variable.
+(defvar gnus-nntp-service "nntp"
+  "NNTP service name (\"nntp\" or 119).
+This is an obsolete variable, which is scarcely used.  If you use an
+nntp server for your newsgroup and want to change the port number
+used to 899, you would say something along these lines:
+
+ (setq gnus-select-method '(nntp \"my.nntp.server\" (nntp-port-number 899)))")
+
+(defcustom gnus-nntpserver-file "/etc/nntpserver"
+  "A file with only the name of the nntp server in it."
+  :group 'gnus-files
+  :group 'gnus-server
+  :type 'file)
+
+;; This function is used to check both the environment variable
+;; NNTPSERVER and the /etc/nntpserver file to see whether one can find
+;; an nntp server name default.
+(defun gnus-getenv-nntpserver ()
+  (or (getenv "NNTPSERVER")
+      (and (file-readable-p gnus-nntpserver-file)
+          (save-excursion
+            (set-buffer (get-buffer-create " *gnus nntp*"))
+            (buffer-disable-undo (current-buffer))
+            (insert-file-contents gnus-nntpserver-file)
+            (let ((name (buffer-string)))
+              (prog1
+                  (if (string-match "^[ \t\n]*$" name)
+                      nil
+                    name)
+                (kill-buffer (current-buffer))))))))
+
+(defcustom gnus-select-method
+  (ignore-errors
+    (nconc
+     (list 'nntp (or (ignore-errors
+                      (gnus-getenv-nntpserver))
+                    (when (and gnus-default-nntp-server
+                               (not (string= gnus-default-nntp-server "")))
+                      gnus-default-nntp-server)
+                    (system-name)))
+     (if (or (null gnus-nntp-service)
+            (equal gnus-nntp-service "nntp"))
+        nil
+       (list gnus-nntp-service))))
+  "Default method for selecting a newsgroup.
+This variable should be a list, where the first element is how the
+news is to be fetched, the second is the address.
+
+For instance, if you want to get your news via NNTP from
+\"flab.flab.edu\", you could say:
+
+\(setq gnus-select-method '(nntp \"flab.flab.edu\"))
+
+If you want to use your local spool, say:
+
+\(setq gnus-select-method (list 'nnspool (system-name)))
+
+If you use this variable, you must set `gnus-nntp-server' to nil.
+
+There is a lot more to know about select methods and virtual servers -
+see the manual for details."
+  :group 'gnus-server
+  :type 'gnus-select-method)
+
+(defcustom gnus-message-archive-method
+  `(nnfolder
+    "archive"
+    (nnfolder-directory ,(nnheader-concat message-directory "archive"))
+    (nnfolder-active-file
+     ,(nnheader-concat message-directory "archive/active"))
+    (nnfolder-get-new-mail nil)
+    (nnfolder-inhibit-expiry t))
+  "Method used for archiving messages you've sent.
+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."
+  :group 'gnus-server
+  :group 'gnus-message
+  :type 'gnus-select-method)
+
+(defcustom 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 implicitly 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."
+  :group 'gnus-message
+  :type '(choice (const :tag "none" nil)
+                string))
+
+(defcustom gnus-secondary-servers nil
+  "List of NNTP servers that the user can choose between interactively.
+To make Gnus query you for a server, you have to give `gnus' a
+non-numeric prefix - `C-u M-x gnus', in short."
+  :group 'gnus-server
+  :type '(repeat string))
+
+(defcustom gnus-nntp-server nil
+  "*The name of the host running the NNTP server.
+This variable is semi-obsolete.         Use the `gnus-select-method'
+variable instead."
+  :group 'gnus-server
+  :type '(choice (const :tag "disable" nil)
+                string))
+
+(defcustom gnus-secondary-select-methods nil
+  "A list of secondary methods that will be used for reading news.
+This is a list where each element is a complete select method (see
+`gnus-select-method').
+
+If, for instance, you want to read your mail with the nnml backend,
+you could set this variable:
+
+\(setq gnus-secondary-select-methods '((nnml \"\")))"
+:group 'gnus-server
+:type '(repeat gnus-select-method))
+
+(defvar gnus-backup-default-subscribed-newsgroups
+  '("news.announce.newusers" "news.groups.questions" "gnu.emacs.gnus")
+  "Default default new newsgroups the first time Gnus is run.
+Should be set in paths.el, and shouldn't be touched by the user.")
+
+(defcustom gnus-local-domain nil
+  "Local domain name without a host name.
+The DOMAINNAME environment variable is used instead if it is defined.
+If the `system-name' function returns the full Internet name, there is
+no need to set this variable."
+  :group 'gnus-message
+  :type '(choice (const :tag "default" nil)
+                string))
+
+(defvar gnus-local-organization nil
+  "String with a description of what organization (if any) the user belongs to.
+Obsolete variable; use `message-user-organization' instead.")
+
+;; Customization variables
+
+(defcustom gnus-refer-article-method nil
+  "Preferred method for fetching an article by Message-ID.
+If you are reading news from the local spool (with nnspool), fetching
+articles by Message-ID is painfully slow.  By setting this method to an
+nntp method, you might get acceptable results.
+
+The value of this variable must be a valid select method as discussed
+in the documentation of `gnus-select-method'."
+  :group 'gnus-server
+  :type '(choice (const :tag "default" nil)
+                gnus-select-method))
+
+(defcustom 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/"
+    "/ftp@ftp.uni-paderborn.de:/pub/FAQ/"
+    "/ftp@ftp.sunet.se:/pub/usenet/"
+    "/ftp@nctuccca.edu.tw:/USENET/FAQ/"
+    "/ftp@hwarang.postech.ac.kr:/pub/usenet/"
+    "/ftp@ftp.hk.super.net:/mirror/faqs/")
+  "Directory where the group FAQs are stored.
+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.  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
+something of value back from them.
+
+If the default site is too slow, try one of these:
+
+   North America: mirrors.aol.com               /pub/rtfm/usenet
+                 ftp.seas.gwu.edu               /pub/rtfm
+                 rtfm.mit.edu                   /pub/usenet
+   Europe:       ftp.uni-paderborn.de           /pub/FAQ
+                  src.doc.ic.ac.uk               /usenet/news-FAQS
+                 ftp.sunet.se                   /pub/usenet
+                 sunsite.auc.dk                 /pub/usenet
+   Asia:         nctuccca.edu.tw                /USENET/FAQ
+                 hwarang.postech.ac.kr          /pub/usenet
+                 ftp.hk.super.net               /mirror/faqs"
+  :group 'gnus-group-various
+  :type '(choice directory
+                (repeat directory)))
+
+(defcustom gnus-use-cross-reference t
+  "*Non-nil means that cross referenced articles will be marked as read.
+If nil, ignore cross references.  If t, mark articles as read in
+subscribed newsgroups. If neither t nor nil, mark as read in all
+newsgroups."
+  :group 'gnus-server
+  :type '(choice (const :tag "off" nil)
+                (const :tag "subscribed" t)
+                (sexp :format "all"
+                      :value always)))
+
+(defcustom gnus-process-mark ?#
+  "*Process mark."
+  :group 'gnus-group-visual
+  :group 'gnus-summary-marks
+  :type 'character)
+
+(defcustom gnus-asynchronous nil
+  "*If non-nil, Gnus will supply backends with data needed for async article fetching."
+  :group 'gnus-asynchronous
+  :type 'boolean)
+
+(defcustom gnus-large-newsgroup 200
+  "*The number of articles which indicates a large newsgroup.
+If the number of articles in a newsgroup is greater than this value,
+confirmation is required for selecting the newsgroup."
+  :group 'gnus-group-select
+  :type 'integer)
+
+(defcustom gnus-use-long-file-name (not (memq system-type '(usg-unix-v xenix)))
+  "*Non-nil means that the default name of a file to save articles in is the group name.
+If it's nil, the directory form of the group name is used instead.
+
+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.
+
+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."
+  :group 'gnus-start
+  :type 'boolean)
+
+(defcustom gnus-kill-files-directory gnus-directory
+  "*Name of the directory where kill files will be stored (default \"~/News\")."
+  :group 'gnus-score-files
+  :group 'gnus-score-kill
+  :type 'directory)
+
+(defcustom gnus-save-score nil
+  "*If non-nil, save group scoring info."
+  :group 'gnus-score-various
+  :group 'gnus-start
+  :type 'boolean)
+
+(defcustom gnus-use-undo t
+  "*If non-nil, allow undoing in Gnus group mode buffers."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-use-adaptive-scoring nil
+  "*If non-nil, use some adaptive scoring scheme.
+If a list, then the values `word' and `line' are meaningful.  The
+former will perform adaption on individual words in the subject
+header while `line' will perform adaption on several headers."
+  :group 'gnus-meta
+  :group 'gnus-score-adapt
+  :type '(set (const word) (const line)))
+
+(defcustom gnus-use-cache 'passive
+  "*If nil, Gnus will ignore the article cache.
+If `passive', it will allow entering (and reading) articles
+explicitly entered into the cache.  If anything else, use the
+cache to the full extent of the law."
+  :group 'gnus-meta
+  :group 'gnus-cache
+  :type '(choice (const :tag "off" nil)
+                (const :tag "passive" passive)
+                (const :tag "active" t)))
+
+(defcustom gnus-use-trees nil
+  "*If non-nil, display a thread tree buffer."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-use-grouplens nil
+  "*If non-nil, use GroupLens ratings."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-keep-backlog nil
+  "*If non-nil, Gnus will keep read articles for later re-retrieval.
+If it is a number N, then Gnus will only keep the last N articles
+read.  If it is neither nil nor a number, Gnus will keep all read
+articles.  This is not a good idea."
+  :group 'gnus-meta
+  :type '(choice (const :tag "off" nil)
+                integer
+                (sexp :format "all"
+                      :value t)))
+
+(defcustom gnus-use-nocem nil
+  "*If non-nil, Gnus will read NoCeM cancel messages."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-suppress-duplicates nil
+  "*If non-nil, Gnus will mark duplicate copies of the same article as read."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-use-demon nil
+  "If non-nil, Gnus might use some demons."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-use-scoring t
+  "*If non-nil, enable scoring."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-use-picons nil
+  "*If non-nil, display picons."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-summary-prepare-exit-hook
+  '(gnus-summary-expire-articles)
+  "A hook called when preparing to exit from the summary buffer.
+It calls `gnus-summary-expire-articles' by default."
+  :group 'gnus-summary-exit
+  :type 'hook)
+
+(defcustom gnus-novice-user t
+  "*Non-nil means that you are a usenet novice.
+If non-nil, verbose messages may be displayed and confirmations may be
+required."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-expert-user nil
+  "*Non-nil means that you will never be asked for confirmation about anything.
+And that means *anything*."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-interactive-catchup t
+  "*If non-nil, require your confirmation when catching up a group."
+  :group 'gnus-group-select
+  :type 'boolean)
+
+(defcustom gnus-interactive-exit t
+  "*If non-nil, require your confirmation when exiting Gnus."
+  :group 'gnus-exit
+  :type 'boolean)
+
+(defcustom gnus-extract-address-components 'gnus-extract-address-components
+  "*Function for extracting address components from a From header.
+Two pre-defined function exist: `gnus-extract-address-components',
+which is the default, quite fast, and too simplistic solution, and
+`mail-extract-address-components', which works much better, but is
+slower."
+  :group 'gnus-summary-format
+  :type '(radio (function-item gnus-extract-address-components)
+               (function-item mail-extract-address-components)
+               (function :tag "Other")))
+
+(defcustom gnus-carpal nil
+  "*If non-nil, display clickable icons."
+  :group 'gnus-meta
+  :type 'boolean)
+
+(defcustom gnus-shell-command-separator ";"
+  "String used to separate to shell commands."
+  :group 'gnus-files
+  :type 'string)
+
+(defcustom gnus-valid-select-methods
+  '(("nntp" post address prompt-address physical-address)
+    ("nnspool" post address)
+    ("nnvirtual" post-mail virtual prompt-address)
+    ("nnmbox" mail respool address)
+    ("nnml" mail respool address)
+    ("nnmh" mail respool address)
+    ("nndir" post-mail prompt-address physical-address)
+    ("nneething" none address prompt-address physical-address)
+    ("nndoc" none address prompt-address)
+    ("nnbabyl" mail address respool)
+    ("nnkiboze" post virtual)
+    ("nnsoup" post-mail address)
+    ("nndraft" post-mail)
+    ("nnfolder" mail respool address)
+    ("nngateway" none address prompt-address physical-address)
+    ("nnweb" none))
+  "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 the category of
+this method (i. e., `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
+this variable. I think."
+  :group 'gnus-server
+  :type '(repeat (group (string :tag "Name")
+                       (radio-button-choice (const :format "%v " post)
+                                            (const :format "%v " mail)
+                                            (const :format "%v " none)
+                                            (const post-mail))
+                       (checklist :inline t
+                                  (const :format "%v " address)
+                                  (const :format "%v " prompt-address)
+                                  (const :format "%v " virtual)
+                                  (const respool)))))
+
+(define-widget 'gnus-select-method 'list
+  "Widget for entering a select method."
+  :args `((choice :tag "Method"
+                 ,@(mapcar (lambda (entry)
+                             (list 'const :format "%v\n"
+                                   (intern (car entry))))
+                           gnus-valid-select-methods))
+         (string :tag "Address")
+         (editable-list  :inline t
+                         (list :format "%v"
+                               variable
+                               (sexp :tag "Value")))))
+
+(defcustom gnus-updated-mode-lines '(group article summary tree)
+  "List of buffers that should update their mode lines.
+The list may contain the symbols `group', `article', `tree' and
+`summary'.  If the corresponding symbol is present, Gnus will keep
+that mode line updated with information that may be pertinent.
+If this variable is nil, screen refresh may be quicker."
+  :group 'gnus-various
+  :type '(set (const group)
+             (const article)
+             (const summary)
+             (const tree)))
+
+;; Added by Keinonen Kari <kk85613@cs.tut.fi>.
+(defcustom gnus-mode-non-string-length nil
+  "*Max length of mode-line non-string contents.
+If this is nil, Gnus will take space as is needed, leaving the rest
+of the modeline intact.  Note that the default of nil is unlikely
+to be desirable; see the manual for further details."
+  :group 'gnus-various
+  :type '(choice (const nil)
+                integer))
+
+(defcustom gnus-auto-expirable-newsgroups nil
+  "*Groups in which to automatically mark read articles as expirable.
+If non-nil, this should be a regexp that should match all groups in
+which to perform auto-expiry.  This only makes sense for mail groups."
+  :group 'nnmail-expire
+  :type '(choice (const nil)
+                regexp))
+
+(defcustom gnus-total-expirable-newsgroups nil
+  "*Groups in which to perform expiry of all read articles.
+Use with extreme caution.  All groups that match this regexp will be
+expiring - which means that all read articles will be deleted after
+\(say) one week.        (This only goes for mail groups and the like, of
+course.)"
+  :group 'nnmail-expire
+  :type '(choice (const nil)
+                regexp))
+
+(defcustom gnus-group-uncollapsed-levels 1
+  "Number of group name elements to leave alone when making a short group name."
+  :group 'gnus-group-visual
+  :type 'integer)
+
+(defcustom gnus-group-use-permanent-levels nil
+  "*If non-nil, once you set a level, Gnus will use this level."
+  :group 'gnus-group-levels
+  :type 'boolean)
+
+;; Hooks.
+
+(defcustom gnus-load-hook nil
+  "A hook run while Gnus is loaded."
+  :group 'gnus-start
+  :type 'hook)
+
+(defcustom gnus-apply-kill-hook '(gnus-apply-kill-file)
+  "A hook called to apply kill files to a group.
+This hook is intended to apply a kill file to the selected newsgroup.
+The function `gnus-apply-kill-file' is called by default.
+
+Since a general kill file is too heavy to use only for a few
+newsgroups, I recommend you to use a lighter hook function.  For
+example, if you'd like to apply a kill file to articles which contains
+a string `rmgroup' in subject in newsgroup `control', you can use the
+following hook:
+
+ (setq gnus-apply-kill-hook
+      (list
+       (lambda ()
+         (cond ((string-match \"control\" gnus-newsgroup-name)
+                (gnus-kill \"Subject\" \"rmgroup\")
+                (gnus-expunge \"X\"))))))"
+  :group 'gnus-score-kill
+  :options '(gnus-apply-kill-file)
+  :type 'hook)
+
+(defcustom gnus-group-change-level-function nil
+  "Function run when a group level is changed.
+It is called with three parameters -- GROUP, LEVEL and OLDLEVEL."
+  :group 'gnus-group-level
+  :type 'function)
+
+;;; Face thingies.
+
+(defcustom gnus-visual
+  '(summary-highlight group-highlight article-highlight
+                     mouse-face
+                     summary-menu group-menu article-menu
+                     tree-highlight menu highlight
+                     browse-menu server-menu
+                     page-marker tree-menu binary-menu pick-menu
+                     grouplens-menu)
+  "Enable visual features.
+If `visual' is disabled, there will be no menus and few faces.  Most of
+the visual customization options below will be ignored.  Gnus will use
+less space and be faster as a result.
+
+This variable can also be a list of visual elements to switch on.  For
+instance, to switch off all visual things except menus, you can say:
+
+   (setq gnus-visual '(menu))
+
+Valid elements include `summary-highlight', `group-highlight',
+`article-highlight', `mouse-face', `summary-menu', `group-menu',
+`article-menu', `tree-highlight', `menu', `highlight', `browse-menu',
+`server-menu', `page-marker', `tree-menu', `binary-menu', `pick-menu',
+and `grouplens-menu'."
+  :group 'gnus-meta
+  :group 'gnus-visual
+  :type '(set (const summary-highlight)
+             (const group-highlight)
+             (const article-highlight)
+             (const mouse-face)
+             (const summary-menu)
+             (const group-menu)
+             (const article-menu)
+             (const tree-highlight)
+             (const menu)
+             (const highlight)
+             (const browse-menu)
+             (const server-menu)
+             (const page-marker)
+             (const tree-menu)
+             (const binary-menu)
+             (const pick-menu)
+             (const grouplens-menu)))
+
+(defcustom gnus-mouse-face
+  (condition-case ()
+      (if (gnus-visual-p 'mouse-face 'highlight)
+         (if (boundp 'gnus-mouse-face)
+             (or gnus-mouse-face 'highlight)
+           'highlight)
+       'default)
+    (error 'highlight))
+  "Face used for group or summary buffer mouse highlighting.
+The line beneath the mouse pointer will be highlighted with this
+face."
+  :group 'gnus-visual
+  :type 'face)
+
+(defcustom gnus-article-display-hook
+  (if (and (string-match "XEmacs" emacs-version)
+          (featurep 'xface))
+      '(gnus-article-hide-headers-if-wanted
+       gnus-article-hide-boring-headers
+       gnus-article-treat-overstrike
+       gnus-article-maybe-highlight
+       gnus-article-display-x-face)
+    '(gnus-article-hide-headers-if-wanted
+      gnus-article-hide-boring-headers
+      gnus-article-treat-overstrike
+      gnus-article-maybe-highlight))
+  "Controls how the article buffer will look.
+
+If you leave the list empty, the article will appear exactly as it is
+stored on the disk.  The list entries will hide or highlight various
+parts of the article, making it easier to find the information you
+want."
+  :group 'gnus-article-highlight
+  :group 'gnus-visual
+  :type 'hook
+  :options '(gnus-article-add-buttons
+            gnus-article-add-buttons-to-head
+            gnus-article-emphasize
+            gnus-article-fill-cited-article
+            gnus-article-remove-cr
+            gnus-article-de-quoted-unreadable
+            gnus-article-display-x-face
+            gnus-summary-stop-page-breaking
+            ;; gnus-summary-caesar-message
+            ;; gnus-summary-verbose-headers
+            gnus-summary-toggle-mime
+            gnus-article-hide
+            gnus-article-hide-headers
+            gnus-article-hide-boring-headers
+            gnus-article-hide-signature
+            gnus-article-hide-citation
+            gnus-article-hide-pgp
+            gnus-article-hide-pem
+            gnus-article-highlight
+            gnus-article-highlight-headers
+            gnus-article-highlight-citation
+            gnus-article-highlight-signature
+            gnus-article-date-ut
+            gnus-article-date-local
+            gnus-article-date-lapsed
+            gnus-article-date-original
+            gnus-article-remove-trailing-blank-lines
+            gnus-article-strip-leading-blank-lines
+            gnus-article-strip-multiple-blank-lines
+            gnus-article-strip-blank-lines
+            gnus-article-treat-overstrike))
+
+(defcustom gnus-article-save-directory gnus-directory
+  "*Name of the directory articles will be saved in (default \"~/News\")."
+  :group 'gnus-article-saving
+  :type 'directory)
+
+\f
+;;; Internal variables
+
+(defvar gnus-group-get-parameter-function 'gnus-group-get-parameter)
+(defvar gnus-original-article-buffer " *Original Article*")
+(defvar gnus-newsgroup-name nil)
+
+(defvar gnus-current-select-method nil
+  "The current method for selecting a newsgroup.")
+
+(defvar gnus-tree-buffer "*Tree*"
+  "Buffer where Gnus thread trees are displayed.")
+
+;; Dummy variable.
+(defvar gnus-use-generic-from nil)
+
+;; Variable holding the user answers to all method prompts.
+(defvar gnus-method-history nil)
+(defvar gnus-group-history nil)
+
+;; Variable holding the user answers to all mail method prompts.
+(defvar gnus-mail-method-history nil)
+
+;; Variable holding the user answers to all group prompts.
+(defvar gnus-group-history nil)
+
+(defvar gnus-server-alist nil
+  "List of available servers.")
+
+(defvar gnus-predefined-server-alist
+  `(("cache"
+     (nnspool "cache"
+             (nnspool-spool-directory "~/News/cache/")
+             (nnspool-nov-directory "~/News/cache/")
+             (nnspool-active-file "~/News/cache/active"))))
+  "List of predefined (convenience) servers.")
+
+(defvar gnus-topic-indentation "") ;; Obsolete variable.
+
+(defconst gnus-article-mark-lists
+  '((marked . tick) (replied . reply)
+    (expirable . expire) (killed . killed)
+    (bookmarks . bookmark) (dormant . dormant)
+    (scored . score) (saved . save)
+    (cached . cache)))
+
+(defvar gnus-headers-retrieved-by nil)
+(defvar gnus-article-reply nil)
+(defvar gnus-override-method nil)
+(defvar gnus-article-check-size nil)
+(defvar gnus-opened-servers nil)
+
+(defvar gnus-current-kill-article nil)
+
+(defvar gnus-have-read-active-file nil)
+
+(defconst gnus-maintainer
+  "gnus-bug@ifi.uio.no (The Gnus Bugfixing Girls + Boys)"
+  "The mail address of the Gnus maintainers.")
+
+(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")
+    (mime/viewer-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*")
+(defvar gnus-article-buffer "*Article*")
+(defvar gnus-server-buffer "*Server*")
+
+(defvar gnus-buffer-list nil
+  "Gnus buffers that should be killed on exit.")
+
+(defvar gnus-slave nil
+  "Whether this Gnus is a slave or not.")
+
+(defvar gnus-batch-mode nil
+  "Whether this Gnus is running in batch mode or not.")
+
+(defvar gnus-variable-list
+  '(gnus-newsrc-options gnus-newsrc-options-n
+    gnus-newsrc-last-checked-date
+    gnus-newsrc-alist gnus-server-alist
+    gnus-killed-list gnus-zombie-list
+    gnus-topic-topology gnus-topic-alist
+    gnus-format-specs)
+  "Gnus variables saved in the quick startup file.")
+
+(defvar gnus-newsrc-alist nil
+  "Assoc list of read articles.
+gnus-newsrc-hashtb should be kept so that both hold the same information.")
+
+(defvar gnus-newsrc-hashtb nil
+  "Hashtable of gnus-newsrc-alist.")
+
+(defvar gnus-killed-list nil
+  "List of killed newsgroups.")
+
+(defvar gnus-killed-hashtb nil
+  "Hash table equivalent of gnus-killed-list.")
+
+(defvar gnus-zombie-list nil
+  "List of almost dead newsgroups.")
+
+(defvar gnus-description-hashtb nil
+  "Descriptions of newsgroups.")
+
+(defvar gnus-list-of-killed-groups nil
+  "List of newsgroups that have recently been killed by the user.")
+
+(defvar gnus-active-hashtb nil
+  "Hashtable of active articles.")
+
+(defvar gnus-moderated-hashtb nil
+  "Hashtable of moderated newsgroups.")
+
+;; Save window configuration.
+(defvar gnus-prev-winconf nil)
+
+(defvar gnus-reffed-article-number nil)
+
+;;; Let the byte-compiler know that we know about this variable.
+(defvar rmail-default-rmail-file)
+
+(defvar gnus-dead-summary nil)
+
+;;; End of variables.
+
+;; Define some autoload functions Gnus might use.
+(eval-and-compile
+
+  ;; This little mapcar goes through the list below and marks the
+  ;; symbols in question as autoloaded functions.
+  (mapcar
+   (lambda (package)
+     (let ((interactive (nth 1 (memq ':interactive package))))
+       (mapcar
+       (lambda (function)
+         (let (keymap)
+           (when (consp function)
+             (setq keymap (car (memq 'keymap function)))
+             (setq function (car function)))
+           (autoload function (car package) nil interactive keymap)))
+       (if (eq (nth 1 package) ':interactive)
+           (cdddr package)
+         (cdr package)))))
+   '(("metamail" metamail-buffer)
+     ("info" Info-goto-node)
+     ("hexl" hexl-hex-string-to-integer)
+     ("pp" pp pp-to-string pp-eval-expression)
+     ("ps-print" ps-print-preprint)
+     ("mail-extr" mail-extract-address-components)
+     ("message" :interactive t
+      message-send-and-exit message-yank-original)
+     ("nnmail" nnmail-split-fancy nnmail-article-group nnmail-date-to-time)
+     ("nnvirtual" nnvirtual-catchup-group nnvirtual-convert-headers)
+     ("timezone" timezone-make-date-arpa-standard timezone-fix-time
+      timezone-make-sortable-date timezone-make-time-string)
+     ("rmailout" rmail-output)
+     ("rmail" rmail-insert-rmail-file-header rmail-count-new-messages
+      rmail-show-message)
+     ("gnus-audio" :interactive t gnus-audio-play)
+     ("gnus-xmas" gnus-xmas-splash)
+     ("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)
+     ("score-mode" :interactive t gnus-score-mode)
+     ("gnus-mh" gnus-summary-save-article-folder
+      gnus-Folder-save-name gnus-folder-save-name)
+     ("gnus-mh" :interactive t gnus-summary-save-in-folder)
+     ("gnus-demon" gnus-demon-add-nocem gnus-demon-add-scanmail
+      gnus-demon-add-rescan gnus-demon-add-scan-timestamps
+      gnus-demon-add-disconnection gnus-demon-add-handler
+      gnus-demon-remove-handler)
+     ("gnus-demon" :interactive t
+      gnus-demon-init gnus-demon-cancel)
+     ("gnus-salt" gnus-highlight-selected-tree gnus-possibly-generate-tree
+      gnus-tree-open gnus-tree-close gnus-carpal-setup-buffer)
+     ("gnus-nocem" gnus-nocem-scan-groups gnus-nocem-close
+      gnus-nocem-unwanted-article-p)
+     ("gnus-srvr" gnus-enter-server-buffer gnus-server-set-info)
+     ("gnus-srvr" gnus-browse-foreign-server)
+     ("gnus-cite" :interactive t
+      gnus-article-highlight-citation gnus-article-hide-citation-maybe
+      gnus-article-hide-citation gnus-article-fill-cited-article
+      gnus-article-hide-citation-in-followups)
+     ("gnus-kill" gnus-kill gnus-apply-kill-file-internal
+      gnus-kill-file-edit-file gnus-kill-file-raise-followups-to-author
+      gnus-execute gnus-expunge)
+     ("gnus-cache" gnus-cache-possibly-enter-article gnus-cache-save-buffers
+      gnus-cache-possibly-remove-articles gnus-cache-request-article
+      gnus-cache-retrieve-headers gnus-cache-possibly-alter-active
+      gnus-cache-enter-remove-article gnus-cached-article-p
+      gnus-cache-open gnus-cache-close gnus-cache-update-article)
+      ("gnus-cache" :interactive t gnus-jog-cache gnus-cache-enter-article
+       gnus-cache-remove-article gnus-summary-insert-cached-articles)
+      ("gnus-score" :interactive t
+       gnus-summary-increase-score gnus-summary-set-score
+       gnus-summary-raise-thread gnus-summary-raise-same-subject
+       gnus-summary-raise-score gnus-summary-raise-same-subject-and-select
+       gnus-summary-lower-thread gnus-summary-lower-same-subject
+       gnus-summary-lower-score gnus-summary-lower-same-subject-and-select
+       gnus-summary-current-score gnus-score-default
+       gnus-score-flush-cache gnus-score-close
+       gnus-possibly-score-headers gnus-score-followup-article
+       gnus-score-followup-thread)
+      ("gnus-score"
+       (gnus-summary-score-map keymap) gnus-score-save gnus-score-headers
+      gnus-current-score-file-nondirectory gnus-score-adaptive
+      gnus-score-find-trace gnus-score-file-name)
+     ("gnus-cus" :interactive t gnus-group-customize gnus-score-customize)
+     ("gnus-topic" :interactive t gnus-topic-mode)
+     ("gnus-topic" gnus-topic-remove-group gnus-topic-set-parameters)
+     ("gnus-salt" :interactive t gnus-pick-mode gnus-binary-mode)
+     ("gnus-uu" (gnus-uu-extract-map keymap) (gnus-uu-mark-map keymap))
+     ("gnus-uu" :interactive t
+      gnus-uu-digest-mail-forward gnus-uu-digest-post-forward
+      gnus-uu-mark-series gnus-uu-mark-region gnus-uu-mark-buffer
+      gnus-uu-mark-by-regexp gnus-uu-mark-all
+      gnus-uu-mark-sparse gnus-uu-mark-thread gnus-uu-decode-uu
+      gnus-uu-decode-uu-and-save gnus-uu-decode-unshar
+      gnus-uu-decode-unshar-and-save gnus-uu-decode-save
+      gnus-uu-decode-binhex gnus-uu-decode-uu-view
+      gnus-uu-decode-uu-and-save-view gnus-uu-decode-unshar-view
+      gnus-uu-decode-unshar-and-save-view gnus-uu-decode-save-view
+      gnus-uu-decode-binhex-view)
+     ("gnus-uu" gnus-uu-delete-work-dir gnus-quote-arg-for-sh-or-csh)
+     ("gnus-msg" (gnus-summary-send-map keymap)
+      gnus-article-mail gnus-copy-article-buffer gnus-extended-version)
+     ("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-cancel-article gnus-summary-supersede-article
+      gnus-post-news gnus-summary-reply gnus-summary-reply-with-original
+      gnus-summary-mail-forward gnus-summary-mail-other-window
+      gnus-summary-resend-message gnus-summary-resend-bounced-mail
+      gnus-bug)
+     ("gnus-picon" :interactive t gnus-article-display-picons
+      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-win" gnus-configure-windows gnus-add-configuration)
+     ("gnus-sum" gnus-summary-insert-line gnus-summary-read-group
+      gnus-list-of-unread-articles gnus-list-of-read-articles
+      gnus-offer-save-summaries gnus-make-thread-indent-array
+      gnus-summary-exit gnus-update-read-articles)
+     ("gnus-group" gnus-group-insert-group-line gnus-group-quit
+      gnus-group-list-groups gnus-group-first-unread-group
+      gnus-group-set-mode-line gnus-group-set-info gnus-group-save-newsrc
+      gnus-group-setup-buffer gnus-group-get-new-news
+      gnus-group-make-help-group gnus-group-update-group)
+     ("gnus-bcklg" gnus-backlog-request-article gnus-backlog-enter-article
+      gnus-backlog-remove-article)
+     ("gnus-art" gnus-article-read-summary-keys gnus-article-save
+      gnus-article-prepare gnus-article-set-window-start
+      gnus-article-next-page gnus-article-prev-page
+      gnus-request-article-this-buffer gnus-article-mode
+      gnus-article-setup-buffer gnus-narrow-to-page
+      gnus-article-delete-invisible-text)
+     ("gnus-art" :interactive t
+      gnus-article-hide-headers gnus-article-hide-boring-headers
+      gnus-article-treat-overstrike gnus-article-word-wrap
+      gnus-article-remove-cr gnus-article-remove-trailing-blank-lines
+      gnus-article-display-x-face gnus-article-de-quoted-unreadable
+      gnus-article-mime-decode-quoted-printable gnus-article-hide-pgp
+      gnus-article-hide-pem gnus-article-hide-signature
+      gnus-article-strip-leading-blank-lines gnus-article-date-local
+      gnus-article-date-original gnus-article-date-lapsed
+      gnus-article-show-all-headers
+      gnus-article-edit-mode gnus-article-edit-article
+      gnus-article-edit-done gnus-decode-rfc1522 article-decode-rfc1522)
+     ("gnus-int" gnus-request-type)
+     ("gnus-start" gnus-newsrc-parse-options gnus-1 gnus-no-server-1
+      gnus-dribble-enter)
+     ("gnus-dup" gnus-dup-suppress-articles gnus-dup-unsuppress-article
+      gnus-dup-enter-articles)
+     ("gnus-range" gnus-copy-sequence)
+     ("gnus-eform" gnus-edit-form)
+     ("gnus-move" :interactive t
+      gnus-group-move-group-to-server gnus-change-server)
+     ("gnus-logic" gnus-score-advanced)
+     ("gnus-undo" gnus-undo-mode gnus-undo-register)
+     ("gnus-async" gnus-async-request-fetched-article gnus-async-prefetch-next
+      gnus-async-prefetch-article gnus-async-prefetch-remove-group
+      gnus-async-halt-prefetch)
+     ("gnus-vm" :interactive t gnus-summary-save-in-vm
+      gnus-summary-save-article-vm))))
+
+;;; gnus-sum.el thingies
+
+
+(defcustom 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,
+with some simple extensions.
+
+%N   Article number, left padded with spaces (string)
+%S   Subject (string)
+%s   Subject if it is at the root of a thread, and \"\" otherwise (string)
+%n   Name of the poster (string)
+%a   Extracted name of the poster (string)
+%A   Extracted address of the poster (string)
+%F   Contents of the From: header (string)
+%x   Contents of the Xref: header (string)
+%D   Date of the article (string)
+%d   Date of the article (string) in DD-MMM format
+%M   Message-id of the article (string)
+%r   References of the article (string)
+%c   Number of characters in the article (integer)
+%L   Number of lines in the article (integer)
+%I   Indentation based on thread level (a string of spaces)
+%T   A string with two possible values: 80 spaces if the article
+     is on thread level two or larger and 0 spaces on level one
+%R   \"A\" if this article has been replied to, \" \" otherwise (character)
+%U   Status of this article (character, \"R\", \"K\", \"-\" or \" \")
+%[   Opening bracket (character, \"[\" or \"<\")
+%]   Closing bracket (character, \"]\" or \">\")
+%>   Spaces of length thread-level (string)
+%<   Spaces of length (- 20 thread-level) (string)
+%i   Article score (number)
+%z   Article zcore (character)
+%t   Number of articles under the current thread (number).
+%e   Whether the thread is empty or not (character).
+%l   GroupLens score (string).
+%V   Total thread score (number).
+%P   The line number (number).
+%u   User defined specifier.  The next character in the format string should
+     be a letter.  Gnus will call the function gnus-user-format-function-X,
+     where X is the letter following %u.  The function will be passed the
+     current header as argument.  The function should return a string, which
+     will be inserted into the summary just like information from any other
+     summary specifier.
+
+Text between %( and %) will be highlighted with `gnus-mouse-face'
+when the mouse point is placed inside the area.         There can only be one
+such area.
+
+The %U (status), %R (replied) and %z (zcore) specs have to be handled
+with care.  For reasons of efficiency, Gnus will compute what column
+these characters will end up in, and \"hard-code\" that.  This means that
+it is illegal to have these specs after a variable-length spec.         Well,
+you might not be arrested, but your summary buffer will look strange,
+which is bad enough.
+
+The smart choice is to have these specs as for to the left as
+possible.
+
+This restriction may disappear in later versions of Gnus."
+  :type 'string
+  :group 'gnus-summary-format)
+
+;;;
+;;; Skeleton keymaps
+;;;
+
+(defun gnus-suppress-keymap (keymap)
+  (suppress-keymap keymap)
+  (let ((keys `([delete] "\177" "\M-u"))) ;gnus-mouse-2
+    (while keys
+      (define-key keymap (pop keys) 'undefined))))
+
+(defvar gnus-article-mode-map
+  (let ((keymap (make-keymap)))
+    (gnus-suppress-keymap keymap)
+    keymap))
+(defvar gnus-summary-mode-map
+  (let ((keymap (make-keymap)))
+    (gnus-suppress-keymap keymap)
+    keymap))
+(defvar gnus-group-mode-map
+  (let ((keymap (make-keymap)))
+    (gnus-suppress-keymap keymap)
+    keymap))
 
 \f
 
 
 \f
 
 (defmacro gnus-sethash (string value hashtable)
   "Set hash value.  Arguments are STRING, VALUE, and HASHTABLE."
   `(set (intern ,string ,hashtable) ,value))
 (defmacro gnus-sethash (string value hashtable)
   "Set hash value.  Arguments are STRING, VALUE, and HASHTABLE."
   `(set (intern ,string ,hashtable) ,value))
-(put 'nnheader-temp-write 'edebug-form-spec '(form form form))
+(put 'gnus-sethash 'edebug-form-spec '(form form form))
 
 (defmacro gnus-group-unread (group)
   "Get the currently computed number of unread articles in GROUP."
 
 (defmacro gnus-group-unread (group)
   "Get the currently computed number of unread articles in GROUP."
 
 (defun gnus-info-set-entry (info entry number)
   ;; Extend the info until we have enough elements.
 
 (defun gnus-info-set-entry (info entry number)
   ;; Extend the info until we have enough elements.
-  (while (< (length info) number)
+  (while (<= (length info) number)
     (nconc info (list nil)))
   ;; Set the entry.
   (setcar (nthcdr number info) entry))
     (nconc info (list nil)))
   ;; Set the entry.
   (setcar (nthcdr number info) entry))
 ;; Add the current buffer to the list of buffers to be killed on exit.
 (defun gnus-add-current-to-buffer-list ()
   (or (memq (current-buffer) gnus-buffer-list)
 ;; Add the current buffer to the list of buffers to be killed on exit.
 (defun gnus-add-current-to-buffer-list ()
   (or (memq (current-buffer) gnus-buffer-list)
-      (setq gnus-buffer-list (cons (current-buffer) gnus-buffer-list))))
+      (push (current-buffer) gnus-buffer-list)))
 
 (defun gnus-version (&optional arg)
   "Version number of this version of Gnus.
 
 (defun gnus-version (&optional arg)
   "Version number of this version of Gnus.
@@ -390,7 +1949,7 @@ If ARG, insert string at point."
       (string-to-number
        (if (zerop major)
           (format "%s00%02d%02d"
       (string-to-number
        (if (zerop major)
           (format "%s00%02d%02d"
-                  (cond 
+                  (cond
                    ((member alpha '("(ding)" "d")) "4.99")
                    ((member alpha '("September" "s")) "5.01")
                    ((member alpha '("Red" "r")) "5.03"))
                    ((member alpha '("(ding)" "d")) "4.99")
                    ((member alpha '("September" "s")) "5.01")
                    ((member alpha '("Red" "r")) "5.03"))
@@ -503,7 +2062,9 @@ that that variable is buffer-local to the summary buffers."
 (defsubst gnus-server-add-address (method)
   (let ((method-name (symbol-name (car method))))
     (if (and (memq 'address (assoc method-name gnus-valid-select-methods))
 (defsubst gnus-server-add-address (method)
   (let ((method-name (symbol-name (car method))))
     (if (and (memq 'address (assoc method-name gnus-valid-select-methods))
-            (not (assq (intern (concat method-name "-address")) method)))
+            (not (assq (intern (concat method-name "-address")) method))
+            (memq 'physical-address (assq (car method)
+                                          gnus-valid-select-methods)))
        (append method (list (list (intern (concat method-name "-address"))
                                   (nth 1 method))))
       method)))
        (append method (list (list (intern (concat method-name "-address"))
                                   (nth 1 method))))
       method)))
@@ -525,7 +2086,7 @@ that that variable is buffer-local to the summary buffers."
 
 (defun gnus-server-to-method (server)
   "Map virtual server names to select methods."
 
 (defun gnus-server-to-method (server)
   "Map virtual server names to select methods."
-  (or 
+  (or
    ;; Is this a method, perhaps?
    (and server (listp server) server)
    ;; Perhaps this is the native server?
    ;; Is this a method, perhaps?
    (and server (listp server) server)
    ;; Perhaps this is the native server?
@@ -576,7 +2137,7 @@ that that variable is buffer-local to the summary buffers."
 
 (defun gnus-archive-server-wanted-p ()
   "Say whether the user wants to use the archive server."
 
 (defun gnus-archive-server-wanted-p ()
   "Say whether the user wants to use the archive server."
-  (cond 
+  (cond
    ((or (not gnus-message-archive-method)
        (not gnus-message-archive-group))
     nil)
    ((or (not gnus-message-archive-method)
        (not gnus-message-archive-group))
     nil)
@@ -594,13 +2155,13 @@ that that variable is buffer-local to the summary buffers."
   (if (not method)
       group
     (concat (format "%s" (car method))
   (if (not method)
       group
     (concat (format "%s" (car method))
-           (if (and
-                (or (assoc (format "%s" (car method)) 
-                           (gnus-methods-using 'address))
-                    (gnus-server-equal method gnus-message-archive-method))
-                (nth 1 method)
-                (not (string= (nth 1 method) "")))
-               (concat "+" (nth 1 method)))
+           (when (and
+                  (or (assoc (format "%s" (car method))
+                             (gnus-methods-using 'address))
+                      (gnus-server-equal method gnus-message-archive-method))
+                  (nth 1 method)
+                  (not (string= (nth 1 method) "")))
+             (concat "+" (nth 1 method)))
            ":" group)))
 
 (defun gnus-group-real-prefix (group)
            ":" group)))
 
 (defun gnus-group-real-prefix (group)
@@ -610,7 +2171,8 @@ that that variable is buffer-local to the summary buffers."
     ""))
 
 (defun gnus-group-method (group)
     ""))
 
 (defun gnus-group-method (group)
-  "Return the server or method used for selecting GROUP."
+  "Return the server or method used for selecting GROUP.
+You should probably use `gnus-find-method-for-group' instead."
   (let ((prefix (gnus-group-real-prefix group)))
     (if (equal prefix "")
        gnus-select-method
   (let ((prefix (gnus-group-real-prefix group)))
     (if (equal prefix "")
        gnus-select-method
@@ -696,9 +2258,9 @@ If SYMBOL, return the value of that symbol in the group parameters."
       (let ((old-params (gnus-info-params info))
            (new-params (list (cons name value))))
        (while old-params
       (let ((old-params (gnus-info-params info))
            (new-params (list (cons name value))))
        (while old-params
-         (if (or (not (listp (car old-params)))
-                 (not (eq (caar old-params) name)))
-             (setq new-params (append new-params (list (car old-params)))))
+         (when (or (not (listp (car old-params)))
+                   (not (eq (caar old-params) name)))
+           (setq new-params (append new-params (list (car old-params)))))
          (setq old-params (cdr old-params)))
        (gnus-group-set-info new-params group 'params)))))
 
          (setq old-params (cdr old-params)))
        (gnus-group-set-info new-params group 'params)))))
 
@@ -724,23 +2286,22 @@ just the host name."
     ;; separate foreign select method from group name and collapse.
     ;; if method contains a server, collapse to non-domain server name,
     ;; otherwise collapse to select method
     ;; separate foreign select method from group name and collapse.
     ;; if method contains a server, collapse to non-domain server name,
     ;; otherwise collapse to select method
-    (if (string-match ":" group)
-       (cond ((string-match "+" group)
-              (let* ((plus (string-match "+" group))
-                     (colon (string-match ":" group))
-                     (dot (string-match "\\." group)))
-                (setq foreign (concat
-                               (substring group (+ 1 plus)
-                                          (cond ((null dot) colon)
-                                                ((< colon dot) colon)
-                                                ((< dot colon) dot))) ":")
-                      group (substring group (+ 1 colon))
-                      )))
-             (t
-              (let* ((colon (string-match ":" group)))
-                (setq foreign (concat (substring group 0 (+ 1 colon)))
-                      group (substring group (+ 1 colon)))
-                ))))
+    (when (string-match ":" group)
+      (cond ((string-match "+" group)
+            (let* ((plus (string-match "+" group))
+                   (colon (string-match ":" group (or plus 0)))
+                   (dot (string-match "\\." group)))
+              (setq foreign (concat
+                             (substring group (+ 1 plus)
+                                        (cond ((null dot) colon)
+                                              ((< colon dot) colon)
+                                              ((< dot colon) dot)))
+                             ":")
+                    group (substring group (+ 1 colon)))))
+           (t
+            (let* ((colon (string-match ":" group)))
+              (setq foreign (concat (substring group 0 (+ 1 colon)))
+                    group (substring group (+ 1 colon)))))))
     ;; collapse group name leaving LEVELS uncollapsed elements
     (while group
       (if (and (string-match "\\." group) (> levels 0))
     ;; collapse group name leaving LEVELS uncollapsed elements
     (while group
       (if (and (string-match "\\." group) (> levels 0))
@@ -752,6 +2313,14 @@ just the host name."
              group nil)))
     name))
 
              group nil)))
     name))
 
+(defun gnus-narrow-to-body ()
+  "Narrow to the body of an article."
+  (narrow-to-region
+   (progn
+     (goto-char (point-min))
+     (or (search-forward "\n\n" nil t)
+        (point-max)))
+   (point-max)))
 
 \f
 ;;;
 
 \f
 ;;;
@@ -771,18 +2340,20 @@ Returns the number of articles marked as read."
     (when (get-file-buffer file)
       (save-excursion
        (set-buffer (get-file-buffer file))
     (when (get-file-buffer file)
       (save-excursion
        (set-buffer (get-file-buffer file))
-       (and (buffer-modified-p) (save-buffer))
+       (when (buffer-modified-p)
+         (save-buffer))
        (kill-buffer (current-buffer))))))
 
 (defcustom gnus-kill-file-name "KILL"
   "Suffix of the kill files."
        (kill-buffer (current-buffer))))))
 
 (defcustom gnus-kill-file-name "KILL"
   "Suffix of the kill files."
-  :group 'gnus-score
+  :group 'gnus-score-kill
+  :group 'gnus-score-files
   :type 'string)
 
 (defun gnus-newsgroup-kill-file (newsgroup)
   "Return the name of a kill file name for NEWSGROUP.
 If NEWSGROUP is nil, return the global kill file name instead."
   :type 'string)
 
 (defun gnus-newsgroup-kill-file (newsgroup)
   "Return the name of a kill file name for NEWSGROUP.
 If NEWSGROUP is nil, return the global kill file name instead."
-  (cond 
+  (cond
    ;; The global KILL file is placed at top of the directory.
    ((or (null newsgroup)
        (string-equal newsgroup ""))
    ;; The global KILL file is placed at top of the directory.
    ((or (null newsgroup)
        (string-equal newsgroup ""))
@@ -814,26 +2385,33 @@ If NEWSGROUP is nil, return the global kill file name instead."
   (memq option (assoc (format "%s" (car method))
                      gnus-valid-select-methods)))
 
   (memq option (assoc (format "%s" (car method))
                      gnus-valid-select-methods)))
 
+(defun gnus-similar-server-opened (method)
+  (let ((opened gnus-opened-servers))
+    (while (and method opened)
+      (when (and (equal (cadr method) (cadaar opened))
+                (not (equal method (caar opened))))
+       (setq method nil))
+      (pop opened))
+    (not method)))
+
 (defun gnus-server-extend-method (group method)
   ;; This function "extends" a virtual server. If the server is
   ;; "hello", and the select method is ("hello" (my-var "something"))
   ;; in the group "alt.alt", this will result in a new virtual server
   ;; called "hello+alt.alt".
 (defun gnus-server-extend-method (group method)
   ;; This function "extends" a virtual server. If the server is
   ;; "hello", and the select method is ("hello" (my-var "something"))
   ;; in the group "alt.alt", this will result in a new virtual server
   ;; called "hello+alt.alt".
-  (let ((entry
-        (gnus-copy-sequence
-         (if (gnus-server-equal method gnus-select-method) gnus-select-method
-           (cdr (assoc (car method) gnus-server-alist))))))
-    (if (not entry)
-       method
-      (setcar (cdr entry) (concat (nth 1 entry) "+" group))
-      (nconc entry (cdr method)))))
+  (if (or (not (inline (gnus-similar-server-opened method)))
+         (not (cddr method)))
+      method
+    `(,(car method) ,(concat (cadr method) "+" group)
+      (,(intern (format "%s-address" (car method))) ,(cadr method))
+      ,@(cddr 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)
 
 (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."
+  "Guess a select method based on GROUP."
   (if (string-match ":" group)
       (let ((server (substring group 0 (match-beginning 0))))
        (if (string-match "\\+" server)
   (if (string-match ":" group)
       (let ((server (substring group 0 (match-beginning 0))))
        (if (string-match "\\+" server)
@@ -855,9 +2433,9 @@ If NEWSGROUP is nil, return the global kill file name instead."
            gnus-select-method
          (setq method
                (cond ((stringp method)
            gnus-select-method
          (setq method
                (cond ((stringp method)
-                      (gnus-server-to-method method))
-                     ((stringp (car method))
-                      (gnus-server-extend-method group method))
+                      (inline (gnus-server-to-method method)))
+                     ((stringp (cadr method))
+                      (inline (gnus-server-extend-method group method)))
                      (t
                       method)))
          (cond ((equal (cadr method) "")
                      (t
                       method)))
          (cond ((equal (cadr method) "")
@@ -867,22 +2445,42 @@ If NEWSGROUP is nil, return the global kill file name instead."
                (t
                 (gnus-server-add-address method)))))))
 
                (t
                 (gnus-server-add-address method)))))))
 
-(defun gnus-check-backend-function (func group)
-  "Check whether GROUP supports function FUNC."
-  (let ((method (if (stringp group) (car (gnus-find-method-for-group group))
-                 group)))
-    (fboundp (intern (format "%s-%s" method func)))))
+(defsubst gnus-check-backend-function (func group)
+  "Check whether GROUP supports function FUNC.
+GROUP can either be a string (a group name) or a select method."
+  (ignore-errors
+    (let ((method (if (stringp group)
+                     (car (gnus-find-method-for-group group))
+                   group)))
+      (unless (featurep method)
+       (require method))
+      (fboundp (intern (format "%s-%s" method func))))))
 
 (defun gnus-methods-using (feature)
   "Find all methods that have FEATURE."
   (let ((valids gnus-valid-select-methods)
        outs)
     (while valids
 
 (defun gnus-methods-using (feature)
   "Find all methods that have FEATURE."
   (let ((valids gnus-valid-select-methods)
        outs)
     (while valids
-      (if (memq feature (car valids))
-         (setq outs (cons (car valids) outs)))
+      (when (memq feature (car valids))
+       (push (car valids) outs))
       (setq valids (cdr valids)))
     outs))
 
       (setq valids (cdr valids)))
     outs))
 
+(defun gnus-read-group (prompt &optional default)
+  "Prompt the user for a group name.
+Disallow illegal group names."
+  (let ((prefix "")
+       group)
+    (while (not group)
+      (when (string-match
+            "[: `'\"/]\\|^$"
+            (setq group (read-string (concat prefix prompt)
+                                     (cons (or default "") 0)
+                                     'gnus-group-history)))
+       (setq prefix (format "Illegal group name: \"%s\".  " group)
+             group nil)))
+    group))
+
 (defun gnus-read-method (prompt)
   "Prompt the user for a method.
 Allow completion over sensible values."
 (defun gnus-read-method (prompt)
   "Prompt the user for a method.
 Allow completion over sensible values."
@@ -891,7 +2489,7 @@ Allow completion over sensible values."
          prompt (append gnus-valid-select-methods gnus-predefined-server-alist
                         gnus-server-alist)
          nil t nil 'gnus-method-history)))
          prompt (append gnus-valid-select-methods gnus-predefined-server-alist
                         gnus-server-alist)
          nil t nil 'gnus-method-history)))
-    (cond 
+    (cond
      ((equal method "")
       (setq method gnus-select-method))
      ((assoc method gnus-valid-select-methods)
      ((equal method "")
       (setq method gnus-select-method))
      ((assoc method gnus-valid-select-methods)
@@ -934,11 +2532,14 @@ As opposed to `gnus', this command will not connect to the local server."
 (defun gnus-other-frame (&optional arg)
   "Pop up a frame to read news."
   (interactive "P")
 (defun gnus-other-frame (&optional arg)
   "Pop up a frame to read news."
   (interactive "P")
-  (if (gnus-alive-p)
-      (let ((pop-up-frames t))
-       (gnus arg))
-    (select-frame (make-frame))
-    (gnus arg)))
+  (let ((window (get-buffer-window gnus-group-buffer)))
+    (cond (window
+          (select-frame (window-frame window)))
+         ((= (length (frame-list)) 1)
+          (select-frame (make-frame)))
+         (t
+          (other-frame 1))))
+  (gnus arg))
 
 ;;;###autoload
 (defun gnus (&optional arg dont-connect slave)
 
 ;;;###autoload
 (defun gnus (&optional arg dont-connect slave)