(Info-directory-list): If path-separator isn't available, bind it here.
[bpt/emacs.git] / lisp / gnus.el
index ea56efd..f9e1f73 100644 (file)
@@ -1,11 +1,8 @@
-;;; gnus.el --- GNUS: an NNTP-based News Reader for GNU Emacs
+;;; gnus.el --- NNTP-based News Reader for GNU Emacs
+;; Copyright (C) 1987,88,89,90,93,94,95 Free Software Foundation, Inc.
 
-;; Author: Masanobu UMEDA <umerin@flab.flab.fujitsu.junet>
-;; Last-Modified: 10 Jun 1992
-
-;; $Header: gnus.el,v 3.13 90/03/23 13:24:27 umerin Locked $
-
-;; Copyright (C) 1987, 1988, 1989, 1990 Free Software Foundation, Inc.
+;; Author: Masanobu UMEDA <umerin@mse.kyutech.ac.jp>
+;; Keywords: news
 
 ;; This file is part of GNU Emacs.
 
 
 ;;; Commentary:
 
-;; GNUS Mailing List:
-;; There are two mailing lists for GNUS lovers in the world:
+;; How to Install GNUS:
+;; (0) First of all, remove GNUS related OLD *.elc files (at least
+;;     nntp.elc).
+;; (1) Unshar gnus.el, gnuspost.el, gnusmail.el, gnusmisc.el, and
+;;     nntp.el.
+;; (2) byte-compile-file nntp.el, gnus.el, gnuspost.el, gnusmail.el,
+;;     and gnusmisc.el.  If you have a local news spool,
+;;     byte-compile-file nnspool.el, too.
+;; (3) Define three environment variables in .login file as follows:
+;;
+;;     setenv  NNTPSERVER      flab
+;;     setenv  DOMAINNAME      "stars.flab.Fujitsu.CO.JP"
+;;     setenv  ORGANIZATION    "Fujitsu Laboratories Ltd., Kawasaki, Japan."
+;;
+;;     Or instead, define lisp variables in your .emacs, site-init.el,
+;;     or default.el as follows:
+;;
+;;     (setq gnus-nntp-server "flab")
+;;     (setq gnus-local-domain "stars.flab.Fujitsu.CO.JP")
+;;     (setq gnus-local-organization "Fujitsu Laboratories Ltd., ...")
+;;
+;;     If the function (system-name) returns the full internet name,
+;;     you don't have to define the domain.
+;;
+;; (4) You may have to define NNTP service name as number 119.
+;;
+;;     (setq gnus-nntp-service 119)
+;;
+;;     Or, if you'd like to use a local news spool directly in stead
+;;     of NNTP, set the variable to nil as follows:
+;;
+;;     (setq gnus-nntp-service nil)
+;;
+;; (5) If you'd like to use the GENERICFROM feature like the Bnews,
+;;     define the variable as follows:
+;;
+;;     (setq gnus-use-generic-from t)
+;;
+;; (6) Define autoload entries in .emacs file as follows:
+;;
+;;     (autoload 'gnus "gnus" "Read network news." t)
+;;     (autoload 'gnus-post-news "gnuspost" "Post a news." t)
+;;
+;; (7) Read nntp.el if you have problems with NNTP or kanji handling.
+;;
+;; (8) Install mhspool.el, tcp.el, and tcp.c if it is necessary.
+;;
+;;     mhspool.el is a package for reading articles or mail in your
+;;     private directory using GNUS.
 ;;
-;;     info-gnus@flab.fujitsu.co.jp, and
-;;     info-gnus-english@tut.cis.ohio-state.edu.
+;;     tcp.el and tcp.c are necessary if and only if your Emacs does
+;;     not have the function `open-network-stream' which is used for
+;;     communicating with NNTP server inside Emacs.
 ;;
-;; They are intended to exchange useful information about GNUS, such
-;; as bug fixes, useful hooks, and extensions.  The major difference
-;; between the lists is what the official language is.  Both Japanese
-;; and English are available in info-gnus, while English is only
-;; available in info-gnus-english. There is no need to subscribe to
-;; info-gnus if you cannot read Japanese messages, because most of the
-;; discussion and important announcements will be sent to
-;; info-gnus-english. Moreover, if you can read gnu.emacs.gnus
-;; newsgroup of USENET, you need not, either. info-gnus-english and
-;; gnu.emacs.gnus are linked each other.
+;; (9) Install an Info file generated from the texinfo manual gnus.texinfo.
 ;;
-;; Please send subscription request to:
+;;     If you are not allowed to create the Info file to the standard
+;;     Info-directory, create it in your private directory and set the
+;;     variable gnus-info-directory to that directory.
 ;;
-;;     info-gnus-request@flab.fujitsu.co.jp, or
-;;     info-gnus-english-request@cis.ohio-state.edu
+;; For getting more information about GNUS, consult USENET newsgorup
+;; gnu.emacs.gnus.
 
 ;; TO DO:
 ;; (1) Incremental update of active info.
-;; (2) GNUS own poster.
-;; (3) Multi-GNUS (Talking to many hosts same time).
-;; (4) Asynchronous transmission of large messages.
+;; (2) Asynchronous transmission of large messages.
 
 ;;; Code:
 
 (require 'nntp)
 (require 'mail-utils)
+(require 'timezone)
 
-(defvar gnus-nntp-server (or (getenv "NNTPSERVER")
-                            (and (boundp 'gnus-default-nntp-server)
-                                 gnus-default-nntp-server))
-  "The name of the host running NNTP server.
-If it is a string such as `:DIRECTORY', the user's private DIRECTORY
-is used as a news spool.
-Initialized from the NNTPSERVER environment variable.")
+(defvar gnus-default-nntp-server nil
+  "*Specify default NNTP server.
+This variable should be defined in `site-init.el'.")
+
+(defvar gnus-nntp-server (or (getenv "NNTPSERVER") gnus-default-nntp-server)
+  "*The name of the host running NNTP server.
+If it is a string starting with a colon, as in as `:DIRECTORY', then the
+directory ~/DIRECTORY is used as the news spool.
+This variable is initialized from the NNTPSERVER environment variable
+or from `gnus-default-nntp-server'.")
 
 (defvar gnus-nntp-service "nntp"
-  "The name of the network service for GNUS to use.  Usually \"nntp\".")
+  "*NNTP service name (\"nntp\" or 119).
+Go to a local news spool if its value is nil.")
+
+(defvar gnus-startup-file "~/.newsrc"
+  "*Your `.newsrc' file.  Use `.newsrc-SERVER' instead if exists.")
 
 (defvar gnus-signature-file "~/.signature"
-  "*Your .signature file. Use `.signature-DISTRIBUTION' instead if exists.")
+  "*Your `.signature' file.  Use `.signature-DISTRIBUTION' instead if exists.")
 
 (defvar gnus-use-cross-reference t
-  "Specifies what to do with cross references (Xref: field).
-If nil, ignore cross references.  If t, mark articles as read in subscribed
-newsgroups.  Otherwise, mark articles as read in all newsgroups.")
+  "*Specifies what to do with cross references (Xref: field).
+If nil, ignore cross references.  If t, mark articles as read in
+subscribed newsgroups.  Otherwise, if not nil nor t, mark articles as
+read in all newsgroups.")
 
 (defvar gnus-use-followup-to t
   "*Specifies what to do with Followup-To: field.
-If nil, ignore followup-to: field.  If t, use its value execpt for
-`poster'.  Otherewise, if not nil nor t, always use its value.")
+If nil, ignore `Followup-to:' field.  If t, use its value except for
+`poster'.  Otherwise, if not nil nor t, always use its value.")
 
 (defvar gnus-large-newsgroup 50
   "*The number of articles which indicates a large newsgroup.
@@ -88,90 +133,100 @@ If the number of articles in a newsgroup is greater than the value,
 confirmation is required for selecting the newsgroup.")
 
 (defvar gnus-author-copy (getenv "AUTHORCOPY")
-  "*Filename for saving a copy of an article posted using FCC: field.
+  "*File name saving a copy of an article posted using FCC: field.
 Initialized from the AUTHORCOPY environment variable.
 
 Articles are saved using a function specified by the the variable
-`gnus-author-copy-saver' (`rmail-output' is the default) if a file name
-is given.  Instead, if the first character of the name is `|', the
+`gnus-author-copy-saver' (`rmail-output' is default) if a file name is
+given.  Instead, if the first character of the name is `|', the
 contents of the article is piped out to the named program.  It is
 possible to save an article in an MH folder as follows:
 
-    (setq gnus-author-copy \"|/usr/local/lib/mh/rcvstore +Article\")")
+\(setq gnus-author-copy \"|/usr/local/lib/mh/rcvstore +Article\")")
 
 (defvar gnus-author-copy-saver (function rmail-output)
   "*A function called with a file name to save an author copy to.
-The default function is `rmail-output' which saves in Unix mailbox format.")
+The default function is `rmail-output' which saves in  inbox format.")
 
 (defvar gnus-use-long-file-name
   (not (memq system-type '(usg-unix-v xenix)))
-  "Non-nil means that a newsgroup name is used as a default file name
-to save articles to.  If nil, the directory form of a newsgroup is
+  "*Non-nil means that a newsgroup name is used as a default file name
+to save articles to.  If it's nil, the directory form of a newsgroup is
 used instead.")
 
 (defvar gnus-article-save-directory (getenv "SAVEDIR")
-  "*The directory in which to save articles; defaults to ~/News.
+  "*A directory name to save articles to (default is `~/News').
+Initialized from the SAVEDIR environment variable.")
+
+(defvar gnus-kill-files-directory (getenv "SAVEDIR")
+  "*A directory name to save kill files to (default to ~/News).
 Initialized from the SAVEDIR environment variable.")
 
-(defvar gnus-default-article-saver (function gnus-Subject-save-in-rmail)
-  "A function used to save articles in your favorite format.
+(defvar gnus-default-article-saver (function gnus-summary-save-in-rmail)
+  "*A function to save articles in your favorite format.
 The function must be interactively callable (in other words, it must
 be an Emacs command).
 
 GNUS provides the following functions:
-       gnus-Subject-save-in-rmail (in Rmail format)
-       gnus-Subject-save-in-mail (in Unix mail format)
-       gnus-Subject-save-in-folder (in an MH folder)
-       gnus-Subject-save-in-file (in article format).")
+       gnus-summary-save-in-rmail (in Rmail format)
+       gnus-summary-save-in-mail (in Unix mail format)
+       gnus-summary-save-in-folder (in an MH folder)
+       gnus-summary-save-in-file (in article format).")
 
 (defvar gnus-rmail-save-name (function gnus-plain-save-name)
-  "A function generating a file name to save articles in Rmail format.
+  "*A function generating a file name to save articles in Rmail format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE.")
 
 (defvar gnus-mail-save-name (function gnus-plain-save-name)
-  "A function generating a file name to save articles in Unix mail format.
+  "*A function generating a file name to save articles in Unix mail format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE.")
 
 (defvar gnus-folder-save-name (function gnus-folder-save-name)
-  "A function generating a file name to save articles in MH folder.
+  "*A function generating a file name to save articles in MH folder.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FOLDER.")
 
 (defvar gnus-file-save-name (function gnus-numeric-save-name)
-  "A function generating a file name to save articles in article format.
+  "*A function generating a file name to save articles in article format.
 The function is called with NEWSGROUP, HEADERS, and optional LAST-FILE.")
 
 (defvar gnus-kill-file-name "KILL"
-  "File name of a KILL file.")
-
-(defvar gnus-default-distribution "local"
-  "*Use this value as distribution if no distribution is specified.")
+  "*File name of a KILL file.")
 
 (defvar gnus-novice-user t
   "*Non-nil means that you are a novice to USENET.
-If non-nil, verbose messages may be displayed or your confirmation
-may be required.")
+If non-nil, verbose messages may be displayed
+or your confirmations may be required.")
+
+(defvar gnus-interactive-catchup t
+  "*Require your confirmation when catching up a newsgroup if non-nil.")
 
 (defvar gnus-interactive-post t
   "*Newsgroup, subject, and distribution will be asked for if non-nil.")
 
+(defvar gnus-interactive-exit t
+  "*Require your confirmation when exiting GNUS if non-nil.")
+
 (defvar gnus-user-login-name nil
   "*The login name of the user.
-Uses USER and LOGNAME environment variables if undefined.")
+Got from the function `user-login-name' if undefined.")
 
 (defvar gnus-user-full-name nil
   "*The full name of the user.
-Uses from the NAME environment variable if undefined.")
+Got from the NAME environment variable if undefined.")
+
+(defvar gnus-show-mime nil
+  "*Show MIME message if non-nil.")
 
 (defvar gnus-show-threads t
-  "*Show conversation threads in Subject Mode if non-nil.")
+  "*Show conversation threads in Summary Mode if non-nil.")
 
 (defvar gnus-thread-hide-subject t
   "*Non-nil means hide subjects for thread subtrees.")
 
 (defvar gnus-thread-hide-subtree nil
   "*Non-nil means hide thread subtrees initially.
-If non-nil, you have to run the command `gnus-Subject-show-thread' by
-hand or by using `gnus-Select-article-hook' to show hidden threads.")
+If non-nil, you have to run the command `gnus-summary-show-thread' by
+hand or by using `gnus-select-article-hook' to show hidden threads.")
 
 (defvar gnus-thread-hide-killed t
   "*Non-nil means hide killed thread subtrees automatically.")
@@ -181,21 +236,37 @@ hand or by using `gnus-Select-article-hook' to show hidden threads.")
 If it is non-nil, some commands work with subjects do not work properly.")
 
 (defvar gnus-thread-indent-level 4
-  "Indentation of thread subtrees.")
+  "*Indentation of thread subtrees.")
+
+(defvar gnus-ignored-newsgroups "^to\\..*$"
+  "*A regexp to match uninteresting newsgroups in the active file.
+Any lines in the active file matching this regular expression are
+removed from the newsgroup list before anything else is done to it,
+thus making them effectively invisible.")
 
 (defvar gnus-ignored-headers
-  "^Path:\\|^Posting-Version:\\|^Article-I.D.:\\|^Expires:\\|^Date-Received:\\|^References:\\|^Control:\\|^Xref:\\|^Lines:\\|^Posted:\\|^Relay-Version:\\|^Message-ID:\\|^Nf-ID:\\|^Nf-From:\\|^Approved:\\|^Sender:\\|^In-Reply-To:"
-  "Regexp matching headers not to display in messages.")
+  "^Path:\\|^Posting-Version:\\|^Article-I.D.:\\|^Expires:\\|^Date-Received:\\|^References:\\|^Control:\\|^Xref:\\|^Lines:\\|^Posted:\\|^Relay-Version:\\|^Message-ID:\\|^Nf-ID:\\|^Nf-From:\\|^Approved:\\|^Sender:"
+  "*Header fields not worth displaying.
+Ordinarily GNUS excludes these when displaying an article.
+If you want to see them, ask to see the message with \"the full header\"
+\(also known as \"the original header\").")
+
+(defvar gnus-required-headers
+  '(From Date Newsgroups Subject Message-ID Path Organization Distribution)
+  "*All required fields for articles you post.
+RFC977 and RFC1036 require From, Date, Newsgroups, Subject, Message-ID
+and Path fields.  Organization, Distribution and Lines are optional.
+If you want GNUS not to insert some field, remove it from this list.")
 
 (defvar gnus-show-all-headers nil
   "*Show all headers of an article if non-nil.")
 
-(defvar gnus-save-all-headers nil
+(defvar gnus-save-all-headers t
   "*Save all headers of an article if non-nil.")
 
 (defvar gnus-optional-headers (function gnus-optional-lines-and-from)
-  "A function generating a optional string displayed in GNUS Subject
-mode buffer.  The function is called with an article HEADER. The
+  "*A function generating a optional string displayed in GNUS Summary
+mode buffer.  The function is called with an article HEADER.  The
 result must be a string excluding `[' and `]'.")
 
 (defvar gnus-auto-extend-newsgroup t
@@ -204,22 +275,27 @@ result must be a string excluding `[' and `]'.")
 (defvar gnus-auto-select-first t
   "*Select the first unread article automagically if non-nil.
 If you want to prevent automatic selection of the first unread article
-in some newsgroups, set the variable to nil in `gnus-Select-group-hook'
-or `gnus-Apply-kill-hook'.")
+in some newsgroups, set the variable to nil in `gnus-select-group-hook'
+or `gnus-apply-kill-hook'.")
 
 (defvar gnus-auto-select-next t
   "*Select the next newsgroup automagically if non-nil.
 If the value is t and the next newsgroup is empty, GNUS will exit
-Subject mode and go back to Group mode.  If the value is neither nil
-nor t, GNUS will select the following unread newsgroup. Especially, if
+Summary mode and go back to Group mode.  If the value is neither nil
+nor t, GNUS will select the following unread newsgroup.  Especially, if
 the value is the symbol `quietly', the next unread newsgroup will be
 selected without any confirmations.")
 
 (defvar gnus-auto-select-same nil
   "*Select the next article with the same subject automagically if non-nil.")
 
-(defvar gnus-auto-center-subject t
-  "*Always center the current subject in GNUS Subject mode window if non-nil.")
+(defvar gnus-auto-center-summary t
+  "*Always center the current summary in GNUS Summary window if non-nil.")
+
+(defvar gnus-auto-mail-to-author nil
+  "*Insert `To: author' of the article when following up if non-nil.
+Mail is sent using the function specified by the variable
+`gnus-mail-send-method'.")
 
 (defvar gnus-break-pages t
   "*Break an article into pages if non-nil.
@@ -238,289 +314,375 @@ Page delimiter is specified by the variable `gnus-page-delimiter'.")
   "*Non-nil means to take up the entire screen of Emacs.")
 
 (defvar gnus-window-configuration
-  '((SelectNewsgroup (0 1 0))
-    (ExitNewsgroup   (1 0 0))
-    (SelectArticle   (0 3 10))
-    (ExpandSubject   (0 1 0)))
-  "Specify window configurations for each action.
-The format of the variable is a list of (ACTION (G S A)), where
-G, S, and A are the relative height of Group, Subject, and Article
-windows, respectively.  ACTION is `SelectNewsgroup', `ExitNewsgroup',
-`SelectArticle', or `ExpandSubject'.")
+  '((summary (0 1 0))
+    (newsgroups   (1 0 0))
+    (article   (0 3 10)))
+  "*Specify window configurations for each action.
+The format of the variable is a list of (ACTION (G S A)), where G, S,
+and A are the relative height of Group, Summary, and Article windows,
+respectively.  ACTION is `summary', `newsgroups', or `article'.")
+
+(defvar gnus-show-mime-method (function metamail-buffer)
+  "*Function to process a MIME message.
+The function is expected to process current buffer as a MIME message.")
 
 (defvar gnus-mail-reply-method
   (function gnus-mail-reply-using-mail)
-  "A function to compose reply mail.
-The function `gnus-mail-reply-using-mail' uses usual the sendmail mail
-program.  The function `gnus-mail-reply-using-mhe' uses the mh-e mail
+  "*Function to compose reply mail.
+The function `gnus-mail-reply-using-mail' uses usual sendmail mail
+program.  The function `gnus-mail-reply-using-mhe' uses the MH-E mail
+program.  You can use yet another program by customizing this variable.")
+
+(defvar gnus-mail-forward-method
+  (function gnus-mail-forward-using-mail)
+  "*Function to forward current message to another user.
+The function `gnus-mail-reply-using-mail' uses usual sendmail mail
 program.  You can use yet another program by customizing this variable.")
 
 (defvar gnus-mail-other-window-method
   (function gnus-mail-other-window-using-mail)
-  "A function to compose mail in other window.
-The function `gnus-mail-other-window-using-mail' uses usual sendmail
-mail program.  The function `gnus-mail-other-window-using-mhe' uses mh-e
+  "*Function to compose mail in other window.
+The function `gnus-mail-other-window-using-mail' uses the usual sendmail
+mail program.  The function `gnus-mail-other-window-using-mhe' uses the MH-E
 mail program.  You can use yet another program by customizing this variable.")
 
+(defvar gnus-mail-send-method send-mail-function
+  "*Function to mail a message too which is being posted as an article.
+The message must have To: or Cc: field.  The default is copied from
+the variable `send-mail-function'.")
+
 (defvar gnus-subscribe-newsgroup-method
-  (function
-   (lambda (newsgroup)
-     (gnus-subscribe-newsgroup newsgroup
-                              (car (car gnus-newsrc-assoc)))))
-  "A function called with a newsgroup name when it is created.")
+  (function gnus-subscribe-alphabetically)
+  "*Function called with a newsgroup name when new newsgroup is found.
+The function `gnus-subscribe-randomly' inserts a new newsgroup a the
+beginning of newsgroups.  The function `gnus-subscribe-alphabetically'
+inserts it in strict alphabetic order.  The function
+`gnus-subscribe-hierarchically' inserts it in hierarchical newsgroup
+order.  The function `gnus-subscribe-interactively' asks for your decision.")
 
-(defvar gnus-Group-mode-hook nil
-  "A hook for GNUS Group Mode.")
+(defvar gnus-group-mode-hook nil
+  "*A hook for GNUS Group Mode.")
 
-(defvar gnus-Subject-mode-hook nil
-  "A hook for GNUS Subject Mode.")
+(defvar gnus-summary-mode-hook nil
+  "*A hook for GNUS Summary Mode.")
 
-(defvar gnus-Article-mode-hook nil
-  "A hook for GNUS Article Mode.")
+(defvar gnus-article-mode-hook nil
+  "*A hook for GNUS Article Mode.")
 
-(defvar gnus-Kill-file-mode-hook nil
-  "A hook for GNUS KILL File Mode.")
+(defvar gnus-kill-file-mode-hook nil
+  "*A hook for GNUS KILL File Mode.")
 
-(defvar gnus-Open-server-hook nil
-  "A hook called just before opening connection to news server.")
+(defvar gnus-open-server-hook nil
+  "*A hook called just before opening connection to news server.")
 
-(defvar gnus-Startup-hook nil
-  "A hook called at start up time.
-This hook is called after GNUS is connected to the NNTP server.
-So, it is possible to change the behavior of GNUS according to the
-selected NNTP server.")
+(defvar gnus-startup-hook nil
+  "*A hook called at start up time.
+This hook is called after GNUS is connected to the NNTP server.  So, it
+is possible to change the behavior of GNUS according to the selected
+NNTP server.")
 
-(defvar gnus-Group-prepare-hook nil
-  "A hook called after newsgroup list is created in the Newsgroup buffer.
+(defvar gnus-group-prepare-hook nil
+  "*A hook called after newsgroup list is created in the Newsgroup buffer.
 If you want to modify the Newsgroup buffer, you can use this hook.")
 
-(defvar gnus-Subject-prepare-hook nil
-  "A hook called after subject list is created in the Subject buffer.
-If you want to modify the Subject buffer, you can use this hook.")
+(defvar gnus-summary-prepare-hook nil
+  "*A hook called after summary list is created in the Summary buffer.
+If you want to modify the Summary buffer, you can use this hook.")
 
-(defvar gnus-Article-prepare-hook nil
-  "A hook called after an article is prepared in the Article buffer.
+(defvar gnus-article-prepare-hook nil
+  "*A hook called after an article is prepared in the Article buffer.
 If you want to run a special decoding program like nkf, use this hook.")
 
-(defvar gnus-Select-group-hook nil
-  "A hook called when a newsgroup is selected.
-If you want to sort Subject buffer by date and then by subject, you
+(defvar gnus-select-group-hook nil
+  "*A hook called when a newsgroup is selected.
+If you want to sort Summary buffer by date and then by subject, you
 can use the following hook:
 
-(setq gnus-Select-group-hook
-      '(lambda ()
-        ;; First of all, sort by date.
-        (gnus-sort-headers
-         '(lambda (a b)
-            (gnus-date-lessp (gnus-header-date a)
-                             (gnus-header-date b))))
-        ;; Then sort by subject string ignoring `Re:'.
-        ;; If case-fold-search is non-nil, case of letters is ignored.
-        (gnus-sort-headers
-         '(lambda (a b)
-            (gnus-string-lessp
-             (gnus-simplify-subject (gnus-header-subject a) 're)
-             (gnus-simplify-subject (gnus-header-subject b) 're)
-             )))))
-
-If you'd like to simplify subjects like the `gnus-Subject-next-same-subject'
-command does, you can use the following hook:
-
-(setq gnus-Select-group-hook
-      '(lambda ()
-        (mapcar (function
-                 (lambda (header)
-                   (nntp-set-header-subject
-                    header
-                    (gnus-simplify-subject
-                     (gnus-header-subject header) 're-only))))
-                gnus-newsgroup-headers)))
+\(add-hook 'gnus-select-group-hook
+       (function
+       (lambda ()
+         ;; First of all, sort by date.
+         (gnus-keysort-headers
+          (function string-lessp)
+          (function
+           (lambda (a)
+             (gnus-sortable-date (gnus-header-date a)))))
+         ;; Then sort by subject string ignoring `Re:'.
+         ;; If case-fold-search is non-nil, case of letters is ignored.
+         (gnus-keysort-headers
+          (function string-lessp)
+          (function
+           (lambda (a)
+             (if case-fold-search
+                 (downcase (gnus-simplify-subject (gnus-header-subject a) t))
+               (gnus-simplify-subject (gnus-header-subject a) t)))))
+         )))
+
+If you'd like to simplify subjects like the
+`gnus-summary-next-same-subject' command does, you can use the
+following hook:
+
+\(add-hook 'gnus-select-group-hook
+       (function
+       (lambda ()
+         (mapcar (function
+                  (lambda (header)
+                    (nntp-set-header-subject
+                     header
+                     (gnus-simplify-subject
+                      (gnus-header-subject header) 're-only))))
+                 gnus-newsgroup-headers))))
 
 In some newsgroups author name is meaningless.  It is possible to
-prevent listing author names in the GNUS Subject buffer as follows:
-
-(setq gnus-Select-group-hook
-      '(lambda ()
-        (cond ((string-equal \"comp.sources.unix\" gnus-newsgroup-name)
-               (setq gnus-optional-headers
-                     (function gnus-optional-lines)))
-              (t
-               (setq gnus-optional-headers
-                     (function gnus-optional-lines-and-from))))))")
-
-(defvar gnus-Select-article-hook
-  (function (lambda () (gnus-Subject-show-thread)))
-  "Hook called when an article is selected.
-The default hook automatically shows conversation thread subtrees
-of the selected article as follows:
-
-(setq gnus-Select-article-hook
-      '(lambda ()
-        (gnus-Subject-show-thread)))
-
-If you'd like to run RMAIL on a digest article automagically, you can
+prevent listing author names in GNUS Summary buffer as follows:
+
+\(add-hook 'gnus-select-group-hook
+       (function
+       (lambda ()
+         (cond ((string-equal \"comp.sources.unix\" gnus-newsgroup-name)
+                (setq gnus-optional-headers
+                      (function gnus-optional-lines)))
+               (t
+                (setq gnus-optional-headers
+                      (function gnus-optional-lines-and-from)))))))")
+
+(defvar gnus-select-article-hook
+  '(gnus-summary-show-thread)
+  "*A hook called when an article is selected.
+The default hook shows conversation thread subtrees of the selected
+article automatically using `gnus-summary-show-thread'.
+
+If you'd like to run Rmail on a digest article automagically, you can
 use the following hook:
 
-(setq gnus-Select-article-hook
-      '(lambda ()
-        (gnus-Subject-show-thread)
-        (cond ((string-equal \"comp.sys.sun\" gnus-newsgroup-name)
-               (gnus-Subject-rmail-digest))
-              ((and (string-equal \"comp.text\" gnus-newsgroup-name)
-                    (string-match \"^TeXhax Digest\"
-                                  (gnus-header-subject gnus-current-headers)))
-               (gnus-Subject-rmail-digest)
-               ))))")
-
-(defvar gnus-Select-digest-hook
-  (function
-   (lambda ()
-     ;; Reply-To: is required by `undigestify-rmail-message'.
-     (or (mail-position-on-field "Reply-to" t)
-        (progn
-          (mail-position-on-field "Reply-to")
-          (insert (gnus-fetch-field "From"))))))
-  "A hook called when reading digest messages using Rmail.
+\(add-hook 'gnus-select-article-hook
+       (function
+       (lambda ()
+         (cond ((string-equal \"comp.sys.sun\" gnus-newsgroup-name)
+                (gnus-summary-rmail-digest))
+               ((and (string-equal \"comp.text\" gnus-newsgroup-name)
+                     (string-match \"^TeXhax Digest\"
+                                   (gnus-header-subject gnus-current-headers)))
+                (gnus-summary-rmail-digest)
+                ))))
+       t)")
+
+(defvar gnus-select-digest-hook
+  (list
+   (function
+    (lambda ()
+      ;; Reply-To: is required by `undigestify-rmail-message'.
+      (or (mail-position-on-field "Reply-to" t)
+         (progn
+           (mail-position-on-field "Reply-to")
+           (insert (gnus-fetch-field "From")))))))
+  "*A hook called when reading digest messages using Rmail.
 This hook can be used to modify incomplete digest articles as follows
-(this is the default):
-
-(setq gnus-Select-digest-hook
-      '(lambda ()
-        ;; Reply-To: is required by `undigestify-rmail-message'.
-        (or (mail-position-on-field \"Reply-to\" t)
-            (progn
-              (mail-position-on-field \"Reply-to\")
-              (insert (gnus-fetch-field \"From\"))))))")
-
-(defvar gnus-Rmail-digest-hook nil
-  "A hook called when reading digest messages using Rmail.
+\(this is the default):
+
+\(add-hook 'gnus-select-digest-hook
+       (function
+       (lambda ()
+         ;; Reply-To: is required by `undigestify-rmail-message'.
+         (or (mail-position-on-field \"Reply-to\" t)
+             (progn
+               (mail-position-on-field \"Reply-to\")
+               (insert (gnus-fetch-field \"From\")))))))")
+
+(defvar gnus-rmail-digest-hook nil
+  "*A hook called when reading digest messages using Rmail.
 This hook is intended to customize Rmail mode for reading digest articles.")
 
-(defvar gnus-Apply-kill-hook (function gnus-apply-kill-file)
-  "A hook called when a newsgroup is selected and subject list is prepared.
+(defvar gnus-apply-kill-hook '(gnus-apply-kill-file)
+  "*A hook called when a newsgroup is selected and summary list is prepared.
 This hook is intended to apply a KILL file to the selected newsgroup.
-The function `gnus-apply-kill-file' is called defaultly.
+The function `gnus-apply-kill-file' is called by default.
 
-Since a general KILL file is too heavy to use for only a few
-newsgroups, we recommend you use a lighter hook function.  For
+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
-      '(lambda ()
-        (cond ((string-match \"control\" gnus-newsgroup-name)
-               (gnus-kill \"Subject\" \"rmgroup\")
-               (gnus-expunge \"X\")))))")
-
-(defvar gnus-Mark-article-hook
-  (function
-   (lambda ()
-     (or (memq gnus-current-article gnus-newsgroup-marked)
-        (gnus-Subject-mark-as-read gnus-current-article))
-     (gnus-Subject-set-current-mark "+")))
-  "A hook called when an article is selected for the first time.
-The hook is intended to mark an article as read when it is selected.
-If you'd like to mark as unread (-) instead, use the following hook:
+\(setq gnus-apply-kill-hook
+      (list
+       (function
+       (lambda ()
+         (cond ((string-match \"control\" gnus-newsgroup-name)
+                (gnus-kill \"Subject\" \"rmgroup\")
+                (gnus-expunge \"X\")))))))")
 
-(setq gnus-Mark-article-hook
-      '(lambda ()
-        (gnus-Subject-mark-as-unread gnus-current-article)
-        (gnus-Subject-set-current-mark \"+\")))")
+(defvar gnus-mark-article-hook
+  (list
+   (function
+    (lambda ()
+      (or (memq gnus-current-article gnus-newsgroup-marked)
+         (gnus-summary-mark-as-read gnus-current-article))
+      (gnus-summary-set-current-mark "+"))))
+  "*A hook called when an article is selected at the first time.
+The hook is intended to mark an article as read (or unread)
+automatically when it is selected.
 
-(defvar gnus-Inews-article-hook nil
-  "A hook called before posting an article.
-If you'd like to run a special encoding program, use this hook.")
+If you'd like to mark as unread (-) instead, use the following hook:
 
-(defvar gnus-Exit-group-hook nil
-  "A hook called when exiting (not quitting) Subject mode.
-If your machine is so slow that exiting from Subject mode takes a
-long time, set the variable `gnus-newsgroup-headers' to nil.  This
+\(setq gnus-mark-article-hook
+      (list
+       (function
+        (lambda ()
+         (gnus-summary-mark-as-unread gnus-current-article)
+         (gnus-summary-set-current-mark \"+\")))))")
+
+(defvar gnus-prepare-article-hook (list (function gnus-inews-insert-signature))
+  "*A hook called after preparing body, but before preparing header fields.
+The default hook (`gnus-inews-insert-signature') inserts a signature
+file specified by the variable `gnus-signature-file'.")
+
+(defvar gnus-inews-article-hook (list (function gnus-inews-do-fcc))
+  "*A hook called before finally posting an article.
+The default hook (`gnus-inews-do-fcc') does FCC processing (save article
+to a file).")
+
+(defvar gnus-exit-group-hook nil
+  "*A hook called when exiting (not quitting) Summary mode.
+If your machine is so slow that exiting from Summary mode takes very
+long time, set the variable `gnus-use-cross-reference' to nil.  This
 inhibits marking articles as read using cross-reference information.")
 
-(defvar gnus-Suspend-gnus-hook nil
-  "A hook called when suspending (not exiting) GNUS.")
-
-(defvar gnus-Exit-gnus-hook nil
-  "A hook called when exiting (not suspending) GNUS.")
+(defvar gnus-suspend-gnus-hook nil
+  "*A hook called when suspending (not exiting) GNUS.")
 
-(defvar gnus-Save-newsrc-hook nil
-  "A hook called when saving the newsrc file.
-This hook is called before saving .newsrc file.")
+(defvar gnus-exit-gnus-hook nil
+  "*A hook called when exiting (not suspending) GNUS.")
 
-(defvar gnus-your-domain nil
-  "*Your domain name without your host name like: \"stars.flab.Fujitsu.CO.JP\"
-The environment variable DOMAINNAME is used instead if defined.  If
-the function `system-name' returns the full internet name, there is no
-need to define this variable.")
+(defvar gnus-save-newsrc-hook nil
+  "*A hook called when saving the newsrc file.
+This hook is called before saving the `.newsrc' file.")
 
-(defvar gnus-your-organization nil
-  "*Your organization like: \"Fujitsu Laboratories Ltd., Kawasaki, Japan.\"
+\f
+;; Site dependent variables.  You have to define these variables in
+;;  site-init.el, default.el or your .emacs.
+
+(defvar gnus-local-timezone nil
+  "*Local time zone.
+This value is used only if `current-time-zone' does not work in your Emacs.
+It specifies the GMT offset, i.e. a decimal integer
+of the form +-HHMM giving the hours and minutes ahead of (i.e. east of) GMT.
+For example, +0900 should be used in Japan, since it is 9 hours ahead of GMT.
+
+For backwards compatibility, it may also be a string like \"JST\",
+but strings are obsolescent: you should use numeric offsets instead.")
+
+(defvar gnus-local-domain nil
+  "*Local domain name without a host name like: \"stars.flab.Fujitsu.CO.JP\"
+The `DOMAINNAME' environment variable is used instead if defined.  If
+the function (system-name) returns the full internet name, there is no
+need to define the name.")
+
+(defvar gnus-local-organization nil
+  "*Local organization like: \"Fujitsu Laboratories Ltd., Kawasaki, Japan.\"
 The `ORGANIZATION' environment variable is used instead if defined.")
 
+(defvar gnus-local-distributions '("local" "world")
+  "*List of distributions.
+The first element in the list is used as default.  If distributions
+file is available, its content is also used.")
+
 (defvar gnus-use-generic-from nil
   "*If nil, prepend local host name to the defined domain in the From:
-field; if stringp, use this; if non-nil, strip of the local host name.")
+field; if a string, use this; if non-nil, strip off the local host name.")
 
 (defvar gnus-use-generic-path nil
   "*If nil, use the NNTP server name in the Path: field; if stringp,
 use this; if non-nil, use no host name (user name only)")
+
+(defvar gnus-newsgroups-regex "^\\([^ \t\n]+\\)[ \t]+\\(.*\\)$"
+  "Regex to retrieve the group name and the group description from
+the output of the newsgroups listing.
+
+If you have ^M at the end of lines try \"^\\([^ \t\n]+\\)[ \t]+\\([^\r]+\\)[\r]*$\"")
+
+(defvar gnus-newsgroups-display t
+  "*display the newsgroup description in *Newsgroup* buffer if not nil")
+
+(defvar gnus-newsgroups-alist nil
+  "alist (groupname . description)")
+
+(defvar gnus-newsgroups-hashtb nil
+  "hashtable of gnus-newsgroups-alist")
+
+(defvar gnus-newsgroups-showall nil
+  "non nil if we display all the groups")
+
 \f
 ;; Internal variables.
 
-(defconst gnus-version "GNUS 3.13"
+(defconst gnus-version "GNUS 4.1"
   "Version numbers of this version of GNUS.")
 
-(defvar gnus-Info-nodes
-  '((gnus-Group-mode . "(gnus)Newsgroup Commands")
-    (gnus-Subject-mode . "(gnus)Subject Commands")
-    (gnus-Article-mode . "(gnus)Article Commands")
-    (gnus-Kill-file-mode . "(gnus)KILL File")
-    (gnus-Browse-killed-mode . "(gnus)Maintenance"))
+(defconst gnus-emacs-version
+  (progn
+    (string-match "[0-9]*" emacs-version)
+    (string-to-int (substring emacs-version
+                             (match-beginning 0) (match-end 0))))
+  "Major version number of this emacs.")
+
+(defvar gnus-info-nodes
+  '((gnus-group-mode           "(gnus)Newsgroup Commands")
+    (gnus-summary-mode         "(gnus)Summary Commands")
+    (gnus-article-mode         "(gnus)Article Commands")
+    (gnus-kill-file-mode       "(gnus)Kill File")
+    (gnus-browse-killed-mode   "(gnus)Maintaining Subscriptions"))
   "Assoc list of major modes and related Info nodes.")
 
+;; Alist syntax is different from that of 3.14.3.
 (defvar gnus-access-methods
   '((nntp
-     (gnus-retrieve-headers .  nntp-retrieve-headers)
-     (gnus-open-server .       nntp-open-server)
-     (gnus-close-server .      nntp-close-server)
-     (gnus-server-opened .     nntp-server-opened)
-     (gnus-status-message .    nntp-status-message)
-     (gnus-request-article .   nntp-request-article)
-     (gnus-request-group .     nntp-request-group)
-     (gnus-request-list .      nntp-request-list)
-     (gnus-request-post .      nntp-request-post))
+     (gnus-retrieve-headers            nntp-retrieve-headers)
+     (gnus-open-server                 nntp-open-server)
+     (gnus-close-server                        nntp-close-server)
+     (gnus-server-opened               nntp-server-opened)
+     (gnus-status-message              nntp-status-message)
+     (gnus-request-article             nntp-request-article)
+     (gnus-request-group               nntp-request-group)
+     (gnus-request-list                        nntp-request-list)
+     (gnus-request-list-newsgroups     nntp-request-list-newsgroups)
+     (gnus-request-list-distributions  nntp-request-list-distributions)
+     (gnus-request-post                        nntp-request-post))
     (nnspool
-     (gnus-retrieve-headers .  nnspool-retrieve-headers)
-     (gnus-open-server .       nnspool-open-server)
-     (gnus-close-server .      nnspool-close-server)
-     (gnus-server-opened .     nnspool-server-opened)
-     (gnus-status-message .    nnspool-status-message)
-     (gnus-request-article .   nnspool-request-article)
-     (gnus-request-group .     nnspool-request-group)
-     (gnus-request-list .      nnspool-request-list)
-     (gnus-request-post .      nnspool-request-post))
+     (gnus-retrieve-headers            nnspool-retrieve-headers)
+     (gnus-open-server                 nnspool-open-server)
+     (gnus-close-server                        nnspool-close-server)
+     (gnus-server-opened               nnspool-server-opened)
+     (gnus-status-message              nnspool-status-message)
+     (gnus-request-article             nnspool-request-article)
+     (gnus-request-group               nnspool-request-group)
+     (gnus-request-list                        nnspool-request-list)
+     (gnus-request-list-newsgroups     nnspool-request-list-newsgroups)
+     (gnus-request-list-distributions  nnspool-request-list-distributions)
+     (gnus-request-post                        nnspool-request-post))
     (mhspool
-     (gnus-retrieve-headers .  mhspool-retrieve-headers)
-     (gnus-open-server .       mhspool-open-server)
-     (gnus-close-server .      mhspool-close-server)
-     (gnus-server-opened .     mhspool-server-opened)
-     (gnus-status-message .    mhspool-status-message)
-     (gnus-request-article .   mhspool-request-article)
-     (gnus-request-group .     mhspool-request-group)
-     (gnus-request-list .      mhspool-request-list)
-     (gnus-request-post .      mhspool-request-post)))
+     (gnus-retrieve-headers            mhspool-retrieve-headers)
+     (gnus-open-server                 mhspool-open-server)
+     (gnus-close-server                        mhspool-close-server)
+     (gnus-server-opened               mhspool-server-opened)
+     (gnus-status-message              mhspool-status-message)
+     (gnus-request-article             mhspool-request-article)
+     (gnus-request-group               mhspool-request-group)
+     (gnus-request-list                        mhspool-request-list)
+     (gnus-request-list-newsgroups     mhspool-request-list-newsgroups)
+     (gnus-request-list-distributions  mhspool-request-list-distributions)
+     (gnus-request-post                        mhspool-request-post)))
   "Access method for NNTP, nnspool, and mhspool.")
 
-(defvar gnus-Group-buffer "*Newsgroup*")
-(defvar gnus-Subject-buffer "*Subject*")
-(defvar gnus-Article-buffer "*Article*")
-(defvar gnus-Digest-buffer "GNUS Digest")
-(defvar gnus-Digest-summary-buffer "GNUS Digest-summary")
+(defvar gnus-group-buffer "*Newsgroup*")
+(defvar gnus-summary-buffer "*Summary*")
+(defvar gnus-article-buffer "*Article*")
+(defvar gnus-digest-buffer "GNUS Digest")
+(defvar gnus-digest-summary-buffer "GNUS Digest-summary")
 
 (defvar gnus-buffer-list
-  (list gnus-Group-buffer gnus-Subject-buffer gnus-Article-buffer
-       gnus-Digest-buffer gnus-Digest-summary-buffer)
+  (list gnus-group-buffer gnus-summary-buffer gnus-article-buffer
+       gnus-digest-buffer gnus-digest-summary-buffer)
   "GNUS buffer names which should be killed when exiting.")
 
 (defvar gnus-variable-list
@@ -535,8 +697,10 @@ use this; if non-nil, use no host name (user name only)")
   "Functions overloaded by gnus.
 It is a list of `(original overload &optional file)'.")
 
+(defvar gnus-distribution-list nil)
+
 (defvar gnus-newsrc-options nil
-  "Options line in the .newsrc file.")
+  "Options line in the `.newsrc' file.")
 
 (defvar gnus-newsrc-options-n-yes nil
   "Regexp representing subscribed newsgroups.")
@@ -545,13 +709,25 @@ It is a list of `(original overload &optional file)'.")
   "Regexp representing unsubscribed newsgroups.")
 
 (defvar gnus-newsrc-assoc nil
-  "Assoc list of read articles.")
+  "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-assoc'.")
 
 (defvar gnus-killed-assoc nil
-  "Assoc list of newsgroups removed from `gnus-newsrc-assoc'.")
+  "Assoc list of newsgroups removed from `gnus-newsrc-assoc'.
+`gnus-killed-hashtb' should be kept so that both hold the same information.")
+
+(defvar gnus-killed-hashtb nil
+  "Hashtable of `gnus-killed-assoc'.")
 
 (defvar gnus-marked-assoc nil
-  "Assoc list of articles marked as unread.")
+  "Assoc list of articles marked as unread.
+`gnus-marked-hashtb' should be kept so that both hold the same information.")
+
+(defvar gnus-marked-hashtb nil
+  "Hashtable of `gnus-marked-assoc'.")
 
 (defvar gnus-unread-hashtb nil
   "Hashtable of unread articles.")
@@ -591,51 +767,66 @@ It is a list of `(original overload &optional file)'.")
   "List of marked articles in the current newsgroup (a subset of unread art).")
 
 (defvar gnus-newsgroup-headers nil
-  "List of article headers in the current newsgroup.")
+  "List of article headers in the current newsgroup.
+If you modify the variable, you must call the function
+`gnus-clear-hashtables-for-newsgroup-headers' to clear the hash tables.")
+(defvar gnus-newsgroup-headers-hashtb-by-id nil)
+(defvar gnus-newsgroup-headers-hashtb-by-number nil)
 
 (defvar gnus-current-article nil)
 (defvar gnus-current-headers nil)
 (defvar gnus-current-history nil)
-(defvar gnus-have-all-headers nil)
+(defvar gnus-have-all-headers nil "Must be either T or NIL.")
 (defvar gnus-last-article nil)
 (defvar gnus-current-kill-article nil)
 
 ;; Save window configuration.
 (defvar gnus-winconf-kill-file nil)
 
-(defvar gnus-Group-mode-map nil)
-(defvar gnus-Subject-mode-map nil)
-(defvar gnus-Article-mode-map nil)
-(defvar gnus-Kill-file-mode-map nil)
+(defvar gnus-group-mode-map nil)
+(defvar gnus-summary-mode-map nil)
+(defvar gnus-article-mode-map nil)
+(defvar gnus-kill-file-mode-map nil)
 
-(defvar rmail-last-file (expand-file-name "~/XMBOX"))
-(defvar rmail-last-rmail-file (expand-file-name "~/XNEWS"))
+(defvar rmail-default-file (expand-file-name "~/XMBOX"))
+(defvar rmail-default-rmail-file (expand-file-name "~/XNEWS"))
 
 ;; Define GNUS Subsystems.
-(autoload 'gnus-Group-post-news "gnuspost"
+(autoload 'gnus-group-post-news "gnuspost"
          "Post an article." t)
-(autoload 'gnus-Subject-post-news "gnuspost"
+(autoload 'gnus-summary-post-news "gnuspost"
          "Post an article." t)
-(autoload 'gnus-Subject-post-reply "gnuspost"
+(autoload 'gnus-summary-followup "gnuspost"
          "Post a reply article." t)
-(autoload 'gnus-Subject-post-reply-with-original "gnuspost"
+(autoload 'gnus-summary-followup-with-original "gnuspost"
          "Post a reply article with original article." t)
-(autoload 'gnus-Subject-cancel-article "gnuspost"
+(autoload 'gnus-summary-cancel-article "gnuspost"
          "Cancel an article you posted." t)
 
-(autoload 'gnus-Subject-mail-reply "gnusmail"
+(autoload 'gnus-summary-reply "gnusmail"
          "Reply mail to news author." t)
-(autoload 'gnus-Subject-mail-reply-with-original "gnusmail"
+(autoload 'gnus-summary-reply-with-original "gnusmail"
          "Reply mail to news author with original article." t)
-(autoload 'gnus-Subject-mail-other-window "gnusmail"
+(autoload 'gnus-summary-mail-forward "gnusmail"
+         "Forward the current message to another user." t)
+(autoload 'gnus-summary-mail-other-window "gnusmail"
          "Compose mail in other window." t)
 
-(autoload 'gnus-Group-kill-group "gnusmisc"
+(autoload 'gnus-group-kill-group "gnusmisc"
          "Kill newsgroup on current line." t)
-(autoload 'gnus-Group-yank-group "gnusmisc"
+(autoload 'gnus-group-yank-group "gnusmisc"
          "Yank the last killed newsgroup on current line." t)
-(autoload 'gnus-Browse-killed-groups "gnusmisc"
-         "Browse the killed newsgroups." t)
+(autoload 'gnus-group-kill-region "gnusmisc"
+         "Kill newsgroups in current region." t)
+(autoload 'gnus-group-transpose-groups "gnusmisc"
+         "Exchange current newsgroup and previous newsgroup." t)
+(autoload 'gnus-list-killed-groups "gnusmisc"
+         "List the killed newsgroups." t)
+(autoload 'gnus-gmt-to-local "gnusmisc"
+         "Rewrite Date field in GMT to local in current buffer.")
+
+(autoload 'metamail-buffer "metamail"
+         "Process current buffer through `metamail'." t)
 
 (autoload 'rmail-output "rmailout"
          "Append this message to Unix mail file named FILE-NAME." t)
@@ -643,12 +834,14 @@ It is a list of `(original overload &optional file)'.")
 (autoload 'mh-find-path "mh-e")
 (autoload 'mh-prompt-for-folder "mh-e")
 
-(put 'gnus-Group-mode 'mode-class 'special)
-(put 'gnus-Subject-mode 'mode-class 'special)
-(put 'gnus-Article-mode 'mode-class 'special)
+(put 'gnus-group-mode 'mode-class 'special)
+(put 'gnus-summary-mode 'mode-class 'special)
+(put 'gnus-article-mode 'mode-class 'special)
 
+(autoload 'gnus-uu-ctl-map "gnus-uu" nil nil 'keymap)
+(autoload 'gnus-uu-mark-article "gnus-uu" nil t)
 \f
-;;(put 'gnus-eval-in-buffer-window 'lisp-indent-function 1)
+;;(put 'gnus-eval-in-buffer-window 'lisp-indent-hook 1)
 
 (defmacro gnus-eval-in-buffer-window (buffer &rest forms)
   "Pop to BUFFER, evaluate FORMS, and then returns to original window."
@@ -659,22 +852,25 @@ It is a list of `(original overload &optional file)'.")
             (,@ forms))
         (select-window GNUSStartBufferWindow)))))
 
-(defmacro gnus-make-hashtable ()
-  '(make-abbrev-table))
+(defmacro gnus-make-hashtable (&optional hashsize)
+  "Make a hash table (default and minimum size is 200).
+Optional argument HASHSIZE specifies the table size."
+  (` (make-vector (, (if hashsize (` (max (, hashsize) 200)) 200)) 0)))
 
 (defmacro gnus-gethash (string hashtable)
   "Get hash value of STRING in HASHTABLE."
   ;;(` (symbol-value (abbrev-symbol (, string) (, hashtable))))
-  (` (abbrev-expansion (, string) (, hashtable))))
+  ;;(` (abbrev-expansion (, string) (, hashtable)))
+  (` (symbol-value (intern-soft (, string) (, hashtable)))))
 
 (defmacro gnus-sethash (string value hashtable)
-  "Set hash value. Arguments are STRING, VALUE, and HASHTABLE."
+  "Set hash value.  Arguments are STRING, VALUE, and HASHTABLE."
   ;; We cannot use define-abbrev since it only accepts string as value.
   (` (set (intern (, string) (, hashtable)) (, value))))
 
-;; Note: Macros defined here are also defined in nntp.el. I don't like
+;; Note: Macros defined here are also defined in nntp.el.  I don't like
 ;; to put them here, but many users got troubled with the old
-;; definitions in nntp.elc. These codes are NNTP 3.10 version.
+;; definitions in nntp.elc.  These codes are NNTP 3.10 version.
 
 (defmacro nntp-header-number (header)
   "Return article number in HEADER."
@@ -745,65 +941,158 @@ It is a list of `(original overload &optional file)'.")
 ;;; GNUS Group Mode
 ;;;
 
-(if gnus-Group-mode-map
+(if gnus-group-mode-map
     nil
-  (setq gnus-Group-mode-map (make-keymap))
-  (suppress-keymap gnus-Group-mode-map)
-  (define-key gnus-Group-mode-map " " 'gnus-Group-read-group)
-  (define-key gnus-Group-mode-map "=" 'gnus-Group-select-group)
-  (define-key gnus-Group-mode-map "j" 'gnus-Group-jump-to-group)
-  (define-key gnus-Group-mode-map "n" 'gnus-Group-next-unread-group)
-  (define-key gnus-Group-mode-map "p" 'gnus-Group-prev-unread-group)
-  (define-key gnus-Group-mode-map "\177" 'gnus-Group-prev-unread-group)
-  (define-key gnus-Group-mode-map "N" 'gnus-Group-next-group)
-  (define-key gnus-Group-mode-map "P" 'gnus-Group-prev-group)
-  (define-key gnus-Group-mode-map "\C-n" 'gnus-Group-next-group)
-  (define-key gnus-Group-mode-map "\C-p" 'gnus-Group-prev-group)
-  (define-key gnus-Group-mode-map "\r" 'next-line)
-  (define-key gnus-Group-mode-map "/" 'isearch-forward)
-  (define-key gnus-Group-mode-map "<" 'beginning-of-buffer)
-  (define-key gnus-Group-mode-map ">" 'end-of-buffer)
-  (define-key gnus-Group-mode-map "u" 'gnus-Group-unsubscribe-current-group)
-  (define-key gnus-Group-mode-map "U" 'gnus-Group-unsubscribe-group)
-  (define-key gnus-Group-mode-map "c" 'gnus-Group-catch-up)
-  (define-key gnus-Group-mode-map "C" 'gnus-Group-catch-up-all)
-  (define-key gnus-Group-mode-map "l" 'gnus-Group-list-groups)
-  (define-key gnus-Group-mode-map "L" 'gnus-Group-list-all-groups)
-  (define-key gnus-Group-mode-map "g" 'gnus-Group-get-new-news)
-  (define-key gnus-Group-mode-map "R" 'gnus-Group-restart)
-  (define-key gnus-Group-mode-map "b" 'gnus-Group-check-bogus-groups)
-  (define-key gnus-Group-mode-map "r" 'gnus-Group-restrict-groups)
-  (define-key gnus-Group-mode-map "a" 'gnus-Group-post-news)
-  (define-key gnus-Group-mode-map "\ek" 'gnus-Group-edit-local-kill)
-  (define-key gnus-Group-mode-map "\eK" 'gnus-Group-edit-global-kill)
-  (define-key gnus-Group-mode-map "\C-k" 'gnus-Group-kill-group)
-  (define-key gnus-Group-mode-map "\C-y" 'gnus-Group-yank-group)
-  (define-key gnus-Group-mode-map "\C-c\C-y" 'gnus-Browse-killed-groups)
-  (define-key gnus-Group-mode-map "V" 'gnus-version)
-  (define-key gnus-Group-mode-map "x" 'gnus-Group-force-update)
-  (define-key gnus-Group-mode-map "s" 'gnus-Group-force-update)
-  (define-key gnus-Group-mode-map "z" 'gnus-Group-suspend)
-  (define-key gnus-Group-mode-map "q" 'gnus-Group-exit)
-  (define-key gnus-Group-mode-map "Q" 'gnus-Group-quit)
-  (define-key gnus-Group-mode-map "?" 'gnus-Group-describe-briefly)
-  (define-key gnus-Group-mode-map "\C-c\C-i" 'gnus-Info-find-node))
-
-(defun gnus-Group-mode ()
+  (setq gnus-group-mode-map (make-keymap))
+  (suppress-keymap gnus-group-mode-map)
+  (define-key gnus-group-mode-map " " 'gnus-group-read-group)
+  (define-key gnus-group-mode-map "=" 'gnus-group-select-group)
+  (define-key gnus-group-mode-map "j" 'gnus-group-jump-to-group)
+  (define-key gnus-group-mode-map "n" 'gnus-group-next-unread-group)
+  (define-key gnus-group-mode-map "p" 'gnus-group-prev-unread-group)
+  (define-key gnus-group-mode-map "\177" 'gnus-group-prev-unread-group)
+  (define-key gnus-group-mode-map "N" 'gnus-group-next-group)
+  (define-key gnus-group-mode-map "P" 'gnus-group-prev-group)
+  (define-key gnus-group-mode-map "\C-n" 'gnus-group-next-group)
+  (define-key gnus-group-mode-map "\C-p" 'gnus-group-prev-group)
+  (define-key gnus-group-mode-map [down] 'gnus-group-next-group)
+  (define-key gnus-group-mode-map [up] 'gnus-group-prev-group)
+  (define-key gnus-group-mode-map "\r" 'next-line)
+  ;;(define-key gnus-group-mode-map "/" 'isearch-forward)
+  (define-key gnus-group-mode-map "<" 'beginning-of-buffer)
+  (define-key gnus-group-mode-map ">" 'end-of-buffer)
+  (define-key gnus-group-mode-map "u" 'gnus-group-unsubscribe-current-group)
+  (define-key gnus-group-mode-map "U" 'gnus-group-unsubscribe-group)
+  (define-key gnus-group-mode-map "c" 'gnus-group-catchup)
+  (define-key gnus-group-mode-map "C" 'gnus-group-catchup-all)
+  (define-key gnus-group-mode-map "l" 'gnus-group-list-groups)
+  (define-key gnus-group-mode-map "L" 'gnus-group-list-all-groups)
+  (define-key gnus-group-mode-map "g" 'gnus-group-get-new-news)
+  (define-key gnus-group-mode-map "R" 'gnus-group-restart)
+  (define-key gnus-group-mode-map "b" 'gnus-group-check-bogus-groups)
+  (define-key gnus-group-mode-map "r" 'gnus-group-restrict-groups)
+  (define-key gnus-group-mode-map "a" 'gnus-group-post-news)
+  (define-key gnus-group-mode-map "\ek" 'gnus-group-edit-local-kill)
+  (define-key gnus-group-mode-map "\eK" 'gnus-group-edit-global-kill)
+  (define-key gnus-group-mode-map "\C-k" 'gnus-group-kill-group)
+  (define-key gnus-group-mode-map "\C-y" 'gnus-group-yank-group)
+  (define-key gnus-group-mode-map "\C-w" 'gnus-group-kill-region)
+  (define-key gnus-group-mode-map "\C-x\C-t" 'gnus-group-transpose-groups)
+  (define-key gnus-group-mode-map "\C-c\C-l" 'gnus-list-killed-groups)
+  (define-key gnus-group-mode-map "V" 'gnus-version)
+  ;;(define-key gnus-group-mode-map "x" 'gnus-group-force-update)
+  (define-key gnus-group-mode-map "s" 'gnus-group-force-update)
+  (define-key gnus-group-mode-map "z" 'gnus-group-suspend)
+  (define-key gnus-group-mode-map "q" 'gnus-group-exit)
+  (define-key gnus-group-mode-map "Q" 'gnus-group-quit)
+  (define-key gnus-group-mode-map "?" 'gnus-group-describe-briefly)
+  (define-key gnus-group-mode-map "\C-c\C-i" 'gnus-info-find-node)
+  (define-key gnus-group-mode-map   [mouse-2] 'gnus-mouse-pick-group)
+  (define-key gnus-group-mode-map "t" 'gnus-newsgroups-display-toggle)
+
+  ;; Make a menu bar item.
+  (define-key gnus-group-mode-map [menu-bar GNUS]
+       (cons "GNUS" (make-sparse-keymap "GNUS")))
+
+  (define-key gnus-group-mode-map [menu-bar GNUS force-update]
+       '("Force Update" . gnus-group-force-update))
+  (define-key gnus-group-mode-map [menu-bar GNUS quit]
+       '("Quit" . gnus-group-quit))
+  (define-key gnus-group-mode-map [menu-bar GNUS exit]
+       '("Exit" . gnus-group-exit))
+  (define-key gnus-group-mode-map [menu-bar GNUS restart]
+       '("Restart" . gnus-group-restart))
+  (define-key gnus-group-mode-map [menu-bar GNUS suspend]
+       '("Suspend" . gnus-group-suspend))
+  (define-key gnus-group-mode-map [menu-bar GNUS get-new-news]
+       '("Get New News" . gnus-group-get-new-news))
+
+  ;; Make a menu bar item.
+  (define-key gnus-group-mode-map [menu-bar groups]
+       (cons "Groups" (make-sparse-keymap "Groups")))
+
+  (define-key gnus-group-mode-map [menu-bar groups catchup]
+       '("Catchup" . gnus-group-catchup))
+  (define-key gnus-group-mode-map [menu-bar groups edit-global-kill]
+       '("Edit Kill File" . gnus-group-edit-global-kill))
+
+  (define-key gnus-group-mode-map [menu-bar groups separator-2]
+       '("--"))
+
+  (define-key gnus-group-mode-map [menu-bar groups yank-group]
+       '("Yank Group" . gnus-group-yank-group))
+  (define-key gnus-group-mode-map [menu-bar groups kill-group]
+       '("Kill Group" . gnus-group-kill-group))
+
+  (define-key gnus-group-mode-map [menu-bar groups separator-1]
+       '("--"))
+
+  (define-key gnus-group-mode-map [menu-bar groups newsgroups-update-description]
+        '("Update descriptions" . gnus-newsgroups-update-description))
+  (define-key gnus-group-mode-map [menu-bar groups newsgroups-display-toggle]
+        '("Toggle descriptions" . gnus-newsgroups-display-toggle))
+  (define-key gnus-group-mode-map [menu-bar groups jump-to-group]
+       '("Jump to Group..." . gnus-group-jump-to-group))
+  (define-key gnus-group-mode-map [menu-bar groups list-all-groups]
+       '("List All Groups" . gnus-group-list-all-groups))
+  (define-key gnus-group-mode-map [menu-bar groups list-groups]
+       '("List Groups" . gnus-group-list-groups))
+  (define-key gnus-group-mode-map [menu-bar groups unsub-current-group]
+       '("Unsubscribe Group" . gnus-group-unsubscribe-current-group))
+  )
+
+(defun gnus-group-mode ()
   "Major mode for reading network news.
 All normal editing commands are turned off.
 Instead, these commands are available:
-\\{gnus-Group-mode-map}
+
+SPC    Read articles in this newsgroup.
+=      Select this newsgroup.
+j      Move to the specified newsgroup.
+n      Move to the next unread newsgroup.
+p      Move to the previous unread newsgroup.
+C-n    Move to the next newsgroup.
+C-p    Move to the previous newsgroup.
+<      Move point to the beginning of this buffer.
+>      Move point to the end of this buffer.
+u      Unsubscribe from (subscribe to) this newsgroup.
+U      Unsubscribe from (subscribe to) the specified newsgroup.
+c      Mark all articles as read, preserving marked articles.
+C      Mark all articles in this newsgroup as read.
+l      Revert this buffer.
+L      List all newsgroups.
+g      Get new news.
+R      Force to read the raw .newsrc file and get new news.
+b      Check bogus newsgroups.
+r      Restrict visible newsgroups to the current region.
+a      Post a new article.
+ESC k  Edit a local KILL file applied to this newsgroup.
+ESC K  Edit a global KILL file applied to all newsgroups.
+C-k    Kill this newsgroup.
+C-y    Yank killed newsgroup here.
+C-w    Kill newsgroups in current region (excluding current point).
+C-x C-t        Exchange this newsgroup and previous newsgroup.
+C-c C-l        list killed newsgroups.
+s      Save .newsrc file.
+z      Suspend reading news.
+q      Quit reading news.
+Q      Quit reading news without saving .newsrc file.
+V      Show the version number of this GNUS.
+?      Describe Group Mode commands briefly.
+C-h m  Describe Group Mode.
+C-c C-i        Read Info about Group Mode.
+t       Toggle displaying newsgroup descriptions.
 
   The name of the host running NNTP server is asked for if no default
-host is specified. It is also possible to choose another NNTP server
+host is specified.  It is also possible to choose another NNTP server
 even when the default server is defined by giving a prefix argument to
 the command `\\[gnus]'.
 
-  If an NNTP server is preceded by a colon such as `:Mail', the user's
-private directory `~/Mail' is used as a news spool. This makes it
+  If the NNTP server name starts with a colon, as in `:Mail', the user's
+own directory `~/Mail' is used as a news spool.  This makes it
 possible to read mail stored in MH folders or articles saved by GNUS.
 File names of mail or articles must consist of only numeric
-characters. Otherwise, they are ignored.
+characters.  Otherwise, they are ignored.
 
   If there is a file named `~/.newsrc-SERVER', it is used as the
 startup file instead of standard one when talking to SERVER.  It is
@@ -811,7 +1100,7 @@ possible to talk to many hosts by using different startup files for
 each.
 
   Option `-n' of the options line in the startup file is recognized
-properly the same as the Bnews system. For example, if the options
+properly the same as the Bnews system.  For example, if the options
 line is `options -n !talk talk.rumors', newsgroups under the `talk'
 hierarchy except for `talk.rumors' are ignored while checking new
 newsgroups.
@@ -822,7 +1111,7 @@ DISTRIBUTION.
 
   If an Info file generated from `gnus.texinfo' is installed, you can
 read an appropriate Info node of the Info file according to the
-current major mode of GNUS by \\[gnus-Info-find-node].
+current major mode of GNUS by \\[gnus-info-find-node].
 
   The variable `gnus-version', `nntp-version', `nnspool-version', and
 `mhspool-version' have the version numbers of this version of gnus.el,
@@ -830,29 +1119,29 @@ nntp.el, nnspool.el, and mhspoo.el, respectively.
 
 User customizable variables:
  gnus-nntp-server
-    Specifies the name of the host running the NNTP server. If its
+    Specifies the name of the host running the NNTP server.  If its
     value is a string such as `:DIRECTORY', the user's private
-    DIRECTORY is used as a news spool.  If its value is `::', then
-    the local news spool on the current machine is used directly.
-    The `NNTPSERVER' environment variable specifies the initial value
-    for this variable.
+    DIRECTORY is used as a news spool.  The variable is initialized
+    from the NNTPSERVER environment variable.
 
  gnus-nntp-service
-    Specifies a NNTP service name.  It is usually \"nntp\".
+    Specifies a NNTP service name.  It is usually \"nntp\" or 119.
+    Nil forces GNUS to use a local news spool if the variable
+    `gnus-nntp-server' is set to the local host name.
 
  gnus-startup-file
-    Specifies a startup file (.newsrc). If there is a file named
-    `.newsrc-SERVER', it's used instead when talking to SERVER. I
+    Specifies a startup file (.newsrc).  If there is a file named
+    `.newsrc-SERVER', it's used instead when talking to SERVER.  I
     recommend you to use the server specific file, if you'd like to
     talk to many servers.  Especially if you'd like to read your
     private directory, the name of the file must be
     `.newsrc-:DIRECTORY'.
 
  gnus-signature-file
-    Specifies a signature file (.signature). If there is a file named
+    Specifies a signature file (.signature).  If there is a file named
     `.signature-DISTRIBUTION', it's used instead when posting an
-    article in DISTRIBUTION. Set the variable to nil to prevent
-    appending the file automatically. If you use an NNTP inews which
+    article in DISTRIBUTION.  Set the variable to nil to prevent
+    appending the file automatically.  If you use an NNTP inews which
     comes with the NNTP package, you may have to set the variable to
     nil.
 
@@ -896,48 +1185,54 @@ User customizable variables:
     Non-nil means to take up the entire screen of Emacs.
 
  gnus-window-configuration
-    Specifies the configuration of Group, Subject, and Article
+    Specifies the configuration of Group, Summary, and Article
     windows.  It is a list of (ACTION (G S A)), where G, S, and A are
-    the relative height of Group, Subject, and Article windows,
-    respectively.  ACTION is `SelectNewsgroup', `ExitNewsgroup',
-    `SelectArticle', or `ExpandSubject'.
+    the relative height of Group, Summary, and Article windows,
+    respectively.  ACTION is `summary', `newsgroups', or `article'.
 
  gnus-subscribe-newsgroup-method
     Specifies a function called with a newsgroup name when new
     newsgroup is found.  The default definition adds new newsgroup at
     the beginning of other newsgroups.
 
+  And more and more.  Please refer to texinfo documentation.
+
 Various hooks for customization:
- gnus-Group-mode-hook
+ gnus-group-mode-hook
     Entry to this mode calls the value with no arguments, if that
-    value is non-nil. This hook is called before GNUS is connected to
-    the NNTP server. So, you can change or define the NNTP server in
+    value is non-nil.  This hook is called before GNUS is connected to
+    the NNTP server.  So, you can change or define the NNTP server in
     this hook.
 
- gnus-Startup-hook
-    Called with no arguments after the NNTP server is selected. It is
+ gnus-startup-hook
+    Called with no arguments after the NNTP server is selected.  It is
     possible to change the behavior of GNUS or initialize the
     variables according to the selected NNTP server.
 
- gnus-Group-prepare-hook
+ gnus-group-prepare-hook
     Called with no arguments after a newsgroup list is created in the
     Newsgroup buffer, if that value is non-nil.
 
- gnus-Save-newsrc-hook
+ gnus-save-newsrc-hook
     Called with no arguments when saving newsrc file if that value is
     non-nil.
 
- gnus-Inews-article-hook
+ gnus-prepare-article-hook
+    Called with no arguments after preparing message body, but before
+    preparing header fields which is automatically generated if that
+    value is non-nil.  The default hook (gnus-inews-insert-signature)
+    inserts a signature file.
+
+ gnus-inews-article-hook
     Called with no arguments when posting an article if that value is
-    non-nil. This hook is called just before posting an article, while
-    `news-inews-hook' is called before preparing article headers. If
-    you'd like to convert kanji code of the article, this hook is recommended.
+    non-nil.  This hook is called just before posting an article.  The
+    default hook does FCC (save an article to the specified file).
 
- gnus-Suspend-gnus-hook
+ gnus-suspend-gnus-hook
     Called with no arguments when suspending (not exiting) GNUS, if
     that value is non-nil.
 
- gnus-Exit-gnus-hook
+ gnus-exit-gnus-hook
     Called with no arguments when exiting (not suspending) GNUS, if
     that value is non-nil."
   (interactive)
@@ -951,14 +1246,20 @@ Various hooks for customization:
        (t
         (setq mode-line-format
               "--- GNUS: List of Newsgroups  %[(%m)%]----%3p-%-")))
-  (setq major-mode 'gnus-Group-mode)
+  (setq major-mode 'gnus-group-mode)
   (setq mode-name "Newsgroup")
   (setq mode-line-buffer-identification        "GNUS: List of Newsgroups")
   (setq mode-line-process nil)
-  (use-local-map gnus-Group-mode-map)
+  (use-local-map gnus-group-mode-map)
   (buffer-flush-undo (current-buffer))
   (setq buffer-read-only t)            ;Disable modification
-  (run-hooks 'gnus-Group-mode-hook))
+  (setq truncate-lines t)              ;In case descriptions are too long.
+  (run-hooks 'gnus-group-mode-hook))
+
+(defun gnus-mouse-pick-group (e)
+  (interactive "e")
+  (mouse-set-point e)
+  (gnus-group-read-group nil))
 
 ;;;###autoload
 (defun gnus (&optional confirm)
@@ -967,40 +1268,41 @@ If optional argument CONFIRM is non-nil, ask NNTP server."
   (interactive "P")
   (unwind-protect
       (progn
-       (switch-to-buffer (get-buffer-create gnus-Group-buffer))
-       (gnus-Group-mode)
+       (switch-to-buffer (get-buffer-create gnus-group-buffer))
+       (gnus-group-mode)
        (gnus-start-news-server confirm))
     (if (not (gnus-server-opened))
-       (gnus-Group-quit)
+       (gnus-group-quit)
       ;; NNTP server is successfully open. 
       (setq mode-line-process (format " {%s}" gnus-nntp-server))
       (let ((buffer-read-only nil))
        (erase-buffer)
-       (gnus-Group-startup-message)
+       (gnus-group-startup-message)
        (sit-for 0))
-      (run-hooks 'gnus-Startup-hook)
-      (gnus-setup-news-info)
+      (run-hooks 'gnus-startup-hook)
+      (gnus-setup-news)
       (if gnus-novice-user
-         (gnus-Group-describe-briefly)) ;Show brief help message.
-      (gnus-Group-list-groups nil)
+         (gnus-group-describe-briefly)) ;Show brief help message.
+      (gnus-group-list-groups nil)
       )))
 
-(defun gnus-Group-startup-message ()
+(defun gnus-group-startup-message ()
   "Insert startup message in current buffer."
   ;; Insert the message.
-  (insert "
-                   GNUS Version 3.13
+  (insert
+   (format "
+                   %s
 
          NNTP-based News Reader for GNU Emacs
 
 
 If you have any trouble with this software, please let me
-know. I will fix your problems in the next release.
+know.  I will fix your problems in the next release.
 
 Comments, suggestions, and bug fixes are welcome.
 
 Masanobu UMEDA
-umerin@tc.Nagasaki.GO.JP")
+umerin@mse.kyutech.ac.jp" gnus-version))
   ;; And then hack it.
   ;; 57 is the longest line.
   (indent-rigidly (point-min) (point-max) (/ (max (- (window-width) 57) 0) 2))
@@ -1008,63 +1310,69 @@ umerin@tc.Nagasaki.GO.JP")
   ;; +4 is fuzzy factor.
   (insert-char ?\n (/ (max (- (window-height) 18) 0) 2)))
 
-(defun gnus-Group-list-groups (show-all)
+(defun gnus-group-list-groups (show-all)
   "List newsgroups in the Newsgroup buffer.
 If argument SHOW-ALL is non-nil, unsubscribed groups are also listed."
   (interactive "P")
-  (let ((last-group                    ;Current newsgroup.
-        (gnus-Group-group-name))
+  (setq gnus-newsgroups-showall show-all)
+  (let ((case-fold-search nil)
+       (last-group                     ;Current newsgroup.
+        (gnus-group-group-name))
        (next-group                     ;Next possible newsgroup.
         (progn
-          (gnus-Group-search-forward nil nil)
-          (gnus-Group-group-name)))
+          (gnus-group-search-forward nil nil)
+          (gnus-group-group-name)))
        (prev-group                     ;Previous possible newsgroup.
         (progn
-          (gnus-Group-search-forward t nil)
-          (gnus-Group-group-name))))
-    (gnus-Group-prepare show-all)
+          (gnus-group-search-forward t nil)
+          (gnus-group-group-name))))
+    (set-buffer gnus-group-buffer)     ;May call from out of Group buffer
+    (gnus-group-prepare show-all)
     (if (zerop (buffer-size))
        (message "No news is good news")
       ;; Go to last newsgroup if possible.  If cannot, try next and
       ;; previous.  If all fail, go to first unread newsgroup.
       (goto-char (point-min))
       (or (and last-group
-              (re-search-forward
-               (concat "^.+: " (regexp-quote last-group) "$") nil t))
+              (re-search-forward (gnus-group-make-regexp last-group) nil t))
          (and next-group
-              (re-search-forward
-               (concat "^.+: " (regexp-quote next-group) "$") nil t))
+              (re-search-forward (gnus-group-make-regexp next-group) nil t))
          (and prev-group
-              (re-search-forward
-               (concat "^.+: " (regexp-quote prev-group) "$") nil t))
-         (re-search-forward "^[ \t]+[1-9][0-9]*:" nil t))
+              (re-search-forward (gnus-group-make-regexp prev-group) nil t))
+         (gnus-group-search-forward nil nil t))
       ;; Adjust cursor point.
       (beginning-of-line)
       (search-forward ":" nil t)
       )))
 
-(defun gnus-Group-prepare (&optional all)
+(defun gnus-group-prepare (&optional all)
   "Prepare list of newsgroups in current buffer.
 If optional argument ALL is non-nil, unsubscribed groups are also listed."
   (let ((buffer-read-only nil)
        (newsrc gnus-newsrc-assoc)
        (group-info nil)
        (group-name nil)
+       (group-description nil)
        (unread-count 0)
+       (nb-tab 0)
        ;; This specifies the format of Group buffer.
-       (cntl "%s%s%5d: %s\n"))
+       (cntl "%s%s%5d: %s"))
     (erase-buffer)
     ;; List newsgroups.
     (while newsrc
       (setq group-info (car newsrc))
       (setq group-name (car group-info))
+      (if gnus-newsgroups-display
+         (progn (setq group-description (gnus-gethash group-name gnus-newsgroups-hashtb))
+                (setq nb-tab (/ (- 38 (length group-name)) tab-width))))
       (setq unread-count (nth 1 (gnus-gethash group-name gnus-unread-hashtb)))
       (if (or all
              (and (nth 1 group-info)   ;Subscribed.
                   (> unread-count 0))) ;There are unread articles.
-         ;; Yes, I can use gnus-Group-prepare-line, but this is faster.
+         ;; Yes, I can use gnus-group-prepare-line, but this is faster.
          (insert
-          (format cntl
+          (format (concat cntl (make-string (if (> nb-tab 0) nb-tab 1) ?\t)
+                          "%s\n")
                   ;; Subscribed or not.
                   (if (nth 1 group-info) " " "U")
                   ;; Has new news?
@@ -1072,25 +1380,30 @@ If optional argument ALL is non-nil, unsubscribed groups are also listed."
                            (>= 0
                                (- unread-count
                                   (length
-                                   (cdr (assoc group-name
-                                               gnus-marked-assoc))))))
+                                   (cdr (gnus-gethash group-name
+                                                      gnus-marked-hashtb))))))
                       "*" " ")
                   ;; Number of unread articles.
                   unread-count
                   ;; Newsgroup name.
-                  group-name))
+                  group-name
+                  ;; Newsgroup description
+                  (if group-description (cdr group-description) "")
+                  ))
        )
       (setq newsrc (cdr newsrc))
       )
     (setq gnus-have-all-newsgroups all)
     (goto-char (point-min))
-    (run-hooks 'gnus-Group-prepare-hook)
+    (run-hooks 'gnus-group-prepare-hook)
     ))
 
-(defun gnus-Group-prepare-line (info)
+(defun gnus-group-prepare-line (info)
   "Return a string for the Newsgroup buffer from INFO.
-INFO is an element of gnus-newsrc-assoc or gnus-killed-assoc."
+INFO is an element of `gnus-newsrc-assoc' or `gnus-killed-assoc'."
   (let* ((group-name (car info))
+        (group-description nil)
+        (nb-tab 0)
         (unread-count
          (or (nth 1 (gnus-gethash group-name gnus-unread-hashtb))
              ;; Not in hash table, so compute it now.
@@ -1099,8 +1412,13 @@ INFO is an element of gnus-newsrc-assoc or gnus-killed-assoc."
                (nth 2 (gnus-gethash group-name gnus-active-hashtb))
                (nthcdr 2 info)))))
         ;; This specifies the format of Group buffer.
-        (cntl "%s%s%5d: %s\n"))
-    (format cntl
+        (cntl "%s%s%5d: %s"))
+    (if gnus-newsgroups-display
+       (progn
+         (setq group-description (gnus-gethash group-name gnus-newsgroups-hashtb))
+         (setq nb-tab (/ (- 38 (length group-name)) tab-width))))
+    (format (concat cntl (make-string (if (> nb-tab 0) nb-tab 1) ?\t)
+                   "%s\n")
            ;; Subscribed or not.
            (if (nth 1 info) " " "U")
            ;; Has new news?
@@ -1108,189 +1426,227 @@ INFO is an element of gnus-newsrc-assoc or gnus-killed-assoc."
                     (>= 0
                         (- unread-count
                            (length
-                            (cdr (assoc group-name gnus-marked-assoc))))))
+                            (cdr (gnus-gethash group-name
+                                               gnus-marked-hashtb))))))
                "*" " ")
            ;; Number of unread articles.
            unread-count
            ;; Newsgroup name.
            group-name
+           ;; Newsgroup description
+           (if group-description (cdr group-description) "")
            )))
 
-(defun gnus-Group-update-group (group &optional visible-only)
+(defun gnus-group-update-group (group &optional visible-only)
   "Update newsgroup info of GROUP.
 If optional argument VISIBLE-ONLY is non-nil, non displayed group is ignored."
   (let ((buffer-read-only nil)
+       (case-fold-search nil)          ;appleIIgs vs. appleiigs
+       (regexp (gnus-group-make-regexp group))
        (visible nil))
     ;; Buffer may be narrowed.
     (save-restriction
       (widen)
-      ;; Search point to modify.
-      (goto-char (point-min))
-      (if (re-search-forward (concat "^.+: " (regexp-quote group) "$") nil t)
-         ;; GROUP is listed in current buffer. So, delete old line.
+      ;; Search a line to modify.  If the buffer is large, the search
+      ;; takes long time.  In most cases, current point is on the line
+      ;; we are looking for.  So, first of all, check current line. 
+      ;; And then if current point is in the first half, search from
+      ;; the beginning.  Otherwise, search from the end.
+      (if (cond ((progn
+                  (beginning-of-line)
+                  (looking-at regexp)))
+               ((and (> (/ (buffer-size) 2) (point)) ;In the first half.
+                     (progn
+                       (goto-char (point-min))
+                       (re-search-forward regexp nil t))))
+               ((progn
+                  (goto-char (point-max))
+                  (re-search-backward regexp nil t))))
+         ;; GROUP is listed in current buffer.  So, delete old line.
          (progn
            (setq visible t)
            (beginning-of-line)
            (delete-region (point) (progn (forward-line 1) (point)))
-           ))
+           )
+       ;; No such line in the buffer, so insert it at the top.
+       (goto-char (point-min)))
       (if (or visible (not visible-only))
          (progn
-           (insert (gnus-Group-prepare-line (assoc group gnus-newsrc-assoc)))
+           (insert (gnus-group-prepare-line
+                    (gnus-gethash group gnus-newsrc-hashtb)))
            (forward-line -1)           ;Move point on that line.
            ))
       )))
 
-;; GNUS Group mode command
-
-(defun gnus-Group-group-name ()
+(defun gnus-group-group-name ()
   "Get newsgroup name around point."
   (save-excursion
     (beginning-of-line)
-    (if (looking-at ".[* \t]*[0-9]+:[ \t]+\\([^ \t\n]+\\)$")
-       (buffer-substring (match-beginning 1) (match-end 1))
-      )))
+    (if (looking-at "^..[0-9 \t]+:[ \t]+\\([^ \t\n]+\\)\\([ \t].*\\|$\\)")
+        (let ((group-name (buffer-substring (match-beginning 1) (match-end 1))))
+          (set-text-properties 0 (length group-name) nil group-name)
+          group-name))))
+
+(defun gnus-group-make-regexp (newsgroup)
+  "Return regexp that matches for a line of NEWSGROUP."
+  (concat "^.+: " (regexp-quote newsgroup) "\\([ \t].*\\|$\\)"))
+
+(defun gnus-group-search-forward (backward norest &optional heretoo)
+  "Search for the next (or previous) newsgroup.
+If 1st argument BACKWARD is non-nil, search backward instead.
+If 2nd argument NOREST is non-nil, don't care about newsgroup property.
+If optional argument HERETOO is non-nil, current line is searched for, too."
+  (let ((case-fold-search nil)
+       (func
+        (if backward
+            (function re-search-backward) (function re-search-forward)))
+       (regexp
+        (format "^%s[ \t]*\\(%s\\):"
+                (if norest ".." " [ \t]")
+                (if norest "[0-9]+" "[1-9][0-9]*")))
+       (found nil))
+    (if backward
+       (if heretoo
+           (end-of-line)
+         (beginning-of-line))
+      (if heretoo
+         (beginning-of-line)
+       (end-of-line)))
+    (setq found (funcall func regexp nil t))
+    ;; Adjust cursor point.
+    (beginning-of-line)
+    (search-forward ":" nil t)
+    ;; Return T if found.
+    found
+    ))
+
+;; GNUS Group mode command
 
-(defun gnus-Group-read-group (all &optional no-article)
+(defun gnus-group-read-group (all &optional no-article)
   "Read news in this newsgroup.
 If argument ALL is non-nil, already read articles become readable.
 If optional argument NO-ARTICLE is non-nil, no article body is displayed."
   (interactive "P")
-  (let ((group (gnus-Group-group-name))) ;Newsgroup name to read.
+  (let ((group (gnus-group-group-name))) ;Newsgroup name to read.
     (if group
-       (gnus-Subject-read-group
+       (gnus-summary-read-group
         group
         (or all
-            ;;(not (nth 1 (assoc group gnus-newsrc-assoc)))    ;Unsubscribed
+            ;;(not (nth 1 (gnus-gethash group gnus-newsrc-hashtb))) ;Unsubscribed
             (zerop
              (nth 1 (gnus-gethash group gnus-unread-hashtb)))) ;No unread
         no-article
         ))
     ))
 
-(defun gnus-Group-select-group (all)
+(defun gnus-group-select-group (all)
   "Select this newsgroup.
 No article is selected automatically.
 If argument ALL is non-nil, already read articles become readable."
   (interactive "P")
-  (gnus-Group-read-group all t))
+  (gnus-group-read-group all t))
 
-(defun gnus-Group-jump-to-group (group)
+(defun gnus-group-jump-to-group (group)
   "Jump to newsgroup GROUP."
   (interactive
    (list (completing-read "Newsgroup: " gnus-newsrc-assoc nil 'require-match)))
-  (goto-char (point-min))
-  (or (re-search-forward (concat "^.+: " (regexp-quote group) "$") nil t)
-      (if (assoc group gnus-newsrc-assoc)
-         ;; Add GROUP entry, then seach again.
-         (gnus-Group-update-group group)))
-  ;; Adjust cursor point.
-  (beginning-of-line)
-  (search-forward ":" nil t))
-
-(defun gnus-Group-search-forward (backward any-group)
-  "Search for newsgroup forward.
-If first argument BACKWARD is non-nil, search backward instead.
-If second argument ANY-GROUP is non-nil, unsubscribed or empty
-group may be selected."
-  (let ((func (if backward 're-search-backward 're-search-forward))
-       (regexp 
-        (format "^%s[ \t]*\\(%s\\):"
-                (if any-group ".." " [ \t]")
-                (if any-group "[0-9]+" "[1-9][0-9]*")))
-       (found nil))
-    (if backward
-       (beginning-of-line)
-      (end-of-line))
-    (setq found (funcall func regexp nil t))
+  (let ((case-fold-search nil))
+    (goto-char (point-min))
+    (or (re-search-forward (gnus-group-make-regexp group) nil t)
+       (if (gnus-gethash group gnus-newsrc-hashtb)
+           ;; Add GROUP entry, then seach again.
+           (gnus-group-update-group group)))
     ;; Adjust cursor point.
     (beginning-of-line)
     (search-forward ":" nil t)
-    ;; Return T if found.
-    found
     ))
 
-(defun gnus-Group-next-group (n)
-  "Go to next N'th newsgroup."
+(defun gnus-group-next-group (n)
+  "Go to Nth following newsgroup."
   (interactive "p")
   (while (and (> n 1)
-             (gnus-Group-search-forward nil t))
+             (gnus-group-search-forward nil t))
     (setq n (1- n)))
-  (or (gnus-Group-search-forward nil t)
+  (or (gnus-group-search-forward nil t)
       (message "No more newsgroups")))
 
-(defun gnus-Group-next-unread-group (n)
-  "Go to next N'th unread newsgroup."
+(defun gnus-group-next-unread-group (n)
+  "Go to Nth following unread newsgroup."
   (interactive "p")
   (while (and (> n 1)
-             (gnus-Group-search-forward nil nil))
+             (gnus-group-search-forward nil nil))
     (setq n (1- n)))
-  (or (gnus-Group-search-forward nil nil)
+  (or (gnus-group-search-forward nil nil)
       (message "No more unread newsgroups")))
 
-(defun gnus-Group-prev-group (n)
-  "Go to previous N'th newsgroup."
+(defun gnus-group-prev-group (n)
+  "Go to Nth previous newsgroup."
   (interactive "p")
   (while (and (> n 1)
-             (gnus-Group-search-forward t t))
+             (gnus-group-search-forward t t))
     (setq n (1- n)))
-  (or (gnus-Group-search-forward t t)
+  (or (gnus-group-search-forward t t)
       (message "No more newsgroups")))
 
-(defun gnus-Group-prev-unread-group (n)
-  "Go to previous N'th unread newsgroup."
+(defun gnus-group-prev-unread-group (n)
+  "Go to Nth previous unread newsgroup."
   (interactive "p")
   (while (and (> n 1)
-             (gnus-Group-search-forward t nil))              
+             (gnus-group-search-forward t nil))              
     (setq n (1- n)))
-  (or (gnus-Group-search-forward t nil)
+  (or (gnus-group-search-forward t nil)
       (message "No more unread newsgroups")))
 
-(defun gnus-Group-catch-up (all &optional quietly)
+(defun gnus-group-catchup (all)
   "Mark all articles not marked as unread in current newsgroup as read.
 If prefix argument ALL is non-nil, all articles are marked as read.
 Cross references (Xref: field) of articles are ignored."
   (interactive "P")
-  (let* ((group (gnus-Group-group-name))
+  (let* ((group (gnus-group-group-name))
          (marked (if (not all)
-                    (cdr (assoc group gnus-marked-assoc)))))
+                    (cdr (gnus-gethash group gnus-marked-hashtb)))))
     (and group
-        (or quietly
+        (or (not gnus-interactive-catchup) ;Without confirmation?
             (y-or-n-p
              (if all
                  "Do you really want to mark everything as read? "
                "Delete all articles not marked as read? ")))
         (progn
-          (message "")                 ;Erase "Yes or No" question.
+          (message "")                 ;Clear "Yes or No" question.
           ;; Any marked articles will be preserved.
           (gnus-update-unread-articles group marked marked)
-          (gnus-Group-update-group group)
-          (gnus-Group-next-group 1)))
+          (gnus-group-update-group group)
+          (gnus-group-next-group 1)))
     ))
 
-(defun gnus-Group-catch-up-all (&optional quietly)
+(defun gnus-group-catchup-all ()
   "Mark all articles in current newsgroup as read.
 Cross references (Xref: field) of articles are ignored."
   (interactive)
-  (gnus-Group-catch-up t quietly))
+  (gnus-group-catchup t))
 
-(defun gnus-Group-unsubscribe-current-group ()
+(defun gnus-group-unsubscribe-current-group ()
   "Toggle subscribe from/to unsubscribe current group."
   (interactive)
-  (gnus-Group-unsubscribe-group (gnus-Group-group-name))
-  (gnus-Group-next-group 1))
+  (let ((group (gnus-group-group-name)))
+    (if group
+        (progn
+          (gnus-group-unsubscribe-group group)
+          (gnus-group-next-group 1))
+      (message "No Newsgroup found to \(un\)subscribe"))))
 
-(defun gnus-Group-unsubscribe-group (group)
+(defun gnus-group-unsubscribe-group (group)
   "Toggle subscribe from/to unsubscribe GROUP.
-New newsgroup is added to .newsrc automatically."
+\(If GROUP is new, it is added to `.newsrc' automatically.)"
   (interactive
    (list (completing-read "Newsgroup: "
                          gnus-active-hashtb nil 'require-match)))
-  (let ((newsrc (assoc group gnus-newsrc-assoc)))
+  (let ((newsrc (gnus-gethash group gnus-newsrc-hashtb)))
     (cond ((not (null newsrc))
           ;; Toggle subscription flag.
           (setcar (nthcdr 1 newsrc) (not (nth 1 newsrc)))
           (gnus-update-newsrc-buffer group)
-          (gnus-Group-update-group group)
+          (gnus-group-update-group group)
           ;; Adjust cursor point.
           (beginning-of-line)
           (search-forward ":" nil t))
@@ -1298,38 +1654,40 @@ New newsgroup is added to .newsrc automatically."
                (gnus-gethash group gnus-active-hashtb))
           ;; Add new newsgroup.
           (gnus-add-newsgroup group)
-          (gnus-Group-update-group group)
+          (gnus-group-update-group group)
           ;; Adjust cursor point.
           (beginning-of-line)
           (search-forward ":" nil t))
          (t (error "No such newsgroup: %s" group)))
     ))
 
-(defun gnus-Group-list-all-groups ()
+(defun gnus-group-list-all-groups ()
   "List all of newsgroups in the Newsgroup buffer."
   (interactive)
-  (gnus-Group-list-groups t))
+  (message "Listing all groups...")
+  (gnus-group-list-groups t)
+  (message "Listing all groups...done"))
 
-(defun gnus-Group-get-new-news ()
+(defun gnus-group-get-new-news ()
   "Get newly arrived articles.  In fact, read the active file again."
   (interactive)
-  (gnus-setup-news-info)
-  (gnus-Group-list-groups gnus-have-all-newsgroups))
+  (gnus-setup-news)
+  (gnus-group-list-groups gnus-have-all-newsgroups))
 
-(defun gnus-Group-restart ()
+(defun gnus-group-restart ()
   "Force GNUS to read the raw startup file."
   (interactive)
   (gnus-save-newsrc-file)
-  (gnus-setup-news-info t)             ;Force to read the raw startup file.
-  (gnus-Group-list-groups gnus-have-all-newsgroups))
+  (gnus-setup-news t)                  ;Force to read the raw startup file.
+  (gnus-group-list-groups gnus-have-all-newsgroups))
 
-(defun gnus-Group-check-bogus-groups ()
+(defun gnus-group-check-bogus-groups ()
   "Check bogus newsgroups."
   (interactive)
   (gnus-check-bogus-newsgroups t)      ;Require confirmation.
-  (gnus-Group-list-groups gnus-have-all-newsgroups))
+  (gnus-group-list-groups gnus-have-all-newsgroups))
 
-(defun gnus-Group-restrict-groups (start end)
+(defun gnus-group-restrict-groups (start end)
   "Restrict visible newsgroups to the current region (START and END).
 Type \\[widen] to remove restriction."
   (interactive "r")
@@ -1344,197 +1702,435 @@ Type \\[widen] to remove restriction."
                        (point))))
   (message (substitute-command-keys "Type \\[widen] to remove restriction")))
 
-(defun gnus-Group-edit-global-kill ()
+(defun gnus-group-edit-global-kill ()
   "Edit a global KILL file."
   (interactive)
   (setq gnus-current-kill-article nil) ;No articles selected.
-  (gnus-Kill-file-edit-file nil)       ;Nil stands for global KILL file.
+  (gnus-kill-file-edit-file nil)       ;Nil stands for global KILL file.
   (message
    (substitute-command-keys
-    "Editing a global KILL file (Type \\[gnus-Kill-file-exit] to exit)")))
+    "Editing a global KILL file (Type \\[gnus-kill-file-exit] to exit)")))
 
-(defun gnus-Group-edit-local-kill ()
+(defun gnus-group-edit-local-kill ()
   "Edit a local KILL file."
   (interactive)
   (setq gnus-current-kill-article nil) ;No articles selected.
-  (gnus-Kill-file-edit-file (gnus-Group-group-name))
+  (gnus-kill-file-edit-file (gnus-group-group-name))
   (message
    (substitute-command-keys
-    "Editing a local KILL file (Type \\[gnus-Kill-file-exit] to exit)")))
+    "Editing a local KILL file (Type \\[gnus-kill-file-exit] to exit)")))
 
-(defun gnus-Group-force-update ()
-  "Update .newsrc file."
+(defun gnus-group-force-update ()
+  "Update `.newsrc' file."
   (interactive)
   (gnus-save-newsrc-file))
 
-(defun gnus-Group-suspend ()
+(defun gnus-group-suspend ()
   "Suspend the current GNUS session.
 In fact, cleanup buffers except for Group Mode buffer.
-The hook `gnus-Suspend-gnus-hook' is called before actually suspending."
+The hook `gnus-suspend-gnus-hook' is called before actually suspending."
   (interactive)
-  (run-hooks 'gnus-Suspend-gnus-hook)
+  (run-hooks 'gnus-suspend-gnus-hook)
   ;; Kill GNUS buffers except for Group Mode buffer.
-  (let ((buffers gnus-buffer-list))
+  (let ((buffers gnus-buffer-list)
+       (group-buf (get-buffer gnus-group-buffer)))
     (while buffers
-      (and (not (eq (car buffers) gnus-Group-buffer))
+      (and (not (eq (car buffers) gnus-group-buffer))
           (get-buffer (car buffers))
           (kill-buffer (car buffers)))
       (setq buffers (cdr buffers))
-      ))
-  (bury-buffer))
+      )
+    (bury-buffer group-buf)
+    (delete-windows-on group-buf t)))
 
-(defun gnus-Group-exit ()
-  "Quit reading news after updating .newsrc.
-The hook `gnus-Exit-gnus-hook' is called before actually quitting."
+(defun gnus-group-exit ()
+  "Quit reading news after updating `.newsrc'.
+The hook `gnus-exit-gnus-hook' is called before actually quitting."
   (interactive)
   (if (or noninteractive               ;For gnus-batch-kill
          (zerop (buffer-size))         ;No news is good news.
          (not (gnus-server-opened))    ;NNTP connection closed.
+         (not gnus-interactive-exit)   ;Without confirmation
          (y-or-n-p "Are you sure you want to quit reading news? "))
       (progn
        (message "")                    ;Erase "Yes or No" question.
-       (run-hooks 'gnus-Exit-gnus-hook)
+       (run-hooks 'gnus-exit-gnus-hook)
        (gnus-save-newsrc-file)
        (gnus-clear-system)
        (gnus-close-server))
     ))
 
-(defun gnus-Group-quit ()
-  "Quit reading news without updating .newsrc.
-The hook `gnus-Exit-gnus-hook' is called before actually quitting."
+(defun gnus-group-quit ()
+  "Quit reading news without updating `.newsrc'.
+The hook `gnus-exit-gnus-hook' is called before actually quitting."
   (interactive)
-  (if (or (zerop (buffer-size))
+  (if (or noninteractive               ;For gnus-batch-kill
+         (zerop (buffer-size))
          (not (gnus-server-opened))
          (yes-or-no-p
           (format "Quit reading news without saving %s? "
                   (file-name-nondirectory gnus-current-startup-file))))
       (progn
        (message "")                    ;Erase "Yes or No" question.
-       (run-hooks 'gnus-Exit-gnus-hook)
+       (run-hooks 'gnus-exit-gnus-hook)
        (gnus-clear-system)
        (gnus-close-server))
     ))
 
-(defun gnus-Group-describe-briefly ()
+(defun gnus-group-describe-briefly ()
   "Describe Group mode commands briefly."
   (interactive)
   (message
    (concat
-    (substitute-command-keys "\\[gnus-Group-read-group]:Select  ")
-    (substitute-command-keys "\\[gnus-Group-next-unread-group]:Forward  ")
-    (substitute-command-keys "\\[gnus-Group-prev-unread-group]:Backward  ")
-    (substitute-command-keys "\\[gnus-Group-exit]:Exit  ")
-    (substitute-command-keys "\\[gnus-Info-find-node]:Run Info  ")
-    (substitute-command-keys "\\[gnus-Group-describe-briefly]:This help")
+    (substitute-command-keys "\\[gnus-group-read-group]:Select  ")
+    (substitute-command-keys "\\[gnus-group-next-unread-group]:Forward  ")
+    (substitute-command-keys "\\[gnus-group-prev-unread-group]:Backward  ")
+    (substitute-command-keys "\\[gnus-group-exit]:Exit  ")
+    (substitute-command-keys "\\[gnus-info-find-node]:Run Info  ")
+    (substitute-command-keys "\\[gnus-group-describe-briefly]:This help")
     )))
 
 \f
 ;;;
-;;; GNUS Subject Mode
+;;; GNUS Summary Mode
 ;;;
 
-(if gnus-Subject-mode-map
+(if gnus-summary-mode-map
     nil
-  (setq gnus-Subject-mode-map (make-keymap))
-  (suppress-keymap gnus-Subject-mode-map)
-  (define-key gnus-Subject-mode-map " " 'gnus-Subject-next-page)
-  (define-key gnus-Subject-mode-map "\177" 'gnus-Subject-prev-page)
-  (define-key gnus-Subject-mode-map "\r" 'gnus-Subject-scroll-up)
-  (define-key gnus-Subject-mode-map "n" 'gnus-Subject-next-unread-article)
-  (define-key gnus-Subject-mode-map "p" 'gnus-Subject-prev-unread-article)
-  (define-key gnus-Subject-mode-map "N" 'gnus-Subject-next-article)
-  (define-key gnus-Subject-mode-map "P" 'gnus-Subject-prev-article)
-  (define-key gnus-Subject-mode-map "\e\C-n" 'gnus-Subject-next-same-subject)
-  (define-key gnus-Subject-mode-map "\e\C-p" 'gnus-Subject-prev-same-subject)
-  ;;(define-key gnus-Subject-mode-map "\e\C-n" 'gnus-Subject-next-unread-same-subject)
-  ;;(define-key gnus-Subject-mode-map "\e\C-p" 'gnus-Subject-prev-unread-same-subject)
-  (define-key gnus-Subject-mode-map "\C-c\C-n" 'gnus-Subject-next-digest)
-  (define-key gnus-Subject-mode-map "\C-c\C-p" 'gnus-Subject-prev-digest)
-  (define-key gnus-Subject-mode-map "\C-n" 'gnus-Subject-next-subject)
-  (define-key gnus-Subject-mode-map "\C-p" 'gnus-Subject-prev-subject)
-  (define-key gnus-Subject-mode-map "\en" 'gnus-Subject-next-unread-subject)
-  (define-key gnus-Subject-mode-map "\ep" 'gnus-Subject-prev-unread-subject)
-  ;;(define-key gnus-Subject-mode-map "\C-cn" 'gnus-Subject-next-group)
-  ;;(define-key gnus-Subject-mode-map "\C-cp" 'gnus-Subject-prev-group)
-  (define-key gnus-Subject-mode-map "." 'gnus-Subject-first-unread-article)
-  (define-key gnus-Subject-mode-map "/" 'isearch-forward)
-  (define-key gnus-Subject-mode-map "s" 'gnus-Subject-isearch-article)
-  (define-key gnus-Subject-mode-map "\es" 'gnus-Subject-search-article-forward)
-  (define-key gnus-Subject-mode-map "\eS" 'gnus-Subject-search-article-backward)
-  (define-key gnus-Subject-mode-map "<" 'gnus-Subject-beginning-of-article)
-  (define-key gnus-Subject-mode-map ">" 'gnus-Subject-end-of-article)
-  (define-key gnus-Subject-mode-map "j" 'gnus-Subject-goto-subject)
-  (define-key gnus-Subject-mode-map "J" 'gnus-Subject-goto-article)
-  (define-key gnus-Subject-mode-map "l" 'gnus-Subject-goto-last-article)
-  (define-key gnus-Subject-mode-map "^" 'gnus-Subject-refer-parent-article)
-  (define-key gnus-Subject-mode-map "\er" 'gnus-Subject-refer-article)
-  (define-key gnus-Subject-mode-map "u" 'gnus-Subject-mark-as-unread-forward)
-  (define-key gnus-Subject-mode-map "U" 'gnus-Subject-mark-as-unread-backward)
-  (define-key gnus-Subject-mode-map "d" 'gnus-Subject-mark-as-read-forward)
-  (define-key gnus-Subject-mode-map "D" 'gnus-Subject-mark-as-read-backward)
-  (define-key gnus-Subject-mode-map "\eu" 'gnus-Subject-clear-mark-forward)
-  (define-key gnus-Subject-mode-map "\eU" 'gnus-Subject-clear-mark-backward)
-  (define-key gnus-Subject-mode-map "k" 'gnus-Subject-kill-same-subject-and-select)
-  (define-key gnus-Subject-mode-map "\C-k" 'gnus-Subject-kill-same-subject)
-  (define-key gnus-Subject-mode-map "\e\C-t" 'gnus-Subject-toggle-threads)
-  (define-key gnus-Subject-mode-map "\e\C-s" 'gnus-Subject-show-thread)
-  (define-key gnus-Subject-mode-map "\e\C-h" 'gnus-Subject-hide-thread)
-  (define-key gnus-Subject-mode-map "\e\C-f" 'gnus-Subject-next-thread)
-  (define-key gnus-Subject-mode-map "\e\C-b" 'gnus-Subject-prev-thread)
-  (define-key gnus-Subject-mode-map "\e\C-u" 'gnus-Subject-up-thread)
-  (define-key gnus-Subject-mode-map "\e\C-d" 'gnus-Subject-down-thread)
-  (define-key gnus-Subject-mode-map "\e\C-k" 'gnus-Subject-kill-thread)
-  (define-key gnus-Subject-mode-map "&" 'gnus-Subject-execute-command)
-  ;;(define-key gnus-Subject-mode-map "c" 'gnus-Subject-catch-up)
-  ;;(define-key gnus-Subject-mode-map "c" 'gnus-Subject-catch-up-all)
-  (define-key gnus-Subject-mode-map "c" 'gnus-Subject-catch-up-and-exit)
-  ;;(define-key gnus-Subject-mode-map "c" 'gnus-Subject-catch-up-all-and-exit)
-  (define-key gnus-Subject-mode-map "\C-t" 'gnus-Subject-toggle-truncation)
-  (define-key gnus-Subject-mode-map "x" 'gnus-Subject-delete-marked-as-read)
-  (define-key gnus-Subject-mode-map "X" 'gnus-Subject-delete-marked-with)
-  (define-key gnus-Subject-mode-map "\C-c\C-sn" 'gnus-Subject-sort-by-number)
-  (define-key gnus-Subject-mode-map "\C-c\C-sa" 'gnus-Subject-sort-by-author)
-  (define-key gnus-Subject-mode-map "\C-c\C-ss" 'gnus-Subject-sort-by-subject)
-  (define-key gnus-Subject-mode-map "\C-c\C-sd" 'gnus-Subject-sort-by-date)
-  (define-key gnus-Subject-mode-map "\C-c\C-s\C-n" 'gnus-Subject-sort-by-number)
-  (define-key gnus-Subject-mode-map "\C-c\C-s\C-a" 'gnus-Subject-sort-by-author)
-  (define-key gnus-Subject-mode-map "\C-c\C-s\C-s" 'gnus-Subject-sort-by-subject)
-  (define-key gnus-Subject-mode-map "\C-c\C-s\C-d" 'gnus-Subject-sort-by-date)
-  (define-key gnus-Subject-mode-map "=" 'gnus-Subject-expand-window)
-  (define-key gnus-Subject-mode-map "G" 'gnus-Subject-reselect-current-group)
-  (define-key gnus-Subject-mode-map "w" 'gnus-Subject-stop-page-breaking)
-  (define-key gnus-Subject-mode-map "\C-c\C-r" 'gnus-Subject-caesar-message)
-  (define-key gnus-Subject-mode-map "g" 'gnus-Subject-show-article)
-  (define-key gnus-Subject-mode-map "t" 'gnus-Subject-toggle-header)
-  (define-key gnus-Subject-mode-map "v" 'gnus-Subject-show-all-headers)
-  (define-key gnus-Subject-mode-map "\C-d" 'gnus-Subject-rmail-digest)
-  (define-key gnus-Subject-mode-map "a" 'gnus-Subject-post-news)
-  (define-key gnus-Subject-mode-map "f" 'gnus-Subject-post-reply)
-  (define-key gnus-Subject-mode-map "F" 'gnus-Subject-post-reply-with-original)
-  (define-key gnus-Subject-mode-map "C" 'gnus-Subject-cancel-article)
-  (define-key gnus-Subject-mode-map "r" 'gnus-Subject-mail-reply)
-  (define-key gnus-Subject-mode-map "R" 'gnus-Subject-mail-reply-with-original)
-  (define-key gnus-Subject-mode-map "m" 'gnus-Subject-mail-other-window)
-  (define-key gnus-Subject-mode-map "o" 'gnus-Subject-save-article)
-  (define-key gnus-Subject-mode-map "\C-o" 'gnus-Subject-save-in-mail)
-  (define-key gnus-Subject-mode-map "|" 'gnus-Subject-pipe-output)
-  (define-key gnus-Subject-mode-map "\ek" 'gnus-Subject-edit-local-kill)
-  (define-key gnus-Subject-mode-map "\eK" 'gnus-Subject-edit-global-kill)
-  (define-key gnus-Subject-mode-map "V" 'gnus-version)
-  (define-key gnus-Subject-mode-map "q" 'gnus-Subject-exit)
-  (define-key gnus-Subject-mode-map "Q" 'gnus-Subject-quit)
-  (define-key gnus-Subject-mode-map "?" 'gnus-Subject-describe-briefly)
-  (define-key gnus-Subject-mode-map "\C-c\C-i" 'gnus-Info-find-node))
-
-(defun gnus-Subject-mode ()
+  (setq gnus-summary-mode-map (make-keymap))
+  (suppress-keymap gnus-summary-mode-map)
+  (define-key gnus-summary-mode-map "\C-c\C-v" 'gnus-uu-ctl-map)
+  (define-key gnus-summary-mode-map "#" 'gnus-uu-mark-article)
+  (define-key gnus-summary-mode-map " " 'gnus-summary-next-page)
+  (define-key gnus-summary-mode-map "\177" 'gnus-summary-prev-page)
+  (define-key gnus-summary-mode-map "\r" 'gnus-summary-scroll-up)
+  (define-key gnus-summary-mode-map "n" 'gnus-summary-next-unread-article)
+  (define-key gnus-summary-mode-map "p" 'gnus-summary-prev-unread-article)
+  (define-key gnus-summary-mode-map "N" 'gnus-summary-next-article)
+  (define-key gnus-summary-mode-map "P" 'gnus-summary-prev-article)
+  (define-key gnus-summary-mode-map "\e\C-n" 'gnus-summary-next-same-subject)
+  (define-key gnus-summary-mode-map "\e\C-p" 'gnus-summary-prev-same-subject)
+  ;;(define-key gnus-summary-mode-map "\e\C-n" 'gnus-summary-next-unread-same-subject)
+  ;;(define-key gnus-summary-mode-map "\e\C-p" 'gnus-summary-prev-unread-same-subject)
+  (define-key gnus-summary-mode-map "\C-c\C-n" 'gnus-summary-next-digest)
+  (define-key gnus-summary-mode-map "\C-c\C-p" 'gnus-summary-prev-digest)
+  (define-key gnus-summary-mode-map "\C-n" 'gnus-summary-next-subject)
+  (define-key gnus-summary-mode-map "\C-p" 'gnus-summary-prev-subject)
+  (define-key gnus-summary-mode-map [down] 'gnus-summary-next-subject)
+  (define-key gnus-summary-mode-map [up] 'gnus-summary-prev-subject)
+  (define-key gnus-summary-mode-map "\en" 'gnus-summary-next-unread-subject)
+  (define-key gnus-summary-mode-map "\ep" 'gnus-summary-prev-unread-subject)
+  ;;(define-key gnus-summary-mode-map "\C-cn" 'gnus-summary-next-group)
+  ;;(define-key gnus-summary-mode-map "\C-cp" 'gnus-summary-prev-group)
+  (define-key gnus-summary-mode-map "." 'gnus-summary-first-unread-article)
+  ;;(define-key gnus-summary-mode-map "/" 'isearch-forward)
+  (define-key gnus-summary-mode-map "s" 'gnus-summary-isearch-article)
+  (define-key gnus-summary-mode-map "\es" 'gnus-summary-search-article-forward)
+  ;;(define-key gnus-summary-mode-map "\eS" 'gnus-summary-search-article-backward)
+  (define-key gnus-summary-mode-map "\er" 'gnus-summary-search-article-backward)
+  (define-key gnus-summary-mode-map "<" 'gnus-summary-beginning-of-article)
+  (define-key gnus-summary-mode-map ">" 'gnus-summary-end-of-article)
+  (define-key gnus-summary-mode-map "j" 'gnus-summary-goto-subject)
+  ;;(define-key gnus-summary-mode-map "J" 'gnus-summary-goto-article)
+  (define-key gnus-summary-mode-map "l" 'gnus-summary-goto-last-article)
+  (define-key gnus-summary-mode-map "^" 'gnus-summary-refer-parent-article)
+  ;;(define-key gnus-summary-mode-map "\er" 'gnus-summary-refer-article)
+  (define-key gnus-summary-mode-map "\e^" 'gnus-summary-refer-article)
+  (define-key gnus-summary-mode-map "u" 'gnus-summary-mark-as-unread-forward)
+  (define-key gnus-summary-mode-map "U" 'gnus-summary-mark-as-unread-backward)
+  (define-key gnus-summary-mode-map "d" 'gnus-summary-mark-as-read-forward)
+  (define-key gnus-summary-mode-map "D" 'gnus-summary-mark-as-read-backward)
+  (define-key gnus-summary-mode-map "\eu" 'gnus-summary-clear-mark-forward)
+  (define-key gnus-summary-mode-map "\eU" 'gnus-summary-clear-mark-backward)
+  (define-key gnus-summary-mode-map "k" 'gnus-summary-kill-same-subject-and-select)
+  (define-key gnus-summary-mode-map "\C-k" 'gnus-summary-kill-same-subject)
+  (define-key gnus-summary-mode-map "\e\C-t" 'gnus-summary-toggle-threads)
+  (define-key gnus-summary-mode-map "\e\C-s" 'gnus-summary-show-thread)
+  (define-key gnus-summary-mode-map "\e\C-h" 'gnus-summary-hide-thread)
+  (define-key gnus-summary-mode-map "\e\C-f" 'gnus-summary-next-thread)
+  (define-key gnus-summary-mode-map "\e\C-b" 'gnus-summary-prev-thread)
+  (define-key gnus-summary-mode-map "\e\C-u" 'gnus-summary-up-thread)
+  (define-key gnus-summary-mode-map "\e\C-d" 'gnus-summary-down-thread)
+  (define-key gnus-summary-mode-map "\e\C-k" 'gnus-summary-kill-thread)
+  (define-key gnus-summary-mode-map "&" 'gnus-summary-execute-command)
+  ;;(define-key gnus-summary-mode-map "c" 'gnus-summary-catchup)
+  ;;(define-key gnus-summary-mode-map "c" 'gnus-summary-catchup-all)
+  (define-key gnus-summary-mode-map "c" 'gnus-summary-catchup-and-exit)
+  ;;(define-key gnus-summary-mode-map "c" 'gnus-summary-catchup-all-and-exit)
+  (define-key gnus-summary-mode-map "\C-t" 'gnus-summary-toggle-truncation)
+  (define-key gnus-summary-mode-map "x" 'gnus-summary-delete-marked-as-read)
+  (define-key gnus-summary-mode-map "X" 'gnus-summary-delete-marked-with)
+  (define-key gnus-summary-mode-map "\C-c\C-sn" 'gnus-summary-sort-by-number)
+  (define-key gnus-summary-mode-map "\C-c\C-sa" 'gnus-summary-sort-by-author)
+  (define-key gnus-summary-mode-map "\C-c\C-ss" 'gnus-summary-sort-by-subject)
+  (define-key gnus-summary-mode-map "\C-c\C-sd" 'gnus-summary-sort-by-date)
+  (define-key gnus-summary-mode-map "\C-c\C-s\C-n" 'gnus-summary-sort-by-number)
+  (define-key gnus-summary-mode-map "\C-c\C-s\C-a" 'gnus-summary-sort-by-author)
+  (define-key gnus-summary-mode-map "\C-c\C-s\C-s" 'gnus-summary-sort-by-subject)
+  (define-key gnus-summary-mode-map "\C-c\C-s\C-d" 'gnus-summary-sort-by-date)
+  (define-key gnus-summary-mode-map "=" 'gnus-summary-expand-window)
+  ;;(define-key gnus-summary-mode-map "G" 'gnus-summary-reselect-current-group)
+  (define-key gnus-summary-mode-map "\C-x\C-s" 'gnus-summary-reselect-current-group)
+  (define-key gnus-summary-mode-map "w" 'gnus-summary-stop-page-breaking)
+  (define-key gnus-summary-mode-map "\C-c\C-r" 'gnus-summary-caesar-message)
+  (define-key gnus-summary-mode-map "g" 'gnus-summary-show-article)
+  (define-key gnus-summary-mode-map "t" 'gnus-summary-toggle-header)
+  ;;(define-key gnus-summary-mode-map "v" 'gnus-summary-show-all-headers)
+  (define-key gnus-summary-mode-map "\et" 'gnus-summary-toggle-mime)
+  (define-key gnus-summary-mode-map "\C-d" 'gnus-summary-rmail-digest)
+  (define-key gnus-summary-mode-map "a" 'gnus-summary-post-news)
+  (define-key gnus-summary-mode-map "f" 'gnus-summary-followup)
+  (define-key gnus-summary-mode-map "F" 'gnus-summary-followup-with-original)
+  (define-key gnus-summary-mode-map "C" 'gnus-summary-cancel-article)
+  (define-key gnus-summary-mode-map "r" 'gnus-summary-reply)
+  (define-key gnus-summary-mode-map "R" 'gnus-summary-reply-with-original)
+  (define-key gnus-summary-mode-map "\C-c\C-f" 'gnus-summary-mail-forward)
+  (define-key gnus-summary-mode-map "m" 'gnus-summary-mail-other-window)
+  (define-key gnus-summary-mode-map "o" 'gnus-summary-save-article)
+  (define-key gnus-summary-mode-map "\C-o" 'gnus-summary-save-in-mail)
+  (define-key gnus-summary-mode-map "|" 'gnus-summary-pipe-output)
+  (define-key gnus-summary-mode-map "\ek" 'gnus-summary-edit-local-kill)
+  (define-key gnus-summary-mode-map "\eK" 'gnus-summary-edit-global-kill)
+  (define-key gnus-summary-mode-map "V" 'gnus-version)
+  (define-key gnus-summary-mode-map "q" 'gnus-summary-exit)
+  (define-key gnus-summary-mode-map "Q" 'gnus-summary-quit)
+  (define-key gnus-summary-mode-map "?" 'gnus-summary-describe-briefly)
+  (define-key gnus-summary-mode-map "\C-c\C-i" 'gnus-info-find-node)
+  (define-key gnus-summary-mode-map [mouse-2] 'gnus-mouse-pick-article)
+
+  (define-key gnus-summary-mode-map [menu-bar misc]
+       (cons "Misc" (make-sparse-keymap "misc")))
+
+  (define-key gnus-summary-mode-map [menu-bar misc caesar-message]
+       '("Caesar Message" . gnus-summary-caesar-message))
+  (define-key gnus-summary-mode-map [menu-bar misc cancel-article]
+       '("Cancel Article" . gnus-summary-cancel-article))
+  (define-key gnus-summary-mode-map [menu-bar misc edit-local-kill]
+       '("Edit Kill File" . gnus-summary-edit-local-kill))
+
+  (define-key gnus-summary-mode-map [menu-bar misc mark-as-unread]
+       '("Mark as Unread" . gnus-summary-mark-as-unread-forward))
+  (define-key gnus-summary-mode-map [menu-bar misc mark-as-read]
+       '("Mark as Read" . gnus-summary-mark-as-read))
+
+  (define-key gnus-summary-mode-map [menu-bar misc quit]
+       '("Quit Group" . gnus-summary-quit))
+  (define-key gnus-summary-mode-map [menu-bar misc exit]
+       '("Exit Group" . gnus-summary-exit))
+
+  (define-key gnus-summary-mode-map [menu-bar sort]
+       (cons "Sort" (make-sparse-keymap "sort")))
+
+  (define-key gnus-summary-mode-map [menu-bar sort sort-by-author]
+       '("Sort by Author" . gnus-summary-sort-by-author))
+  (define-key gnus-summary-mode-map [menu-bar sort sort-by-date]
+       '("Sort by Date" . gnus-summary-sort-by-date))
+  (define-key gnus-summary-mode-map [menu-bar sort sort-by-number]
+       '("Sort by Number" . gnus-summary-sort-by-number))
+  (define-key gnus-summary-mode-map [menu-bar sort sort-by-subject]
+       '("Sort by Subject" . gnus-summary-sort-by-subject))
+
+  (define-key gnus-summary-mode-map [menu-bar show/hide]
+       (cons "Show/Hide" (make-sparse-keymap "show/hide")))
+
+  (define-key gnus-summary-mode-map [menu-bar show/hide hide-all-threads]
+       '("Hide All Threads" . gnus-summary-hide-all-threads))
+  (define-key gnus-summary-mode-map [menu-bar show/hide hide-thread]
+       '("Hide Thread" . gnus-summary-hide-thread))
+  (define-key gnus-summary-mode-map [menu-bar show/hide show-all-threads]
+       '("Show All Threads" . gnus-summary-show-all-threads))
+  (define-key gnus-summary-mode-map [menu-bar show/hide show-all-headers]
+       '("Show All Headers" . gnus-summary-show-all-headers))
+  (define-key gnus-summary-mode-map [menu-bar show/hide show-thread]
+       '("Show Thread" . gnus-summary-show-thread))
+  (define-key gnus-summary-mode-map [menu-bar show/hide show-article]
+       '("Show Article" . gnus-summary-show-article))
+  (define-key gnus-summary-mode-map [menu-bar show/hide toggle-truncation]
+       '("Toggle Truncation" . gnus-summary-toggle-truncation))
+  (define-key gnus-summary-mode-map [menu-bar show/hide toggle-mime]
+       '("Toggle Mime" . gnus-summary-toggle-mime))
+  (define-key gnus-summary-mode-map [menu-bar show/hide toggle-header]
+       '("Toggle Header" . gnus-summary-toggle-header))
+
+  (define-key gnus-summary-mode-map [menu-bar action]
+       (cons "Action" (make-sparse-keymap "action")))
+
+  (define-key gnus-summary-mode-map [menu-bar action kill-same-subject]
+       '("Kill Same Subject" . gnus-summary-kill-same-subject))
+  (define-key gnus-summary-mode-map [menu-bar action kill-thread]
+       '("Kill Thread" . gnus-summary-kill-thread))
+  (define-key gnus-summary-mode-map [menu-bar action delete-marked-with]
+       '("Delete Marked With" . gnus-summary-delete-marked-with))
+  (define-key gnus-summary-mode-map [menu-bar action delete-marked-as-read]
+       '("Delete Marked As Read" . gnus-summary-delete-marked-as-read))
+  (define-key gnus-summary-mode-map [menu-bar action catchup-and-exit]
+       '("Catchup And Exit" . gnus-summary-catchup-and-exit))
+  (define-key gnus-summary-mode-map [menu-bar action catchup-to-here]
+       '("Catchup to Here" . gnus-summary-catchup-to-here))
+
+  (define-key gnus-summary-mode-map [menu-bar action ignore]
+    '("---"))
+
+  (define-key gnus-summary-mode-map [menu-bar action save-in-file]
+       '("Save in File" . gnus-summary-save-in-file))
+  (define-key gnus-summary-mode-map [menu-bar action save-article]
+       '("Save Article" . gnus-summary-save-article))
+
+  (define-key gnus-summary-mode-map [menu-bar action lambda]
+    '("---"))
+
+  (define-key gnus-summary-mode-map [menu-bar action forward]
+       '("Forward" . gnus-summary-mail-forward))
+  (define-key gnus-summary-mode-map [menu-bar action followup-with-original]
+       '("Followup with Original" . gnus-summary-followup-with-original))
+  (define-key gnus-summary-mode-map [menu-bar action followup]
+       '("Followup" . gnus-summary-followup))
+  (define-key gnus-summary-mode-map [menu-bar action reply-with-original]
+       '("Reply with Original" . gnus-summary-reply-with-original))
+  (define-key gnus-summary-mode-map [menu-bar action reply]
+       '("Reply" . gnus-summary-reply))
+  (define-key gnus-summary-mode-map [menu-bar action post]
+       '("Post News" . gnus-summary-post-news))
+
+  (define-key gnus-summary-mode-map [menu-bar move]
+       (cons "Move" (make-sparse-keymap "move")))
+
+  (define-key gnus-summary-mode-map [menu-bar move isearch-article]
+       '("Search in Article" . gnus-summary-isearch-article))
+  (define-key gnus-summary-mode-map [menu-bar move search-through-articles]
+       '("Search through Articles" . gnus-summary-search-article-forward))
+  (define-key gnus-summary-mode-map [menu-bar move down-thread]
+       '("Down Thread" . gnus-summary-down-thread))
+  (define-key gnus-summary-mode-map [menu-bar move prev-same-subject]
+       '("Prev Same Subject" . gnus-summary-prev-same-subject))
+  (define-key gnus-summary-mode-map [menu-bar move prev-group]
+       '("Prev Group" . gnus-summary-prev-group))
+  (define-key gnus-summary-mode-map [menu-bar move next-unread-same-subject]
+       '("Next Unread Same Subject" . gnus-summary-next-unread-same-subject))
+  (define-key gnus-summary-mode-map [menu-bar move next-unread-article]
+       '("Next Unread Article" . gnus-summary-next-unread-article))
+  (define-key gnus-summary-mode-map [menu-bar move next-thread]
+       '("Next Thread" . gnus-summary-next-thread))
+  (define-key gnus-summary-mode-map [menu-bar move next-group]
+       '("Next Group" . gnus-summary-next-group))
+  (define-key gnus-summary-mode-map [menu-bar move first-unread-article]
+       '("First Unread Article" . gnus-summary-first-unread-article))
+  )
+\f
+
+(defun gnus-summary-mode ()
   "Major mode for reading articles in this newsgroup.
 All normal editing commands are turned off.
 Instead, these commands are available:
-\\{gnus-Subject-mode-map}
+
+SPC    Scroll to the next page of the current article.  The next unread
+       article is selected automatically at the end of the message.
+DEL    Scroll to the previous page of the current article.
+RET    Scroll up (or down) one line the current article.
+n      Move to the next unread article.
+p      Move to the previous unread article.
+N      Move to the next article.
+P      Move to the previous article.
+ESC C-n        Move to the next article which has the same subject as the
+       current article.
+ESC C-p        Move to the previous article which has the same subject as the
+       current article.
+\\[gnus-summary-next-unread-same-subject]
+       Move to the next unread article which has the same subject as the
+       current article.
+\\[gnus-summary-prev-unread-same-subject]
+       Move to the previous unread article which has the same subject as
+       the current article.
+C-c C-n        Scroll to the next digested message of the current article.
+C-c C-p        Scroll to the previous digested message of the current article.
+C-n    Move to the next subject.
+C-p    Move to the previous subject.
+ESC n  Move to the next unread subject.
+ESC p  Move to the previous unread subject.
+\\[gnus-summary-next-group]
+       Exit the current newsgroup and select the next unread newsgroup.
+\\[gnus-summary-prev-group]
+       Exit the current newsgroup and select the previous unread newsgroup.
+.      Jump to the first unread article in the current newsgroup.
+s      Do an incremental search forward on the current article.
+ESC s  Search for an article containing a regexp forward.
+ESC r  Search for an article containing a regexp backward.
+<      Move point to the beginning of the current article.
+>      Move point to the end of the current article.
+j      Jump to the article specified by the numeric article ID.
+l      Jump to the article you read last.
+^      Refer to parent of the current article.
+ESC ^  Refer to the article specified by the Message-ID.
+u      Mark the current article as unread, and go forward.
+U      Mark the current article as unread, and go backward.
+d      Mark the current article as read, and go forward.
+D      Mark the current article as read, and go backward.
+ESC u  Clear the current article's mark, and go forward.
+ESC U  Clear the current article's mark, and go backward.
+k      Mark articles which has the same subject as the current article as
+       read, and then select the next unread article.
+C-k    Mark articles which has the same subject as the current article as
+       read.
+ESC k  Edit a local KILL file applied to the current newsgroup.
+ESC K  Edit a global KILL file applied to all newsgroups.
+ESC C-t        Toggle showing conversation threads.
+ESC C-s        Show thread subtrees.
+ESC C-h        Hide thread subtrees.
+\\[gnus-summary-show-all-threads]      Show all thread subtrees.
+\\[gnus-summary-hide-all-threads]      Hide all thread subtrees.
+ESC C-f        Go to the same level next thread.
+ESC C-b        Go to the same level previous thread.
+ESC C-d        Go downward current thread.
+ESC C-u        Go upward current thread.
+ESC C-k        Mark articles under current thread as read.
+&      Execute a command for each article conditionally.
+\\[gnus-summary-catchup]
+       Mark all articles as read in the current newsgroup, preserving
+       articles marked as unread.
+\\[gnus-summary-catchup-all]
+       Mark all articles as read in the current newsgroup.
+\\[gnus-summary-catchup-and-exit]
+       Catch up all articles not marked as unread, and then exit the
+       current newsgroup.
+\\[gnus-summary-catchup-all-and-exit]
+       Catch up all articles, and then exit the current newsgroup.
+C-t    Toggle truncations of subject lines.
+x      Delete subject lines marked as read.
+X      Delete subject lines with the specific marks.
+C-c C-s C-n    Sort subjects by article number.
+C-c C-s C-a    Sort subjects by article author.
+C-c C-s C-s    Sort subjects alphabetically.
+C-c C-s C-d    Sort subjects by date.
+=      Expand Summary window to show headers full window.
+C-x C-s        Reselect the current newsgroup.  Prefix argument means to select all.
+w      Stop page breaking by linefeed.
+C-c C-r        Caesar rotates letters by 13/47 places.
+g      Force to show the current article.
+t      Show original article header if pruned header currently shown, or
+       vice versa.
+ESC-t  Toggle MIME processing.
+C-d    Run RMAIL on the current digest article.
+a      Post a new article.
+f      Post a reply article.
+F      Post a reply article with original article.
+C      Cancel the current article.
+r      Mail a message to the author.
+R      Mail a message to the author with original author.
+C-c C-f        Forward the current message to another user.
+m      Mail a message in other window.
+o      Save the current article in your favorite format.
+C-o    Append the current article to a file in Unix mail format.
+|      Pipe the contents of the current article to a subprocess.
+q      Quit reading news in the current newsgroup.
+Q      Quit reading news without recording unread articles information.
+V      Show the version number of this GNUS.
+?      Describe Summary mode commands briefly.
+C-h m  Describe Summary mode.
+C-c C-i        Read Info about Summary mode.
 
 User customizable variables:
  gnus-large-newsgroup
-    The number of articles which indicates a large newsgroup. If the
+    The number of articles which indicates a large newsgroup.  If the
     number of articles in a newsgroup is greater than the value, the
     number of articles to be selected is asked for.  If the given value
     N is positive, the last N articles is selected.  If N is negative,
@@ -1550,10 +2146,10 @@ User customizable variables:
     Specifies your favorite article saver which is interactively
     funcallable.  Following functions are available:
 
-       gnus-Subject-save-in-rmail (in Rmail format)
-       gnus-Subject-save-in-mail (in Unix mail format)
-       gnus-Subject-save-in-folder (in MH folder)
-       gnus-Subject-save-in-file (in article format).
+       gnus-summary-save-in-rmail (in Rmail format)
+       gnus-summary-save-in-mail (in Unix mail format)
+       gnus-summary-save-in-folder (in MH folder)
+       gnus-summary-save-in-file (in article format).
 
  gnus-rmail-save-name
  gnus-mail-save-name
@@ -1562,20 +2158,29 @@ User customizable variables:
     Specifies a function generating a file name to save articles in
     specified format.  The function is called with NEWSGROUP, HEADERS,
     and optional LAST-FILE.  Access macros to the headers are defined
-    as nntp-header-FIELD, and functions are defined as `gnus-header-FIELD'.
+    as `nntp-header-FIELD', and functions are defined as
+    `gnus-header-FIELD'.
 
  gnus-article-save-directory
     Specifies a directory name to save articles to using the commands
-    `gnus-Subject-save-in-rmail', `gnus-Subject-save-in-mail' and
-    `gnus-Subject-save-in-file'.  The variable is initialized from the
+    `gnus-summary-save-in-rmail', `gnus-summary-save-in-mail' and
+    `gnus-summary-save-in-file'.  The variable is initialized from the
     SAVEDIR environment variable.
 
+ gnus-kill-files-directory
+    Specifies a directory name to save KILL files to using the commands
+    `gnus-edit-global-kill', and `gnus-edit-local-kill'.  The variable is
+    initialized from the SAVEDIR environment variable.
+
  gnus-show-all-headers
     Non-nil means that all headers of an article are shown.
 
  gnus-save-all-headers
     Non-nil means that all headers of an article are saved in a file.
 
+ gnus-show-mime
+    Non-nil means that show a MIME message.
+
  gnus-show-threads
     Non-nil means that conversation threads are shown in tree structure.
 
@@ -1597,7 +2202,7 @@ User customizable variables:
 
  gnus-optional-headers
     Specifies a function which generates an optional string displayed
-    in the Subject buffer.  The function is called with an article
+    in the Summary buffer.  The function is called with an article
     HEADERS.  The result must be a string excluding `[' and `]'.  The
     default function returns a string like NNN:AUTHOR, where NNN is
     the number of lines in an article and AUTHOR is the name of the
@@ -1609,17 +2214,17 @@ User customizable variables:
 
  gnus-auto-select-first
     Non-nil means the first unread article is selected automagically
-    when a newsgroup is selected normally (by gnus-Group-read-group).
+    when a newsgroup is selected normally (by `gnus-group-read-group').
     If you'd like to prevent automatic selection of the first unread
     article in some newsgroups, set the variable to nil in
-    gnus-Select-group-hook or gnus-Apply-kill-hook.
+    `gnus-select-group-hook' or `gnus-apply-kill-hook'.
 
  gnus-auto-select-next
     Non-nil means the next newsgroup is selected automagically at the
-    end of the newsgroup. If the value is t and the next newsgroup is
-    empty (no unread articles), GNUS will exit Subject mode and go
-    back to Group mode. If the value is neither nil nor t, GNUS won't
-    exit Subject mode but select the following unread newsgroup.
+    end of the newsgroup.  If the value is t and the next newsgroup is
+    empty (no unread articles), GNUS will exit Summary mode and go
+    back to Group mode.  If the value is neither nil nor t, GNUS won't
+    exit Summary mode but select the following unread newsgroup.
     Especially, if the value is the symbol `quietly', the next unread
     newsgroup will be selected without any confirmations.
 
@@ -1627,8 +2232,8 @@ User customizable variables:
     Non-nil means an article with the same subject as the current
     article is selected automagically like `rn -S'.
 
- gnus-auto-center-subject
-    Non-nil means the point of Subject Mode window is always kept
+ gnus-auto-center-summary
+    Non-nil means the point of Summary Mode window is always kept
     centered.
 
  gnus-break-pages
@@ -1640,12 +2245,10 @@ User customizable variables:
     Specifies a regexp describing line-beginnings that separate pages
     of news article.
 
- [gnus-more-message is obsolete.  overlay-arrow-string interfares
-    with other subsystems, such as dbx mode.]
-
  gnus-digest-show-summary
     Non-nil means that a summary of digest messages is shown when
-    reading a digest article using `gnus-Subject-rmail-digest' command.
+    reading a digest article using `gnus-summary-rmail-digest'
+    command.
 
  gnus-digest-separator
     Specifies a regexp separating messages in a digest article.
@@ -1653,65 +2256,70 @@ User customizable variables:
  gnus-mail-reply-method
  gnus-mail-other-window-method
     Specifies a function to begin composing mail message using
-    commands gnus-Subject-mail-reply and
-    gnus-Subject-mail-other-window.  Functions
-    gnus-mail-reply-using-mail and gnus-mail-reply-using-mhe are
-    available for the value of gnus-mail-reply-method.  And functions
-    gnus-mail-other-window-using-mail and
-    gnus-mail-other-window-using-mhe are available for the value of
-    gnus-mail-other-window-method.
+    commands `gnus-summary-reply' and `gnus-summary-mail-other-window'.
+    Functions `gnus-mail-reply-using-mail' and `gnus-mail-reply-using-mhe'
+    are available for the value of `gnus-mail-reply-method'.  And
+    functions `gnus-mail-other-window-using-mail' and
+    `gnus-mail-other-window-using-mhe' are available for the value of
+    `gnus-mail-other-window-method'.
+
+ gnus-mail-send-method
+    Specifies a function to mail a message too which is being posted
+    as an article.  The message must have To: or Cc: field.  The value
+    of the variable `send-mail-function' is the default function, which
+    uses sendmail mail program.
 
 Various hooks for customization:
- gnus-Subject-mode-hook
+ gnus-summary-mode-hook
     Entry to this mode calls the value with no arguments, if that
     value is non-nil.
 
- gnus-Select-group-hook
+ gnus-select-group-hook
     Called with no arguments when newsgroup is selected, if that value
     is non-nil.  It is possible to sort subjects in this hook.  See the
     documentation of this variable for more information.
 
- gnus-Subject-prepare-hook
-    Called with no arguments after a subject list is created in the
-    Subject buffer, if that value is non-nil.  If you'd like to modify
+ gnus-summary-prepare-hook
+    Called with no arguments after a summary list is created in the
+    Summary buffer, if that value is non-nil.  If you'd like to modify
     the buffer, you can use this hook.
 
- gnus-Select-article-hook
+ gnus-select-article-hook
     Called with no arguments when an article is selected, if that
-    value is non-nil.  See the documentation of this variable for
-    more information.
+    value is non-nil.  See the documentation of this variable for more
+    information.
 
- gnus-Select-digest-hook
+ gnus-select-digest-hook
     Called with no arguments when reading digest messages using Rmail,
     if that value is non-nil.  This hook can be used to modify an
     article so that Rmail can work with it.  See the documentation of
     the variable for more information.
 
- gnus-Rmail-digest-hook
+ gnus-rmail-digest-hook
     Called with no arguments when reading digest messages using Rmail,
     if that value is non-nil.  This hook is intended to customize Rmail
     mode.
 
- gnus-Apply-kill-hook
+ gnus-apply-kill-hook
     Called with no arguments when a newsgroup is selected and the
-    Subject buffer is prepared.  This hook is intended to apply a KILL
+    Summary buffer is prepared.  This hook is intended to apply a KILL
     file to the selected newsgroup.  The format of KILL file is
-    completely different from that of version 3.8. You have to rewrite
+    completely different from that of version 3.8.  You have to rewrite
     them in the new format.  See the documentation of Kill file mode
     for more information.
 
- gnus-Mark-article-hook
+ gnus-mark-article-hook
     Called with no arguments when an article is selected at the first
     time.  The hook is intended to mark an article as read (or unread)
     automatically when it is selected.  See the documentation of the
     variable for more information.
 
- gnus-Exit-group-hook
+ gnus-exit-group-hook
     Called with no arguments when exiting the current newsgroup, if
     that value is non-nil.  If your machine is so slow that exiting
-    from Subject mode takes very long time, inhibit marking articles
+    from Summary mode takes very long time, inhibit marking articles
     as read using cross-references by setting the variable
-    `gnus-newsgroup-headers' to nil in this hook."
+    gnus-use-cross-reference to nil in this hook."
   (interactive)
   (kill-all-local-variables)
   ;; Gee.  Why don't you upgrade?
@@ -1720,38 +2328,44 @@ Various hooks for customization:
        ((listp (default-value 'mode-line-format))
         (setq mode-line-format
               (cons "--- " (cdr (default-value 'mode-line-format))))))
-  (make-local-variable 'global-mode-string)
-  (setq global-mode-string nil)
-  (setq major-mode 'gnus-Subject-mode)
-  (setq mode-name "Subject")
+  ;; To disable display-time facility.
+  ;;(make-local-variable 'global-mode-string)
+  ;;(setq global-mode-string nil)
+  (setq major-mode 'gnus-summary-mode)
+  (setq mode-name "Summary")
   ;;(setq mode-line-process '(" " gnus-newsgroup-name))
   (make-local-variable 'minor-mode-alist)
   (or (assq 'gnus-show-threads minor-mode-alist)
       (setq minor-mode-alist
            (cons (list 'gnus-show-threads " Thread") minor-mode-alist)))
-  (gnus-Subject-set-mode-line)
-  (use-local-map gnus-Subject-mode-map)
+  (gnus-summary-set-mode-line)
+  (use-local-map gnus-summary-mode-map)
   (buffer-flush-undo (current-buffer))
   (setq buffer-read-only t)            ;Disable modification
   (setq truncate-lines t)              ;Stop line folding
   (setq selective-display t)
   (setq selective-display-ellipses t)  ;Display `...'
   ;;(setq case-fold-search t)
-  (run-hooks 'gnus-Subject-mode-hook))
-
-(defun gnus-Subject-setup-buffer ()
-  "Initialize subject display buffer."
-  (if (get-buffer gnus-Subject-buffer)
-      (set-buffer gnus-Subject-buffer)
-    (set-buffer (get-buffer-create gnus-Subject-buffer))
-    (gnus-Subject-mode)
+  (run-hooks 'gnus-summary-mode-hook))
+
+(defun gnus-mouse-pick-article (e)
+  (interactive "e")
+  (mouse-set-point e)
+  (gnus-summary-next-page nil))
+
+(defun gnus-summary-setup-buffer ()
+  "Initialize Summary buffer."
+  (if (get-buffer gnus-summary-buffer)
+      (set-buffer gnus-summary-buffer)
+    (set-buffer (get-buffer-create gnus-summary-buffer))
+    (gnus-summary-mode)
     ))
 
-(defun gnus-Subject-read-group (group &optional show-all no-article)
+(defun gnus-summary-read-group (group &optional show-all no-article)
   "Start reading news in newsgroup GROUP.
-If optional first argument SHOW-ALL is non-nil, already read articles are
+If optional 1st argument SHOW-ALL is non-nil, already read articles are
 also listed.
-If optional second argument NO-ARTICLE is non-nil, no article is selected
+If optional 2nd argument NO-ARTICLE is non-nil, no article is selected
 initially."
   (message "Retrieving newsgroup: %s..." group)
   (if (gnus-select-newsgroup group show-all)
@@ -1759,48 +2373,48 @@ initially."
        ;; Don't switch-to-buffer to prevent displaying old contents
        ;;  of the buffer until new subjects list is created.
        ;; Suggested by Juha Heinanen <jh@tut.fi>
-       (gnus-Subject-setup-buffer)
+       (gnus-summary-setup-buffer)
        ;; You can change the order of subjects in this hook.
-       (run-hooks 'gnus-Select-group-hook)
-       (gnus-Subject-prepare)
+       (run-hooks 'gnus-select-group-hook)
+       (gnus-summary-prepare)
        ;; Function `gnus-apply-kill-file' must be called in this hook.
-       (run-hooks 'gnus-Apply-kill-hook)
+       (run-hooks 'gnus-apply-kill-hook)
        (if (zerop (buffer-size))
            ;; This newsgroup is empty.
            (progn
-             (gnus-Subject-catch-up-and-exit nil t) ;Without confirmations.
+             (gnus-summary-catchup-and-exit nil t) ;Without confirmations.
              (message "No unread news"))
          ;; Hide conversation thread subtrees.  We cannot do this in
-         ;; gnus-Subject-prepare-hook since kill processing may not
+         ;; gnus-summary-prepare-hook since kill processing may not
          ;; work with hidden articles.
          (and gnus-show-threads
               gnus-thread-hide-subtree
-              (gnus-Subject-hide-all-threads))
+              (gnus-summary-hide-all-threads))
          ;; Show first unread article if requested.
          (goto-char (point-min))
          (if (and (not no-article)
                   gnus-auto-select-first
-                  (gnus-Subject-first-unread-article))
+                  (gnus-summary-first-unread-article))
              ;; Window is configured automatically.
              ;; Current buffer may be changed as a result of hook
-             ;; evaluation, especially by gnus-Subject-rmail-digest
+             ;; evaluation, especially by gnus-summary-rmail-digest
              ;; command, so we should adjust cursor point carefully.
-             (if (eq (current-buffer) (get-buffer gnus-Subject-buffer))
+             (if (eq (current-buffer) (get-buffer gnus-summary-buffer))
                  (progn
                    ;; Adjust cursor point.
                    (beginning-of-line)
                    (search-forward ":" nil t)))
-           (gnus-configure-windows 'SelectNewsgroup)
-           (pop-to-buffer gnus-Subject-buffer)
-           (gnus-Subject-set-mode-line)
+           (gnus-configure-windows 'summary)
+           (pop-to-buffer gnus-summary-buffer)
+           (gnus-summary-set-mode-line)
            ;; I sometime get confused with the old Article buffer.
-           (if (get-buffer gnus-Article-buffer)
-               (if (get-buffer-window gnus-Article-buffer)
+           (if (get-buffer gnus-article-buffer)
+               (if (get-buffer-window gnus-article-buffer)
                    (save-excursion
-                     (set-buffer gnus-Article-buffer)
+                     (set-buffer gnus-article-buffer)
                      (let ((buffer-read-only nil))
                        (erase-buffer)))
-                 (kill-buffer gnus-Article-buffer)))
+                 (kill-buffer gnus-article-buffer)))
            ;; Adjust cursor point.
            (beginning-of-line)
            (search-forward ":" nil t))
@@ -1811,43 +2425,50 @@ initially."
          ;; If NNTP is used, nntp_access file may not be installed
          ;; properly.  Otherwise, may be active file problem.
          (ding)
-         (message "Cannot select %s.  May be security or active file problem." group)
+         (message
+          (gnus-nntp-message
+           (format "Cannot select %s.  May be security or active file problem." group)))
          (sit-for 0))
       ;; Check bogus newsgroups.
       ;; We must be in Group Mode buffer.
-      (gnus-Group-check-bogus-groups))
+      (gnus-group-check-bogus-groups))
     ))
 
-(defun gnus-Subject-prepare ()
-  "Prepare subject list of current newsgroup in Subject mode buffer."
+(defun gnus-summary-prepare ()
+  "Prepare summary list of current newsgroup in Summary buffer."
   (let ((buffer-read-only nil))
     ;; Note: The next codes are not actually used because the user who
-    ;; want it can define them in gnus-Select-group-hook.
+    ;; want it can define them in gnus-select-group-hook.
     ;; Print verbose messages if too many articles are selected.
     ;;    (and (numberp gnus-large-newsgroup)
     ;;       (> (length gnus-newsgroup-headers) gnus-large-newsgroup)
     ;;       (message "Preparing headers..."))
     (erase-buffer)
-    (gnus-Subject-prepare-threads
+    (gnus-summary-prepare-threads
      (if gnus-show-threads
         (gnus-make-threads gnus-newsgroup-headers)
        gnus-newsgroup-headers) 0)
     ;; Erase header retrieval message.
     (message "")
-    ;; Call hooks for modifying Subject mode buffer.
+    ;; Call hooks for modifying Summary buffer.
     ;; Suggested by sven@tde.LTH.Se (Sven Mattisson).
     (goto-char (point-min))
-    (run-hooks 'gnus-Subject-prepare-hook)
+    (run-hooks 'gnus-summary-prepare-hook)
     ))
 
 ;; Basic ideas by Paul Dworkin <paul@media-lab.media.mit.edu>
+;; Subject bug fix by jbw@bigbird.bu.edu (Joe Wells)
 
-(defun gnus-Subject-prepare-threads (threads level)
-  "Prepare Subject buffer from THREADS and indentation LEVEL.
-THREADS is a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...]).'"
+(defun gnus-summary-prepare-threads (threads level &optional parent-subject)
+  "Prepare Summary buffer from THREADS and indentation LEVEL.
+THREADS is a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...]).'
+Optional PARENT-SUBJECT specifies the subject of the parent."
   (let ((thread nil)
        (header nil)
        (number nil)
+       (subject nil)
+       (child-subject nil)
+       (parent-subject (or parent-subject ""))
        ;; `M Indent NUM: [OPT] SUBJECT'
        (cntl (format "%%s %%s%%%dd: [%%s] %%s\n"
                      (length (prin1-to-string gnus-newsgroup-end)))))
@@ -1863,6 +2484,8 @@ THREADS is a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...]).'"
       (if (vectorp header)             ;Depends on nntp.el.
          (progn
            (setq number (nntp-header-number header))
+           (setq subject (nntp-header-subject header))
+           (setq child-subject (gnus-simplify-subject subject 're-only))
            (insert
             (format cntl
                     ;; Read or not.
@@ -1878,57 +2501,93 @@ THREADS is a list of `(PARENT [(CHILD1 [(GRANDCHILD ...]...) ...]).'"
                              (funcall gnus-optional-headers header)) "")
                     ;; Its subject string.
                     (concat (if (or (zerop level)
-                                    (not gnus-thread-hide-subject))
+                                    (not gnus-thread-hide-subject)
+                                    ;; Subject is different from the parent.
+                                    (not (string-equal
+                                          parent-subject child-subject)))
                                 nil
                               (make-string (window-width) ? ))
-                            (nntp-header-subject header))
+                            subject)
                     ))
            ))
       ;; Print subthreads.
       (and (consp thread)
           (cdr thread)
-          (gnus-Subject-prepare-threads (cdr thread) (1+ level)))
+          (gnus-summary-prepare-threads
+           (cdr thread) (1+ level) child-subject))
       )))
 
-(defun gnus-Subject-set-mode-line ()
-  "Set Subject mode line string."
-  ;; The value must be a string to escape %-constructs.
-  (let ((subject
-        (if gnus-current-headers
-            (nntp-header-subject gnus-current-headers) gnus-newsgroup-name)))
+;;(defun gnus-summary-set-mode-line ()
+;;  "Set Summary mode line string."
+;;  ;; The value must be a string to escape %-constructs.
+;;  (let ((subject
+;;      (if gnus-current-headers
+;;          (nntp-header-subject gnus-current-headers) gnus-newsgroup-name)))
+;;    (setq mode-line-buffer-identification
+;;       (concat "GNUS: "
+;;               subject
+;;               ;; Enough spaces to pad subject to 17 positions.
+;;               (make-string (max 0 (- 17 (length subject))) ? ))))
+;;  (set-buffer-modified-p t))
+
+;; New implementation in gnus 3.14.3
+
+(defun gnus-summary-set-mode-line ()
+  "Set Summary mode line string.
+If you don't like it, define your own `gnus-summary-set-mode-line'."
+  (let ((unmarked
+        (- (length gnus-newsgroup-unreads)
+           (length (gnus-intersection
+                    gnus-newsgroup-unreads gnus-newsgroup-marked))))
+       (unselected
+        (- (length gnus-newsgroup-unselected)
+           (length (gnus-intersection
+                    gnus-newsgroup-unselected gnus-newsgroup-marked)))))
     (setq mode-line-buffer-identification
-         (concat "GNUS: "
-                 subject
-                 ;; Enough spaces to pad subject to 17 positions.
-                 (make-string (max 0 (- 17 (length subject))) ? ))))
+         (list 17
+               (format "GNUS: %s%s %s"
+                       gnus-newsgroup-name
+                       (if gnus-current-article
+                           (format "/%d" gnus-current-article) "")
+                       ;; Basic ideas by tale@pawl.rpi.edu.
+                       (cond ((and (zerop unmarked)
+                                   (zerop unselected))
+                              "")
+                             ((zerop unselected)
+                              (format "{%d more}" unmarked))
+                             (t
+                              (format "{%d(+%d) more}" unmarked unselected)))
+                       ))))
   (set-buffer-modified-p t))
 
-;; GNUS Subject mode command.
+;; GNUS Summary mode command.
 
-(defun gnus-Subject-search-group (&optional backward)
+(defun gnus-summary-search-group (&optional backward)
   "Search for next unread newsgroup.
 If optional argument BACKWARD is non-nil, search backward instead."
   (save-excursion
-    (set-buffer gnus-Group-buffer)
+    (set-buffer gnus-group-buffer)
     (save-excursion
       ;; We don't want to alter current point of Group mode buffer.
-      (if (gnus-Group-search-forward backward nil)
-         (gnus-Group-group-name))
+      (if (gnus-group-search-forward backward nil)
+         (gnus-group-group-name))
       )))
 
-(defun gnus-Subject-search-subject (backward unread subject)
+(defun gnus-summary-search-subject (backward unread subject)
   "Search for article forward.
-If first argument BACKWARD is non-nil, search backward.
-If second argument UNREAD is non-nil, only unread article is selected.
-If third argument SUBJECT is non-nil, the article which has
+If 1st argument BACKWARD is non-nil, search backward.
+If 2nd argument UNREAD is non-nil, only unread article is selected.
+If 3rd argument SUBJECT is non-nil, the article which has
 the same subject will be searched for."
-  (let ((func (if backward 're-search-backward 're-search-forward))
+  (let ((func
+        (if backward
+            (function re-search-backward) (function re-search-forward)))
        (article nil)
        ;; We have to take care of hidden lines.
        (regexp 
         (format "^%s[ \t]+\\([0-9]+\\):.\\[[^]\r\n]*\\][ \t]+%s"
                 ;;(if unread " " ".")
-                (cond ((eq unread t) " ") (unread "[ ---]") (t "."))
+                (cond ((eq unread t) " ") (unread "[]") (t "."))
                 (if subject
                     (concat "\\([Rr][Ee]:[ \t]+\\)*"
                             (regexp-quote (gnus-simplify-subject subject))
@@ -1950,22 +2609,23 @@ the same subject will be searched for."
     article
     ))
 
-(defun gnus-Subject-search-forward (&optional unread subject)
+(defun gnus-summary-search-forward (&optional unread subject)
   "Search for article forward.
-If first optional argument UNREAD is non-nil, only unread article is selected.
-If second optional argument SUBJECT is non-nil, the article which has
+If 1st optional argument UNREAD is non-nil, only unread article is selected.
+If 2nd optional argument SUBJECT is non-nil, the article which has
 the same subject will be searched for."
-  (gnus-Subject-search-subject nil unread subject))
+  (gnus-summary-search-subject nil unread subject))
 
-(defun gnus-Subject-search-backward (&optional unread subject)
+(defun gnus-summary-search-backward (&optional unread subject)
   "Search for article backward.
-If first optional argument UNREAD is non-nil, only unread article is selected.
-If second optional argument SUBJECT is non-nil, the article which has
+If 1st optional argument UNREAD is non-nil, only unread article is selected.
+If 2nd optional argument SUBJECT is non-nil, the article which has
 the same subject will be searched for."
-  (gnus-Subject-search-subject t unread subject))
+  (gnus-summary-search-subject t unread subject))
 
-(defun gnus-Subject-article-number ()
-  "Article number around point. If nothing, return current number."
+(defun gnus-summary-article-number ()
+  "Return the Article number around point.
+If none, return current article number."
   (save-excursion
     (beginning-of-line)
     (if (looking-at ".[ \t]+\\([0-9]+\\):")
@@ -1975,18 +2635,18 @@ the same subject will be searched for."
       gnus-current-article
       )))
 
-(defun gnus-Subject-subject-string ()
+(defun gnus-summary-subject-string ()
   "Return current subject string or nil if nothing."
   (save-excursion
     ;; It is possible to implement this function using
-    ;;  `gnus-Subject-article-number' and `gnus-newsgroup-headers'.
+    ;;  `gnus-summary-article-number' and `gnus-newsgroup-headers'.
     (beginning-of-line)
     ;; We have to take care of hidden lines.
     (if (looking-at ".[ \t]+[0-9]+:.\\[[^]\r\n]*\\][ \t]+\\([^\r\n]*\\)[\r\n]")
        (buffer-substring (match-beginning 1) (match-end 1)))
     ))
 
-(defun gnus-Subject-goto-subject (article)
+(defun gnus-summary-goto-subject (article)
   "Move point to ARTICLE's subject."
   (interactive
    (list
@@ -2005,185 +2665,188 @@ the same subject will be searched for."
        (progn (goto-char current) nil))
     ))
 
-(defun gnus-Subject-recenter ()
-  "Center point in Subject mode window."
-  ;; Scroll window so as to cursor comes center of Subject mode window
+(defun gnus-summary-recenter ()
+  "Center point in Summary window."
+  ;; Scroll window so as to cursor comes center of Summary window
   ;;  only when article is displayed.
   ;; Suggested by earle@mahendo.JPL.NASA.GOV (Greg Earle).
   ;; Recenter only when requested.
-  ;; Suggested by popovich@park.cs.columbia.edu
-  (and gnus-auto-center-subject
-       (get-buffer-window gnus-Article-buffer)
+  ;; Subbested by popovich@park.cs.columbia.edu
+  (and gnus-auto-center-summary
+       (get-buffer-window gnus-article-buffer)
        (< (/ (- (window-height) 1) 2)
          (count-lines (point) (point-max)))
        (recenter (/ (- (window-height) 2) 2))))
 
 ;; Walking around Group mode buffer.
 
-(defun gnus-Subject-jump-to-group (newsgroup)
+(defun gnus-summary-jump-to-group (newsgroup)
   "Move point to NEWSGROUP in Group mode buffer."
   ;; Keep update point of Group mode buffer if visible.
   (if (eq (current-buffer)
-         (get-buffer gnus-Group-buffer))
+         (get-buffer gnus-group-buffer))
       (save-window-excursion
        ;; Take care of tree window mode.
-       (if (get-buffer-window gnus-Group-buffer)
-           (pop-to-buffer gnus-Group-buffer))
-       (gnus-Group-jump-to-group newsgroup))
+       (if (get-buffer-window gnus-group-buffer)
+           (pop-to-buffer gnus-group-buffer))
+       (gnus-group-jump-to-group newsgroup))
     (save-excursion
       ;; Take care of tree window mode.
-      (if (get-buffer-window gnus-Group-buffer)
-         (pop-to-buffer gnus-Group-buffer)
-       (set-buffer gnus-Group-buffer))
-      (gnus-Group-jump-to-group newsgroup))))
+      (if (get-buffer-window gnus-group-buffer)
+         (pop-to-buffer gnus-group-buffer)
+       (set-buffer gnus-group-buffer))
+      (gnus-group-jump-to-group newsgroup))))
 
-(defun gnus-Subject-next-group (no-article)
+(defun gnus-summary-next-group (no-article)
   "Exit current newsgroup and then select next unread newsgroup.
 If prefix argument NO-ARTICLE is non-nil, no article is selected initially."
   (interactive "P")
   ;; Make sure Group mode buffer point is on current newsgroup.
-  (gnus-Subject-jump-to-group gnus-newsgroup-name)
-  (let ((group (gnus-Subject-search-group)))
+  (gnus-summary-jump-to-group gnus-newsgroup-name)
+  (let ((group (gnus-summary-search-group)))
     (if (null group)
        (progn
          (message "Exiting %s..." gnus-newsgroup-name)  
-         (gnus-Subject-exit)
+         (gnus-summary-exit)
          (message ""))
       (message "Selecting %s..." group)
-      (gnus-Subject-exit t)            ;Exit Subject mode temporary.
+      (gnus-summary-exit t)            ;Exit Summary mode temporary.
       ;; We are now in Group mode buffer.
       ;; Make sure Group mode buffer point is on GROUP.
-      (gnus-Subject-jump-to-group group)
-      (gnus-Subject-read-group group nil no-article)
+      (gnus-summary-jump-to-group group)
+      (gnus-summary-read-group group nil no-article)
       (or (eq (current-buffer)
-             (get-buffer gnus-Subject-buffer))
+             (get-buffer gnus-summary-buffer))
          (eq gnus-auto-select-next t)
          ;; Expected newsgroup has nothing to read since the articles
-         ;; are marked as read by cross-referencing. So, try next
-         ;; newsgroup. (Make sure we are in Group mode buffer now.)
+         ;; are marked as read by cross-referencing.  So, try next
+         ;; newsgroup.  (Make sure we are in Group mode buffer now.)
          (and (eq (current-buffer)
-                  (get-buffer gnus-Group-buffer))
-              (gnus-Group-group-name)
-              (gnus-Subject-read-group
-               (gnus-Group-group-name) nil no-article))
+                  (get-buffer gnus-group-buffer))
+              (gnus-group-group-name)
+              (gnus-summary-read-group
+               (gnus-group-group-name) nil no-article))
          )
       )))
 
-(defun gnus-Subject-prev-group (no-article)
+(defun gnus-summary-prev-group (no-article)
   "Exit current newsgroup and then select previous unread newsgroup.
 If prefix argument NO-ARTICLE is non-nil, no article is selected initially."
   (interactive "P")
   ;; Make sure Group mode buffer point is on current newsgroup.
-  (gnus-Subject-jump-to-group gnus-newsgroup-name)
-  (let ((group (gnus-Subject-search-group t)))
+  (gnus-summary-jump-to-group gnus-newsgroup-name)
+  (let ((group (gnus-summary-search-group t)))
     (if (null group)
        (progn
          (message "Exiting %s..." gnus-newsgroup-name)  
-         (gnus-Subject-exit)
+         (gnus-summary-exit)
          (message ""))
       (message "Selecting %s..." group)
-      (gnus-Subject-exit t)            ;Exit Subject mode temporary.
+      (gnus-summary-exit t)            ;Exit Summary mode temporary.
       ;; We are now in Group mode buffer.
       ;; We have to adjust point of Group mode buffer because current
       ;; point is moved to next unread newsgroup by exiting.
-      (gnus-Subject-jump-to-group group)
-      (gnus-Subject-read-group group nil no-article)
+      (gnus-summary-jump-to-group group)
+      (gnus-summary-read-group group nil no-article)
       (or (eq (current-buffer)
-             (get-buffer gnus-Subject-buffer))
+             (get-buffer gnus-summary-buffer))
          (eq gnus-auto-select-next t)
          ;; Expected newsgroup has nothing to read since the articles
-         ;; are marked as read by cross-referencing. So, try next
-         ;; newsgroup. (Make sure we are in Group mode buffer now.)
+         ;; are marked as read by cross-referencing.  So, try next
+         ;; newsgroup.  (Make sure we are in Group mode buffer now.)
          (and (eq (current-buffer)
-                  (get-buffer gnus-Group-buffer))
-              (gnus-Subject-search-group t)
-              (gnus-Subject-read-group
-               (gnus-Subject-search-group t) nil no-article))
+                  (get-buffer gnus-group-buffer))
+              (gnus-summary-search-group t)
+              (gnus-summary-read-group
+               (gnus-summary-search-group t) nil no-article))
          )
       )))
 
-;; Walking around subject lines.
+;; Walking around summary lines.
 
-(defun gnus-Subject-next-subject (n &optional unread)
-  "Go to next N'th subject line.
+(defun gnus-summary-next-subject (n &optional unread)
+  "Go to Nth following summary line.
 If optional argument UNREAD is non-nil, only unread article is selected."
   (interactive "p")
   (while (and (> n 1)
-             (gnus-Subject-search-forward unread))
+             (gnus-summary-search-forward unread))
     (setq n (1- n)))
-  (cond ((gnus-Subject-search-forward unread)
-        (gnus-Subject-recenter))
+  (cond ((gnus-summary-search-forward unread)
+        (gnus-summary-recenter))
        (unread
         (message "No more unread articles"))
        (t
         (message "No more articles"))
        ))
 
-(defun gnus-Subject-next-unread-subject (n)
-  "Go to next N'th unread subject line."
+(defun gnus-summary-next-unread-subject (n)
+  "Go to Nth following unread summary line."
   (interactive "p")
-  (gnus-Subject-next-subject n t))
+  (gnus-summary-next-subject n t))
 
-(defun gnus-Subject-prev-subject (n &optional unread)
-  "Go to previous N'th subject line.
+(defun gnus-summary-prev-subject (n &optional unread)
+  "Go to Nth previous summary line.
 If optional argument UNREAD is non-nil, only unread article is selected."
   (interactive "p")
   (while (and (> n 1)
-             (gnus-Subject-search-backward unread))
+             (gnus-summary-search-backward unread))
     (setq n (1- n)))
-  (cond ((gnus-Subject-search-backward unread)
-        (gnus-Subject-recenter))
+  (cond ((gnus-summary-search-backward unread)
+        (gnus-summary-recenter))
        (unread
         (message "No more unread articles"))
        (t
         (message "No more articles"))
        ))
 
-(defun gnus-Subject-prev-unread-subject (n)
-  "Go to previous N'th unread subject line."
+(defun gnus-summary-prev-unread-subject (n)
+  "Go to Nth previous unread summary line."
   (interactive "p")
-  (gnus-Subject-prev-subject n t))
+  (gnus-summary-prev-subject n t))
 
-;; Walking around subject lines with displaying articles.
+;; Walking around summary lines with displaying articles.
 
-(defun gnus-Subject-expand-window ()
-  "Expand Subject window to show headers full window."
+(defun gnus-summary-expand-window ()
+  "Expand Summary window to show headers full window."
   (interactive)
-  (gnus-configure-windows 'ExpandSubject)
-  (pop-to-buffer gnus-Subject-buffer))
+  (gnus-configure-windows 'summary)
+  (pop-to-buffer gnus-summary-buffer))
 
-(defun gnus-Subject-display-article (article &optional all-header)
+(defun gnus-summary-display-article (article &optional all-header)
   "Display ARTICLE in Article buffer."
   (if (null article)
       nil
-    (gnus-configure-windows 'SelectArticle)
-    (pop-to-buffer gnus-Subject-buffer)
-    (gnus-Article-prepare article all-header)
-    (gnus-Subject-recenter)
-    (gnus-Subject-set-mode-line)
-    (run-hooks 'gnus-Select-article-hook)
+    (gnus-configure-windows 'article)
+    (pop-to-buffer gnus-summary-buffer)
+    (gnus-article-prepare article all-header)
+    (gnus-summary-recenter)
+    (gnus-summary-set-mode-line)
+    (run-hooks 'gnus-select-article-hook)
     ;; Successfully display article.
     t
     ))
 
-(defun gnus-Subject-select-article (&optional all-headers force)
+(defun gnus-summary-select-article (&optional all-headers force)
   "Select the current article.
-Optional argument ALL-HEADERS is non-nil, show all headers."
-  (let ((article (gnus-Subject-article-number)))
+Optional first argument ALL-HEADERS is non-nil, show all header fields.
+Optional second argument FORCE is nil, the article is only selected
+again when current header does not match with ALL-HEADERS option."
+  (let ((article (gnus-summary-article-number))
+       (all-headers (not (not all-headers)))) ;Must be T or NIL.
     (if (or (null gnus-current-article)
            (/= article gnus-current-article)
            (and force (not (eq all-headers gnus-have-all-headers))))
-       ;; The selected subject is different from that of the current article.
-       (gnus-Subject-display-article article all-headers)
-      (gnus-configure-windows 'SelectArticle)
-      (pop-to-buffer gnus-Subject-buffer))
+       ;; The selected one is different from that of the current article.
+       (gnus-summary-display-article article all-headers)
+      (gnus-configure-windows 'article)
+      (pop-to-buffer gnus-summary-buffer))
     ))
 
-(defun gnus-Subject-set-current-mark (&optional current-mark)
+(defun gnus-summary-set-current-mark (&optional current-mark)
   "Put `+' at the current article.
 Optional argument specifies CURRENT-MARK instead of `+'."
   (save-excursion
-    (set-buffer gnus-Subject-buffer)
+    (set-buffer gnus-summary-buffer)
     (let ((buffer-read-only nil))
       (goto-char (point-min))
       ;; First of all clear mark at last article.
@@ -2198,43 +2861,56 @@ Optional argument specifies CURRENT-MARK instead of `+'."
            (insert (or current-mark "+"))))
       )))
 
-(defun gnus-Subject-next-article (unread &optional subject)
+;;(defun gnus-summary-next-article (unread &optional subject)
+;;  "Select article after current one.
+;;If argument UNREAD is non-nil, only unread article is selected."
+;;  (interactive "P")
+;;  (cond ((gnus-summary-display-article
+;;       (gnus-summary-search-forward unread subject)))
+;;     (unread
+;;      (message "No more unread articles"))
+;;     (t
+;;      (message "No more articles"))
+;;     ))
+
+(defun gnus-summary-next-article (unread &optional subject)
   "Select article after current one.
 If argument UNREAD is non-nil, only unread article is selected."
   (interactive "P")
   (let ((header nil))
-    (cond ((gnus-Subject-display-article
-           (gnus-Subject-search-forward unread subject)))
+    (cond ((gnus-summary-display-article
+           (gnus-summary-search-forward unread subject)))
          ((and subject
                gnus-auto-select-same
                (gnus-set-difference gnus-newsgroup-unreads
                                     gnus-newsgroup-marked)
                (memq this-command
-                     '(gnus-Subject-next-unread-article
-                       gnus-Subject-next-page
-                       gnus-Subject-kill-same-subject-and-select
-                       ;;gnus-Subject-next-article
-                       ;;gnus-Subject-next-same-subject
-                       ;;gnus-Subject-next-unread-same-subject
+                     '(gnus-summary-next-unread-article
+                       gnus-summary-next-page
+                       gnus-summary-kill-same-subject-and-select
+                       ;;gnus-summary-next-article
+                       ;;gnus-summary-next-same-subject
+                       ;;gnus-summary-next-unread-same-subject
                        )))
           ;; Wrap article pointer if there are unread articles.
-          ;; Hook function, such as gnus-Subject-rmail-digest, may
+          ;; Hook function, such as gnus-summary-rmail-digest, may
           ;; change current buffer, so need check.
           (let ((buffer (current-buffer))
                 (last-point (point)))
             ;; No more articles with same subject, so jump to the first
             ;; unread article.
-            (gnus-Subject-first-unread-article)
+            (gnus-summary-first-unread-article)
             ;;(and (eq buffer (current-buffer))
             ;; (= (point) last-point)
             ;; ;; Ignore given SUBJECT, and try again.
-            ;; (gnus-Subject-next-article unread nil))
+            ;; (gnus-summary-next-article unread nil))
             (and (eq buffer (current-buffer))
                  (< (point) last-point)
                  (message "Wrapped"))
             ))
-         ((and (not unread)
-               gnus-auto-extend-newsgroup
+         ((and gnus-auto-extend-newsgroup
+               (not unread)            ;Not unread only
+               (not subject)           ;Only if subject is not specified.
                (setq header (gnus-more-header-forward)))
           ;; Extend to next article if possible.
           ;; Basic ideas by himacdonald@watdragon.waterloo.edu
@@ -2242,189 +2918,196 @@ If argument UNREAD is non-nil, only unread article is selected."
           ;; Threads feature must be turned off.
           (let ((buffer-read-only nil))
             (goto-char (point-max))
-            (gnus-Subject-prepare-threads (list header) 0))
-          (gnus-Subject-goto-article gnus-newsgroup-end))
+            (gnus-summary-prepare-threads (list header) 0))
+          (gnus-summary-goto-article gnus-newsgroup-end))
          (t
           ;; Select next newsgroup automatically if requested.
-          (let ((cmd (string-to-char (this-command-keys)))
-                (group (gnus-Subject-search-group))
+          (let ((cmd (aref (this-command-keys) 0))
+                (group (gnus-summary-search-group))
                 (auto-select
                  (and gnus-auto-select-next
                       ;;(null (gnus-set-difference gnus-newsgroup-unreads
                       ;;                               gnus-newsgroup-marked))
                       (memq this-command
-                            '(gnus-Subject-next-unread-article
-                              gnus-Subject-next-article
-                              gnus-Subject-next-page
-                              gnus-Subject-next-same-subject
-                              gnus-Subject-next-unread-same-subject
-                              gnus-Subject-kill-same-subject
-                              gnus-Subject-kill-same-subject-and-select
+                            '(gnus-summary-next-unread-article
+                              gnus-summary-next-article
+                              gnus-summary-next-page
+                              gnus-summary-next-same-subject
+                              gnus-summary-next-unread-same-subject
+                              gnus-summary-kill-same-subject
+                              gnus-summary-kill-same-subject-and-select
                               ))
                       ;; Ignore characters typed ahead.
                       (not (input-pending-p))
                       )))
+            ;; Keep just the event type of CMD.
+            (if (listp cmd)
+                (setq cmd (car cmd)))
             (message "No more%s articles%s"
                      (if unread " unread" "")
                      (if (and auto-select
                               (not (eq gnus-auto-select-next 'quietly)))
                          (if group
-                             (format " (Type %s to %s [%d])"
-                                     (key-description (char-to-string cmd))
+                             (format " (Type %s for %s [%d])"
+                                     (single-key-description cmd)
                                      group
                                      (nth 1 (gnus-gethash group
                                                           gnus-unread-hashtb)))
                            (format " (Type %s to exit %s)"
-                                   (key-description (char-to-string cmd))
-                                   gnus-newsgroup-name
-                                   ))
+                                   (single-key-description cmd)
+                                   gnus-newsgroup-name))
                        ""))
             ;; Select next unread newsgroup automagically.
             (cond ((and auto-select
                         (eq gnus-auto-select-next 'quietly))
                    ;; Select quietly.
-                   (gnus-Subject-next-group nil))
+                   (gnus-summary-next-group nil))
                   (auto-select
                    ;; Confirm auto selection.
-                   (let ((char (read-char)))
-                     (if (= char cmd)
-                         (gnus-Subject-next-group nil)
-                       (setq unread-command-char char))))
+                   (let* ((event (read-event))
+                          (type
+                           (if (listp event)
+                               (car event)
+                             event)))
+                     (if (and (eq event type) (eq event cmd))
+                         (gnus-summary-next-group nil)
+                       (setq unread-command-events (list event)))))
                   )
             ))
          )))
 
-(defun gnus-Subject-next-unread-article ()
+(defun gnus-summary-next-unread-article ()
   "Select unread article after current one."
   (interactive)
-  (gnus-Subject-next-article t (and gnus-auto-select-same
-                                   (gnus-Subject-subject-string))))
+  (gnus-summary-next-article t (and gnus-auto-select-same
+                                   (gnus-summary-subject-string))))
 
-(defun gnus-Subject-prev-article (unread &optional subject)
+(defun gnus-summary-prev-article (unread &optional subject)
   "Select article before current one.
 If argument UNREAD is non-nil, only unread article is selected."
   (interactive "P")
   (let ((header nil))
-    (cond ((gnus-Subject-display-article
-           (gnus-Subject-search-backward unread subject)))
+    (cond ((gnus-summary-display-article
+           (gnus-summary-search-backward unread subject)))
          ((and subject
                gnus-auto-select-same
                (gnus-set-difference gnus-newsgroup-unreads
                                     gnus-newsgroup-marked)
                (memq this-command
-                     '(gnus-Subject-prev-unread-article
-                       ;;gnus-Subject-prev-page
-                       ;;gnus-Subject-prev-article
-                       ;;gnus-Subject-prev-same-subject
-                       ;;gnus-Subject-prev-unread-same-subject
+                     '(gnus-summary-prev-unread-article
+                       ;;gnus-summary-prev-page
+                       ;;gnus-summary-prev-article
+                       ;;gnus-summary-prev-same-subject
+                       ;;gnus-summary-prev-unread-same-subject
                        )))
           ;; Ignore given SUBJECT, and try again.
-          (gnus-Subject-prev-article unread nil))
+          (gnus-summary-prev-article unread nil))
          (unread
           (message "No more unread articles"))
          ((and gnus-auto-extend-newsgroup
+               (not subject)           ;Only if subject is not specified.
                (setq header (gnus-more-header-backward)))
           ;; Extend to previous article if possible.
           ;; Basic ideas by himacdonald@watdragon.waterloo.edu
           (gnus-extend-newsgroup header t)
           (let ((buffer-read-only nil))
             (goto-char (point-min))
-            (gnus-Subject-prepare-threads (list header) 0))
-          (gnus-Subject-goto-article gnus-newsgroup-begin))
+            (gnus-summary-prepare-threads (list header) 0))
+          (gnus-summary-goto-article gnus-newsgroup-begin))
          (t
           (message "No more articles"))
          )))
 
-(defun gnus-Subject-prev-unread-article ()
-  "Select unred article before current one."
+(defun gnus-summary-prev-unread-article ()
+  "Select unread article before current one."
   (interactive)
-  (gnus-Subject-prev-article t (and gnus-auto-select-same
-                                   (gnus-Subject-subject-string))))
+  (gnus-summary-prev-article t (and gnus-auto-select-same
+                                   (gnus-summary-subject-string))))
 
-(defun gnus-Subject-next-page (lines)
+(defun gnus-summary-next-page (lines)
   "Show next page of selected article.
-If end of artile, select next article.
+If end of article, select next article.
 Argument LINES specifies lines to be scrolled up."
   (interactive "P")
-  (let ((article (gnus-Subject-article-number))
+  (let ((article (gnus-summary-article-number))
        (endp nil))
     (if (or (null gnus-current-article)
            (/= article gnus-current-article))
        ;; Selected subject is different from current article's.
-       (gnus-Subject-display-article article)
-      (gnus-configure-windows 'SelectArticle)
-      (pop-to-buffer gnus-Subject-buffer)
-      (gnus-eval-in-buffer-window gnus-Article-buffer
-       (setq endp (gnus-Article-next-page lines)))
+       (gnus-summary-display-article article)
+      (gnus-configure-windows 'article)
+      (pop-to-buffer gnus-summary-buffer)
+      (gnus-eval-in-buffer-window gnus-article-buffer
+       (setq endp (gnus-article-next-page lines)))
       (cond ((and endp lines)
             (message "End of message"))
            ((and endp (null lines))
-            (gnus-Subject-next-unread-article)))
+            (gnus-summary-next-unread-article)))
       )))
 
-(defun gnus-Subject-prev-page (lines)
+(defun gnus-summary-prev-page (lines)
   "Show previous page of selected article.
 Argument LINES specifies lines to be scrolled down."
   (interactive "P")
-  (let ((article (gnus-Subject-article-number)))
+  (let ((article (gnus-summary-article-number)))
     (if (or (null gnus-current-article)
            (/= article gnus-current-article))
        ;; Selected subject is different from current article's.
-       (gnus-Subject-display-article article)
-      (gnus-configure-windows 'SelectArticle)
-      (pop-to-buffer gnus-Subject-buffer)
-      (gnus-eval-in-buffer-window gnus-Article-buffer
-       (gnus-Article-prev-page lines))
+       (gnus-summary-display-article article)
+      (gnus-configure-windows 'article)
+      (pop-to-buffer gnus-summary-buffer)
+      (gnus-eval-in-buffer-window gnus-article-buffer
+       (gnus-article-prev-page lines))
       )))
 
-(defun gnus-Subject-scroll-up (lines)
+(defun gnus-summary-scroll-up (lines)
   "Scroll up (or down) one line current article.
 Argument LINES specifies lines to be scrolled up (or down if negative)."
   (interactive "p")
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (cond ((> lines 0)
-          (if (gnus-Article-next-page lines)
+          (if (gnus-article-next-page lines)
               (message "End of message")))
          ((< lines 0)
-          (gnus-Article-prev-page (- 0 lines))))
+          (gnus-article-prev-page (- 0 lines))))
     ))
 
-(defun gnus-Subject-next-same-subject ()
+(defun gnus-summary-next-same-subject ()
   "Select next article which has the same subject as current one."
   (interactive)
-  (gnus-Subject-next-article nil (gnus-Subject-subject-string)))
+  (gnus-summary-next-article nil (gnus-summary-subject-string)))
 
-(defun gnus-Subject-prev-same-subject ()
+(defun gnus-summary-prev-same-subject ()
   "Select previous article which has the same subject as current one."
   (interactive)
-  (gnus-Subject-prev-article nil (gnus-Subject-subject-string)))
+  (gnus-summary-prev-article nil (gnus-summary-subject-string)))
 
-(defun gnus-Subject-next-unread-same-subject ()
+(defun gnus-summary-next-unread-same-subject ()
   "Select next unread article which has the same subject as current one."
   (interactive)
-  (gnus-Subject-next-article t (gnus-Subject-subject-string)))
+  (gnus-summary-next-article t (gnus-summary-subject-string)))
 
-(defun gnus-Subject-prev-unread-same-subject ()
+(defun gnus-summary-prev-unread-same-subject ()
   "Select previous unread article which has the same subject as current one."
   (interactive)
-  (gnus-Subject-prev-article t (gnus-Subject-subject-string)))
+  (gnus-summary-prev-article t (gnus-summary-subject-string)))
 
-(defun gnus-Subject-refer-parent-article (child)
+(defun gnus-summary-refer-parent-article (child)
   "Refer parent article of current article.
 If a prefix argument CHILD is non-nil, go back to the child article
 using internally maintained articles history.
-NOTE: This command may not work with nnspool.el."
+NOTE: This command may not work with `nnspool.el'."
   (interactive "P")
-  (gnus-Subject-select-article t t)    ;Request all headers.
+  (gnus-summary-select-article t t)    ;Request all headers.
   (let ((referenced-id nil))           ;Message-id of parent or child article.
     (if child
        ;; Go back to child article using history.
-       (gnus-Subject-refer-article nil)
-      (gnus-eval-in-buffer-window gnus-Article-buffer
+       (gnus-summary-refer-article nil)
+      (gnus-eval-in-buffer-window gnus-article-buffer
        ;; Look for parent Message-ID.
        ;; We cannot use gnus-current-headers to get references
-       ;; because we may be looking at parent or refered article.
+       ;; because we may be looking at parent or referred article.
        (let ((references (gnus-fetch-field "References")))
          ;; Get the last message-id in the references.
          (and references
@@ -2434,23 +3117,23 @@ NOTE: This command may not work with nnspool.el."
                                (match-beginning 1) (match-end 1))))
          ))
       (if (stringp referenced-id)
-         (gnus-Subject-refer-article referenced-id)
+         (gnus-summary-refer-article referenced-id)
        (error "No more parents"))
       )))
 
-(defun gnus-Subject-refer-article (message-id)
+(defun gnus-summary-refer-article (message-id)
   "Refer article specified by MESSAGE-ID.
-If MESSAGE-ID is nil or an empty string, it is popped from an
+If the MESSAGE-ID is nil or an empty string, Message-ID is poped from
 internally maintained articles history.
-NOTE: This command may not work with nnspool.el."
+NOTE: This command may not work with `nnspool.el' nor `mhspool.el'."
   (interactive "sMessage-ID: ")
   ;; Make sure that this command depends on the fact that article
   ;; related information is not updated when an article is retrieved
   ;; by Message-ID.
-  (gnus-Subject-select-article t t)    ;Request all headers.
+  (gnus-summary-select-article t t)    ;Request all headers.
   (if (and (stringp message-id)
           (> (length message-id) 0))
-      (gnus-eval-in-buffer-window gnus-Article-buffer
+      (gnus-eval-in-buffer-window gnus-article-buffer
        ;; Construct the correct Message-ID if necessary.
        ;; Suggested by tale@pawl.rpi.edu.
        (or (string-match "^<" message-id)
@@ -2459,7 +3142,7 @@ NOTE: This command may not work with nnspool.el."
            (setq message-id (concat message-id ">")))
        ;; Push current message-id on history.
        ;; We cannot use gnus-current-headers to get current
-       ;; message-id because we may be looking at parent or refered
+       ;; message-id because we may be looking at parent or referred
        ;; article.
        (let ((current (gnus-fetch-field "Message-ID")))
          (or (equal current message-id) ;Nothing to do.
@@ -2471,53 +3154,53 @@ NOTE: This command may not work with nnspool.el."
     (setq message-id (car gnus-current-history))
     (setq gnus-current-history (cdr gnus-current-history)))
   (if (stringp message-id)
-      ;; Retrieve article by message-id.  This may not work with nnspool.
-      (gnus-Article-prepare message-id t)
+      ;; Retrieve article by message-id.  This may not work with
+      ;; nnspool nor mhspool.
+      (gnus-article-prepare message-id t)
     (error "No such references"))
   )
 
-(defun gnus-Subject-next-digest (nth)
-  "Move to head of NTH next digested message."
+(defun gnus-summary-next-digest (n)
+  "Move to head of Nth next digested message."
   (interactive "p")
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
-    (gnus-Article-next-digest (or nth 1))
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (gnus-article-next-digest (or n 1))
     ))
 
-(defun gnus-Subject-prev-digest (nth)
-  "Move to head of NTH previous digested message."
+(defun gnus-summary-prev-digest (n)
+  "Move to head of Nth previous digested message."
   (interactive "p")
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
-    (gnus-Article-prev-digest (or nth 1))
-    ))
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (gnus-article-prev-digest (or n 1))))
 
-(defun gnus-Subject-first-unread-article ()
+(defun gnus-summary-first-unread-article ()
   "Select first unread article.  Return non-nil if successfully selected."
   (interactive)
   (let ((begin (point)))
     (goto-char (point-min))
     (if (re-search-forward "^ [ \t]+[0-9]+:" nil t)
-       (gnus-Subject-display-article (gnus-Subject-article-number))
+       (gnus-summary-display-article (gnus-summary-article-number))
       ;; If there is no unread articles, stay there.
       (goto-char begin)
-      ;;(gnus-Subject-display-article (gnus-Subject-article-number))
+      ;;(gnus-summary-display-article (gnus-summary-article-number))
       (message "No more unread articles")
       nil
       )
     ))
 
-(defun gnus-Subject-isearch-article ()
+(defun gnus-summary-isearch-article ()
   "Do incremental search forward on current article."
   (interactive)
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
-    (call-interactively 'isearch-forward)
-    ))
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
+                             (isearch-forward)))
 
-(defun gnus-Subject-search-article-forward (regexp)
+(defun gnus-summary-search-article-forward (regexp)
   "Search for an article containing REGEXP forward.
-`gnus-Select-article-hook' is not called during the search."
+`gnus-select-article-hook' is not called for articles examined
+by searching search."
   (interactive
    (list (read-string
          (concat "Search forward (regexp): "
@@ -2526,17 +3209,18 @@ NOTE: This command may not work with nnspool.el."
   (if (string-equal regexp "")
       (setq regexp (or gnus-last-search-regexp ""))
     (setq gnus-last-search-regexp regexp))
-  (if (gnus-Subject-search-article regexp nil)
-      (gnus-eval-in-buffer-window gnus-Article-buffer
+  (if (gnus-summary-search-article regexp nil)
+      (gnus-eval-in-buffer-window gnus-article-buffer
        (recenter 0)
        ;;(sit-for 1)
        )
     (error "Search failed: \"%s\"" regexp)
     ))
 
-(defun gnus-Subject-search-article-backward (regexp)
+(defun gnus-summary-search-article-backward (regexp)
   "Search for an article containing REGEXP backward.
-`gnus-Select-article-hook' is not called during the search."
+`gnus-select-article-hook' is not called for articles examined
+by searching search."
   (interactive
    (list (read-string
          (concat "Search backward (regexp): "
@@ -2545,44 +3229,45 @@ NOTE: This command may not work with nnspool.el."
   (if (string-equal regexp "")
       (setq regexp (or gnus-last-search-regexp ""))
     (setq gnus-last-search-regexp regexp))
-  (if (gnus-Subject-search-article regexp t)
-      (gnus-eval-in-buffer-window gnus-Article-buffer
+  (if (gnus-summary-search-article regexp t)
+      (gnus-eval-in-buffer-window gnus-article-buffer
        (recenter 0)
        ;;(sit-for 1)
        )
     (error "Search failed: \"%s\"" regexp)
     ))
 
-(defun gnus-Subject-search-article (regexp &optional backward)
+(defun gnus-summary-search-article (regexp &optional backward)
   "Search for an article containing REGEXP.
 Optional argument BACKWARD means do search for backward.
-`gnus-Select-article-hook' is not called during the search."
-  (let ((gnus-Select-article-hook nil) ;Disable hook.
-       (gnus-Mark-article-hook nil)    ;Inhibit marking as read.
+`gnus-select-article-hook' is not called for articles examined
+by searching search."
+  (let ((gnus-select-article-hook nil) ;Disable hook.
+       (gnus-mark-article-hook nil)    ;Inhibit marking as read.
        (re-search
         (if backward
             (function re-search-backward) (function re-search-forward)))
        (found nil)
        (last nil))
     ;; Hidden thread subtrees must be searched for ,too.
-    (gnus-Subject-show-all-threads)
+    (gnus-summary-show-all-threads)
     ;; First of all, search current article.
     ;; We don't want to read article again from NNTP server nor reset
     ;; current point.
-    (gnus-Subject-select-article)
+    (gnus-summary-select-article)
     (message "Searching article: %d..." gnus-current-article)
     (setq last gnus-current-article)
-    (gnus-eval-in-buffer-window gnus-Article-buffer
+    (gnus-eval-in-buffer-window gnus-article-buffer
       (save-restriction
        (widen)
        ;; Begin search from current point.
        (setq found (funcall re-search regexp nil t))))
     ;; Then search next articles.
     (while (and (not found)
-               (gnus-Subject-display-article 
-                (gnus-Subject-search-subject backward nil nil)))
+               (gnus-summary-display-article 
+                (gnus-summary-search-subject backward nil nil)))
       (message "Searching article: %d..." gnus-current-article)
-      (gnus-eval-in-buffer-window gnus-Article-buffer
+      (gnus-eval-in-buffer-window gnus-article-buffer
        (save-restriction
          (widen)
          (goto-char (if backward (point-max) (point-min)))
@@ -2596,8 +3281,8 @@ Optional argument BACKWARD means do search for backward.
     found
     ))
 
-(defun gnus-Subject-execute-command (field regexp command &optional backward)
-  "If FIELD of article header matches REGEXP, execute COMMAND string.
+(defun gnus-summary-execute-command (field regexp command &optional backward)
+  "If FIELD of article header matches REGEXP, execute COMMAND string.
 If FIELD is an empty string (or nil), entire article body is searched for.
 If optional (prefix) argument BACKWARD is non-nil, do backward instead."
   (interactive
@@ -2611,7 +3296,7 @@ If optional (prefix) argument BACKWARD is non-nil, do backward instead."
         (read-key-sequence "Command: ")
         current-prefix-arg))
   ;; Hidden thread subtrees must be searched for ,too.
-  (gnus-Subject-show-all-threads)
+  (gnus-summary-show-all-threads)
   ;; We don't want to change current point nor window configuration.
   (save-excursion
     (save-window-excursion
@@ -2621,33 +3306,33 @@ If optional (prefix) argument BACKWARD is non-nil, do backward instead."
                    (` (lambda ()
                         (call-interactively '(, (key-binding command)))))
                    backward)
-      (message "Executing %s... done" (key-description command)))))
+      (message "Executing %s...done" (key-description command)))))
 
-(defun gnus-Subject-beginning-of-article ()
-  "Go to beginning of article body"
+(defun gnus-summary-beginning-of-article ()
+  "Go to beginning of article body."
   (interactive)
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (widen)
     (beginning-of-buffer)
     (if gnus-break-pages
        (gnus-narrow-to-page))
     ))
 
-(defun gnus-Subject-end-of-article ()
-  "Go to end of article body"
+(defun gnus-summary-end-of-article ()
+  "Go to end of article body."
   (interactive)
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (widen)
     (end-of-buffer)
     (if gnus-break-pages
        (gnus-narrow-to-page))
     ))
 
-(defun gnus-Subject-goto-article (article &optional all-headers)
-  "Read ARTICLE if exists.
-Optional argument ALL-HEADERS means all headers are shown."
+(defun gnus-summary-goto-article (article &optional all-headers)
+  "Read article number ARTICLE if it exists.
+Optional argument ALL-HEADERS means show the full header."
   (interactive
    (list
     (string-to-int
@@ -2659,23 +3344,23 @@ Optional argument ALL-HEADERS means all headers are shown."
                           (int-to-string (nntp-header-number headers)))))
                       gnus-newsgroup-headers)
                      nil 'require-match))))
-  (if (gnus-Subject-goto-subject article)
-      (gnus-Subject-display-article article all-headers)))
+  (if (gnus-summary-goto-subject article)
+      (gnus-summary-display-article article all-headers)))
 
-(defun gnus-Subject-goto-last-article ()
+(defun gnus-summary-goto-last-article ()
   "Go to last subject line."
   (interactive)
   (if gnus-last-article
-      (gnus-Subject-goto-article gnus-last-article)))
+      (gnus-summary-goto-article gnus-last-article)))
 
-(defun gnus-Subject-show-article ()
+(defun gnus-summary-show-article ()
   "Force to show current article."
   (interactive)
   ;; The following is a trick to force to read the current article again.
   (setq gnus-have-all-headers (not gnus-have-all-headers))
-  (gnus-Subject-select-article (not gnus-have-all-headers) t))
+  (gnus-summary-select-article (not gnus-have-all-headers) t))
 
-(defun gnus-Subject-toggle-header (arg)
+(defun gnus-summary-toggle-header (arg)
   "Show original header if pruned header currently shown, or vice versa.
 With arg, show original header iff arg is positive."
   (interactive "P")
@@ -2684,21 +3369,33 @@ With arg, show original header iff arg is positive."
        (all-headers
         (if (null arg) (not gnus-have-all-headers)
           (> (prefix-numeric-value arg) 0))))
-    (gnus-Subject-select-article all-headers t)))
+    (gnus-summary-select-article all-headers t)))
 
-(defun gnus-Subject-show-all-headers ()
+(defun gnus-summary-show-all-headers ()
   "Show original article header."
   (interactive)
-  (gnus-Subject-select-article t t))
+  (gnus-summary-select-article t t))
 
-(defun gnus-Subject-stop-page-breaking ()
-  "Stop page breaking by linefeed temporary (Widen article buffer)."
+(defun gnus-summary-toggle-mime (arg)
+  "Toggle MIME processing.
+With arg, turn MIME processing on iff arg is positive."
+  (interactive "P")
+  (setq gnus-show-mime
+       (if (null arg) (not gnus-show-mime)
+         (> (prefix-numeric-value arg) 0)))
+  ;; The following is a trick to force to read the current article again.
+  (setq gnus-have-all-headers (not gnus-have-all-headers))
+  (gnus-summary-select-article (not gnus-have-all-headers) t))
+
+(defun gnus-summary-stop-page-breaking ()
+  "Stop page breaking by linefeed temporary (widen article buffer)."
   (interactive)
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
-    (widen)))
+  (gnus-summary-select-article)
+  (gnus-eval-in-buffer-window gnus-article-buffer
+    (widen)
+    ))
 
-(defun gnus-Subject-kill-same-subject-and-select (unmark)
+(defun gnus-summary-kill-same-subject-and-select (unmark)
   "Mark articles which has the same subject as read, and then select next.
 If argument UNMARK is positive, remove any kinds of marks.
 If argument UNMARK is negative, mark articles as unread instead."
@@ -2706,17 +3403,17 @@ If argument UNMARK is negative, mark articles as unread instead."
   (if unmark
       (setq unmark (prefix-numeric-value unmark)))
   (let ((count
-        (gnus-Subject-mark-same-subject
-         (gnus-Subject-subject-string) unmark)))
-    ;; Select next unread article. If auto-select-same mode, should
+        (gnus-summary-mark-same-subject
+         (gnus-summary-subject-string) unmark)))
+    ;; Select next unread article.  If auto-select-same mode, should
     ;; select the first unread article.
-    (gnus-Subject-next-article t (and gnus-auto-select-same
-                                     (gnus-Subject-subject-string)))
+    (gnus-summary-next-article t (and gnus-auto-select-same
+                                     (gnus-summary-subject-string)))
     (message "%d articles are marked as %s"
             count (if unmark "unread" "read"))
     ))
 
-(defun gnus-Subject-kill-same-subject (unmark)
+(defun gnus-summary-kill-same-subject (unmark)
   "Mark articles which has the same subject as read. 
 If argument UNMARK is positive, remove any kinds of marks.
 If argument UNMARK is negative, mark articles as unread instead."
@@ -2724,161 +3421,160 @@ If argument UNMARK is negative, mark articles as unread instead."
   (if unmark
       (setq unmark (prefix-numeric-value unmark)))
   (let ((count
-        (gnus-Subject-mark-same-subject
-         (gnus-Subject-subject-string) unmark)))
+        (gnus-summary-mark-same-subject
+         (gnus-summary-subject-string) unmark)))
     ;; If marked as read, go to next unread subject.
     (if (null unmark)
        ;; Go to next unread subject.
-       (gnus-Subject-next-subject 1 t))
+       (gnus-summary-next-subject 1 t))
     (message "%d articles are marked as %s"
             count (if unmark "unread" "read"))
     ))
 
-(defun gnus-Subject-mark-same-subject (subject &optional unmark)
+(defun gnus-summary-mark-same-subject (subject &optional unmark)
   "Mark articles with same SUBJECT as read, and return marked number.
 If optional argument UNMARK is positive, remove any kinds of marks.
 If optional argument UNMARK is negative, mark articles as unread instead."
   (let ((count 1))
     (save-excursion
       (cond ((null unmark)
-            (gnus-Subject-mark-as-read nil "K"))
+            (gnus-summary-mark-as-read nil "K"))
            ((> unmark 0)
-            (gnus-Subject-mark-as-unread nil t))
+            (gnus-summary-mark-as-unread nil t))
            (t
-            (gnus-Subject-mark-as-unread)))
+            (gnus-summary-mark-as-unread)))
       (while (and subject
-                 (gnus-Subject-search-forward nil subject))
+                 (gnus-summary-search-forward nil subject))
        (cond ((null unmark)
-              (gnus-Subject-mark-as-read nil "K"))
+              (gnus-summary-mark-as-read nil "K"))
              ((> unmark 0)
-              (gnus-Subject-mark-as-unread nil t))
+              (gnus-summary-mark-as-unread nil t))
              (t
-              (gnus-Subject-mark-as-unread)))
+              (gnus-summary-mark-as-unread)))
        (setq count (1+ count))
        ))
     ;; Hide killed thread subtrees.  Does not work properly always.
     ;;(and (null unmark)
     ;;     gnus-thread-hide-killed
-    ;;    (gnus-Subject-hide-thread))
+    ;;    (gnus-summary-hide-thread))
     ;; Return number of articles marked as read.
     count
     ))
 
-(defun gnus-Subject-mark-as-unread-forward (count)
+(defun gnus-summary-mark-as-unread-forward (count)
   "Mark current article as unread, and then go forward.
 Argument COUNT specifies number of articles marked as unread."
   (interactive "p")
   (while (> count 0)
-    (gnus-Subject-mark-as-unread nil nil)
-    (gnus-Subject-next-subject 1 nil)
+    (gnus-summary-mark-as-unread nil nil)
+    (gnus-summary-next-subject 1 nil)
     (setq count (1- count))))
 
-(defun gnus-Subject-mark-as-unread-backward (count)
+(defun gnus-summary-mark-as-unread-backward (count)
   "Mark current article as unread, and then go backward.
 Argument COUNT specifies number of articles marked as unread."
   (interactive "p")
   (while (> count 0)
-    (gnus-Subject-mark-as-unread nil nil)
-    (gnus-Subject-prev-subject 1 nil)
+    (gnus-summary-mark-as-unread nil nil)
+    (gnus-summary-prev-subject 1 nil)
     (setq count (1- count))))
 
-(defun gnus-Subject-mark-as-unread (&optional article clear-mark)
+(defun gnus-summary-mark-as-unread (&optional article clear-mark)
   "Mark current article as unread.
-Optional first argument ARTICLE specifies article number to be
-marked as unread.  Optional second argument CLEAR-MARK removes
-any kind of mark."
+Optional 1st argument ARTICLE specifies article number to be marked as unread.
+Optional 2nd argument CLEAR-MARK remove any kinds of mark."
   (save-excursion
-    (set-buffer gnus-Subject-buffer)
+    (set-buffer gnus-summary-buffer)
     ;; First of all, show hidden thread subtrees.
-    (gnus-Subject-show-thread)
+    (gnus-summary-show-thread)
     (let* ((buffer-read-only nil)
-          (current (gnus-Subject-article-number))
+          (current (gnus-summary-article-number))
           (article (or article current)))
       (gnus-mark-article-as-unread article clear-mark)
       (if (or (eq article current)
-             (gnus-Subject-goto-subject article))
+             (gnus-summary-goto-subject article))
          (progn
            (beginning-of-line)
            (delete-char 1)
            (insert (if clear-mark " " "-"))))
       )))
 
-(defun gnus-Subject-mark-as-read-forward (count)
+(defun gnus-summary-mark-as-read-forward (count)
   "Mark current article as read, and then go forward.
-Argument COUNT specifies number of articles marked as read"
+Argument COUNT specifies number of articles marked as read."
   (interactive "p")
   (while (> count 0)
-    (gnus-Subject-mark-as-read)
-    (gnus-Subject-next-subject 1 'unread-only)
+    (gnus-summary-mark-as-read)
+    (gnus-summary-next-subject 1 'unread-only)
     (setq count (1- count))))
 
-(defun gnus-Subject-mark-as-read-backward (count)
+(defun gnus-summary-mark-as-read-backward (count)
   "Mark current article as read, and then go backward.
-Argument COUNT specifies number of articles marked as read"
+Argument COUNT specifies number of articles marked as read."
   (interactive "p")
   (while (> count 0)
-    (gnus-Subject-mark-as-read)
-    (gnus-Subject-prev-subject 1 'unread-only)
+    (gnus-summary-mark-as-read)
+    (gnus-summary-prev-subject 1 'unread-only)
     (setq count (1- count))))
 
-(defun gnus-Subject-mark-as-read (&optional article mark)
+(defun gnus-summary-mark-as-read (&optional article mark)
   "Mark current article as read.
-Optional first argument ARTICLE specifies article number to be marked as read.
-Optional second argument MARK specifies a string inserted at beginning of line.
+Optional 1st argument ARTICLE specifies article number to be marked as read.
+Optional 2nd argument MARK specifies a string inserted at beginning of line.
 Any kind of string (length 1) except for a space and `-' is ok."
   (save-excursion
-    (set-buffer gnus-Subject-buffer)
+    (set-buffer gnus-summary-buffer)
     ;; First of all, show hidden thread subtrees.
-    (gnus-Subject-show-thread)
+    (gnus-summary-show-thread)
     (let* ((buffer-read-only nil)
           (mark (or mark "D"))         ;Default mark is `D'.
-          (current (gnus-Subject-article-number))
+          (current (gnus-summary-article-number))
           (article (or article current)))
       (gnus-mark-article-as-read article)
       (if (or (eq article current)
-             (gnus-Subject-goto-subject article))
+             (gnus-summary-goto-subject article))
          (progn
            (beginning-of-line)
            (delete-char 1)
            (insert mark)))
       )))
 
-(defun gnus-Subject-clear-mark-forward (count)
+(defun gnus-summary-clear-mark-forward (count)
   "Remove current article's mark, and go forward.
-Argument COUNT specifies number of articles unmarked"
+Argument COUNT specifies number of articles unmarked."
   (interactive "p")
   (while (> count 0)
-    (gnus-Subject-mark-as-unread nil t)
-    (gnus-Subject-next-subject 1 nil)
+    (gnus-summary-mark-as-unread nil t)
+    (gnus-summary-next-subject 1 nil)
     (setq count (1- count))))
 
-(defun gnus-Subject-clear-mark-backward (count)
+(defun gnus-summary-clear-mark-backward (count)
   "Remove current article's mark, and go backward.
-Argument COUNT specifies number of articles unmarked"
+Argument COUNT specifies number of articles unmarked."
   (interactive "p")
   (while (> count 0)
-    (gnus-Subject-mark-as-unread nil t)
-    (gnus-Subject-prev-subject 1 nil)
+    (gnus-summary-mark-as-unread nil t)
+    (gnus-summary-prev-subject 1 nil)
     (setq count (1- count))))
 
-(defun gnus-Subject-delete-marked-as-read ()
-  "Delete lines which are marked as read."
+(defun gnus-summary-delete-marked-as-read ()
+  "Delete summary lines for articles that are marked as read."
   (interactive)
   (if gnus-newsgroup-unreads
       (let ((buffer-read-only nil))
        (save-excursion
          (goto-char (point-min))
-         (delete-non-matching-lines "^[ ---]"))
+         (delete-non-matching-lines "^[]"))
        ;; Adjust point.
        (if (eobp)
-           (gnus-Subject-prev-subject 1)
+           (gnus-summary-prev-subject 1)
          (beginning-of-line)
          (search-forward ":" nil t)))
     ;; It is not so good idea to make the buffer empty.
     (message "All articles are marked as read")
     ))
 
-(defun gnus-Subject-delete-marked-with (marks)
+(defun gnus-summary-delete-marked-with (marks)
   "Delete lines which are marked with MARKS (e.g. \"DK\")."
   (interactive "sMarks: ")
   (let ((buffer-read-only nil))
@@ -2888,26 +3584,26 @@ Argument COUNT specifies number of articles unmarked"
     ;; Adjust point.
     (or (zerop (buffer-size))
        (if (eobp)
-           (gnus-Subject-prev-subject 1)
+           (gnus-summary-prev-subject 1)
          (beginning-of-line)
          (search-forward ":" nil t)))
     ))
 
 ;; Thread-based commands.
 
-(defun gnus-Subject-toggle-threads (arg)
+(defun gnus-summary-toggle-threads (arg)
   "Toggle showing conversation threads.
 With arg, turn showing conversation threads on iff arg is positive."
   (interactive "P")
-  (let ((current (gnus-Subject-article-number)))
+  (let ((current (gnus-summary-article-number)))
     (setq gnus-show-threads
          (if (null arg) (not gnus-show-threads)
            (> (prefix-numeric-value arg) 0)))
-    (gnus-Subject-prepare)
-    (gnus-Subject-goto-subject current)
+    (gnus-summary-prepare)
+    (gnus-summary-goto-subject current)
     ))
 
-(defun gnus-Subject-show-all-threads ()
+(defun gnus-summary-show-all-threads ()
   "Show all thread subtrees."
   (interactive)
   (if gnus-show-threads
@@ -2916,7 +3612,7 @@ With arg, turn showing conversation threads on iff arg is positive."
          (subst-char-in-region (point-min) (point-max) ?\^M ?\n t)
          ))))
 
-(defun gnus-Subject-show-thread ()
+(defun gnus-summary-show-thread ()
   "Show thread subtrees."
   (interactive)
   (if gnus-show-threads
@@ -2929,7 +3625,7 @@ With arg, turn showing conversation threads on iff arg is positive."
                                ?\^M ?\n t)
          ))))
 
-(defun gnus-Subject-hide-all-threads ()
+(defun gnus-summary-hide-all-threads ()
   "Hide all thread subtrees."
   (interactive)
   (if gnus-show-threads
@@ -2938,13 +3634,13 @@ With arg, turn showing conversation threads on iff arg is positive."
        (goto-char (point-min))
        (search-forward ":" nil t)
        (let ((level (current-column)))
-         (gnus-Subject-hide-thread)
-         (while (gnus-Subject-search-forward)
+         (gnus-summary-hide-thread)
+         (while (gnus-summary-search-forward)
            (and (>= level (current-column))
-                (gnus-Subject-hide-thread)))
+                (gnus-summary-hide-thread)))
          ))))
 
-(defun gnus-Subject-hide-thread ()
+(defun gnus-summary-hide-thread ()
   "Hide thread subtrees."
   (interactive)
   (if gnus-show-threads
@@ -2956,7 +3652,7 @@ With arg, turn showing conversation threads on iff arg is positive."
              (init (point))
              (last (point))
              (level (current-column)))
-         (while (and (gnus-Subject-search-forward)
+         (while (and (gnus-summary-search-forward)
                      (< level (current-column)))
            ;; Interested in lower levels.
            (if (< level (current-column))
@@ -2967,7 +3663,7 @@ With arg, turn showing conversation threads on iff arg is positive."
          (subst-char-in-region init last ?\n ?\^M t)
          ))))
 
-(defun gnus-Subject-next-thread (n)
+(defun gnus-summary-next-thread (n)
   "Go to the same level next thread.
 Argument N specifies the number of threads."
   (interactive "p")
@@ -2978,7 +3674,7 @@ Argument N specifies the number of threads."
        (last (point))
        (level (current-column)))
     (while (and (> n 0)
-               (gnus-Subject-search-forward)
+               (gnus-summary-search-forward)
                (<= level (current-column)))
       ;; We have to skip lower levels.
       (if (= level (current-column))
@@ -2992,7 +3688,7 @@ Argument N specifies the number of threads."
       (goto-char last))
     ))
 
-(defun gnus-Subject-prev-thread (n)
+(defun gnus-summary-prev-thread (n)
   "Go to the same level previous thread.
 Argument N specifies the number of threads."
   (interactive "p")
@@ -3003,7 +3699,7 @@ Argument N specifies the number of threads."
        (last (point))
        (level (current-column)))
     (while (and (> n 0)
-               (gnus-Subject-search-backward)
+               (gnus-summary-search-backward)
                (<= level (current-column)))
       ;; We have to skip lower levels.
       (if (= level (current-column))
@@ -3017,7 +3713,7 @@ Argument N specifies the number of threads."
       (goto-char last))
     ))
 
-(defun gnus-Subject-down-thread (d)
+(defun gnus-summary-down-thread (d)
   "Go downward current thread.
 Argument D specifies the depth goes down."
   (interactive "p")
@@ -3027,7 +3723,7 @@ Argument D specifies the depth goes down."
   (let ((last (point))
        (level (current-column)))
     (while (and (> d 0)
-               (gnus-Subject-search-forward)
+               (gnus-summary-search-forward)
                (<= level (current-column))) ;<= can be <.  Which do you like?
       ;; We have to skip the same levels.
       (if (< level (current-column))
@@ -3040,7 +3736,7 @@ Argument D specifies the depth goes down."
     (goto-char last)
     ))
 
-(defun gnus-Subject-up-thread (d)
+(defun gnus-summary-up-thread (d)
   "Go upward current thread.
 Argument D specifies the depth goes up."
   (interactive "p")
@@ -3050,7 +3746,7 @@ Argument D specifies the depth goes up."
   (let ((last (point))
        (level (current-column)))
     (while (and (> d 0)
-               (gnus-Subject-search-backward))
+               (gnus-summary-search-backward))
       ;; We have to skip the same levels.
       (if (> level (current-column))
          (progn
@@ -3062,7 +3758,7 @@ Argument D specifies the depth goes up."
     (goto-char last)
     ))
 
-(defun gnus-Subject-kill-thread (unmark)
+(defun gnus-summary-kill-thread (unmark)
   "Mark articles under current thread as read.
 If argument UNMARK is positive, remove any kinds of marks.
 If argument UNMARK is negative, mark articles as unread instead."
@@ -3076,121 +3772,136 @@ If argument UNMARK is negative, mark articles as unread instead."
     (let ((level (current-column)))
       ;; Mark current article.
       (cond ((null unmark)
-            (gnus-Subject-mark-as-read nil "K"))
+            (gnus-summary-mark-as-read nil "K"))
            ((> unmark 0)
-            (gnus-Subject-mark-as-unread nil t))
+            (gnus-summary-mark-as-unread nil t))
            (t
-            (gnus-Subject-mark-as-unread))
+            (gnus-summary-mark-as-unread))
            )
       ;; Mark following articles.
-      (while (and (gnus-Subject-search-forward)
+      (while (and (gnus-summary-search-forward)
                  (< level (current-column)))
        (cond ((null unmark)
-              (gnus-Subject-mark-as-read nil "K"))
+              (gnus-summary-mark-as-read nil "K"))
              ((> unmark 0)
-              (gnus-Subject-mark-as-unread nil t))
+              (gnus-summary-mark-as-unread nil t))
              (t
-              (gnus-Subject-mark-as-unread))
+              (gnus-summary-mark-as-unread))
              ))
       ))
   ;; Hide killed subtrees.
   (and (null unmark)
        gnus-thread-hide-killed
-       (gnus-Subject-hide-thread))
+       (gnus-summary-hide-thread))
   ;; If marked as read, go to next unread subject.
   (if (null unmark)
       ;; Go to next unread subject.
-      (gnus-Subject-next-subject 1 t))
+      (gnus-summary-next-subject 1 t))
   )
 
-(defun gnus-Subject-toggle-truncation (arg)
-  "Toggle truncation of subject lines.
-With ARG, turn line truncation on iff ARG is positive."
+(defun gnus-summary-toggle-truncation (arg)
+  "Toggle truncation of summary lines.
+With arg, turn line truncation on iff arg is positive."
   (interactive "P")
   (setq truncate-lines
        (if (null arg) (not truncate-lines)
          (> (prefix-numeric-value arg) 0)))
   (redraw-display))
 
-(defun gnus-Subject-sort-by-number (reverse)
-  "Sort subject display buffer by article number.
+(defun gnus-summary-sort-by-number (reverse)
+  "Sort Summary buffer by article number.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-Subject-sort-subjects
+  (gnus-summary-keysort-summary
+   (function <)
    (function
-    (lambda (a b)
-      (< (nntp-header-number a) (nntp-header-number b))))
+    (lambda (a)
+      (nntp-header-number a)))
    reverse
    ))
 
-(defun gnus-Subject-sort-by-author (reverse)
-  "Sort subject display buffer by author name alphabetically.
+(defun gnus-summary-sort-by-author (reverse)
+  "Sort Summary buffer by author name alphabetically.
 If case-fold-search is non-nil, case of letters is ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-Subject-sort-subjects
+  (gnus-summary-keysort-summary
+   (function string-lessp)
    (function
-    (lambda (a b)
-      (gnus-string-lessp (nntp-header-from a) (nntp-header-from b))))
+    (lambda (a)
+      (if case-fold-search
+         (downcase (nntp-header-from a))
+       (nntp-header-from a))))
    reverse
    ))
 
-(defun gnus-Subject-sort-by-subject (reverse)
-  "Sort subject display buffer by subject alphabetically. `Re:'s are ignored.
+(defun gnus-summary-sort-by-subject (reverse)
+  "Sort Summary buffer by subject alphabetically.  `Re:'s are ignored.
 If case-fold-search is non-nil, case of letters is ignored.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-Subject-sort-subjects
+  (gnus-summary-keysort-summary
+   (function string-lessp)
    (function
-    (lambda (a b)
-      (gnus-string-lessp
-       (gnus-simplify-subject (nntp-header-subject a) 're-only)
-       (gnus-simplify-subject (nntp-header-subject b) 're-only))))
+    (lambda (a)
+      (if case-fold-search
+         (downcase (gnus-simplify-subject (nntp-header-subject a) 're-only))
+       (gnus-simplify-subject (nntp-header-subject a) 're-only))))
    reverse
    ))
 
-(defun gnus-Subject-sort-by-date (reverse)
-  "Sort subject display buffer by posted date.
+(defun gnus-summary-sort-by-date (reverse)
+  "Sort Summary buffer by date.
 Argument REVERSE means reverse order."
   (interactive "P")
-  (gnus-Subject-sort-subjects
+  (gnus-summary-keysort-summary
+   (function string-lessp)
    (function
-    (lambda (a b)
-      (gnus-date-lessp (nntp-header-date a) (nntp-header-date b))))
+    (lambda (a)
+      (gnus-sortable-date (nntp-header-date a))))
    reverse
    ))
 
-(defun gnus-Subject-sort-subjects (predicate &optional reverse)
-  "Sort subject display buffer by PREDICATE.
+(defun gnus-summary-keysort-summary (predicate key &optional reverse)
+  "Sort Summary buffer by PREDICATE using a value passed by KEY.
 Optional argument REVERSE means reverse order."
-  (let ((current (gnus-Subject-article-number)))
+  (let ((current (gnus-summary-article-number)))
+    (gnus-keysort-headers predicate key reverse)
+    (gnus-summary-prepare)
+    (gnus-summary-goto-subject current)
+    ))
+
+(defun gnus-summary-sort-summary (predicate &optional reverse)
+  "Sort Summary buffer by PREDICATE.
+Optional argument REVERSE means reverse order."
+  (let ((current (gnus-summary-article-number)))
     (gnus-sort-headers predicate reverse)
-    (gnus-Subject-prepare)
-    (gnus-Subject-goto-subject current)
+    (gnus-summary-prepare)
+    (gnus-summary-goto-subject current)
     ))
 
-(defun gnus-Subject-reselect-current-group (show-all)
+(defun gnus-summary-reselect-current-group (show-all)
   "Once exit and then reselect the current newsgroup.
 Prefix argument SHOW-ALL means to select all articles."
   (interactive "P")
-  (let ((current-subject (gnus-Subject-article-number)))
-    (gnus-Subject-exit t)
+  (let ((current-subject (gnus-summary-article-number)))
+    (gnus-summary-exit t)
     ;; We have to adjust the point of Group mode buffer because the
     ;; current point was moved to the next unread newsgroup by
     ;; exiting.
-    (gnus-Subject-jump-to-group gnus-newsgroup-name)
-    (gnus-Group-read-group show-all t)
-    (gnus-Subject-goto-subject current-subject)
+    (gnus-summary-jump-to-group gnus-newsgroup-name)
+    (gnus-group-read-group show-all t)
+    (gnus-summary-goto-subject current-subject)
     ))
 
-(defun gnus-Subject-caesar-message (rotnum)
+(defun gnus-summary-caesar-message (rotnum)
   "Caesar rotates all letters of current message by 13/47 places.
 With prefix arg, specifies the number of places to rotate each letter forward.
 Caesar rotates Japanese letters by 47 places in any case."
   (interactive "P")
-  (gnus-Subject-select-article)
+  (gnus-summary-select-article)
   (gnus-overload-functions)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (save-restriction
       (widen)
       ;; We don't want to jump to the beginning of the message.
@@ -3203,26 +3914,25 @@ Caesar rotates Japanese letters by 47 places in any case."
        ))
     ))
 
-(defun gnus-Subject-rmail-digest ()
+(defun gnus-summary-rmail-digest ()
   "Run RMAIL on current digest article.
-`gnus-Select-digest-hook' will be called with no arguments, if that
+`gnus-select-digest-hook' will be called with no arguments, if that
 value is non-nil.  It is possible to modify the article so that Rmail
 can work with it.
-
-`gnus-Rmail-digest-hook' will be called with no arguments, if that value
+`gnus-rmail-digest-hook' will be called with no arguments, if that value
 is non-nil.  The hook is intended to customize Rmail mode."
   (interactive)
-  (gnus-Subject-select-article)
+  (gnus-summary-select-article)
   (require 'rmail)
-  (let ((artbuf gnus-Article-buffer)
-       (digbuf (get-buffer-create gnus-Digest-buffer))
+  (let ((artbuf gnus-article-buffer)
+       (digbuf (get-buffer-create gnus-digest-buffer))
        (mail-header-separator ""))
     (set-buffer digbuf)
     (buffer-flush-undo (current-buffer))
     (setq buffer-read-only nil)
     (erase-buffer)
     (insert-buffer-substring artbuf)
-    (run-hooks 'gnus-Select-digest-hook)
+    (run-hooks 'gnus-select-digest-hook)
     (gnus-convert-article-to-rmail)
     (goto-char (point-min))
     ;; Rmail initializations.
@@ -3248,13 +3958,13 @@ is non-nil.  The hook is intended to customize Rmail mode."
                         (message "(No changes need to be saved)")
                         'no-need-to-write-this-buffer))))
          ;; Default file name saving digest messages.
-         (setq rmail-last-rmail-file
+         (setq rmail-default-rmail-file
                (funcall gnus-rmail-save-name
                         gnus-newsgroup-name
                         gnus-current-headers
                         gnus-newsgroup-last-rmail
                         ))
-         (setq rmail-last-file
+         (setq rmail-default-file
                (funcall gnus-mail-save-name
                         gnus-newsgroup-name
                         gnus-current-headers
@@ -3262,33 +3972,33 @@ is non-nil.  The hook is intended to customize Rmail mode."
                         ))
          ;; Prevent generating new buffer named ***<N> each time.
          (setq rmail-summary-buffer
-               (get-buffer-create gnus-Digest-summary-buffer))
-         (run-hooks 'gnus-Rmail-digest-hook)
+               (get-buffer-create gnus-digest-summary-buffer))
+         (run-hooks 'gnus-rmail-digest-hook)
          ;; Take all windows safely.
          (gnus-configure-windows '(1 0 0))
-         (pop-to-buffer gnus-Group-buffer)
-         ;; Use Subject and Article windows for Digest summary and
+         (pop-to-buffer gnus-group-buffer)
+         ;; Use Summary Article windows for Digest summary and
          ;; Digest buffers.
          (if gnus-digest-show-summary
-             (let ((gnus-Subject-buffer gnus-Digest-summary-buffer)
-                   (gnus-Article-buffer gnus-Digest-buffer))
-               (gnus-configure-windows 'SelectArticle)
-               (pop-to-buffer gnus-Digest-buffer)
+             (let ((gnus-summary-buffer gnus-digest-summary-buffer)
+                   (gnus-article-buffer gnus-digest-buffer))
+               (gnus-configure-windows 'article)
+               (pop-to-buffer gnus-digest-buffer)
                (rmail-summary)
-               (pop-to-buffer gnus-Digest-summary-buffer)
+               (pop-to-buffer gnus-digest-summary-buffer)
                (message (substitute-command-keys
                          "Type \\[rmail-summary-quit] to return to GNUS")))
-           (let ((gnus-Subject-buffer gnus-Digest-buffer))
-             (gnus-configure-windows 'ExpandSubject)
-             (pop-to-buffer gnus-Digest-buffer)
+           (let ((gnus-summary-buffer gnus-digest-buffer))
+             (gnus-configure-windows 'summary)
+             (pop-to-buffer gnus-digest-buffer)
              (message (substitute-command-keys
                        "Type \\[rmail-quit] to return to GNUS")))
            )
          ;; Move the buffers to the end of buffer list.
-         (bury-buffer gnus-Article-buffer)
-         (bury-buffer gnus-Group-buffer)
-         (bury-buffer gnus-Digest-summary-buffer)
-         (bury-buffer gnus-Digest-buffer))
+         (bury-buffer gnus-article-buffer)
+         (bury-buffer gnus-group-buffer)
+         (bury-buffer gnus-digest-summary-buffer)
+         (bury-buffer gnus-digest-buffer))
       (error (set-buffer-modified-p nil)
             (kill-buffer digbuf)
             ;; This command should not signal an error because the
@@ -3296,25 +4006,23 @@ is non-nil.  The hook is intended to customize Rmail mode."
             (ding) (message "Article is not a digest")))
     ))
 
-(defun gnus-Subject-save-article ()
+(defun gnus-summary-save-article ()
   "Save this article using default saver function.
-Variable `gnus-default-article-saver' specifies the saver function."
+The variable `gnus-default-article-saver' specifies the saver function."
   (interactive)
-  (gnus-Subject-select-article
-   (not (null gnus-save-all-headers)) gnus-save-all-headers)
+  (gnus-summary-select-article gnus-save-all-headers gnus-save-all-headers)
   (if gnus-default-article-saver
       (call-interactively gnus-default-article-saver)
     (error "No default saver is defined.")))
 
-(defun gnus-Subject-save-in-rmail (&optional filename)
+(defun gnus-summary-save-in-rmail (&optional filename)
   "Append this article to Rmail file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory' which
 is initialized from the SAVEDIR environment variable."
   (interactive)
-  (gnus-Subject-select-article
-   (not (null gnus-save-all-headers)) gnus-save-all-headers)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article gnus-save-all-headers gnus-save-all-headers)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (save-excursion
       (save-restriction
        (widen)
@@ -3339,15 +4047,14 @@ is initialized from the SAVEDIR environment variable."
          )))
     ))
 
-(defun gnus-Subject-save-in-mail (&optional filename)
+(defun gnus-summary-save-in-mail (&optional filename)
   "Append this article to Unix mail file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory' which
 is initialized from the SAVEDIR environment variable."
   (interactive)
-  (gnus-Subject-select-article
-   (not (null gnus-save-all-headers)) gnus-save-all-headers)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article gnus-save-all-headers gnus-save-all-headers)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (save-excursion
       (save-restriction
        (widen)
@@ -3365,22 +4072,27 @@ is initialized from the SAVEDIR environment variable."
                             ") ")
                     (file-name-directory default-name)
                     default-name)))
+         (setq filename
+               (expand-file-name filename
+                                 (and default-name
+                                      (file-name-directory default-name))))
          (gnus-make-directory (file-name-directory filename))
-         (rmail-output filename)
+         (if (and (file-readable-p filename) (rmail-file-p filename))
+             (gnus-output-to-rmail filename)
+           (rmail-output filename 1 t t))
          ;; Remember the directory name to save articles.
          (setq gnus-newsgroup-last-mail filename)
          )))
     ))
 
-(defun gnus-Subject-save-in-file (&optional filename)
+(defun gnus-summary-save-in-file (&optional filename)
   "Append this article to file.
 Optional argument FILENAME specifies file name.
 Directory to save to is default to `gnus-article-save-directory' which
 is initialized from the SAVEDIR environment variable."
   (interactive)
-  (gnus-Subject-select-article
-   (not (null gnus-save-all-headers)) gnus-save-all-headers)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article gnus-save-all-headers gnus-save-all-headers)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (save-excursion
       (save-restriction
        (widen)
@@ -3405,13 +4117,12 @@ is initialized from the SAVEDIR environment variable."
          )))
     ))
 
-(defun gnus-Subject-save-in-folder (&optional folder)
+(defun gnus-summary-save-in-folder (&optional folder)
   "Save this article to MH folder (using `rcvstore' in MH library).
 Optional argument FOLDER specifies folder name."
   (interactive)
-  (gnus-Subject-select-article
-   (not (null gnus-save-all-headers)) gnus-save-all-headers)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  (gnus-summary-select-article gnus-save-all-headers gnus-save-all-headers)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (save-restriction
       (widen)
       ;; Thanks to yuki@flab.Fujitsu.JUNET and ohm@kaba.junet.
@@ -3440,12 +4151,14 @@ Optional argument FOLDER specifies folder name."
        ))
     ))
 
-(defun gnus-Subject-pipe-output ()
+(defun gnus-summary-pipe-output ()
   "Pipe this article to subprocess."
   (interactive)
   ;; Ignore `gnus-save-all-headers' since this is not save command.
-  (gnus-Subject-select-article)
-  (gnus-eval-in-buffer-window gnus-Article-buffer
+  ;;(gnus-summary-select-article)
+  ;; Huuum.  Is this right?
+  (gnus-summary-select-article gnus-save-all-headers gnus-save-all-headers)
+  (gnus-eval-in-buffer-window gnus-article-buffer
     (save-restriction
       (widen)
       (let ((command (read-string "Shell command on article: "
@@ -3457,11 +4170,12 @@ Optional argument FOLDER specifies folder name."
        ))
     ))
 
-(defun gnus-Subject-catch-up (all &optional quietly)
+(defun gnus-summary-catchup (all &optional quietly)
   "Mark all articles not marked as unread in this newsgroup as read.
 If prefix argument ALL is non-nil, all articles are marked as read."
   (interactive "P")
   (if (or quietly
+         (not gnus-interactive-catchup) ;Without confirmation?
          (y-or-n-p
           (if all
               "Do you really want to mark everything as read? "
@@ -3470,22 +4184,35 @@ If prefix argument ALL is non-nil, all articles are marked as read."
             (gnus-set-difference gnus-newsgroup-unreads
                                  (if (not all) gnus-newsgroup-marked))))
         (message "")                   ;Erase "Yes or No" question.
+       ;; Hidden thread subtrees must be searched for ,too.
+       (gnus-summary-show-all-threads)
        (while unmarked
-          (gnus-Subject-mark-as-read (car unmarked) "C")
+          (gnus-summary-mark-as-read (car unmarked) "C")
          (setq unmarked (cdr unmarked))
          ))
     ))
 
-(defun gnus-Subject-catch-up-all (&optional quietly)
+(defun gnus-summary-catchup-to-here ()
+  "Mark all articles before the current one in this newsgroup as read."
+  (interactive)
+  (beginning-of-line)
+  (let ((current (gnus-summary-article-number)))
+       (beginning-of-buffer)
+       (while (not (= (gnus-summary-article-number) current))
+         (gnus-summary-mark-as-read)
+         (gnus-summary-next-subject 1))))
+
+(defun gnus-summary-catchup-all (&optional quietly)
   "Mark all articles in this newsgroup as read."
   (interactive)
-  (gnus-Subject-catch-up t quietly))
+  (gnus-summary-catchup t quietly))
 
-(defun gnus-Subject-catch-up-and-exit (all &optional quietly)
+(defun gnus-summary-catchup-and-exit (all &optional quietly)
   "Mark all articles not marked as unread in this newsgroup as read, then exit.
 If prefix argument ALL is non-nil, all articles are marked as read."
   (interactive "P")
   (if (or quietly
+         (not gnus-interactive-catchup) ;Without confirmation?
          (y-or-n-p
           (if all
               "Do you really want to mark everything as read? "
@@ -3500,46 +4227,46 @@ If prefix argument ALL is non-nil, all articles are marked as read."
        ;; Select next newsgroup or exit.
        (cond ((eq gnus-auto-select-next 'quietly)
               ;; Select next newsgroup quietly.
-              (gnus-Subject-next-group nil))
+              (gnus-summary-next-group nil))
              (t
-              (gnus-Subject-exit)))
+              (gnus-summary-exit)))
        )))
 
-(defun gnus-Subject-catch-up-all-and-exit (&optional quietly)
+(defun gnus-summary-catchup-all-and-exit (&optional quietly)
   "Mark all articles in this newsgroup as read, and then exit."
   (interactive)
-  (gnus-Subject-catch-up-and-exit t quietly))
+  (gnus-summary-catchup-and-exit t quietly))
 
-(defun gnus-Subject-edit-global-kill ()
+(defun gnus-summary-edit-global-kill ()
   "Edit a global KILL file."
   (interactive)
-  (setq gnus-current-kill-article (gnus-Subject-article-number))
-  (gnus-Kill-file-edit-file nil)       ;Nil stands for global KILL file.
+  (setq gnus-current-kill-article (gnus-summary-article-number))
+  (gnus-kill-file-edit-file nil)       ;Nil stands for global KILL file.
   (message
    (substitute-command-keys
-    "Editing a global KILL file (Type \\[gnus-Kill-file-exit] to exit)")))
+    "Editing a global KILL file (Type \\[gnus-kill-file-exit] to exit)")))
 
-(defun gnus-Subject-edit-local-kill ()
+(defun gnus-summary-edit-local-kill ()
   "Edit a local KILL file applied to the current newsgroup."
   (interactive)
-  (setq gnus-current-kill-article (gnus-Subject-article-number))
-  (gnus-Kill-file-edit-file gnus-newsgroup-name)
+  (setq gnus-current-kill-article (gnus-summary-article-number))
+  (gnus-kill-file-edit-file gnus-newsgroup-name)
   (message
    (substitute-command-keys
-    "Editing a local KILL file (Type \\[gnus-Kill-file-exit] to exit)")))
+    "Editing a local KILL file (Type \\[gnus-kill-file-exit] to exit)")))
 
-(defun gnus-Subject-exit (&optional temporary)
+(defun gnus-summary-exit (&optional temporary)
   "Exit reading current newsgroup, and then return to group selection mode.
-gnus-Exit-group-hook is called with no arguments if that value is non-nil."
+`gnus-exit-group-hook' is called with no arguments if that value is non-nil."
   (interactive)
   (let ((updated nil)
        (gnus-newsgroup-headers gnus-newsgroup-headers)
        (gnus-newsgroup-unreads gnus-newsgroup-unreads)
        (gnus-newsgroup-unselected gnus-newsgroup-unselected)
        (gnus-newsgroup-marked gnus-newsgroup-marked))
-    ;; Important internal variables are save, so we can reenter
-    ;; Subject Mode buffer even if hook changes them.
-    (run-hooks 'gnus-Exit-group-hook)
+    ;; Important internal variables are saved, so we can reenter
+    ;; Summary buffer even if hook changes them.
+    (run-hooks 'gnus-exit-group-hook)
     (gnus-update-unread-articles gnus-newsgroup-name
                                 (append gnus-newsgroup-unselected
                                         gnus-newsgroup-unreads)
@@ -3553,55 +4280,55 @@ gnus-Exit-group-hook is called with no arguments if that value is non-nil."
                                         (eq gnus-use-cross-reference t)
                                         )))
     ;; Do not switch windows but change the buffer to work.
-    (set-buffer gnus-Group-buffer)
+    (set-buffer gnus-group-buffer)
     ;; Update cross referenced group info.
     (while updated
-      (gnus-Group-update-group (car updated) t) ;Ignore invisible group.
+      (gnus-group-update-group (car updated) t) ;Ignore invisible group.
       (setq updated (cdr updated)))
-    (gnus-Group-update-group gnus-newsgroup-name))
+    (gnus-group-update-group gnus-newsgroup-name))
   ;; Make sure where I was, and go to next newsgroup.
-  (gnus-Group-jump-to-group gnus-newsgroup-name)
-  (gnus-Group-next-unread-group 1)
+  (gnus-group-jump-to-group gnus-newsgroup-name)
+  (gnus-group-next-unread-group 1)
   (if temporary
       ;; If exiting temporary, caller should adjust Group mode
       ;; buffer point by itself.
       nil                              ;Nothing to do.
     ;; Return to Group mode buffer.
-    (if (get-buffer gnus-Subject-buffer)
-       (bury-buffer gnus-Subject-buffer))
-    (if (get-buffer gnus-Article-buffer)
-       (bury-buffer gnus-Article-buffer))
-    (gnus-configure-windows 'ExitNewsgroup)
-    (pop-to-buffer gnus-Group-buffer)))
-
-(defun gnus-Subject-quit ()
+    (if (get-buffer gnus-summary-buffer)
+       (bury-buffer gnus-summary-buffer))
+    (if (get-buffer gnus-article-buffer)
+       (bury-buffer gnus-article-buffer))
+    (gnus-configure-windows 'newsgroups)
+    (pop-to-buffer gnus-group-buffer)))
+
+(defun gnus-summary-quit ()
   "Quit reading current newsgroup without updating read article info."
   (interactive)
   (if (y-or-n-p "Do you really wanna quit reading this group? ")
       (progn
        (message "")                    ;Erase "Yes or No" question.
        ;; Return to Group selection mode.
-       (if (get-buffer gnus-Subject-buffer)
-           (bury-buffer gnus-Subject-buffer))
-       (if (get-buffer gnus-Article-buffer)
-           (bury-buffer gnus-Article-buffer))
-       (gnus-configure-windows 'ExitNewsgroup)
-       (pop-to-buffer gnus-Group-buffer)
-       (gnus-Group-jump-to-group gnus-newsgroup-name) ;Make sure where I was.
-       (gnus-Group-next-group 1)       ;(gnus-Group-next-unread-group 1)
+       (if (get-buffer gnus-summary-buffer)
+           (bury-buffer gnus-summary-buffer))
+       (if (get-buffer gnus-article-buffer)
+           (bury-buffer gnus-article-buffer))
+       (gnus-configure-windows 'newsgroups)
+       (pop-to-buffer gnus-group-buffer)
+       (gnus-group-jump-to-group gnus-newsgroup-name) ;Make sure where I was.
+       (gnus-group-next-group 1)       ;(gnus-group-next-unread-group 1)
        )))
 
-(defun gnus-Subject-describe-briefly ()
-  "Describe Subject mode commands briefly."
+(defun gnus-summary-describe-briefly ()
+  "Describe Summary mode commands briefly."
   (interactive)
   (message
    (concat
-    (substitute-command-keys "\\[gnus-Subject-next-page]:Select  ")
-    (substitute-command-keys "\\[gnus-Subject-next-unread-article]:Forward  ")
-    (substitute-command-keys "\\[gnus-Subject-prev-unread-article]:Backward  ")
-    (substitute-command-keys "\\[gnus-Subject-exit]:Exit  ")
-    (substitute-command-keys "\\[gnus-Info-find-node]:Run Info  ")
-    (substitute-command-keys "\\[gnus-Subject-describe-briefly]:This help")
+    (substitute-command-keys "\\[gnus-summary-next-page]:Select  ")
+    (substitute-command-keys "\\[gnus-summary-next-unread-article]:Forward  ")
+    (substitute-command-keys "\\[gnus-summary-prev-unread-article]:Backward  ")
+    (substitute-command-keys "\\[gnus-summary-exit]:Exit  ")
+    (substitute-command-keys "\\[gnus-info-find-node]:Run Info  ")
+    (substitute-command-keys "\\[gnus-summary-describe-briefly]:This help")
     )))
 
 \f
@@ -3609,31 +4336,31 @@ gnus-Exit-group-hook is called with no arguments if that value is non-nil."
 ;;; GNUS Article Mode
 ;;;
 
-(if gnus-Article-mode-map
+(if gnus-article-mode-map
     nil
-  (setq gnus-Article-mode-map (make-keymap))
-  (suppress-keymap gnus-Article-mode-map)
-  (define-key gnus-Article-mode-map " " 'gnus-Article-next-page)
-  (define-key gnus-Article-mode-map "\177" 'gnus-Article-prev-page)
-  (define-key gnus-Article-mode-map "r" 'gnus-Article-refer-article)
-  (define-key gnus-Article-mode-map "o" 'gnus-Article-pop-article)
-  (define-key gnus-Article-mode-map "h" 'gnus-Article-show-subjects)
-  (define-key gnus-Article-mode-map "s" 'gnus-Article-show-subjects)
-  (define-key gnus-Article-mode-map "?" 'gnus-Article-describe-briefly)
-  (define-key gnus-Article-mode-map "\C-c\C-i" 'gnus-Info-find-node))
-
-(defun gnus-Article-mode ()
+  (setq gnus-article-mode-map (make-keymap))
+  (suppress-keymap gnus-article-mode-map)
+  (define-key gnus-article-mode-map " " 'gnus-article-next-page)
+  (define-key gnus-article-mode-map "\177" 'gnus-article-prev-page)
+  (define-key gnus-article-mode-map "r" 'gnus-article-refer-article)
+  (define-key gnus-article-mode-map "o" 'gnus-article-pop-article)
+  (define-key gnus-article-mode-map "h" 'gnus-article-show-summary)
+  (define-key gnus-article-mode-map "s" 'gnus-article-show-summary)
+  (define-key gnus-article-mode-map "?" 'gnus-article-describe-briefly)
+  (define-key gnus-article-mode-map "\C-c\C-i" 'gnus-info-find-node))
+
+(defun gnus-article-mode ()
   "Major mode for browsing through an article.
 All normal editing commands are turned off.
 Instead, these commands are available:
-\\{gnus-Article-mode-map}
+\\{gnus-article-mode-map}
 
 Various hooks for customization:
- gnus-Article-mode-hook
+ gnus-article-mode-hook
     Entry to this mode calls the value with no arguments, if that
     value is non-nil.
 
- gnus-Article-prepare-hook
+ gnus-article-prepare-hook
     Called with no arguments after an article is prepared for reading,
     if that value is non-nil."
   (interactive)
@@ -3644,80 +4371,114 @@ Various hooks for customization:
        ((listp (default-value 'mode-line-format))
         (setq mode-line-format
               (cons "--- " (cdr (default-value 'mode-line-format))))))
-  (make-local-variable 'global-mode-string)
-  (setq global-mode-string nil)
-  (setq major-mode 'gnus-Article-mode)
+  ;; To disable display-time facility.
+  ;;(make-local-variable 'global-mode-string)
+  ;;(setq global-mode-string nil)
+  (setq major-mode 'gnus-article-mode)
   (setq mode-name "Article")
-  (gnus-Article-set-mode-line)
-  (use-local-map gnus-Article-mode-map)
+  (make-local-variable 'minor-mode-alist)
+  (or (assq 'gnus-show-mime minor-mode-alist)
+      (setq minor-mode-alist
+           (cons (list 'gnus-show-mime " MIME") minor-mode-alist)))
+  (gnus-article-set-mode-line)
+  (use-local-map gnus-article-mode-map)
   (make-local-variable 'page-delimiter)
   (setq page-delimiter gnus-page-delimiter)
   (make-local-variable 'mail-header-separator)
   (setq mail-header-separator "")      ;For caesar function.
   (buffer-flush-undo (current-buffer))
   (setq buffer-read-only t)            ;Disable modification
-  (run-hooks 'gnus-Article-mode-hook))
+  (run-hooks 'gnus-article-mode-hook))
 
-(defun gnus-Article-setup-buffer ()
+(defun gnus-article-setup-buffer ()
   "Initialize Article mode buffer."
-  (or (get-buffer gnus-Article-buffer)
+  (or (get-buffer gnus-article-buffer)
       (save-excursion
-       (set-buffer (get-buffer-create gnus-Article-buffer))
-       (gnus-Article-mode))
+       (set-buffer (get-buffer-create gnus-article-buffer))
+       (gnus-article-mode))
       ))
 
-(defun gnus-Article-prepare (article &optional all-headers)
+(defun gnus-article-prepare (article &optional all-headers)
   "Prepare ARTICLE in Article mode buffer.
-If optional argument ALL-HEADERS is non-nil, all headers are inserted."
+ARTICLE can be either a article number or Message-ID.
+If optional argument ALL-HEADERS is non-nil,
+include the article's whole original header."
+  ;; Make sure a connection to NNTP server is alive.
+  (if (not (gnus-server-opened))
+      (progn
+       (gnus-start-news-server)
+       (gnus-request-group gnus-newsgroup-name)))
   (save-excursion
-    (set-buffer gnus-Article-buffer)
+    (set-buffer gnus-article-buffer)
     (let ((buffer-read-only nil))
       (erase-buffer)
-      (if (gnus-request-article article)
+      ;; mhspool does not work with Message-ID.  So, let's translate
+      ;; it into an article number as possible as can.  This may help
+      ;; nnspool too.
+      ;; Note: this conversion must be done here since if the article
+      ;; is specified by number or message-id has a different meaning
+      ;; in the following.
+      (if (let* ((header
+                 (and (stringp article)
+                      (gnus-get-header-by-id article)))
+                (article
+                 (if header
+                     (nntp-header-number header) article)))
+           (gnus-request-article article))
          (progn
            ;; Prepare article buffer
            (insert-buffer-substring nntp-server-buffer)
-           (setq gnus-have-all-headers (or all-headers gnus-show-all-headers))
+           ;; gnus-have-all-headers must be either T or NIL.
+           (setq gnus-have-all-headers
+                 (not (not (or all-headers gnus-show-all-headers))))
            (if (and (numberp article)
                     (not (eq article gnus-current-article)))
-               ;; Seems me that a new article is selected.
+               ;; Seems me that a new article has been selected.
                (progn
                  ;; gnus-current-article must be an article number.
                  (setq gnus-last-article gnus-current-article)
                  (setq gnus-current-article article)
+;;               (setq gnus-current-headers
+;;                     (gnus-find-header-by-number gnus-newsgroup-headers
+;;                                                 gnus-current-article))
                  (setq gnus-current-headers
-                       (gnus-find-header-by-number gnus-newsgroup-headers
-                                                   gnus-current-article))
-                 ;; Clear articles history only when articles are
-                 ;; retrieved by article numbers.
-                 (setq gnus-current-history nil)
-                 (run-hooks 'gnus-Mark-article-hook)
+                       (gnus-get-header-by-number gnus-current-article))
+                 (run-hooks 'gnus-mark-article-hook)
                  ))
-           ;; Hooks for modifying contents of the article. This hook
+           ;; Clear article history only when the article is
+           ;; retrieved by the article number.
+           (if (numberp article)
+               (setq gnus-current-history nil))
+           ;; Hooks for modifying contents of the article.  This hook
            ;; must be called before being narrowed.
-           (run-hooks 'gnus-Article-prepare-hook)
+           (run-hooks 'gnus-article-prepare-hook)
+           ;; Decode MIME message.
+           (if (and gnus-show-mime
+                    (gnus-fetch-field "Mime-Version"))
+               (funcall gnus-show-mime-method))
            ;; Delete unnecessary headers.
            (or gnus-have-all-headers
-               (gnus-Article-delete-headers))
+               (gnus-article-delete-headers))
            ;; Do page break.
            (goto-char (point-min))
            (if gnus-break-pages
                (gnus-narrow-to-page))
            ;; Next function must be called after setting
            ;;  `gnus-current-article' variable and narrowed to page.
-           (gnus-Article-set-mode-line)
+           (gnus-article-set-mode-line)
            )
+       ;; There is no such article.
        (if (numberp article)
-           (gnus-Subject-mark-as-read article))
+           (gnus-summary-mark-as-read article))
        (ding) (message "No such article (may be canceled)"))
       )))
 
-(defun gnus-Article-show-all-headers ()
+(defun gnus-article-show-all-headers ()
   "Show all article headers in Article mode buffer."
   (or gnus-have-all-headers
-      (gnus-Article-prepare gnus-current-article t)))
+      (gnus-article-prepare gnus-current-article t)))
 
-;;(defun gnus-Article-set-mode-line ()
+;;(defun gnus-article-set-mode-line ()
 ;;  "Set Article mode line string."
 ;;  (setq mode-line-buffer-identification
 ;;     (list 17
@@ -3729,33 +4490,54 @@ If optional argument ALL-HEADERS is non-nil, all headers are inserted."
 ;;                    )))
 ;;  (set-buffer-modified-p t))
 
-(defun gnus-Article-set-mode-line ()
-  "Set Article mode line string."
-  (let ((unmarked
-        (- (length gnus-newsgroup-unreads)
-           (length (gnus-intersection
-                    gnus-newsgroup-unreads gnus-newsgroup-marked))))
-       (unselected
-        (- (length gnus-newsgroup-unselected)
-           (length (gnus-intersection
-                    gnus-newsgroup-unselected gnus-newsgroup-marked)))))
+;;(defun gnus-article-set-mode-line ()
+;;  "Set Article mode line string."
+;;  (let ((unmarked
+;;      (- (length gnus-newsgroup-unreads)
+;;         (length (gnus-intersection
+;;                  gnus-newsgroup-unreads gnus-newsgroup-marked))))
+;;     (unselected
+;;      (- (length gnus-newsgroup-unselected)
+;;         (length (gnus-intersection
+;;                  gnus-newsgroup-unselected gnus-newsgroup-marked)))))
+;;    (setq mode-line-buffer-identification
+;;       (list 17
+;;             (format "GNUS: %s{%d} %s"
+;;                     gnus-newsgroup-name
+;;                     gnus-current-article
+;;                     ;; This is proposed by tale@pawl.rpi.edu.
+;;                     (cond ((and (zerop unmarked)
+;;                                 (zerop unselected))
+;;                            "      ")
+;;                           ((zerop unselected)
+;;                            (format "%d more" unmarked))
+;;                           (t
+;;                            (format "%d(+%d) more" unmarked unselected)))
+;;                     ))))
+;;  (set-buffer-modified-p t))
+
+;; New implementation in gnus 3.14.3
+
+(defun gnus-article-set-mode-line ()
+  "Set Article mode line string.
+If you don't like it, define your own `gnus-article-set-mode-line'."
+  (let ((maxlen 15)                    ;Maximum subject length
+       (subject
+        (if gnus-current-headers
+            (nntp-header-subject gnus-current-headers) "")))
+    ;; The value must be a string to escape %-constructs because of subject.
     (setq mode-line-buffer-identification
-         (list 17
-               (format "GNUS: %s{%d} %s"
-                       gnus-newsgroup-name
-                       gnus-current-article
-                       ;; This is proposed by tale@pawl.rpi.edu.
-                       (cond ((and (zerop unmarked)
-                                   (zerop unselected))
-                              "      ")
-                             ((zerop unselected)
-                              (format "%d more" unmarked))
-                             (t
-                              (format "%d(+%d) more" unmarked unselected)))
-                       ))))
+         (format "GNUS: %s%s %s%s%s"
+                 gnus-newsgroup-name
+                 (if gnus-current-article
+                     (format "/%d" gnus-current-article) "")
+                 (substring subject 0 (min (length subject) maxlen))
+                 (if (> (length subject) maxlen) "..." "")
+                 (make-string (max 0 (- 17 (length subject))) ? )
+                 )))
   (set-buffer-modified-p t))
 
-(defun gnus-Article-delete-headers ()
+(defun gnus-article-delete-headers ()
   "Delete unnecessary headers."
   (save-excursion
     (save-restriction
@@ -3774,9 +4556,9 @@ If optional argument ALL-HEADERS is non-nil, all headers are inserted."
 
 ;; Working on article's buffer
 
-(defun gnus-Article-next-page (lines)
+(defun gnus-article-next-page (lines)
   "Show next page of current article.
-If end of article, return non-nil. Otherwise return nil.
+If end of article, return non-nil.  Otherwise return nil.
 Argument LINES specifies lines to be scrolled up."
   (interactive "P")
   (move-to-window-line -1)
@@ -3803,7 +4585,7 @@ Argument LINES specifies lines to be scrolled up."
     nil
     ))
 
-(defun gnus-Article-prev-page (lines)
+(defun gnus-article-prev-page (lines)
   "Show previous page of current article.
 Argument LINES specifies lines to be scrolled down."
   (interactive "P")
@@ -3817,7 +4599,7 @@ Argument LINES specifies lines to be scrolled down."
        (recenter -1))
     (scroll-down lines)))
 
-(defun gnus-Article-next-digest (nth)
+(defun gnus-article-next-digest (nth)
   "Move to head of NTH next digested message.
 Set mark at end of digested message."
   ;; Stop page breaking in digest mode.
@@ -3847,18 +4629,18 @@ Set mark at end of digested message."
     (message "End of message")
     ))
 
-(defun gnus-Article-prev-digest (nth)
-  "Move to head of NTH previous digested message."
+(defun gnus-article-prev-digest (n)
+  "Move to head of Nth previous digested message."
   ;; Stop page breaking in digest mode.
   (widen)
   (beginning-of-line)
-  ;; Skip NTH - 1 digest.
+  ;; Skip N - 1 digest.
   ;; Suggested by Khalid Sattar <admin@cs.exeter.ac.uk>.
   ;; Digest separator is customizable.
   ;; Suggested by Skip Montanaro <montanaro@sprite.crd.ge.com>.
-  (while (and (> nth 1)
+  (while (and (> n 1)
              (re-search-backward gnus-digest-separator nil 'move))
-    (setq nth (1- nth)))
+    (setq n (1- n)))
   (if (re-search-backward gnus-digest-separator nil t)
       (let ((begin (point)))
        ;; Search for end of this message.
@@ -3876,7 +4658,7 @@ Set mark at end of digested message."
     (message "Top of message")
     ))
 
-(defun gnus-Article-refer-article ()
+(defun gnus-article-refer-article ()
   "Read article specified by message-id around point."
   (interactive)
   (save-window-excursion
@@ -3885,35 +4667,35 @@ Set mark at end of digested message."
       (if (re-search-backward "\\(<[^<> \t\n]+>\\)" nil t)
          (let ((message-id
                 (buffer-substring (match-beginning 1) (match-end 1))))
-           (set-buffer gnus-Subject-buffer)
-           (gnus-Subject-refer-article message-id))
+           (set-buffer gnus-summary-buffer)
+           (gnus-summary-refer-article message-id))
        (error "No references around point"))
       )))
 
-(defun gnus-Article-pop-article ()
+(defun gnus-article-pop-article ()
   "Pop up article history."
   (interactive)
   (save-window-excursion
-    (set-buffer gnus-Subject-buffer)
-    (gnus-Subject-refer-article nil)))
+    (set-buffer gnus-summary-buffer)
+    (gnus-summary-refer-article nil)))
 
-(defun gnus-Article-show-subjects ()
-  "Reconfigure windows to show headers."
+(defun gnus-article-show-summary ()
+  "Reconfigure windows to show Summary buffer."
   (interactive)
-  (gnus-configure-windows 'SelectArticle)
-  (pop-to-buffer gnus-Subject-buffer)
-  (gnus-Subject-goto-subject gnus-current-article))
+  (gnus-configure-windows 'article)
+  (pop-to-buffer gnus-summary-buffer)
+  (gnus-summary-goto-subject gnus-current-article))
 
-(defun gnus-Article-describe-briefly ()
+(defun gnus-article-describe-briefly ()
   "Describe Article mode commands briefly."
   (interactive)
   (message
    (concat
-    (substitute-command-keys "\\[gnus-Article-next-page]:Next page  ")
-    (substitute-command-keys "\\[gnus-Article-prev-page]:Prev page  ")
-    (substitute-command-keys "\\[gnus-Article-show-subjects]:Show headers  ")
-    (substitute-command-keys "\\[gnus-Info-find-node]:Run Info  ")
-    (substitute-command-keys "\\[gnus-Article-describe-briefly]:This help")
+    (substitute-command-keys "\\[gnus-article-next-page]:Next page  ")
+    (substitute-command-keys "\\[gnus-article-prev-page]:Prev page  ")
+    (substitute-command-keys "\\[gnus-article-show-summary]:Show Summary  ")
+    (substitute-command-keys "\\[gnus-info-find-node]:Run Info  ")
+    (substitute-command-keys "\\[gnus-article-describe-briefly]:This help")
     )))
 
 \f
@@ -3921,50 +4703,50 @@ Set mark at end of digested message."
 ;;; GNUS KILL-File Mode
 ;;;
 
-(if gnus-Kill-file-mode-map
+(if gnus-kill-file-mode-map
     nil
-  (setq gnus-Kill-file-mode-map (copy-keymap emacs-lisp-mode-map))
-  (define-key gnus-Kill-file-mode-map "\C-c\C-k\C-s" 'gnus-Kill-file-kill-by-subject)
-  (define-key gnus-Kill-file-mode-map "\C-c\C-k\C-a" 'gnus-Kill-file-kill-by-author)
-  (define-key gnus-Kill-file-mode-map "\C-c\C-a" 'gnus-Kill-file-apply-buffer)
-  (define-key gnus-Kill-file-mode-map "\C-c\C-e" 'gnus-Kill-file-apply-last-sexp)
-  (define-key gnus-Kill-file-mode-map "\C-c\C-c" 'gnus-Kill-file-exit)
-  (define-key gnus-Kill-file-mode-map "\C-c\C-i" 'gnus-Info-find-node))
-
-(defun gnus-Kill-file-mode ()
+  (setq gnus-kill-file-mode-map (copy-keymap emacs-lisp-mode-map))
+  (define-key gnus-kill-file-mode-map "\C-c\C-k\C-s" 'gnus-kill-file-kill-by-subject)
+  (define-key gnus-kill-file-mode-map "\C-c\C-k\C-a" 'gnus-kill-file-kill-by-author)
+  (define-key gnus-kill-file-mode-map "\C-c\C-a" 'gnus-kill-file-apply-buffer)
+  (define-key gnus-kill-file-mode-map "\C-c\C-e" 'gnus-kill-file-apply-last-sexp)
+  (define-key gnus-kill-file-mode-map "\C-c\C-c" 'gnus-kill-file-exit)
+  (define-key gnus-kill-file-mode-map "\C-c\C-i" 'gnus-info-find-node))
+
+(defun gnus-kill-file-mode ()
   "Major mode for editing KILL file.
 
 In addition to Emacs-Lisp Mode, the following commands are available:
 
-\\[gnus-Kill-file-kill-by-subject]     Insert KILL command for current subject.
-\\[gnus-Kill-file-kill-by-author]      Insert KILL command for current author.
-\\[gnus-Kill-file-apply-buffer]        Apply current buffer to selected newsgroup.
-\\[gnus-Kill-file-apply-last-sexp]     Apply sexp before point to selected newsgroup.
-\\[gnus-Kill-file-exit]        Save file and exit editing KILL file.
-\\[gnus-Info-find-node]        Read Info about KILL file.
-
-  A KILL file contains lisp expressions to be applied to a selected
-newsgroup. The purpose is to mark articles as read on the basis of
-some set of regexps. A global KILL file is applied to every newsgroup,
-and a local KILL file is applied to a specified newsgroup. Since a
+\\[gnus-kill-file-kill-by-subject]     Insert KILL command for current subject.
+\\[gnus-kill-file-kill-by-author]      Insert KILL command for current author.
+\\[gnus-kill-file-apply-buffer]        Apply current buffer to selected newsgroup.
+\\[gnus-kill-file-apply-last-sexp]     Apply sexp before point to selected newsgroup.
+\\[gnus-kill-file-exit]        Save file and exit editing KILL file.
+\\[gnus-info-find-node]        Read Info about KILL file.
+
+  A KILL file contains Lisp expressions to be applied to a selected
+newsgroup.  The purpose is to mark articles as read on the basis of
+some set of regexps.  A global KILL file is applied to every newsgroup,
+and a local KILL file is applied to a specified newsgroup.  Since a
 global KILL file is applied to every newsgroup, for better performance
 use a local one.
 
-  A KILL file can contain any kind of Emacs lisp expressions expected
-to be evaluated in the Subject buffer. Writing lisp programs for this
+  A KILL file can contain any kind of Emacs Lisp expressions expected
+to be evaluated in the Summary buffer.  Writing Lisp programs for this
 purpose is not so easy because the internal working of GNUS must be
-well-known. For this reason, GNUS provides a general function which
+well-known.  For this reason, GNUS provides a general function which
 does this easily for non-Lisp programmers.
 
-  The `gnus-kill' function executes commands available in Subject Mode
-by their key sequences. `gnus-kill' should be called with FIELD,
-REGEXP and optional COMMAND and ALL. FIELD is a string representing
-the header field or an empty string. If FIELD is an empty string, the
-entire article body is searched for. REGEXP is a string which is
-compared with FIELD value. COMMAND is a string representing a valid
-key sequence in Subject Mode or Lisp expression. COMMAND is default to
-'(gnus-Subject-mark-as-read nil \"X\"). Make sure that COMMAND is
-executed in the Subject buffer.  If the second optional argument ALL
+  The `gnus-kill' function executes commands available in Summary Mode
+by their key sequences.  `gnus-kill' should be called with FIELD,
+REGEXP and optional COMMAND and ALL.  FIELD is a string representing
+the header field or an empty string.  If FIELD is an empty string, the
+entire article body is searched for.  REGEXP is a string which is
+compared with FIELD value.  COMMAND is a string representing a valid
+key sequence in Summary mode or Lisp expression.  COMMAND defaults to
+\(gnus-summary-mark-as-read nil \"X\").  Make sure that COMMAND is
+executed in the Summary buffer.  If the second optional argument ALL
 is non-nil, the COMMAND is applied to articles which are already
 marked as read or unread.  Articles which are marked are skipped over
 by default.
@@ -3979,32 +4761,32 @@ the following expression:
 
        (gnus-kill \"Subject\" \"AI\" \"d\")
 
-In this example it is assumed that the command
-`gnus-Subject-mark-as-read-forward' is assigned to `d' in Subject Mode.
+\(Here we assume the command `gnus-summary-mark-as-read-forward' is
+assigned to `d' in Summary Mode.)
 
   It is possible to delete unnecessary headers which are marked with
 `X' in a KILL file as follows:
 
        (gnus-expunge \"X\")
 
-  If the Subject buffer is empty after applying KILL files, GNUS will
+  If the Summary buffer is empty after applying KILL files, GNUS will
 exit the selected newsgroup normally.  If headers which are marked
 with `D' are deleted in a KILL file, it is impossible to read articles
 which are marked as read in the previous GNUS sessions.  Marks other
 than `D' should be used for articles which should really be deleted.
 
-Entry to this mode calls emacs-lisp-mode-hook and
-gnus-Kill-file-mode-hook with no arguments, if that value is non-nil."
+Entry to this mode calls `emacs-lisp-mode-hook' and
+`gnus-kill-file-mode-hook' with no arguments, if that value is non-nil."
   (interactive)
   (kill-all-local-variables)
-  (use-local-map gnus-Kill-file-mode-map)
+  (use-local-map gnus-kill-file-mode-map)
   (set-syntax-table emacs-lisp-mode-syntax-table)
-  (setq major-mode 'gnus-Kill-file-mode)
+  (setq major-mode 'gnus-kill-file-mode)
   (setq mode-name "KILL-File")
   (lisp-mode-variables nil)
-  (run-hooks 'emacs-lisp-mode-hook 'gnus-Kill-file-mode-hook))
+  (run-hooks 'emacs-lisp-mode-hook 'gnus-kill-file-mode-hook))
 
-(defun gnus-Kill-file-edit-file (newsgroup)
+(defun gnus-kill-file-edit-file (newsgroup)
   "Begin editing a KILL file of NEWSGROUP.
 If NEWSGROUP is nil, the global KILL file is selected."
   (interactive "sNewsgroup: ")
@@ -4018,24 +4800,24 @@ If NEWSGROUP is nil, the global KILL file is selected."
     (let ((buffer (find-file-noselect file)))
       (cond ((get-buffer-window buffer)
             (pop-to-buffer buffer))
-           ((eq major-mode 'gnus-Group-mode)
+           ((eq major-mode 'gnus-group-mode)
             (gnus-configure-windows '(1 0 0)) ;Take all windows.
-            (pop-to-buffer gnus-Group-buffer)
-            (let ((gnus-Subject-buffer buffer))
+            (pop-to-buffer gnus-group-buffer)
+            (let ((gnus-summary-buffer buffer))
               (gnus-configure-windows '(1 1 0)) ;Split into two.
               (pop-to-buffer buffer)))
-           ((eq major-mode 'gnus-Subject-mode)
-            (gnus-configure-windows 'SelectArticle)
-            (pop-to-buffer gnus-Article-buffer)
-            (bury-buffer gnus-Article-buffer)
+           ((eq major-mode 'gnus-summary-mode)
+            (gnus-configure-windows 'article)
+            (pop-to-buffer gnus-article-buffer)
+            (bury-buffer gnus-article-buffer)
             (switch-to-buffer buffer))
            (t                          ;No good rules.
             (find-file-other-window file))
            ))
-    (gnus-Kill-file-mode)
+    (gnus-kill-file-mode)
     ))
 
-(defun gnus-Kill-file-kill-by-subject ()
+(defun gnus-kill-file-kill-by-subject ()
   "Insert KILL command for current subject."
   (interactive)
   (insert
@@ -4044,11 +4826,13 @@ If NEWSGROUP is nil, the global KILL file is selected."
            (if gnus-current-kill-article
                (regexp-quote
                 (nntp-header-subject
+                 ;; No need to speed up this command.
+                 ;;(gnus-get-header-by-number gnus-current-kill-article)
                  (gnus-find-header-by-number gnus-newsgroup-headers
                                              gnus-current-kill-article)))
              "")))))
 
-(defun gnus-Kill-file-kill-by-author ()
+(defun gnus-kill-file-kill-by-author ()
   "Insert KILL command for current author."
   (interactive)
   (insert
@@ -4057,46 +4841,48 @@ If NEWSGROUP is nil, the global KILL file is selected."
            (if gnus-current-kill-article
                (regexp-quote
                 (nntp-header-from
+                 ;; No need to speed up this command.
+                 ;;(gnus-get-header-by-number gnus-current-kill-article)
                  (gnus-find-header-by-number gnus-newsgroup-headers
                                              gnus-current-kill-article)))
              "")))))
 
-(defun gnus-Kill-file-apply-buffer ()
+(defun gnus-kill-file-apply-buffer ()
   "Apply current buffer to current newsgroup."
   (interactive)
   (if (and gnus-current-kill-article
-          (get-buffer gnus-Subject-buffer))
+          (get-buffer gnus-summary-buffer))
       ;; Assume newsgroup is selected.
       (let ((string (concat "(progn \n" (buffer-string) "\n)" )))
        (save-excursion
          (save-window-excursion
-           (pop-to-buffer gnus-Subject-buffer)
+           (pop-to-buffer gnus-summary-buffer)
            (eval (car (read-from-string string))))))
     (ding) (message "No newsgroup is selected.")))
 
-(defun gnus-Kill-file-apply-last-sexp ()
+(defun gnus-kill-file-apply-last-sexp ()
   "Apply sexp before point in current buffer to current newsgroup."
   (interactive)
   (if (and gnus-current-kill-article
-          (get-buffer gnus-Subject-buffer))
+          (get-buffer gnus-summary-buffer))
       ;; Assume newsgroup is selected.
       (let ((string
             (buffer-substring
              (save-excursion (forward-sexp -1) (point)) (point))))
        (save-excursion
          (save-window-excursion
-           (pop-to-buffer gnus-Subject-buffer)
+           (pop-to-buffer gnus-summary-buffer)
            (eval (car (read-from-string string))))))
     (ding) (message "No newsgroup is selected.")))
 
-(defun gnus-Kill-file-exit ()
+(defun gnus-kill-file-exit ()
   "Save a KILL file, then return to the previous buffer."
   (interactive)
   (save-buffer)
   (let ((killbuf (current-buffer)))
     ;; We don't want to return to Article buffer.
-    (and (get-buffer gnus-Article-buffer)
-        (bury-buffer (get-buffer gnus-Article-buffer)))
+    (and (get-buffer gnus-article-buffer)
+        (bury-buffer (get-buffer gnus-article-buffer)))
     ;; Delete the KILL file windows.
     (delete-windows-on killbuf)
     ;; Restore last window configuration if available.
@@ -4149,16 +4935,18 @@ Usage: emacs -batch -l gnus -f gnus-batch-kill NEWSGROUP ..."
               (or (null no)
                   (not (string-match no group))))
          (progn
-           (gnus-Subject-read-group group nil t)
-           (if (eq (current-buffer) (get-buffer gnus-Subject-buffer))
-               (gnus-Subject-exit t))
+           (gnus-summary-read-group group nil t)
+           (if (eq (current-buffer) (get-buffer gnus-summary-buffer))
+               (gnus-summary-exit t))
            ))
       )
     ;; Finally, exit Emacs.
-    (set-buffer gnus-Group-buffer)
-    (gnus-Group-exit)
+    (set-buffer gnus-group-buffer)
+    (gnus-group-exit)
     ))
 
+;; For saving articles
+
 (defun gnus-Numeric-save-name (newsgroup headers &optional last-file)
   "Generate file name from NEWSGROUP, HEADERS, and optional LAST-FILE.
 If variable `gnus-use-long-file-name' is nil, it is ~/News/News.group/num.
@@ -4166,7 +4954,7 @@ Otherwise, it is like ~/News/news/group/num."
   (let ((default
          (expand-file-name
           (concat (if gnus-use-long-file-name
-                      (capitalize newsgroup)
+                      (gnus-capitalize-newsgroup newsgroup)
                     (gnus-newsgroup-directory-form newsgroup))
                   "/" (int-to-string (nntp-header-number headers)))
           (or gnus-article-save-directory "~/News"))))
@@ -4202,7 +4990,7 @@ Otherwise, it is like ~/News/news/group/news."
   (or last-file
       (expand-file-name
        (if gnus-use-long-file-name
-          (capitalize newsgroup)
+          (gnus-capitalize-newsgroup newsgroup)
         (concat (gnus-newsgroup-directory-form newsgroup) "/news"))
        (or gnus-article-save-directory "~/News"))))
 
@@ -4224,7 +5012,7 @@ Otherwise, it is like +news/group."
   (or last-folder
       (concat "+"
              (if gnus-use-long-file-name
-                 (capitalize newsgroup)
+                 (gnus-capitalize-newsgroup newsgroup)
                (gnus-newsgroup-directory-form newsgroup)))))
 
 (defun gnus-folder-save-name (newsgroup headers &optional last-folder)
@@ -4237,6 +5025,8 @@ Otherwise, it is like +news/group."
                  newsgroup
                (gnus-newsgroup-directory-form newsgroup)))))
 
+;; For KILL files
+
 (defun gnus-apply-kill-file ()
   "Apply KILL file to the current newsgroup."
   ;; Apply the global KILL file.
@@ -4251,17 +5041,17 @@ If NEWSGROUP is nil, return the global KILL file instead."
             (string-equal newsgroup ""))
         ;; The global KILL file is placed at top of the directory.
         (expand-file-name gnus-kill-file-name
-                          (or gnus-article-save-directory "~/News")))
+                          (or gnus-kill-files-directory "~/News")))
        (gnus-use-long-file-name
         ;; Append ".KILL" to capitalized newsgroup name.
-        (expand-file-name (concat (capitalize newsgroup)
+        (expand-file-name (concat (gnus-capitalize-newsgroup newsgroup)
                                   "." gnus-kill-file-name)
-                          (or gnus-article-save-directory "~/News")))
+                          (or gnus-kill-files-directory "~/News")))
        (t
         ;; Place "KILL" under the hierarchical directory.
         (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
                                   "/" gnus-kill-file-name)
-                          (or gnus-article-save-directory "~/News")))
+                          (or gnus-kill-files-directory "~/News")))
        ))
 
 (defun gnus-newsgroup-kill-file (newsgroup)
@@ -4271,24 +5061,85 @@ If NEWSGROUP is nil, return the global KILL file instead."
             (string-equal newsgroup ""))
         ;; The global KILL file is placed at top of the directory.
         (expand-file-name gnus-kill-file-name
-                          (or gnus-article-save-directory "~/News")))
+                          (or gnus-kill-files-directory "~/News")))
        (gnus-use-long-file-name
         ;; Append ".KILL" to newsgroup name.
         (expand-file-name (concat newsgroup "." gnus-kill-file-name)
-                          (or gnus-article-save-directory "~/News")))
+                          (or gnus-kill-files-directory "~/News")))
        (t
         ;; Place "KILL" under the hierarchical directory.
         (expand-file-name (concat (gnus-newsgroup-directory-form newsgroup)
                                   "/" gnus-kill-file-name)
-                          (or gnus-article-save-directory "~/News")))
+                          (or gnus-kill-files-directory "~/News")))
        ))
 
+;; For subscribing new newsgroup
+
+(defun gnus-subscribe-randomly (newsgroup)
+  "Subscribe new NEWSGROUP and insert it at the beginning of newsgroups."
+  (gnus-subscribe-newsgroup newsgroup
+                           (car (car gnus-newsrc-assoc))))
+
+(defun gnus-subscribe-alphabetically (newgroup)
+  "Subscribe new NEWSGROUP and insert it in strict alphabetic order."
+  ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams)
+  (let ((groups gnus-newsrc-assoc)
+       (before nil))
+    (while (and (not before) groups)
+      (if (string< newgroup (car (car groups)))
+         (setq before (car (car groups)))
+       (setq groups (cdr groups))))
+    (gnus-subscribe-newsgroup newgroup before)
+    ))
+
+(defun gnus-subscribe-hierarchically (newgroup)
+  "Subscribe new NEWSGROUP and insert it in hierarchical newsgroup order."
+  ;; Basic ideas by mike-w@cs.aukuni.ac.nz (Mike Williams)
+  (save-excursion
+    (set-buffer (find-file-noselect gnus-current-startup-file))
+    (let ((groupkey newgroup)
+         (before nil))
+      (while (and (not before) groupkey)
+       (goto-char (point-min))
+       (let ((groupkey-re
+              (concat "^\\(" (regexp-quote groupkey) ".*\\)[!:]")))
+         (while (and (re-search-forward groupkey-re nil t)
+                     (progn
+                       (setq before (buffer-substring
+                                     (match-beginning 1) (match-end 1)))
+                       (string< before newgroup)))
+           ))
+       ;; Remove tail of newsgroup name (eg. a.b.c -> a.b)
+       (setq groupkey
+             (if (string-match "^\\(.*\\)\\.[^.]+$" groupkey)
+                 (substring groupkey (match-beginning 1) (match-end 1)))))
+      (gnus-subscribe-newsgroup newgroup before)
+      )))
+
+(defun gnus-subscribe-interactively (newsgroup)
+  "Subscribe new NEWSGROUP interactively.
+It is inserted in hierarchical newsgroup order if subscribed.
+Unless, it is killed."
+  (if (y-or-n-p (format "Subscribe new newsgroup: %s " newsgroup))
+      (gnus-subscribe-hierarchically newsgroup)
+    ;; Save in kill-ring
+    (gnus-subscribe-newsgroup newsgroup)
+    (gnus-kill-newsgroup newsgroup)))
+
+(defun gnus-subscribe-newsgroup (newsgroup &optional next)
+  "Subscribe new NEWSGROUP.
+If optional argument NEXT is non-nil, it is inserted before NEXT."
+  (gnus-insert-newsgroup (list newsgroup t) next)
+  (message "Subscribe newsgroup: %s" newsgroup))
+
+;; For directories
+
 (defun gnus-newsgroup-directory-form (newsgroup)
   "Make hierarchical directory name from NEWSGROUP name."
   (let ((newsgroup (substring newsgroup 0)) ;Copy string.
        (len (length newsgroup))
        (idx 0))
-    ;; Replace all occurence of `.' with `/'.
+    ;; Replace all occurrences of `.' with `/'.
     (while (< idx len)
       (if (= (aref newsgroup idx) ?.)
          (aset newsgroup idx ?/))
@@ -4305,15 +5156,30 @@ If NEWSGROUP is nil, return the global KILL file instead."
 
 (defun gnus-make-directory-1 (head tail)
   (cond ((string-match "^/\\([^/]+\\)" tail)
-        (setq head
-              (concat (file-name-as-directory head)
-                      (substring tail (match-beginning 1) (match-end 1))))
-        (or (file-exists-p head)
-            (call-process "mkdir" nil nil nil head))
-        (gnus-make-directory-1 head (substring tail (match-end 1))))
+        ;; ange-ftp interferes with calling match-* after
+        ;; calling file-name-as-directory.
+        (let ((beg (match-beginning 1))
+              (end (match-end 1)))
+          (setq head (concat (file-name-as-directory head)
+                             (substring tail beg end)))
+          (or (file-exists-p head)
+              (call-process "mkdir" nil nil nil head))
+          (gnus-make-directory-1 head (substring tail end))))
        ((string-equal tail "") t)
        ))
 
+(defun gnus-capitalize-newsgroup (newsgroup)
+  "Capitalize NEWSGROUP name with treating `.' and `-' as part of words."
+  ;; Suggested by "Jonathan I. Kamens" <jik@pit-manager.MIT.EDU>.
+  (let ((current-syntax-table (syntax-table)))
+    (unwind-protect
+       (progn
+         (set-syntax-table (copy-syntax-table current-syntax-table))
+         (modify-syntax-entry ?- "w")
+         (modify-syntax-entry ?. "w")
+         (capitalize newsgroup))
+      (set-syntax-table current-syntax-table))))
+
 (defun gnus-simplify-subject (subject &optional re-only)
   "Remove `Re:' and words in parentheses.
 If optional argument RE-ONLY is non-nil, strip `Re:' only."
@@ -4347,58 +5213,100 @@ If optional argument RE-ONLY is non-nil, strip `Re:' only."
   "Return a string like `NNN' from HEADER."
   (format "%4d" (nntp-header-lines header)))
 
+;; Basic ideas by flee@cs.psu.edu (Felix Lee)
+
+(defun gnus-keysort-headers (predicate key &optional reverse)
+  "Sort current headers by PREDICATE using a value passed by KEY safely.
+*Safely* means C-g quitting is disabled during sort.
+Optional argument REVERSE means reverse order."
+  (let ((inhibit-quit t))
+    (setq gnus-newsgroup-headers
+         (if reverse
+             (nreverse
+              (gnus-keysort (nreverse gnus-newsgroup-headers) predicate key))
+           (gnus-keysort gnus-newsgroup-headers predicate key)))
+    ;; Make sure we don't have to call
+    ;; gnus-clear-hashtables-for-newsgroup-headers to clear hash
+    ;; tables for the variable gnus-newsgroup-headers since no new
+    ;; entry is added to nor deleted from the variable.
+    ))
+
+(defun gnus-keysort (list predicate key)
+  "Sort LIST by PREDICATE using a value passed by KEY."
+  (mapcar (function cdr)
+         (sort (mapcar (function (lambda (a) (cons (funcall key a) a))) list)
+               (function (lambda (a b)
+                           (funcall predicate (car a) (car b)))))))
+
 (defun gnus-sort-headers (predicate &optional reverse)
-  "Sort current group headers by PREDICATE safely.
-*Safely* means C-g quitting is disabled during sorting.
+  "Sort current headers by PREDICATE safely.
+*Safely* means C-g quitting is disabled during sort.
 Optional argument REVERSE means reverse order."
   (let ((inhibit-quit t))
     (setq gnus-newsgroup-headers
          (if reverse
              (nreverse (sort (nreverse gnus-newsgroup-headers) predicate))
            (sort gnus-newsgroup-headers predicate)))
+    ;; Make sure we don't have to call
+    ;; gnus-clear-hashtables-for-newsgroup-headers to clear hash
+    ;; tables for the variable gnus-newsgroup-headers since no new
+    ;; entry is added to nor deleted from the variable.
     ))
 
 (defun gnus-string-lessp (a b)
   "Return T if first arg string is less than second in lexicographic order.
-If case-fold-search is non-nil, case of letters is ignored."
+If `case-fold-search' is non-nil, case of letters is ignored."
   (if case-fold-search
-      (string-lessp (downcase a) (downcase b)) (string-lessp a b)))
+      (string-lessp (downcase a) (downcase b))
+    (string-lessp a b)))
 
 (defun gnus-date-lessp (date1 date2)
   "Return T if DATE1 is earlyer than DATE2."
-  (string-lessp (gnus-comparable-date date1)
-               (gnus-comparable-date date2)))
-
-(defun gnus-comparable-date (date)
-  "Make comparable string by string-lessp from DATE."
-  (let ((month '(("JAN" . " 1")("FEB" . " 2")("MAR" . " 3")
-                ("APR" . " 4")("MAY" . " 5")("JUN" . " 6")
-                ("JUL" . " 7")("AUG" . " 8")("SEP" . " 9")
-                ("OCT" . "10")("NOV" . "11")("DEC" . "12")))
-       (date (or date "")))
-    ;; Can understand the following styles:
-    ;; (1) 14 Apr 89 03:20:12 GMT
-    ;; (2) Fri, 17 Mar 89 4:01:33 GMT
-    (if (string-match
-        "\\([0-9]+\\) \\([^ ,]+\\) \\([0-9]+\\) \\([0-9:]+\\)" date)
-       (concat
-        ;; Year
-        (substring date (match-beginning 3) (match-end 3))
-        ;; Month
-        (cdr
-         (assoc
-          (upcase (substring date (match-beginning 2) (match-end 2))) month))
-        ;; Day
-        (format "%2d" (string-to-int
-                       (substring date
-                                  (match-beginning 1) (match-end 1))))
-        ;; Time
-        (substring date (match-beginning 4) (match-end 4)))
-      ;; Cannot understand DATE string.
-      date
-      )
+  (string-lessp (gnus-sortable-date date1)
+               (gnus-sortable-date date2)))
+
+(defun gnus-sortable-date (date)
+  "Convert DATE into a string that can be sorted with `string-lessp'.
+Timezone package is used."
+  (let* ((date   (timezone-fix-time date nil nil)) ;[Y M D H M S]
+        (year   (aref date 0))
+        (month  (aref date 1))
+        (day    (aref date 2)))
+    (timezone-make-sortable-date year month day 
+                                (timezone-make-time-string
+                                 (aref date 3) (aref date 4) (aref date 5)))
     ))
 
+;;(defun gnus-sortable-date (date)
+;;  "Make sortable string by string-lessp from DATE."
+;;  (let ((month '(("JAN" . " 1")("FEB" . " 2")("MAR" . " 3")
+;;              ("APR" . " 4")("MAY" . " 5")("JUN" . " 6")
+;;              ("JUL" . " 7")("AUG" . " 8")("SEP" . " 9")
+;;              ("OCT" . "10")("NOV" . "11")("DEC" . "12")))
+;;     (date (or date "")))
+;;    ;; Can understand the following styles:
+;;    ;; (1) 14 Apr 89 03:20:12 GMT
+;;    ;; (2) Fri, 17 Mar 89 4:01:33 GMT
+;;    (if (string-match
+;;      "\\([0-9]+\\) \\([^ ,]+\\) \\([0-9]+\\) \\([0-9:]+\\)" date)
+;;     (concat
+;;      ;; Year
+;;      (substring date (match-beginning 3) (match-end 3))
+;;      ;; Month
+;;      (cdr
+;;       (assoc
+;;        (upcase (substring date (match-beginning 2) (match-end 2))) month))
+;;      ;; Day
+;;      (format "%2d" (string-to-int
+;;                     (substring date
+;;                                (match-beginning 1) (match-end 1))))
+;;      ;; Time
+;;      (substring date (match-beginning 4) (match-end 4)))
+;;      ;; Cannot understand DATE string.
+;;      date
+;;      )
+;;    ))
+
 (defun gnus-fetch-field (field)
   "Return the value of the header FIELD of current article."
   (save-excursion
@@ -4409,33 +5317,33 @@ If case-fold-search is non-nil, case of letters is ignored."
                        (progn (search-forward "\n\n" nil 'move) (point)))
       (mail-fetch-field field))))
 
-(fset 'gnus-expunge 'gnus-Subject-delete-marked-with)
+(defalias 'gnus-expunge 'gnus-summary-delete-marked-with)
 
 (defun gnus-kill (field regexp &optional command all)
   "If FIELD of an article matches REGEXP, execute COMMAND.
-Optional third argument COMMAND is default to
-       (gnus-Subject-mark-as-read nil \"X\").
-If optional fourth argument ALL is non-nil, articles marked are also applied
-to.  If FIELD is an empty string (or nil), entire article body is searched for.
-COMMAND must be a lisp expression or a string representing a key sequence."
+Optional 1st argument COMMAND is default to
+       (gnus-summary-mark-as-read nil \"X\").
+If optional 2nd argument ALL is non-nil, articles marked are also applied to.
+If FIELD is an empty string (or nil), entire article body is searched for.
+COMMAND must be a Lisp expression or a string representing a key sequence."
   ;; We don't want to change current point nor window configuration.
   (save-excursion
     (save-window-excursion
-      ;; Selected window must be Subject mode buffer to execute
-      ;; keyboard macros correctly. See command_loop_1.
-      (switch-to-buffer gnus-Subject-buffer 'norecord)
+      ;; Selected window must be Summary buffer to execute keyboard
+      ;; macros correctly.  See command_loop_1.
+      (switch-to-buffer gnus-summary-buffer 'norecord)
       (goto-char (point-min))          ;From the beginning.
       (if (null command)
-         (setq command '(gnus-Subject-mark-as-read nil "X")))
+         (setq command '(gnus-summary-mark-as-read nil "X")))
       (gnus-execute field regexp command nil (not all))
       )))
 
 (defun gnus-execute (field regexp form &optional backward ignore-marked)
   "If FIELD of article header matches REGEXP, execute lisp FORM (or a string).
 If FIELD is an empty string (or nil), entire article body is searched for.
-If optional fifth argument BACKWARD is non-nil, do backward instead.
-If optional sixth argument IGNORE-MARKED is non-nil, articles which are
-marked as read or unread are ignored."
+If optional 1st argument BACKWARD is non-nil, do backward instead.
+If optional 2nd argument IGNORE-MARKED is non-nil, ignore articles
+marked as read or unread."
   (let ((function nil)
        (header nil)
        (article nil))
@@ -4456,25 +5364,26 @@ marked as read or unread are ignored."
     ;; Starting from the current article.
     (or (and ignore-marked
             ;; Articles marked as read and unread should be ignored.
-            (setq article (gnus-Subject-article-number))
+            (setq article (gnus-summary-article-number))
             (or (not (memq article gnus-newsgroup-unreads)) ;Marked as read.
                 (memq article gnus-newsgroup-marked) ;Marked as unread.
                 ))
        (gnus-execute-1 function regexp form))
-    (while (gnus-Subject-search-subject backward ignore-marked nil)
+    (while (gnus-summary-search-subject backward ignore-marked nil)
       (gnus-execute-1 function regexp form))
     ))
 
 (defun gnus-execute-1 (function regexp form)
   (save-excursion
-    ;; The point of Subject mode buffer must be saved during execution.
-    (let ((article (gnus-Subject-article-number)))
+    ;; The point of Summary buffer must be saved during execution.
+    (let ((article (gnus-summary-article-number)))
       (if (null article)
          nil                           ;Nothing to do.
        (if function
            ;; Compare with header field.
-           (let ((header (gnus-find-header-by-number
-                          gnus-newsgroup-headers article))
+           (let (;;(header (gnus-find-header-by-number
+                 ;;        gnus-newsgroup-headers article))
+                 (header (gnus-get-header-by-number article))
                  (value nil))
              (and header
                   (progn
@@ -4490,12 +5399,12 @@ marked as read or unread are ignored."
          (let ((gnus-current-article nil) ;Save article pointer.
                (gnus-last-article nil)
                (gnus-break-pages nil)  ;No need to break pages.
-               (gnus-Mark-article-hook nil)) ;Inhibit marking as read.
+               (gnus-mark-article-hook nil)) ;Inhibit marking as read.
            (message "Searching for article: %d..." article)
-           (gnus-Article-setup-buffer)
-           (gnus-Article-prepare article t)
+           (gnus-article-setup-buffer)
+           (gnus-article-prepare article t)
            (if (save-excursion
-                 (set-buffer gnus-Article-buffer)
+                 (set-buffer gnus-article-buffer)
                  (goto-char (point-min))
                  (re-search-forward regexp nil t))
                (if (stringp form)      ;Keyboard macro.
@@ -4515,8 +5424,7 @@ ROT47 will be performed for Japanese text in any case."
                   (list (prefix-numeric-value current-prefix-arg))
                 (list nil)))
   (cond ((not (numberp n)) (setq n 13))
-       ((< n 0) (setq n (- 26 (% (- n) 26))))
-       (t (setq n (% n 26))))          ;canonicalize N
+       (t (setq n (mod n 26))))        ;canonicalize N
   (if (not (zerop n))          ; no action needed for a rot of 0
       (progn
        (if (or (not (boundp 'caesar-translate-table))
@@ -4544,7 +5452,7 @@ ROT47 will be performed for Japanese text in any case."
                          (if (<= v t1) (if (< v t2) v (+ v 47))
                            (if (<= v t3) (- v 47) v))))
                  (setq i (1+ i))))
-             (message "Building caesar-translate-table... done")))
+             (message "Building caesar-translate-table...done")))
        (let ((from (region-beginning))
              (to (region-end))
              (i 0) str len)
@@ -4602,7 +5510,7 @@ ROT47 will be performed for Japanese text in any case."
   (require 'rmail)
   ;; Most of these codes are borrowed from rmailout.el.
   (setq file-name (expand-file-name file-name))
-  (setq rmail-last-rmail-file file-name)
+  (setq rmail-default-rmail-file file-name)
   (let ((artbuf (current-buffer))
        (tmpbuf (get-buffer-create " *GNUS-output*")))
     (save-excursion
@@ -4707,26 +5615,35 @@ ROT47 will be performed for Japanese text in any case."
   "Open network stream to remote NNTP server.
 If optional argument CONFIRM is non-nil, ask you host that NNTP server
 is running even if it is defined.
-Run gnus-Open-server-hook just before opening news server."
+Run `gnus-open-server-hook' just before opening news server."
   (if (gnus-server-opened)
       ;; Stream is already opened.
       nil
     ;; Open NNTP server.
     (if (or confirm
            (null gnus-nntp-server))
-       (if (and (boundp 'gnus-secondary-servers) gnus-secondary-servers)
-           ;; Read server name with completion.
-           (setq gnus-nntp-server
-                 (completing-read "NNTP server: "
-                                  (cons (list gnus-nntp-server)
-                                        gnus-secondary-servers)
-                                  nil nil gnus-nntp-server))
-         (setq gnus-nntp-server
-               (read-string "NNTP server: " gnus-nntp-server))))
+       ;; If someone has set the service to nil, then this should always
+       ;; be the local host.
+       (if gnus-nntp-service
+           (if (and (boundp 'gnus-secondary-servers) gnus-secondary-servers)
+               ;; Read server name with completion.
+               (setq gnus-nntp-server
+                     (completing-read "NNTP server: "
+                                      (cons (list gnus-nntp-server)
+                                            gnus-secondary-servers)
+                                      nil nil gnus-nntp-server))
+             (setq gnus-nntp-server
+                   (read-string "NNTP server: " gnus-nntp-server)))
+         (setq gnus-nntp-server "")))
     ;; If no server name is given, local host is assumed.
-    (if (string-equal gnus-nntp-server "")
+    (if (or (string-equal gnus-nntp-server "")
+           (string-equal gnus-nntp-server "::")) ;RMS preference.
        (setq gnus-nntp-server (system-name)))
-    (cond ((string= gnus-nntp-server) "::")
+    ;; gnus-nntp-server must be either (system-name), ':DIRECTORY', or
+    ;; nntp server name.  I mean '::' cannot be a value of
+    ;; gnus-nntp-server.
+    (cond ((and (null gnus-nntp-service)
+               (string-equal gnus-nntp-server (system-name)))
           (require 'nnspool)
           (gnus-define-access-method 'nnspool)
           (message "Looking up local news spool..."))
@@ -4738,30 +5655,42 @@ Run gnus-Open-server-hook just before opening news server."
          (t
           (gnus-define-access-method 'nntp)
           (message "Connecting to NNTP server on %s..." gnus-nntp-server)))
-    (run-hooks 'gnus-Open-server-hook)
-    (cond ((gnus-open-server gnus-nntp-server gnus-nntp-service))
-         ((and (stringp (gnus-status-message))
-               (> (length (gnus-status-message)) 0))
-          ;; Show valuable message if available.
-          (error (gnus-status-message)))
-         (t (error "Cannot open NNTP server on %s" gnus-nntp-server)))
+    (run-hooks 'gnus-open-server-hook)
+    (cond ((gnus-server-opened)                ;Maybe opened in gnus-open-server-hook.
+          (message ""))
+         ((gnus-open-server gnus-nntp-server gnus-nntp-service)
+          (message ""))
+         (t
+          (error "%s"
+           (gnus-nntp-message
+            (format "Cannot open NNTP server on %s" gnus-nntp-server)))))
     ))
 
-;; Dummy functions used only once. Should return nil.
+;; Dummy functions used only once.  Should return nil.
 (defun gnus-server-opened () nil)
 (defun gnus-close-server () nil)
 
+(defun gnus-nntp-message (&optional message)
+  "Return a message returned from NNTP server.
+If no message is available and optional MESSAGE is given, return it."
+  (let ((status (gnus-status-message))
+       (message (or message "")))
+    (if (and (stringp status)
+            (> (length status) 0))
+       status message)))
+
 (defun gnus-define-access-method (method &optional access-methods)
   "Define access functions for the access METHOD.
-Methods defintion is taken from optional argument ACCESS-METHODS or
-the variable gnus-access-methods."
+Methods definition is taken from optional argument ACCESS-METHODS or
+the variable `gnus-access-methods'."
   (let ((bindings
         (cdr (assoc method (or access-methods gnus-access-methods)))))
     (if (null bindings)
        (error "Unknown access method: %s" method)
       ;; Should not use symbol-function here since overload does not work.
       (while bindings
-       (fset (car (car bindings)) (cdr (car bindings)))
+       ;; Alist syntax is different from that of 3.14.3.
+       (fset (car (car bindings)) (car (cdr (car bindings))))
        (setq bindings (cdr bindings)))
       )))
 
@@ -4769,6 +5698,8 @@ the variable gnus-access-methods."
   "Select newsgroup GROUP.
 If optional argument SHOW-ALL is non-nil, all of articles in the group
 are selected."
+  ;; Make sure a connection to NNTP server is alive.
+  (gnus-start-news-server)
   (if (gnus-request-group group)
       (let ((articles nil))
        (setq gnus-newsgroup-name group)
@@ -4836,7 +5767,8 @@ are selected."
        (setq gnus-newsgroup-marked
              (gnus-intersection (append gnus-newsgroup-unselected
                                         gnus-newsgroup-unreads)
-                                (cdr (assoc group gnus-marked-assoc))))
+                                (cdr
+                                 (gnus-gethash group gnus-marked-hashtb))))
        ;; First and last article in this newsgroup.
        (setq gnus-newsgroup-begin
              (if gnus-newsgroup-headers
@@ -4860,11 +5792,66 @@ are selected."
        (setq gnus-current-history nil)
        (setq gnus-have-all-headers nil)
        (setq gnus-last-article nil)
+       ;; Clear old hash tables for the variable gnus-newsgroup-headers.
+       (gnus-clear-hashtables-for-newsgroup-headers)
        ;; GROUP is successfully selected.
        t
        )
     ))
 
+;; Hacking for making header search much faster.
+
+(defun gnus-get-header-by-number (number)
+  "Return a header specified by a NUMBER.
+If you update the variable `gnus-newsgroup-headers', you must set the
+hash table `gnus-newsgroup-headers-hashtb-by-number' to nil to indicate
+rehash is necessary."
+  (or gnus-newsgroup-headers-hashtb-by-number
+      (gnus-make-headers-hashtable-by-number))
+  (gnus-gethash (int-to-string number)
+               gnus-newsgroup-headers-hashtb-by-number))
+
+(defun gnus-get-header-by-id (id)
+  "Return a header specified by an ID.
+If you update the variable `gnus-newsgroup-headers', you must set the
+hash table `gnus-newsgroup-headers-hashtb-by-id' to nil to indicate
+rehash is necessary."
+  (or gnus-newsgroup-headers-hashtb-by-id
+      (gnus-make-headers-hashtable-by-id))
+  (and (stringp id)
+       (gnus-gethash id gnus-newsgroup-headers-hashtb-by-id)))
+
+(defun gnus-make-headers-hashtable-by-number ()
+  "Make hashtable for the variable `gnus-newsgroup-headers' by number."
+  (let ((header nil)
+       (headers gnus-newsgroup-headers))
+    (setq gnus-newsgroup-headers-hashtb-by-number
+         (gnus-make-hashtable (length headers)))
+    (while headers
+      (setq header (car headers))
+      (gnus-sethash (int-to-string (nntp-header-number header))
+                   header gnus-newsgroup-headers-hashtb-by-number)
+      (setq headers (cdr headers))
+      )))
+
+(defun gnus-make-headers-hashtable-by-id ()
+  "Make hashtable for the variable `gnus-newsgroup-headers' by id."
+  (let ((header nil)
+       (headers gnus-newsgroup-headers))
+    (setq gnus-newsgroup-headers-hashtb-by-id
+         (gnus-make-hashtable (length headers)))
+    (while headers
+      (setq header (car headers))
+      (gnus-sethash (nntp-header-id header)
+                   header gnus-newsgroup-headers-hashtb-by-id)
+      (setq headers (cdr headers))
+      )))
+
+(defun gnus-clear-hashtables-for-newsgroup-headers ()
+  "Clear hash tables created for the variable `gnus-newsgroup-headers'."
+  (setq gnus-newsgroup-headers-hashtb-by-id nil)
+  (setq gnus-newsgroup-headers-hashtb-by-number nil))
+
 (defun gnus-more-header-backward ()
   "Find new header backward."
   (let ((first
@@ -4900,6 +5887,8 @@ Optional argument BACKWARD means extend toward backward."
              (if backward
                  (cons header gnus-newsgroup-headers)
                (append gnus-newsgroup-headers (list header))))
+       ;; Clear current hash tables for the variable gnus-newsgroup-headers.
+       (gnus-clear-hashtables-for-newsgroup-headers)
        ;; We have to update unreads and unselected, but don't have to
        ;; care about gnus-newsgroup-marked.
        (if (memq artnum gnus-newsgroup-unselected)
@@ -4944,8 +5933,15 @@ that it was marked as read once."
       (set (car variables) nil)
       (setq variables (cdr variables))))
   ;; Clear other internal variables.
+  (setq gnus-newsrc-hashtb nil)
+  (setq gnus-marked-hashtb nil)
+  (setq gnus-killed-hashtb nil)
   (setq gnus-active-hashtb nil)
+  (setq gnus-octive-hashtb nil)
   (setq gnus-unread-hashtb nil)
+  (setq gnus-newsgroup-headers nil)
+  (setq gnus-newsgroup-headers-hashtb-by-id nil)
+  (setq gnus-newsgroup-headers-hashtb-by-number nil)
   ;; Kill the startup file.
   (and gnus-current-startup-file
        (get-file-buffer gnus-current-startup-file)
@@ -4961,20 +5957,22 @@ that it was marked as read once."
 
 (defun gnus-configure-windows (action)
   "Configure GNUS windows according to the next ACTION.
-The ACTION is either a symbol, such as `SelectNewsgroup', or a
+The ACTION is either a symbol, such as `summary', or a
 configuration list such as `(1 1 2)'.  If ACTION is not a list,
-configuration list is got from the variable gnus-window-configuration."
+configuration list is got from the variable `gnus-window-configuration'."
   (let* ((windows
          (if (listp action)
              action (car (cdr (assq action gnus-window-configuration)))))
-        (grpwin (get-buffer-window gnus-Group-buffer))
-        (subwin (get-buffer-window gnus-Subject-buffer))
-        (artwin (get-buffer-window gnus-Article-buffer))
+        (grpwin (get-buffer-window gnus-group-buffer))
+        (subwin (get-buffer-window gnus-summary-buffer))
+        (artwin (get-buffer-window gnus-article-buffer))
         (winsum nil)
         (height nil)
         (grpheight 0)
         (subheight 0)
-        (artheight 0))
+        (artheight 0)
+        ;; Make split-window-vertically leave focus in upper window.
+        (split-window-keep-point t))
     (if (or (null windows)             ;No configuration is specified.
            (and (eq (null grpwin)
                     (zerop (nth 0 windows)))
@@ -4994,13 +5992,13 @@ configuration list is got from the variable gnus-window-configuration."
             (setq height (+ (if grpwin (window-height grpwin) 0)
                             (if subwin (window-height subwin) 0)
                             (if artwin (window-height artwin) 0)))))
-      ;; The Newsgroup buffer exits always. So, use it to extend the
+      ;; The Newsgroup buffer exits always.  So, use it to extend the
       ;; Group window so as to get enough window space.
-      (switch-to-buffer gnus-Group-buffer 'norecord)
-      (and (get-buffer gnus-Subject-buffer)
-          (delete-windows-on gnus-Subject-buffer))
-      (and (get-buffer gnus-Article-buffer)
-          (delete-windows-on gnus-Article-buffer))
+      (switch-to-buffer gnus-group-buffer 'norecord)
+      (and (get-buffer gnus-summary-buffer)
+          (delete-windows-on gnus-summary-buffer))
+      (and (get-buffer gnus-article-buffer)
+          (delete-windows-on gnus-article-buffer))
       ;; Compute expected window height.
       (setq winsum (apply (function +) windows))
       (if (not (zerop (nth 0 windows)))
@@ -5025,18 +6023,18 @@ configuration list is got from the variable gnus-window-configuration."
       ;; Then select buffers in each window.
       (and (not (zerop grpheight))
           (progn
-            (switch-to-buffer gnus-Group-buffer 'norecord)
+            (switch-to-buffer gnus-group-buffer 'norecord)
             (other-window 1)))
       (and (not (zerop subheight))
           (progn
-            (switch-to-buffer gnus-Subject-buffer 'norecord)
+            (switch-to-buffer gnus-summary-buffer 'norecord)
             (other-window 1)))
       (and (not (zerop artheight))
           (progn
             ;; If Article buffer does not exist, it will be created
             ;; and initialized.
-            (gnus-Article-setup-buffer)
-            (switch-to-buffer gnus-Article-buffer 'norecord)))
+            (gnus-article-setup-buffer)
+            (switch-to-buffer gnus-article-buffer 'norecord)))
       )
     ))
 
@@ -5076,29 +6074,29 @@ configuration list is got from the variable gnus-window-configuration."
        (t
         (message "%s; %s" gnus-version nntp-version))))
 
-(defun gnus-Info-find-node ()
+(defun gnus-info-find-node ()
   "Find Info documentation of GNUS."
   (interactive)
   (require 'info)
   ;; Enlarge info window if needed.
-  (cond ((eq major-mode 'gnus-Group-mode)
+  (cond ((eq major-mode 'gnus-group-mode)
         (gnus-configure-windows '(1 0 0)) ;Take all windows.
-        (pop-to-buffer gnus-Group-buffer))
-       ((eq major-mode 'gnus-Subject-mode)
+        (pop-to-buffer gnus-group-buffer))
+       ((eq major-mode 'gnus-summary-mode)
         (gnus-configure-windows '(0 1 0)) ;Take all windows.
-        (pop-to-buffer gnus-Subject-buffer)))
-  (Info-goto-node (cdr (assq major-mode gnus-Info-nodes))))
+        (pop-to-buffer gnus-summary-buffer)))
+  (Info-goto-node (car (cdr (assq major-mode gnus-info-nodes)))))
 
 (defun gnus-overload-functions (&optional overloads)
   "Overload functions specified by optional argument OVERLOADS.
-If nothing is specified, use the variable gnus-overload-functions."
+If nothing is specified, use the variable `gnus-overload-functions'."
   (let ((defs nil)
        (overloads (or overloads gnus-overload-functions)))
     (while overloads
       (setq defs (car overloads))
       (setq overloads (cdr overloads))
       ;; Load file before overloading function if necessary.  Make
-      ;; sure we cannot use `requre' always.
+      ;; sure we cannot use `require' always.
       (and (not (fboundp (car defs)))
           (car (cdr (cdr defs)))
           (load (car (cdr (cdr defs))) nil 'nomessage))
@@ -5108,6 +6106,7 @@ If nothing is specified, use the variable gnus-overload-functions."
 (defun gnus-make-threads (newsgroup-headers)
   "Make conversation threads tree from NEWSGROUP-HEADERS."
   (let ((headers newsgroup-headers)
+       (refer nil)
        (h nil)
        (d nil)
        (roots nil)
@@ -5120,13 +6119,19 @@ If nothing is specified, use the variable gnus-overload-functions."
       (if (vectorp h)                  ;Depends on nntp.el.
          (progn
            ;; Ignore broken references, e.g "<123@a.b.c".
-           (setq d (and (nntp-header-references h)
-                        (string-match "\\(<[^<>]+>\\)[^>]*$"
-                                      (nntp-header-references h))
-                        (gnus-find-header-by-id
-                         newsgroup-headers
-                         (substring (nntp-header-references h)
-                                    (match-beginning 1) (match-end 1)))))
+           (setq refer (nntp-header-references h))
+           (setq d (and refer
+                        (string-match "\\(<[^<>]+>\\)[^>]*$" refer)
+;;                      (gnus-find-header-by-id
+;;                       newsgroup-headers
+;;                       (substring refer (match-beginning 1) (match-end 1)))
+                        ;; In fact if the variable newsgroup-headers
+                        ;; is not 'equal' to the variable
+                        ;; gnus-newsgroup-headers, the following
+                        ;; function call may return bogus value.
+                        (gnus-get-header-by-id
+                         (substring refer (match-beginning 1) (match-end 1)))
+                        ))
            ;; Check subject equality.
            (or gnus-thread-ignore-subject
                (null d)
@@ -5208,6 +6213,22 @@ thus showing a page other than the one point was originally in."
                        (point)))
     ))
 
+;; Create hash table for alist, such as gnus-newsrc-assoc,
+;; gnus-killed-assoc, and gnus-marked-assoc.
+
+(defun gnus-make-hashtable-from-alist (alist &optional hashsize)
+  "Return hash table for ALIST.
+Optional argument HASHSIZE specifies the hashtable size.
+Hash key is a car of alist element, which must be a string."
+  (let ((hashtb (gnus-make-hashtable (or hashsize (length alist)))))
+    (while alist
+      (gnus-sethash (car (car alist))  ;Newsgroup name
+                   (car alist)         ;Alist element
+                   hashtb)
+      (setq alist (cdr alist)))
+    hashtb
+    ))
+
 (defun gnus-last-element (list)
   "Return last element of LIST."
   (let ((last nil))
@@ -5259,7 +6280,7 @@ thus showing a page other than the one point was originally in."
 ;;  ("misc"   14 (1 . 10) (12 . 15))
 ;;  ("test"   99 (1 . 99)) ...)
 
-(defun gnus-setup-news-info (&optional rawfile)
+(defun gnus-setup-news (&optional rawfile)
   "Setup news information.
 If optional argument RAWFILE is non-nil, force to read raw startup file."
   (let ((init (not (and gnus-newsrc-assoc
@@ -5272,11 +6293,27 @@ If optional argument RAWFILE is non-nil, force to read raw startup file."
        (setq gnus-newsrc-assoc nil
              gnus-active-hashtb nil
              gnus-unread-hashtb nil))
-    (if init
-       (gnus-read-newsrc-file rawfile))
     (gnus-read-active-file)
+    ;; Initialize only once.
+    (if init
+       (progn
+         ;; Get distributions only once.
+         (gnus-read-distributions-file)
+         ;; newsrc file must be read after reading active file since
+         ;; its size is used to guess the size of gnus-newsrc-hashtb.
+         (gnus-read-newsrc-file rawfile)
+         ))
     (gnus-expire-marked-articles)
     (gnus-get-unread-articles)
+    
+    ;; newsgroups description
+    (if gnus-newsgroups-display
+       (if (not gnus-newsgroups-alist)
+           ;; Get newsgroups file only once.
+           (gnus-newsgroups-retrieve-description)))
+       
+    (setq gnus-newsgroups-hashtb (gnus-make-hashtable-from-alist gnus-newsgroups-alist))
+    
     ;; Check new newsgroups and subscribe them.
     (if init
        (let ((new-newsgroups (gnus-find-new-newsgroups)))
@@ -5286,23 +6323,17 @@ If optional argument RAWFILE is non-nil, force to read raw startup file."
            )))
     ))
 
-(defun gnus-subscribe-newsgroup (newsgroup &optional next)
-  "Subscribe new NEWSGROUP.
-If optional argument NEXT is non-nil, it is inserted before NEXT."
-  (gnus-insert-newsgroup (list newsgroup t) next)
-  (message "Newsgroup %s is subscribed" newsgroup))
-
 (defun gnus-add-newsgroup (newsgroup)
   "Subscribe new NEWSGROUP safely and put it at top."
-  (and (null (assoc newsgroup gnus-newsrc-assoc)) ;Really new?
+  (and (null (gnus-gethash newsgroup gnus-newsrc-hashtb)) ;Really new?
        (gnus-gethash newsgroup gnus-active-hashtb) ;Really exist?
-       (gnus-insert-newsgroup (or (assoc newsgroup gnus-killed-assoc)
+       (gnus-insert-newsgroup (or (gnus-gethash newsgroup gnus-killed-hashtb)
                                  (list newsgroup t))
                              (car (car gnus-newsrc-assoc)))))
 
 (defun gnus-find-new-newsgroups ()
   "Looking for new newsgroups and return names.
-`-n' option of options line in .newsrc file is recognized."
+`-n' option of options line in `.newsrc' file is recognized."
   (let ((group nil)
        (new-newsgroups nil))
     (mapatoms
@@ -5314,8 +6345,8 @@ If optional argument NEXT is non-nil, it is inserted before NEXT."
                 (not (string-match gnus-newsrc-options-n-no group))
                 (and gnus-newsrc-options-n-yes
                      (string-match gnus-newsrc-options-n-yes group)))
-            (null (assoc group gnus-killed-assoc)) ;Ignore killed.
-            (null (assoc group gnus-newsrc-assoc)) ;Really new.
+            (null (gnus-gethash group gnus-killed-hashtb)) ;Ignore killed.
+            (null (gnus-gethash group gnus-newsrc-hashtb)) ;Really new.
             ;; Find new newsgroup.
             (setq new-newsgroups
                   (cons group new-newsgroups)))
@@ -5326,16 +6357,19 @@ If optional argument NEXT is non-nil, it is inserted before NEXT."
     ))
 
 (defun gnus-kill-newsgroup (group)
-  "Kill GROUP from gnus-newsrc-assoc, .newsrc and gnus-unread-hashtb."
-  (let ((info (assoc group gnus-newsrc-assoc)))
+  "Kill GROUP from `gnus-newsrc-assoc', `.newsrc' and `gnus-unread-hashtb'."
+  (let ((info (gnus-gethash group gnus-newsrc-hashtb)))
     (if (null info)
        nil
-      ;; Delete from gnus-newsrc-assoc
+      ;; Delete from gnus-newsrc-assoc and gnus-newsrc-hashtb.
       (setq gnus-newsrc-assoc (delq info gnus-newsrc-assoc))
-      ;; Add to gnus-killed-assoc.
+      (gnus-sethash group nil gnus-newsrc-hashtb)
+      ;; Add to gnus-killed-assoc and gnus-killed-hashtb.
       (setq gnus-killed-assoc
            (cons info
-                 (delq (assoc group gnus-killed-assoc) gnus-killed-assoc)))
+                 (delq (gnus-gethash group gnus-killed-hashtb)
+                       gnus-killed-assoc)))
+      (gnus-sethash group info gnus-killed-hashtb)
       ;; Clear unread hashtable.
       ;; Thanks cwitty@csli.Stanford.EDU (Carl Witty).
       (gnus-sethash group nil gnus-unread-hashtb)
@@ -5355,15 +6389,15 @@ If optional argument NEXT is nil, appended to the last."
          (gnus-difference-of-range
           (nth 2 (gnus-gethash group gnus-active-hashtb)) (nthcdr 2 info))))
     ;; Check duplication.
-    (if (assoc group gnus-newsrc-assoc)
+    (if (gnus-gethash group gnus-newsrc-hashtb)
        (error "Duplicated: %s" group))
-    ;; Insert to gnus-newsrc-assoc.
+    ;; Insert to gnus-newsrc-assoc and gnus-newsrc-hashtb.
     (if (string-equal next (car (car gnus-newsrc-assoc)))
        (setq gnus-newsrc-assoc
              (cons info gnus-newsrc-assoc))
       (let ((found nil)
-           (rest gnus-newsrc-assoc)
-           (tail (cons nil gnus-newsrc-assoc)))
+           (rest (cdr gnus-newsrc-assoc))
+           (tail gnus-newsrc-assoc))
        ;; Seach insertion point.
        (while (and (not found) rest)
          (if (string-equal next (car (car rest)))
@@ -5372,13 +6406,17 @@ If optional argument NEXT is nil, appended to the last."
            (setq tail (cdr tail))
            ))
        ;; Find it.
-       (setcdr tail nil)
-       (setq gnus-newsrc-assoc
-             (append gnus-newsrc-assoc (cons info rest)))
+       (if (consp tail)
+           (setcdr tail (cons info rest))
+         ;; gnus-newsrc-assoc must be nil.
+         (setq gnus-newsrc-assoc
+               (append gnus-newsrc-assoc (cons info rest))))
        ))
-    ;; Delete from gnus-killed-assoc.
+    (gnus-sethash group info gnus-newsrc-hashtb)
+    ;; Delete from gnus-killed-assoc and gnus-killed-hashtb.
     (setq gnus-killed-assoc
-         (delq (assoc group gnus-killed-assoc) gnus-killed-assoc))
+         (delq (gnus-gethash group gnus-killed-hashtb) gnus-killed-assoc))
+    (gnus-sethash group nil gnus-killed-hashtb)
     ;; Then insert to .newsrc.
     (gnus-update-newsrc-buffer group nil next)
     ;; Add to gnus-unread-hashtb.
@@ -5389,7 +6427,8 @@ If optional argument NEXT is nil, appended to the last."
     ))
 
 (defun gnus-check-killed-newsgroups ()
-  "Check consistency between gnus-newsrc-assoc and gnus-killed-assoc."
+  "Update `gnus-killed-assoc' based on `gnus-newsrc-assoc'.
+Update `gnus-killed-hashtb' also."
   (let ((group nil)
        (new-killed nil)
        (old-killed gnus-killed-assoc))
@@ -5399,13 +6438,15 @@ If optional argument NEXT is nil, appended to the last."
               (not (string-match gnus-newsrc-options-n-no group))
               (and gnus-newsrc-options-n-yes
                    (string-match gnus-newsrc-options-n-yes group)))
-          (null (assoc group gnus-newsrc-assoc)) ;No duplication.
+          (null (gnus-gethash group gnus-newsrc-hashtb)) ;No duplication.
           ;; Subscribed in options line and not in gnus-newsrc-assoc.
           (setq new-killed
                 (cons (car old-killed) new-killed)))
       (setq old-killed (cdr old-killed))
       )
     (setq gnus-killed-assoc (nreverse new-killed))
+    (setq gnus-killed-hashtb
+         (gnus-make-hashtable-from-alist gnus-killed-assoc))
     ))
 
 (defun gnus-check-bogus-newsgroups (&optional confirm)
@@ -5420,7 +6461,7 @@ If optional argument CONFIRM is non-nil, confirm deletion of newsgroups."
        (old-marked gnus-marked-assoc)
        (new-marked nil))
     (message "Checking bogus newsgroups...")
-    ;; Update gnus-newsrc-assoc.
+    ;; Update gnus-newsrc-assoc and gnus-newsrc-hashtb.
     (while old-newsrc
       (setq group (car (car old-newsrc)))
       (if (or (gnus-gethash group gnus-active-hashtb)
@@ -5434,30 +6475,36 @@ If optional argument CONFIRM is non-nil, confirm deletion of newsgroups."
       (setq old-newsrc (cdr old-newsrc))
       )
     (setq gnus-newsrc-assoc (nreverse new-newsrc))
-    ;; Update gnus-killed-assoc.
+    (setq gnus-newsrc-hashtb
+         (gnus-make-hashtable-from-alist gnus-newsrc-assoc))
+    ;; Update gnus-killed-assoc and gnus-killed-hashtb.
     ;; The killed newsgroups are deleted without any confirmations.
     (while old-killed
       (setq group (car (car old-killed)))
       (and (gnus-gethash group gnus-active-hashtb)
-          (null (assoc group gnus-newsrc-assoc))
+          (null (gnus-gethash group gnus-newsrc-hashtb))
           ;; Active and really killed newsgroup.
           (setq new-killed (cons (car old-killed) new-killed)))
       (setq old-killed (cdr old-killed))
       )
     (setq gnus-killed-assoc (nreverse new-killed))
+    (setq gnus-killed-hashtb
+         (gnus-make-hashtable-from-alist gnus-killed-assoc))
     ;; Remove BOGUS from .newsrc file.
     (while bogus
       (gnus-update-newsrc-buffer (car bogus) 'delete)
       (setq bogus (cdr bogus)))
-    ;; Update gnus-marked-assoc.
+    ;; Update gnus-marked-assoc and gnus-marked-hashtb.
     (while old-marked
       (setq group (car (car old-marked)))
       (if (and (cdr (car old-marked))  ;Non-empty?
-              (assoc group gnus-newsrc-assoc)) ;Not bogus?
+              (gnus-gethash group gnus-newsrc-hashtb)) ;Not bogus?
          (setq new-marked (cons (car old-marked) new-marked)))
       (setq old-marked (cdr old-marked)))
     (setq gnus-marked-assoc new-marked)
-    (message "Checking bogus newsgroups... done")
+    (setq gnus-marked-hashtb
+         (gnus-make-hashtable-from-alist gnus-marked-assoc))
+    (message "Checking bogus newsgroups...done")
     ))
 
 (defun gnus-get-unread-articles ()
@@ -5469,7 +6516,8 @@ If optional argument CONFIRM is non-nil, confirm deletion of newsgroups."
        (range nil))
     (message "Checking new news...")
     (or gnus-unread-hashtb
-       (setq gnus-unread-hashtb (gnus-make-hashtable)))
+       (setq gnus-unread-hashtb
+             (gnus-make-hashtable (length gnus-active-hashtb))))
     (while read
       (setq group-info (car read))     ;About one newsgroup
       (setq group-name (car group-info))
@@ -5491,7 +6539,7 @@ If optional argument CONFIRM is non-nil, confirm deletion of newsgroups."
        )
       (setq read (cdr read))
       )
-    (message "Checking new news... done")
+    (message "Checking new news...done")
     ))
 
 (defun gnus-expire-marked-articles ()
@@ -5518,6 +6566,8 @@ If optional argument CONFIRM is non-nil, confirm deletion of newsgroups."
                (cons (cons (car marked) updated) updated-assoc)))
       (setq marked-assoc (cdr marked-assoc)))
     (setq gnus-marked-assoc updated-assoc)
+    (setq gnus-marked-hashtb
+         (gnus-make-hashtable-from-alist gnus-marked-assoc))
     ))
 
 (defun gnus-mark-as-read-by-xref
@@ -5544,9 +6594,9 @@ Arguments are GROUP, HEADERS, UNREADS, and optional SUBSCRIBED-ONLY."
          (or (string-equal group gname) ;Ignore current newsgroup.
              ;; Ignore unsubscribed newsgroup if requested.
              (and subscribed-only
-                  (not (nth 1 (assoc gname gnus-newsrc-assoc))))
+                  (not (nth 1 (gnus-gethash gname gnus-newsrc-hashtb))))
              ;; Ignore article marked as unread.
-             (memq article (cdr (assoc gname gnus-marked-assoc)))
+             (memq article (cdr (gnus-gethash gname gnus-marked-hashtb)))
              (let ((group-xref (assoc gname xref-list)))
                (if group-xref
                    (if (memq article (cdr group-xref))
@@ -5630,40 +6680,49 @@ Arguments are GROUP, HEADERS, UNREADS, and optional SUBSCRIBED-ONLY."
       (if (> (car active) 0)
          ;; Articles from 1 to N are not active.
          (setq active (cons 1 (cdr active))))
-      (setcdr (cdr (assoc group gnus-newsrc-assoc))
+      (setcdr (cdr (gnus-gethash group gnus-newsrc-hashtb))
              (gnus-difference-of-range active (nthcdr 2 unread)))
       ;; Update .newsrc buffer.
       (gnus-update-newsrc-buffer group)
       ;; Update gnus-marked-assoc.
       (if (listp marked-list)          ;Includes NIL.
-         (let ((marked (assoc group gnus-marked-assoc)))
-           (cond (marked
+         (let ((marked (gnus-gethash group gnus-marked-hashtb)))
+           (cond (marked               ;There is an entry.
                   (setcdr marked marked-list))
                  (marked-list          ;Non-NIL.
-                  (setq gnus-marked-assoc
-                        (cons (cons group marked-list)
-                              gnus-marked-assoc)))
+                  (let ((info (cons group marked-list)))
+                    ;; hashtb must share the same cons cell.
+                    (setq gnus-marked-assoc
+                          (cons info gnus-marked-assoc))
+                    (gnus-sethash group info gnus-marked-hashtb)
+                    ))
                  )))
       )))
 
 (defun gnus-read-active-file ()
   "Get active file from NNTP server."
+  ;; Make sure a connection to NNTP server is alive.
+  (gnus-start-news-server)
   (message "Reading active file...")
   (if (gnus-request-list)              ;Get active file from server
       (save-excursion
        (set-buffer nntp-server-buffer)
-       ;; Save OLD active info.
-       (setq gnus-octive-hashtb gnus-active-hashtb)
-       (setq gnus-active-hashtb (gnus-make-hashtable))
        (gnus-active-to-gnus-format)
-       (message "Reading active file... done"))
+       (message "Reading active file...done"))
     (error "Cannot read active file from NNTP server.")))
 
 (defun gnus-active-to-gnus-format ()
-  "Convert active file format to internal format."
+  "Convert active file format to internal format.
+Lines matching `gnus-ignored-newsgroups' are ignored."
   ;; Delete unnecessary lines.
   (goto-char (point-min))
-  (delete-matching-lines "^to\\..*$")
+  ;;(delete-matching-lines "^to\\..*$")
+  (delete-matching-lines gnus-ignored-newsgroups)
+  ;; Save OLD active info.
+  (setq gnus-octive-hashtb gnus-active-hashtb)
+  ;; Make large enough hash table.
+  (setq gnus-active-hashtb
+       (gnus-make-hashtable (count-lines (point-min) (point-max))))
   ;; Store active file in hashtable.
   (goto-char (point-min))
   (while
@@ -5679,16 +6738,13 @@ Arguments are GROUP, HEADERS, UNREADS, and optional SUBSCRIBED-ONLY."
                  (buffer-substring (match-beginning 3) (match-end 3)))
                 (string-to-int
                  (buffer-substring (match-beginning 2) (match-end 2)))))
-     gnus-active-hashtb)))
+     gnus-active-hashtb)
+    ))
 
 (defun gnus-read-newsrc-file (&optional rawfile)
   "Read startup FILE.
 If optional argument RAWFILE is non-nil, the raw startup file is read."
-  (setq gnus-current-startup-file
-       (let* ((file (expand-file-name gnus-startup-file nil))
-              (real-file (concat file "-" gnus-nntp-server)))
-         (if (file-exists-p real-file)
-             real-file file)))
+  (setq gnus-current-startup-file (gnus-make-newsrc-file gnus-startup-file))
   ;; Reset variables which may be included in the quick startup file.
   (let ((variables gnus-variable-list))
     (while variables
@@ -5696,9 +6752,7 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
       (setq variables (cdr variables))))
   (let* ((newsrc-file gnus-current-startup-file)
         (quick-file (concat newsrc-file ".el"))
-        (quick-loaded nil)
-        (newsrc-mod (nth 5 (file-attributes newsrc-file)))
-        (quick-mod (nth 5 (file-attributes quick-file))))
+        (quick-loaded nil))
     (save-excursion
       ;; Prepare .newsrc buffer.
       (set-buffer (find-file-noselect newsrc-file))
@@ -5707,30 +6761,34 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
       ;; Load quick .newsrc to restore gnus-marked-assoc and
       ;; gnus-killed-assoc even if gnus-newsrc-assoc is out of date.
       (condition-case nil
-         (setq quick-loaded (load quick-file t t t))
+         (progn
+           (setq quick-loaded (load quick-file t t t))
+           ;; Recreate hashtables.
+           (setq gnus-killed-hashtb
+                 (gnus-make-hashtable-from-alist gnus-killed-assoc))
+           (setq gnus-marked-hashtb
+                 (gnus-make-hashtable-from-alist gnus-marked-assoc))
+           )
        (error nil))
       (cond ((and (not rawfile)                ;Not forced to read the raw file.
-                 (or (and (fboundp 'file-newer-than-file-p)
-                          (file-newer-than-file-p quick-file newsrc-file))
-                     (and newsrc-mod quick-mod
-                          ;; .newsrc.el is newer than .newsrc.
-                          ;; Some older version does not support function
-                          ;; `file-newer-than-file-p'.
-                          (or (< (car newsrc-mod) (car quick-mod))
-                              (and (= (car newsrc-mod) (car quick-mod))
-                                   (<= (nth 1 newsrc-mod) (nth 1 quick-mod))))
-                          ))
+                 ;; .newsrc.el is newer than .newsrc.
+                 ;; Do it this way in case timestamps are identical
+                 ;; (on fast machines/disks).
+                 (not (file-newer-than-file-p newsrc-file quick-file))
                  quick-loaded
                  gnus-newsrc-assoc     ;Really loaded?
                  )
             ;; We don't have to read the raw startup file.
-            )
+            ;; gnus-newsrc-assoc may be defined in the quick startup file.
+            ;; So, we have to define the hashtable here.
+            (setq gnus-newsrc-hashtb
+                  (gnus-make-hashtable-from-alist gnus-newsrc-assoc)))
            (t
             ;; Since .newsrc file is newer than quick file, read it.
             (message "Reading %s..." newsrc-file)
             (gnus-newsrc-to-gnus-format)
             (gnus-check-killed-newsgroups)
-            (message "Reading %s... Done" newsrc-file)))
+            (message "Reading %s...done" newsrc-file)))
       )))
 
 (defun gnus-make-newsrc-file (file)
@@ -5742,7 +6800,7 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
     ))
 
 (defun gnus-newsrc-to-gnus-format ()
-  "Parse current buffer as .newsrc file."
+  "Parse current buffer as `.newsrc' file."
   (let ((newsgroup nil)
        (subscribe nil)
        (ranges nil)
@@ -5755,6 +6813,11 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
     (setq gnus-newsrc-options-n-yes nil)
     (setq gnus-newsrc-options-n-no nil)
     (setq gnus-newsrc-assoc nil)
+    ;; Make large enough hash table.
+    (setq gnus-newsrc-hashtb
+         (gnus-make-hashtable
+          (max (length gnus-active-hashtb)
+               (count-lines (point-min) (point-max)))))
     ;; Save options line to variable.
     ;; Lines beginning with white spaces are treated as continuation
     ;; line.  Refer man page of newsrc(5).
@@ -5779,20 +6842,28 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
     ;; Before supporting continuation lines, " newsgroup ! 1-5" was
     ;; okay, but now it is invalid.  It should be "newsgroup! 1-5".
     (goto-char (point-min))
-    ;; Due to overflows in regex.c, change the following regexp:
+    ;; We used this regexp, but it caused overflows.
     ;; "^\\([^:! \t\n]+\\)\\([:!]\\)[ \t]*\\(.*\\)$"
-    ;; Suggested by composer@bucsf.bu.edu (Jeff Kellem).
-    (while (re-search-forward
-           "^\\([^:! \t\n]+\\)\\([:!]\\)[ \t]*\\(\\(...\\)*.*\\)$" nil t)
+    ;; Suggested by composer@bucsf.bu.edu (Jeff Kellem)
+    ;; but no longer viable because of extensive backtracking in Emacs 19:
+    ;; "^\\([^:! \t\n]+\\)\\([:!]\\)[ \t]*\\(\\(...\\)*.*\\)$"
+    ;; but, the following causes trouble on some case:
+    ;; "^\\([^:! \t\n]+\\)\\([:!]\\)[ \t]*\\(\\|[^ \t\n].*\\)$"
+    ;; So now we don't try to match the tail of the line at all.
+    ;; It's just as easy to extract it later.
+    (while (re-search-forward "^\\([^:! \t\n]+\\)\\([:!]\\)"
+                             nil t)
       (setq newsgroup (buffer-substring (match-beginning 1) (match-end 1)))
       ;; Check duplications of newsgroups.
       ;; Note: Checking the duplications takes very long time.
-      (if (assoc newsgroup gnus-newsrc-assoc)
+      (if (gnus-gethash newsgroup gnus-newsrc-hashtb)
          (message "Ignore duplicated newsgroup: %s" newsgroup)
        (setq subscribe
              (string-equal
               ":" (buffer-substring (match-beginning 2) (match-end 2))))
-       (setq ranges (buffer-substring (match-beginning 3) (match-end 3)))
+       (skip-chars-forward " \t")
+       (setq ranges (buffer-substring (point) (save-excursion
+                                                (end-of-line) (point))))
        (setq read-list nil)
        (while (string-match "^[, \t]*\\([0-9-]+\\)" ranges)
          (setq subrange (substring ranges (match-beginning 1) (match-end 1)))
@@ -5819,9 +6890,10 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
        (setq gnus-newsrc-assoc
              (cons (cons newsgroup (cons subscribe (nreverse read-list)))
                    gnus-newsrc-assoc))
+       ;; Update gnus-newsrc-hashtb one by one.
+       (gnus-sethash newsgroup (car gnus-newsrc-assoc) gnus-newsrc-hashtb)
        ))
-    (setq gnus-newsrc-assoc
-         (nreverse gnus-newsrc-assoc))
+    (setq gnus-newsrc-assoc (nreverse gnus-newsrc-assoc))
     ))
 
 (defun gnus-parse-n-options (options)
@@ -5833,7 +6905,7 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
     ;; Parse each newsgroup description such as "comp.all".  Commas
     ;; and white spaces can be a newsgroup separator.
     (while
-       (string-match "^[ \t\n,]*\\(!?\\)\\([^--- \t\n,][^ \t\n,]*\\)" options)
+       (string-match "^[ \t\n,]*\\(!?\\)\\([^- \t\n,][^ \t\n,]*\\)" options)
       (setq yes-or-no
            (substring options (match-beginning 1) (match-end 1)))
       (setq newsgroup
@@ -5848,13 +6920,18 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
              (concat (substring newsgroup 0 (match-end 1))
                      ".+"
                      (substring newsgroup (match-beginning 2)))))
+      ;; It is yes or no.
       (cond ((string-equal yes-or-no "!")
             (setq no (cons newsgroup no)))
            ((string-equal newsgroup ".+")) ;Ignore `all'.
            (t
-            (setq yes (cons newsgroup yes)))
-           ))
+            (setq yes (cons newsgroup yes))))
+      )
     ;; Make a cons of regexps from parsing result.
+    ;; We have to append \(\.\|$\) to prevent matching substring of
+    ;; newsgroup.  For example, "jp.net" should not match with
+    ;; "jp.network".
+    ;; Fixes for large regexp problems are from yonezu@nak.math.keio.ac.jp.
     (cons (if yes
              (concat "^\\("
                      (apply (function concat)
@@ -5863,7 +6940,7 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
                               (lambda (newsgroup)
                                 (concat newsgroup "\\|")))
                              (cdr yes)))
-                     (car yes) "\\)"))
+                     (car yes) "\\)\\(\\.\\|$\\)"))
          (if no
              (concat "^\\("
                      (apply (function concat)
@@ -5872,11 +6949,11 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
                               (lambda (newsgroup)
                                 (concat newsgroup "\\|")))
                              (cdr no)))
-                     (car no) "\\)")))
+                     (car no) "\\)\\(\\.\\|$\\)")))
     ))
 
 (defun gnus-save-newsrc-file ()
-  "Save to .newsrc FILE."
+  "Save current status in the `.newsrc' file."
   ;; Note: We cannot save .newsrc file if all newsgroups are removed
   ;; from the variable gnus-newsrc-assoc.
   (and (or gnus-newsrc-assoc gnus-killed-assoc)
@@ -5893,7 +6970,7 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
             ;; Make backup file of master newsrc.
             ;; You can stop or change version control of backup file.
             ;; Suggested by jason@violet.berkeley.edu.
-            (run-hooks 'gnus-Save-newsrc-hook)
+            (run-hooks 'gnus-save-newsrc-hook)
             (save-buffer))
           ;; Quickly loadable .newsrc.
           (set-buffer (get-buffer-create " *GNUS-newsrc*"))
@@ -5905,14 +6982,14 @@ If optional argument RAWFILE is non-nil, the raw startup file is read."
                 (require-final-newline t)) ;Don't ask even if requested.
             (write-file (concat gnus-current-startup-file ".el")))
           (kill-buffer (current-buffer))
-          (message "Saving %s... Done" gnus-current-startup-file)
+          (message "Saving %s...done" gnus-current-startup-file)
           ))
     ))
 
 (defun gnus-update-newsrc-buffer (group &optional delete next)
-  "Incrementally update .newsrc buffer about GROUP.
-If optional second argument DELETE is non-nil, delete the group.
-If optional third argument NEXT is non-nil, inserted before it."
+  "Incrementally update `.newsrc' buffer about GROUP.
+If optional 1st argument DELETE is non-nil, delete the group.
+If optional 2nd argument NEXT is non-nil, inserted before it."
   (save-excursion
     ;; Taking account of the killed startup file.
     ;; Suggested by tale@pawl.rpi.edu.
@@ -5922,6 +6999,7 @@ If optional third argument NEXT is non-nil, inserted before it."
     ;; Before supporting continuation lines, " newsgroup ! 1-5" was
     ;; okay, but now it is invalid.  It should be "newsgroup! 1-5".
     (let ((deleted nil)
+         (case-fold-search nil)        ;Should NOT ignore case.
          (buffer-read-only nil))       ;May be not modifiable.
       ;; Delete ALL entries which match for GROUP.
       (goto-char (point-min))
@@ -5934,7 +7012,7 @@ If optional third argument NEXT is non-nil, inserted before it."
       (if delete
          nil
        ;; Insert group entry.
-       (let ((newsrc (assoc group gnus-newsrc-assoc)))
+       (let ((newsrc (gnus-gethash group gnus-newsrc-hashtb)))
          (if (null newsrc)
              nil
            ;; Find insertion point.
@@ -5970,9 +7048,12 @@ If optional third argument NEXT is non-nil, inserted before it."
   (insert ";; Touch .newsrc instead if you think to remove this file.\n")
   (let ((variable nil)
        (variables gnus-variable-list)
-       ;; Temporary rebind to make changes invisible.
-       (gnus-killed-assoc gnus-killed-assoc))
-    ;; Remove duplicated or unsubscribed newsgroups in gnus-killed-assoc.
+       ;; Temporary rebind to make changes
+       ;; gnus-check-killed-newsgroups in invisible.
+       (gnus-killed-assoc gnus-killed-assoc)
+       (gnus-killed-hashtb gnus-killed-hashtb))
+    ;; Remove duplicated or unsubscribed newsgroups in
+    ;; gnus-killed-assoc (and gnus-killed-hashtb).
     (gnus-check-killed-newsgroups)
     ;; Then, insert lisp expressions.
     (while variables
@@ -6047,7 +7128,7 @@ If optional third argument NEXT is non-nil, inserted before it."
   (let ((count 0))
     (while range
       (if (/= (cdr (car range)) 0)
-         ;; If end1 is 0, it must be skipped. Usually no articles in
+         ;; If end1 is 0, it must be skipped.  Usually no articles in
          ;;  this group.
          (setq count (+ count 1 (- (cdr (car range)) (car (car range))))))
       (setq range (cdr range))
@@ -6085,11 +7166,78 @@ Range of OBJ is expressed as `((beg1 . end1) (beg2 . end2) ...)."
       (list (cons 0 0)))
     ))
 
+(defun gnus-read-distributions-file ()
+  "Get distributions file from NNTP server (NNTP2 functionality)."
+  ;; Make sure a connection to NNTP server is alive.
+  (gnus-start-news-server)
+  (message "Reading distributions file...")
+  (setq gnus-distribution-list nil)
+  (if (gnus-request-list-distributions)
+      (save-excursion
+       (set-buffer nntp-server-buffer)
+       (gnus-distributions-to-gnus-format)
+       (message "Reading distributions file...done"))
+    ;; It's not a fatal error.
+    ;;(error "Cannot read distributions file from NNTP server.")
+    )
+  ;; Merge with user supplied default distributions.
+  (let ((defaults (reverse gnus-local-distributions))
+       (dist nil))
+    (while defaults
+      (setq dist (assoc (car defaults) gnus-distribution-list))
+      (if dist
+         (setq gnus-distribution-list
+               (delq dist gnus-distribution-list)))
+      (setq gnus-distribution-list
+           (cons (list (car defaults)) gnus-distribution-list))
+      (setq defaults (cdr defaults))
+      )))
+
+(defun gnus-distributions-to-gnus-format ()
+  "Convert distributions file format to internal format."
+  (setq gnus-distribution-list nil)
+  (goto-char (point-min))
+  (while (re-search-forward "^\\([^ \t\n]+\\).*$" nil t)
+    (setq gnus-distribution-list
+         (cons (list (buffer-substring (match-beginning 1) (match-end 1)))
+               gnus-distribution-list)))
+  (setq gnus-distribution-list
+       (nreverse gnus-distribution-list)))
 \f
-;;Local variables:
-;;eval: (put 'gnus-eval-in-buffer-window 'lisp-indent-function 1)
-;;end:
+(defun gnus-newsgroups-retrieve-description ()
+  "Retrieve newsgroups description and build gnus-newsgroups-alist"
+  (message "Reading newsgroups file...")
+  (if (gnus-request-list-newsgroups)
+      (save-excursion
+       (setq gnus-newsgroups-alist nil)
+       (set-buffer nntp-server-buffer)
+       (goto-char (point-min))
+       (while (re-search-forward gnus-newsgroups-regex nil t)
+         (setq gnus-newsgroups-alist
+               (cons (cons (buffer-substring (match-beginning 1) (match-end 1))
+                           (buffer-substring (match-beginning 2) (match-end 2)))
+                     gnus-newsgroups-alist)))
+       (message "Reading newsgroups file...done"))
+    (message "Cannot read newsgroups file")))
+
+(defun gnus-newsgroups-update-description ()
+  "Update the newsgroups description"
+  (interactive)
+  (gnus-newsgroups-retrieve-description)
+  (setq gnus-newsgroups-hashtb (gnus-make-hashtable-from-alist gnus-newsgroups-alist)))
 
+(defun gnus-newsgroups-display-toggle ()
+  "Toggle displaying newsgroup descriptions in *Newsgroup* buffer."
+  (interactive)
+  (setq gnus-newsgroups-display (not gnus-newsgroups-display))
+  (if gnus-newsgroups-showall
+        (gnus-group-list-groups t)
+    (gnus-group-list-groups nil)))
+\f
 (provide 'gnus)
 
+;;Local variables:
+;;eval: (put 'gnus-eval-in-buffer-window 'lisp-indent-hook 1)
+;;end:
+
 ;;; gnus.el ends here