Synch to Gnus 200311102021.
[elisp/gnus.git-] / lisp / message.el
index 16fb745..fed132e 100644 (file)
-;;; message.el --- composing mail and news messages\r
-;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.\r
-\r
-;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>\r
-;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>\r
-;;     Shuhei KOBAYASHI <shuhei-k@jaist.ac.jp>\r
-;;     Keiichi Suzuki <kei-suzu@mail.wbs.ne.jp>\r
-;;     Tatsuya Ichikawa <t-ichi@po.shiojiri.ne.jp>\r
-;;     Katsumi Yamaoka <yamaoka@jpl.org>\r
-;; Keywords: mail, news, MIME\r
-\r
-;; This file is part of GNU Emacs.\r
-\r
-;; GNU Emacs is free software; you can redistribute it and/or modify\r
-;; it under the terms of the GNU General Public License as published by\r
-;; the Free Software Foundation; either version 2, or (at your option)\r
-;; any later version.\r
-\r
-;; GNU Emacs is distributed in the hope that it will be useful,\r
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the\r
-;; GNU General Public License for more details.\r
-\r
-;; You should have received a copy of the GNU General Public License\r
-;; along with GNU Emacs; see the file COPYING.  If not, write to the\r
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,\r
-;; Boston, MA 02111-1307, USA.\r
-\r
-;;; Commentary:\r
-\r
-;; This mode provides mail-sending facilities from within Emacs.  It\r
-;; consists mainly of large chunks of code from the sendmail.el,\r
-;; gnus-msg.el and rnewspost.el files.\r
-\r
-;;; Code:\r
-\r
-(eval-when-compile\r
-  (require 'cl)\r
-  (require 'smtp)\r
-  )\r
-\r
-(require 'mailheader)\r
-(require 'nnheader)\r
-(require 'easymenu)\r
-(require 'custom)\r
-(if (string-match "XEmacs\\|Lucid" emacs-version)\r
-    (require 'mail-abbrevs)\r
-  (require 'mailabbrev))\r
-(require 'mime-edit)\r
-\r
-;; Avoid byte-compile warnings.\r
-(eval-when-compile\r
-  (require 'mail-parse)\r
-  (require 'mm-bodies)\r
-  (require 'mm-encode)\r
-  (require 'mml)\r
-  )\r
-\r
-(defgroup message '((user-mail-address custom-variable)\r
-                   (user-full-name custom-variable))\r
-  "Mail and news message composing."\r
-  :link '(custom-manual "(message)Top")\r
-  :group 'mail\r
-  :group 'news)\r
-\r
-(put 'user-mail-address 'custom-type 'string)\r
-(put 'user-full-name 'custom-type 'string)\r
-\r
-(defgroup message-various nil\r
-  "Various Message Variables"\r
-  :link '(custom-manual "(message)Various Message Variables")\r
-  :group 'message)\r
-\r
-(defgroup message-buffers nil\r
-  "Message Buffers"\r
-  :link '(custom-manual "(message)Message Buffers")\r
-  :group 'message)\r
-\r
-(defgroup message-sending nil\r
-  "Message Sending"\r
-  :link '(custom-manual "(message)Sending Variables")\r
-  :group 'message)\r
-\r
-(defgroup message-interface nil\r
-  "Message Interface"\r
-  :link '(custom-manual "(message)Interface")\r
-  :group 'message)\r
-\r
-(defgroup message-forwarding nil\r
-  "Message Forwarding"\r
-  :link '(custom-manual "(message)Forwarding")\r
-  :group 'message-interface)\r
-\r
-(defgroup message-insertion nil\r
-  "Message Insertion"\r
-  :link '(custom-manual "(message)Insertion")\r
-  :group 'message)\r
-\r
-(defgroup message-headers nil\r
-  "Message Headers"\r
-  :link '(custom-manual "(message)Message Headers")\r
-  :group 'message)\r
-\r
-(defgroup message-news nil\r
-  "Composing News Messages"\r
-  :group 'message)\r
-\r
-(defgroup message-mail nil\r
-  "Composing Mail Messages"\r
-  :group 'message)\r
-\r
-(defgroup message-faces nil\r
-  "Faces used for message composing."\r
-  :group 'message\r
-  :group 'faces)\r
-\r
-(defgroup message-frames nil\r
-  "Message frames"\r
-  :group 'message)\r
-\r
-(defcustom message-directory "~/Mail/"\r
-  "*Directory from which all other mail file variables are derived."\r
-  :group 'message-various\r
-  :type 'directory)\r
-\r
-(defcustom message-max-buffers 10\r
-  "*How many buffers to keep before starting to kill them off."\r
-  :group 'message-buffers\r
-  :type 'integer)\r
-\r
-(defcustom message-send-rename-function nil\r
-  "Function called to rename the buffer after sending it."\r
-  :group 'message-buffers\r
-  :type 'function)\r
-\r
-(defcustom message-fcc-handler-function 'message-output\r
-  "*A function called to save outgoing articles.\r
-This function will be called with the name of the file to store the\r
-article in.  The default function is `message-output' which saves in Unix\r
-mailbox format."\r
-  :type '(radio (function-item message-output)\r
-               (function :tag "Other"))\r
-  :group 'message-sending)\r
-\r
-(defcustom message-encode-function 'message-maybe-encode\r
-  "*A function called to encode messages."\r
-  :group 'message-sending\r
-  :type 'function)\r
-\r
-(defcustom message-8bit-encoding-list '(8bit binary)\r
-  "*8bit encoding type in Content-Transfer-Encoding field."\r
-  :group 'message-sending\r
-  :type '(repeat (symbol :tag "Type")))\r
-\r
-(defcustom message-courtesy-message\r
-  "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n"\r
-  "*This is inserted at the start of a mailed copy of a posted message.\r
-If the string contains the format spec \"%s\", the Newsgroups\r
-the article has been posted to will be inserted there.\r
-If this variable is nil, no such courtesy message will be added."\r
-  :group 'message-sending\r
-  :type 'string)\r
-\r
-(defcustom message-ignored-bounced-headers "^\\(Received\\|Return-Path\\):"\r
-  "*Regexp that matches headers to be removed in resent bounced mail."\r
-  :group 'message-interface\r
-  :type 'regexp)\r
-\r
-(defcustom message-bounce-setup-function 'message-bounce-setup-for-mime-edit\r
-  "Function to setup a re-sending bounced message."\r
-  :group 'message-sending\r
-  :type 'function)\r
-\r
-;;;###autoload\r
-(defcustom message-from-style 'default\r
-  "*Specifies how \"From\" headers look.\r
-\r
-If `nil', they contain just the return address like:\r
-       king@grassland.com\r
-If `parens', they look like:\r
-       king@grassland.com (Elvis Parsley)\r
-If `angles', they look like:\r
-       Elvis Parsley <king@grassland.com>\r
-\r
-Otherwise, most addresses look like `angles', but they look like\r
-`parens' if `angles' would need quoting and `parens' would not."\r
-  :type '(choice (const :tag "simple" nil)\r
-                (const parens)\r
-                (const angles)\r
-                (const default))\r
-  :group 'message-headers)\r
-\r
-(defcustom message-syntax-checks nil\r
-  ; Guess this one shouldn't be easy to customize...\r
-  "*Controls what syntax checks should not be performed on outgoing posts.\r
-To disable checking of long signatures, for instance, add\r
- `(signature . disabled)' to this list.\r
-\r
-Don't touch this variable unless you really know what you're doing.\r
-\r
-Checks include subject-cmsg multiple-headers sendsys message-id from\r
-long-lines control-chars size new-text redirected-followup signature\r
-approved sender empty empty-headers message-id from subject\r
-shorten-followup-to existing-newsgroups buffer-file-name unchanged."\r
-  :group 'message-news)\r
-\r
-(defcustom message-required-news-headers\r
-  '(From Newsgroups Subject Date Message-ID\r
-        (optional . Organization) Lines\r
-        (optional . User-Agent))\r
-  "*Headers to be generated or prompted for when posting an article.\r
-RFC977 and RFC1036 require From, Date, Newsgroups, Subject,\r
-Message-ID.  Organization, Lines, In-Reply-To, Expires, and\r
-User-Agent are optional.  If don't you want message to insert some\r
-header, remove it from this list."\r
-  :group 'message-news\r
-  :group 'message-headers\r
-  :type '(repeat sexp))\r
-\r
-(defcustom message-required-mail-headers\r
-  '(From Subject Date (optional . In-Reply-To) Message-ID Lines\r
-        (optional . User-Agent))\r
-  "*Headers to be generated or prompted for when mailing a message.\r
-RFC822 required that From, Date, To, Subject and Message-ID be\r
-included.  Organization, Lines and User-Agent are optional."\r
-  :group 'message-mail\r
-  :group 'message-headers\r
-  :type '(repeat sexp))\r
-\r
-(defcustom message-deletable-headers '(Message-ID Date Lines)\r
-  "Headers to be deleted if they already exist and were generated by message previously."\r
-  :group 'message-headers\r
-  :type 'sexp)\r
-\r
-(defcustom message-ignored-news-headers\r
-  "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:"\r
-  "*Regexp of headers to be removed unconditionally before posting."\r
-  :group 'message-news\r
-  :group 'message-headers\r
-  :type 'regexp)\r
-\r
-(defcustom message-ignored-mail-headers "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:"\r
-  "*Regexp of headers to be removed unconditionally before mailing."\r
-  :group 'message-mail\r
-  :group 'message-headers\r
-  :type 'regexp)\r
-\r
-(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:"\r
-  "*Header lines matching this regexp will be deleted before posting.\r
-It's best to delete old Path and Date headers before posting to avoid\r
-any confusion."\r
-  :group 'message-interface\r
-  :type 'regexp)\r
-\r
-(defcustom message-supersede-setup-function\r
-  'message-supersede-setup-for-mime-edit\r
-  "Function to setup a supersede message."\r
-  :group 'message-sending\r
-  :type 'function)\r
-\r
-(defcustom message-subject-re-regexp "^[ \t]*\\([Rr][Ee]:[ \t]*\\)*[ \t]*"\r
-  "*Regexp matching \"Re: \" in the subject line."\r
-  :group 'message-various\r
-  :type 'regexp)\r
-\r
-;;; Some sender agents encode the whole subject including leading "Re: ".\r
-;;; And if followup agent does not decode it for some reason (e.g. unknown\r
-;;; charset) and just add a new "Re: " in front of the encoded-word, the\r
-;;; result will contain multiple "Re: "'s.\r
-(defcustom message-subject-encoded-re-regexp\r
-  (concat\r
-   "^[ \t]*"\r
-   (regexp-quote "=?")\r
-   "[-!#$%&'*+0-9A-Z^_`a-z{|}~]+" ; charset\r
-   (regexp-quote "?")\r
-   "\\("\r
-   "[Bb]" (regexp-quote "?") ; B encoding\r
-   "\\(\\(CQk\\|CSA\\|IAk\\|ICA\\)[Jg]\\)*" ; \([ \t][ \t][ \t]\)*\r
-   "\\("\r
-   "[Uc][km]U6" ; [Rr][Ee]:\r
-   "\\|"\r
-   "\\(C[VX]\\|I[FH]\\)J[Fl]O[g-v]" ; [ \t][Rr][Ee]:\r
-   "\\|"\r
-   "\\(CQl\\|CSB\\|IAl\\|ICB\\)[Sy][RZ]T[o-r]" ; [ \t][ \t][Rr][Ee]:\r
-   "\\)"\r
-   "\\|"\r
-   "[Qb]" (regexp-quote "?") ; Q encoding\r
-   "\\(_\\|=09\\|=20\\)*"\r
-   "\\([Rr]\\|=[57]2\\)\\([Ee]\\|=[46]5\\)\\(:\\|=3[Aa]\\)"\r
-   "\\)"\r
-   )\r
-  "*Regexp matching \"Re: \" in the subject line.\r
-Unlike `message-subject-re-regexp', this regexp matches \"Re: \" within\r
-an encoded-word."\r
-  :group 'message-various\r
-  :type 'regexp)\r
-\r
-(defcustom message-use-subject-re t\r
-  "*If t, remove any (buggy) \"Re: \"'s from the subject of the precursor\r
-and add a new \"Re: \".  If it is nil, use the subject \"as-is\".  If it\r
-is the symbol `guess', try to detect \"Re: \" within an encoded-word."\r
-  :group 'message-various\r
-  :type '(choice (const :tag "off" nil)\r
-                 (const :tag "on" t)\r
-                 (const guess)))\r
-\r
-;;;###autoload\r
-(defcustom message-signature-separator "^-- *$"\r
-  "Regexp matching the signature separator."\r
-  :type 'regexp\r
-  :group 'message-various)\r
-\r
-(defcustom message-elide-elipsis "\n[...]\n\n"\r
-  "*The string which is inserted for elided text."\r
-  :type 'string\r
-  :group 'message-various)\r
-\r
-(defcustom message-interactive nil\r
-  "Non-nil means when sending a message wait for and display errors.\r
-nil means let mailer mail back a message to report errors."\r
-  :group 'message-sending\r
-  :group 'message-mail\r
-  :type 'boolean)\r
-\r
-(defcustom message-generate-new-buffers 'unique\r
-  "*Non-nil means that a new message buffer will be created whenever `message-setup' is called.\r
-If this is a function, call that function with three parameters:  The type,\r
-the to address and the group name.  (Any of these may be nil.)  The function\r
-should return the new buffer name."\r
-  :group 'message-buffers\r
-  :type '(choice (const :tag "off" nil)\r
-                (const :tag "unique" unique)\r
-                (const :tag "unsent" unsent)\r
-                (function fun)))\r
-\r
-(defcustom message-kill-buffer-on-exit nil\r
-  "*Non-nil means that the message buffer will be killed after sending a message."\r
-  :group 'message-buffers\r
-  :type 'boolean)\r
-\r
-(defcustom message-kill-buffer-query-function 'yes-or-no-p\r
-  "*A function called to query the user whether to kill buffer anyway or not.\r
-If it is t, the buffer will be killed peremptorily."\r
-  :type '(radio (function-item yes-or-no-p)\r
-               (function-item y-or-n-p)\r
-               (function-item nnheader-Y-or-n-p)\r
-               (function :tag "Other" t))\r
-  :group 'message-buffers)\r
-\r
-(defvar gnus-local-organization)\r
-(defcustom message-user-organization\r
-  (or (and (boundp 'gnus-local-organization)\r
-          (stringp gnus-local-organization)\r
-          gnus-local-organization)\r
-      (getenv "ORGANIZATION")\r
-      t)\r
-  "*String to be used as an Organization header.\r
-If t, use `message-user-organization-file'."\r
-  :group 'message-headers\r
-  :type '(choice string\r
-                (const :tag "consult file" t)))\r
-\r
-;;;###autoload\r
-(defcustom message-user-organization-file "/usr/lib/news/organization"\r
-  "*Local news organization file."\r
-  :type 'file\r
-  :group 'message-headers)\r
-\r
-(defcustom message-forward-start-separator\r
-  (concat (mime-make-tag "message" "rfc822") "\n")\r
-  "*Delimiter inserted before forwarded messages."\r
-  :group 'message-forwarding\r
-  :type 'string)\r
-\r
-(defcustom message-forward-end-separator\r
-  (concat (mime-make-tag "text" "plain") "\n")\r
-  "*Delimiter inserted after forwarded messages."\r
-  :group 'message-forwarding\r
-  :type 'string)\r
-\r
-(defcustom message-signature-before-forwarded-message t\r
-  "*If non-nil, put the signature before any included forwarded message."\r
-  :group 'message-forwarding\r
-  :type 'boolean)\r
-\r
-(defcustom message-included-forward-headers\r
-  "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^\\(Mail-\\)?Followup-To:\\|^\\(Mail-\\)?Reply-To:\\|^Mail-Copies-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:\\|^Content-\\|^MIME-Version:"\r
-  "*Regexp matching headers to be included in forwarded messages."\r
-  :group 'message-forwarding\r
-  :type 'regexp)\r
-\r
-(defcustom message-make-forward-subject-function\r
-  'message-forward-subject-author-subject\r
- "*A list of functions that are called to generate a subject header for forwarded messages.\r
-The subject generated by the previous function is passed into each\r
-successive function.\r
-\r
-The provided functions are:\r
-\r
-* message-forward-subject-author-subject (Source of article (author or\r
-      newsgroup)), in brackets followed by the subject\r
-* message-forward-subject-fwd (Subject of article with 'Fwd:' prepended\r
-      to it."\r
- :group 'message-forwarding\r
- :type '(radio (function-item message-forward-subject-author-subject)\r
-              (function-item message-forward-subject-fwd)))\r
-\r
-(defcustom message-wash-forwarded-subjects nil\r
-  "*If non-nil, try to remove as much old cruft as possible from the subject of messages before generating the new subject of a forward."\r
-  :group 'message-forwarding\r
-  :type 'boolean)\r
-\r
-(defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:"\r
-  "*All headers that match this regexp will be deleted when resending a message."\r
-  :group 'message-interface\r
-  :type 'regexp)\r
-\r
-(defcustom message-ignored-cited-headers "."\r
-  "*Delete these headers from the messages you yank."\r
-  :group 'message-insertion\r
-  :type 'regexp)\r
-\r
-(defcustom message-cancel-message "I am canceling my own article."\r
-  "Message to be inserted in the cancel message."\r
-  :group 'message-interface\r
-  :type 'string)\r
-\r
-;; Useful to set in site-init.el\r
-;;;###autoload\r
-(defcustom message-send-mail-function 'message-send-mail-with-sendmail\r
-  "Function to call to send the current buffer as mail.\r
-The headers should be delimited by a line whose contents match the\r
-variable `mail-header-separator'.\r
-\r
-Legal values include `message-send-mail-with-sendmail' (the default),\r
-`message-send-mail-with-mh', `message-send-mail-with-qmail' and\r
-`message-send-mail-with-smtp'."\r
-  :type '(radio (function-item message-send-mail-with-sendmail)\r
-               (function-item message-send-mail-with-mh)\r
-               (function-item message-send-mail-with-qmail)\r
-               (function-item message-send-mail-with-smtp)\r
-               (function :tag "Other"))\r
-  :group 'message-sending\r
-  :group 'message-mail)\r
-\r
-;; 1997-09-29 by MORIOKA Tomohiko\r
-(defcustom message-send-news-function 'message-send-news-with-gnus\r
-  "Function to call to send the current buffer as news.\r
-The headers should be delimited by a line whose contents match the\r
-variable `mail-header-separator'."\r
-  :group 'message-sending\r
-  :group 'message-news\r
-  :type 'function)\r
-\r
-(defcustom message-reply-to-function nil\r
-  "Function that should return a list of headers.\r
-This function should pick out addresses from the To, Cc, and From headers\r
-and respond with new To and Cc headers."\r
-  :group 'message-interface\r
-  :type 'function)\r
-\r
-(defcustom message-wide-reply-to-function nil\r
-  "Function that should return a list of headers.\r
-This function should pick out addresses from the To, Cc, and From headers\r
-and respond with new To and Cc headers."\r
-  :group 'message-interface\r
-  :type 'function)\r
-\r
-(defcustom message-followup-to-function nil\r
-  "Function that should return a list of headers.\r
-This function should pick out addresses from the To, Cc, and From headers\r
-and respond with new To and Cc headers."\r
-  :group 'message-interface\r
-  :type 'function)\r
-\r
-(defcustom message-use-followup-to 'ask\r
-  "*Specifies what to do with Followup-To header.\r
-If nil, always ignore the header.  If it is t, use its value, but\r
-query before using the \"poster\" value.  If it is the symbol `ask',\r
-always query the user whether to use the value.  If it is the symbol\r
-`use', always use the value."\r
-  :group 'message-interface\r
-  :type '(choice (const :tag "ignore" nil)\r
-                (const :tag "maybe" t)\r
-                (const :tag "always" use)\r
-                (const :tag "ask" ask)))\r
-\r
-(defcustom message-use-mail-copies-to 'ask\r
-  "*Specifies what to do with Mail-Copies-To header.\r
-If nil, always ignore the header.  If it is t, use its value, but\r
-query before using the value other than \"always\" or \"never\".\r
-If it is the symbol `ask', always query the user whether to use\r
-the value.  If it is the symbol `use', always use the value."\r
-  :group 'message-interface\r
-  :type '(choice (const :tag "ignore" nil)\r
-                (const :tag "maybe" t)\r
-                (const :tag "always" use)\r
-                (const :tag "ask" ask)))\r
-\r
-(defcustom message-use-mail-followup-to 'ask\r
-  "*Specifies what to do with Mail-Followup-To header.\r
-If nil, always ignore the header.  If it is the symbol `ask', always\r
-query the user whether to use the value.  If it is t or the symbol\r
-`use', always use the value."\r
-  :group 'message-interface\r
-  :type '(choice (const :tag "ignore" nil)\r
-                (const :tag "maybe" t)\r
-                (const :tag "always" use)\r
-                (const :tag "ask" ask)))\r
-\r
-;;; XXX: 'ask and 'use are not implemented yet.\r
-(defcustom message-use-mail-reply-to 'ask\r
-  "*Specifies what to do with Mail-Reply-To/Reply-To header.\r
-If nil, always ignore the header.  If it is t or the symbol `use', use\r
-its value.  If it is the symbol `ask', always query the user whether to\r
-use the value.  Note that if \"Reply-To\" is marked as \"broken\", its value\r
-is never used."\r
-  :group 'message-interface\r
-  :type '(choice (const :tag "ignore" nil)\r
-                (const :tag "maybe" t)\r
-                (const :tag "always" use)\r
-                (const :tag "ask" ask)))\r
-\r
-;; stuff relating to broken sendmail in MMDF\r
-(defcustom message-sendmail-f-is-evil nil\r
-  "*Non-nil means that \"-f username\" should not be added to the sendmail\r
-command line, because it is even more evil than leaving it out."\r
-  :group 'message-sending\r
-  :type 'boolean)\r
-\r
-;; qmail-related stuff\r
-(defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"\r
-  "Location of the qmail-inject program."\r
-  :group 'message-sending\r
-  :type 'file)\r
-\r
-(defcustom message-qmail-inject-args nil\r
-  "Arguments passed to qmail-inject programs.\r
-This should be a list of strings, one string for each argument.\r
-\r
-For e.g., if you wish to set the envelope sender address so that bounces\r
-go to the right place or to deal with listserv's usage of that address, you\r
-might set this variable to '(\"-f\" \"you@some.where\")."\r
-  :group 'message-sending\r
-  :type '(repeat string))\r
-\r
-(defvar gnus-post-method)\r
-(defvar gnus-select-method)\r
-(defcustom message-post-method\r
-  (cond ((and (boundp 'gnus-post-method)\r
-             (listp gnus-post-method)\r
-             gnus-post-method)\r
-        gnus-post-method)\r
-       ((boundp 'gnus-select-method)\r
-        gnus-select-method)\r
-       (t '(nnspool "")))\r
-  "*Method used to post news.\r
-Note that when posting from inside Gnus, for instance, this\r
-variable isn't used."\r
-  :group 'message-news\r
-  :group 'message-sending\r
-  ;; This should be the `gnus-select-method' widget, but that might\r
-  ;; create a dependence to `gnus.el'.\r
-  :type 'sexp)\r
-\r
-(defcustom message-generate-headers-first nil\r
-  "*If non-nil, generate all possible headers before composing."\r
-  :group 'message-headers\r
-  :type 'boolean)\r
-\r
-(defcustom message-setup-hook '(turn-on-mime-edit)\r
-  "Normal hook, run each time a new outgoing message is initialized.\r
-The function `message-setup' runs this hook."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-cancel-hook nil\r
-  "Hook run when cancelling articles."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-signature-setup-hook nil\r
-  "Normal hook, run each time a new outgoing message is initialized.\r
-It is run after the headers have been inserted and before\r
-the signature is inserted."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-bounce-setup-hook nil\r
-  "Normal hook, run each time a re-sending bounced message is initialized.\r
-The function `message-bounce' runs this hook."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-supersede-setup-hook nil\r
-  "Normal hook, run each time a supersede message is initialized.\r
-The function `message-supersede' runs this hook."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-mode-hook nil\r
-  "Hook run in message mode buffers."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-header-hook '(eword-encode-header)\r
-  "Hook run in a message mode buffer narrowed to the headers."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-header-setup-hook nil\r
-  "Hook called narrowed to the headers when setting up a message buffer."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-;;;###autoload\r
-(defcustom message-citation-line-function 'message-insert-citation-line\r
-  "*Function called to insert the \"Whomever writes:\" line."\r
-  :type 'function\r
-  :group 'message-insertion)\r
-\r
-;;;###autoload\r
-(defcustom message-yank-prefix "> "\r
-  "*Prefix inserted on the lines of yanked messages."\r
-  :type 'string\r
-  :group 'message-insertion)\r
-\r
-(defcustom message-yank-add-new-references t\r
-  "*Non-nil means new IDs will be added to \"References\" field when an\r
-article is yanked by the command `message-yank-original' interactively."\r
-  :type 'boolean\r
-  :group 'message-insertion)\r
-\r
-(defcustom message-indentation-spaces 3\r
-  "*Number of spaces to insert at the beginning of each cited line.\r
-Used by `message-yank-original' via `message-yank-cite'."\r
-  :group 'message-insertion\r
-  :type 'integer)\r
-\r
-;;;###autoload\r
-(defcustom message-cite-function 'message-cite-original\r
-  "*Function for citing an original message.\r
-Predefined functions include `message-cite-original' and\r
-`message-cite-original-without-signature'.\r
-Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil."\r
-  :type '(radio (function-item message-cite-original)\r
-               (function-item sc-cite-original)\r
-               (function :tag "Other"))\r
-  :group 'message-insertion)\r
-\r
-;;;###autoload\r
-(defcustom message-indent-citation-function 'message-indent-citation\r
-  "*Function for modifying a citation just inserted in the mail buffer.\r
-This can also be a list of functions.  Each function can find the\r
-citation between (point) and (mark t).  And each function should leave\r
-point and mark around the citation text as modified."\r
-  :type 'function\r
-  :group 'message-insertion)\r
-\r
-(defvar message-abbrevs-loaded nil)\r
-\r
-;;;###autoload\r
-(defcustom message-signature t\r
-  "*String to be inserted at the end of the message buffer.\r
-If t, the `message-signature-file' file will be inserted instead.\r
-If a function, the result from the function will be used instead.\r
-If a form, the result from the form will be used instead."\r
-  :type 'sexp\r
-  :group 'message-insertion)\r
-\r
-;;;###autoload\r
-(defcustom message-signature-file "~/.signature"\r
-  "*File containing the text inserted at end of message buffer."\r
-  :type 'file\r
-  :group 'message-insertion)\r
-\r
-(defcustom message-distribution-function nil\r
-  "*Function called to return a Distribution header."\r
-  :group 'message-news\r
-  :group 'message-headers\r
-  :type 'function)\r
-\r
-(defcustom message-expires 14\r
-  "Number of days before your article expires."\r
-  :group 'message-news\r
-  :group 'message-headers\r
-  :link '(custom-manual "(message)News Headers")\r
-  :type 'integer)\r
-\r
-(defcustom message-user-path nil\r
-  "If nil, use the NNTP server name in the Path header.\r
-If stringp, use this; if non-nil, use no host name (user name only)."\r
-  :group 'message-news\r
-  :group 'message-headers\r
-  :link '(custom-manual "(message)News Headers")\r
-  :type '(choice (const :tag "nntp" nil)\r
-                (string :tag "name")\r
-                (sexp :tag "none" :format "%t" t)))\r
-\r
-(defvar message-reply-buffer nil)\r
-(defvar message-reply-headers nil)\r
-(defvar message-sent-message-via nil)\r
-(defvar message-checksum nil)\r
-(defvar message-send-actions nil\r
-  "A list of actions to be performed upon successful sending of a message.")\r
-(defvar message-exit-actions nil\r
-  "A list of actions to be performed upon exiting after sending a message.")\r
-(defvar message-kill-actions nil\r
-  "A list of actions to be performed before killing a message buffer.")\r
-(defvar message-postpone-actions nil\r
-  "A list of actions to be performed after postponing a message.")\r
-(defvar message-original-frame nil)\r
-(defvar message-parameter-alist nil)\r
-(defvar message-startup-parameter-alist nil)\r
-\r
-(define-widget 'message-header-lines 'text\r
-  "All header lines must be LFD terminated."\r
-  :format "%t:%n%v"\r
-  :valid-regexp "^\\'"\r
-  :error "All header lines must be newline terminated")\r
-\r
-(defcustom message-default-headers ""\r
-  "*A string containing header lines to be inserted in outgoing messages.\r
-It is inserted before you edit the message, so you can edit or delete\r
-these lines."\r
-  :group 'message-headers\r
-  :type 'message-header-lines)\r
-\r
-(defcustom message-default-mail-headers ""\r
-  "*A string of header lines to be inserted in outgoing mails."\r
-  :group 'message-headers\r
-  :group 'message-mail\r
-  :type 'message-header-lines)\r
-\r
-(defcustom message-default-news-headers ""\r
-  "*A string of header lines to be inserted in outgoing news\r
-articles."\r
-  :group 'message-headers\r
-  :group 'message-news\r
-  :type 'message-header-lines)\r
-\r
-;; Note: could use /usr/ucb/mail instead of sendmail;\r
-;; options -t, and -v if not interactive.\r
-(defcustom message-mailer-swallows-blank-line\r
-  (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)"\r
-                        system-configuration)\r
-          (file-readable-p "/etc/sendmail.cf")\r
-          (let ((buffer (get-buffer-create " *temp*")))\r
-            (unwind-protect\r
-                (save-excursion\r
-                  (set-buffer buffer)\r
-                  (insert-file-contents "/etc/sendmail.cf")\r
-                  (goto-char (point-min))\r
-                  (let ((case-fold-search nil))\r
-                    (re-search-forward "^OR\\>" nil t)))\r
-              (kill-buffer buffer))))\r
-      ;; According to RFC822, "The field-name must be composed of printable\r
-      ;; ASCII characters (i. e., characters that have decimal values between\r
-      ;; 33 and 126, except colon)", i. e., any chars except ctl chars,\r
-      ;; space, or colon.\r
-      '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))\r
-  "*Set this non-nil if the system's mailer runs the header and body together.\r
-\(This problem exists on Sunos 4 when sendmail is run in remote mode.)\r
-The value should be an expression to test whether the problem will\r
-actually occur."\r
-  :group 'message-sending\r
-  :type 'sexp)\r
-\r
-;;; XXX: This symbol is overloaded!  See below.\r
-(defvar message-user-agent nil\r
-  "String of the form of PRODUCT/VERSION.  Used for User-Agent header field.")\r
-\r
-;; Ignore errors in case this is used in Emacs 19.\r
-;; Don't use ignore-errors because this is copied into loaddefs.el.\r
-;;;###autoload\r
-(condition-case nil\r
-    (define-mail-user-agent 'message-user-agent\r
-      'message-mail 'message-send-and-exit\r
-      'message-kill-buffer 'message-send-hook)\r
-  (error nil))\r
-\r
-(defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)\r
-  "If non-nil, delete the deletable headers before feeding to mh.")\r
-\r
-(defvar message-send-method-alist\r
-  '((news message-news-p message-send-via-news)\r
-    (mail message-mail-p message-send-via-mail))\r
-  "Alist of ways to send outgoing messages.\r
-Each element has the form\r
-\r
-  \(TYPE PREDICATE FUNCTION)\r
-\r
-where TYPE is a symbol that names the method; PREDICATE is a function\r
-called without any parameters to determine whether the message is\r
-a message of type TYPE; and FUNCTION is a function to be called if\r
-PREDICATE returns non-nil.  FUNCTION is called with one parameter --\r
-the prefix.")\r
-\r
-(defvar message-mail-alias-type 'abbrev\r
-  "*What alias expansion type to use in Message buffers.\r
-The default is `abbrev', which uses mailabbrev.  nil switches\r
-mail aliases off.")\r
-\r
-(defcustom message-auto-save-directory\r
-  (nnheader-concat message-directory "drafts/")\r
-  "*Directory where Message auto-saves buffers if Gnus isn't running.\r
-If nil, Message won't auto-save."\r
-  :group 'message-buffers\r
-  :type 'directory)\r
-\r
-(defcustom message-buffer-naming-style 'unique\r
-  "*The way new message buffers are named.\r
-Valid valued are `unique' and `unsent'."\r
-  :group 'message-buffers\r
-  :type '(choice (const :tag "unique" unique)\r
-                (const :tag "unsent" unsent)))\r
-\r
-(defcustom message-default-charset nil\r
-  "Default charset used in non-MULE XEmacsen.")\r
-\r
-;;; Internal variables.\r
-;;; Well, not really internal.\r
-\r
-(defvar message-mode-syntax-table\r
-  (let ((table (copy-syntax-table text-mode-syntax-table)))\r
-    (modify-syntax-entry ?% ". " table)\r
-    (modify-syntax-entry ?> ". " table)\r
-    (modify-syntax-entry ?< ". " table)\r
-    table)\r
-  "Syntax table used while in Message mode.")\r
-\r
-(defvar message-mode-abbrev-table text-mode-abbrev-table\r
-  "Abbrev table used in Message mode buffers.\r
-Defaults to `text-mode-abbrev-table'.")\r
-(defgroup message-headers nil\r
-  "Message headers."\r
-  :link '(custom-manual "(message)Variables")\r
-  :group 'message)\r
-\r
-(defface message-header-to-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "green2" :bold t))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "MidnightBlue" :bold t))\r
-    (t\r
-     (:bold t :italic t)))\r
-  "Face used for displaying From headers."\r
-  :group 'message-faces)\r
-\r
-(defface message-header-cc-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "green4" :bold t))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "MidnightBlue"))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying Cc headers."\r
-  :group 'message-faces)\r
-\r
-(defface message-header-subject-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "green3"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "navy blue" :bold t))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying subject headers."\r
-  :group 'message-faces)\r
-\r
-(defface message-header-newsgroups-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "yellow" :bold t :italic t))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "blue4" :bold t :italic t))\r
-    (t\r
-     (:bold t :italic t)))\r
-  "Face used for displaying newsgroups headers."\r
-  :group 'message-faces)\r
-\r
-(defface message-header-other-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "#b00000"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "steel blue"))\r
-    (t\r
-     (:bold t :italic t)))\r
-  "Face used for displaying newsgroups headers."\r
-  :group 'message-faces)\r
-\r
-(defface message-header-name-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "DarkGreen"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "cornflower blue"))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying header names."\r
-  :group 'message-faces)\r
-\r
-(defface message-header-xheader-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "blue"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "blue"))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying X-Header headers."\r
-  :group 'message-faces)\r
-\r
-(defface message-separator-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "blue3"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "brown"))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying the separator."\r
-  :group 'message-faces)\r
-\r
-(defface message-cited-text-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "red"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "red"))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying cited text names."\r
-  :group 'message-faces)\r
-\r
-(defface message-mml-face\r
-  '((((class color)\r
-      (background dark))\r
-     (:foreground "ForestGreen"))\r
-    (((class color)\r
-      (background light))\r
-     (:foreground "ForestGreen"))\r
-    (t\r
-     (:bold t)))\r
-  "Face used for displaying MML."\r
-  :group 'message-faces)\r
-\r
-(defvar message-font-lock-keywords\r
-  (let* ((cite-prefix "A-Za-z")\r
-        (cite-suffix (concat cite-prefix "0-9_.@-"))\r
-        (content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)"))\r
-    `((,(concat "^\\([Tt]o:\\)" content)\r
-       (1 'message-header-name-face)\r
-       (2 'message-header-to-face nil t))\r
-      (,(concat "^\\([GBF]?[Cc][Cc]:\\|[Rr]eply-[Tt]o:\\|"\r
-               "[Mm]ail-[Cc]opies-[Tt]o:\\|"\r
-               "[Mm]ail-[Rr]eply-[Tt]o:\\|"\r
-               "[Mm]ail-[Ff]ollowup-[Tt]o:\\)" content)\r
-       (1 'message-header-name-face)\r
-       (2 'message-header-cc-face nil t))\r
-      (,(concat "^\\([Ss]ubject:\\)" content)\r
-       (1 'message-header-name-face)\r
-       (2 'message-header-subject-face nil t))\r
-      (,(concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content)\r
-       (1 'message-header-name-face)\r
-       (2 'message-header-newsgroups-face nil t))\r
-      (,(concat "^\\([A-Z][^: \n\t]+:\\)" content)\r
-       (1 'message-header-name-face)\r
-       (2 'message-header-other-face nil t))\r
-      (,(concat "^\\(X-[A-Za-z0-9-]+\\|In-Reply-To\\):" content)\r
-       (1 'message-header-name-face)\r
-       (2 'message-header-name-face))\r
-      ,@(if (and mail-header-separator\r
-                (not (equal mail-header-separator "")))\r
-           `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")\r
-              1 'message-separator-face))\r
-         nil)\r
-      (,(concat "^[ \t]*"\r
-               "\\([" cite-prefix "]+[" cite-suffix "]*\\)?"\r
-               "[:>|}].*")\r
-       (0 'message-cited-text-face))\r
-      ("<#/?\\(multipart\\|part\\|external\\).*>"\r
-       (0 'message-mml-face))))\r
-  "Additional expressions to highlight in Message mode.")\r
-\r
-;; XEmacs does it like this.  For Emacs, we have to set the\r
-;; `font-lock-defaults' buffer-local variable.\r
-(put 'message-mode 'font-lock-defaults '(message-font-lock-keywords t))\r
-\r
-(defvar message-face-alist\r
-  '((bold . bold-region)\r
-    (underline . underline-region)\r
-    (default . (lambda (b e)\r
-                (unbold-region b e)\r
-                (ununderline-region b e))))\r
-  "Alist of mail and news faces for facemenu.\r
-The cdr of ech entry is a function for applying the face to a region.")\r
-\r
-(defcustom message-send-hook nil\r
-  "Hook run before sending messages."\r
-  :group 'message-various\r
-  :options '(ispell-message)\r
-  :type 'hook)\r
-\r
-(defcustom message-send-mail-hook nil\r
-  "Hook run before sending mail messages."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-send-news-hook nil\r
-  "Hook run before sending news messages."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-sent-hook nil\r
-  "Hook run after sending messages."\r
-  :group 'message-various\r
-  :type 'hook)\r
-\r
-(defcustom message-use-multi-frames nil\r
-  "Make new frame when sending messages."\r
-  :group 'message-frames\r
-  :type 'boolean)\r
-\r
-(defcustom message-delete-frame-on-exit nil\r
-  "Delete frame after sending messages."\r
-  :group 'message-frames\r
-  :type '(choice (const :tag "off" nil)\r
-                (const :tag "always" t)\r
-                (const :tag "ask" ask)))\r
-\r
-(defvar message-draft-coding-system\r
-  (cond\r
-   ((not (fboundp 'find-coding-system)) nil)\r
-   ((find-coding-system 'emacs-mule) 'emacs-mule)\r
-   ((find-coding-system 'escape-quoted) 'escape-quoted)\r
-   ((find-coding-system 'no-conversion) 'no-conversion)\r
-   (t nil))\r
-  "Coding system to compose mail.")\r
-\r
-;;; Internal variables.\r
-\r
-(defvar message-buffer-list nil)\r
-(defvar message-this-is-news nil)\r
-(defvar message-this-is-mail nil)\r
-(defvar message-draft-article nil)\r
-(defvar message-mime-part nil)\r
-(defvar message-posting-charset nil)\r
-\r
-;; Byte-compiler warning\r
-(defvar gnus-active-hashtb)\r
-(defvar gnus-read-active-file)\r
-\r
-;;; Regexp matching the delimiter of messages in UNIX mail format\r
-;;; (UNIX From lines), minus the initial ^.  It should be a copy\r
-;;; of rmail.el's rmail-unix-mail-delimiter.\r
-(defvar message-unix-mail-delimiter\r
-  (let ((time-zone-regexp\r
-        (concat "\\([A-Z]?[A-Z]?[A-Z][A-Z]\\( DST\\)?"\r
-                "\\|[-+]?[0-9][0-9][0-9][0-9]"\r
-                "\\|"\r
-                "\\) *")))\r
-    (concat\r
-     "From "\r
-\r
-     ;; Many things can happen to an RFC 822 mailbox before it is put into\r
-     ;; a `From' line.  The leading phrase can be stripped, e.g.\r
-     ;; `Joe <@w.x:joe@y.z>' -> `<@w.x:joe@y.z>'.  The <> can be stripped, e.g.\r
-     ;; `<@x.y:joe@y.z>' -> `@x.y:joe@y.z'.  Everything starting with a CRLF\r
-     ;; can be removed, e.g.\r
-     ;;                From: joe@y.z (Joe      K\r
-     ;;                        User)\r
-     ;; can yield `From joe@y.z (Joe   K Fri Mar 22 08:11:15 1996', and\r
-     ;;                From: Joe User\r
-     ;;                        <joe@y.z>\r
-     ;; can yield `From Joe User Fri Mar 22 08:11:15 1996'.\r
-     ;; The mailbox can be removed or be replaced by white space, e.g.\r
-     ;;                From: "Joe User"{space}{tab}\r
-     ;;                        <joe@y.z>\r
-     ;; can yield `From {space}{tab} Fri Mar 22 08:11:15 1996',\r
-     ;; where {space} and {tab} represent the Ascii space and tab characters.\r
-     ;; We want to match the results of any of these manglings.\r
-     ;; The following regexp rejects names whose first characters are\r
-     ;; obviously bogus, but after that anything goes.\r
-     "\\([^\0-\b\n-\r\^?].*\\)? "\r
-\r
-     ;; The time the message was sent.\r
-     "\\([^\0-\r \^?]+\\) +"                           ; day of the week\r
-     "\\([^\0-\r \^?]+\\) +"                           ; month\r
-     "\\([0-3]?[0-9]\\) +"                             ; day of month\r
-     "\\([0-2][0-9]:[0-5][0-9]\\(:[0-6][0-9]\\)?\\) *" ; time of day\r
-\r
-     ;; Perhaps a time zone, specified by an abbreviation, or by a\r
-     ;; numeric offset.\r
-     time-zone-regexp\r
-\r
-     ;; The year.\r
-     " \\([0-9][0-9]+\\) *"\r
-\r
-     ;; On some systems the time zone can appear after the year, too.\r
-     time-zone-regexp\r
-\r
-     ;; Old uucp cruft.\r
-     "\\(remote from .*\\)?"\r
-\r
-     "\n"))\r
-  "Regexp matching the delimiter of messages in UNIX mail format.")\r
-\r
-(defvar message-unsent-separator\r
-  (concat "^ *---+ +Unsent message follows +---+ *$\\|"\r
-         "^ *---+ +Returned message +---+ *$\\|"\r
-         "^Start of returned message$\\|"\r
-         "^ *---+ +Original message +---+ *$\\|"\r
-         "^ *--+ +begin message +--+ *$\\|"\r
-         "^ *---+ +Original message follows +---+ *$\\|"\r
-         "^|? *---+ +Message text follows: +---+ *|?$")\r
-  "A regexp that matches the separator before the text of a failed message.")\r
-\r
-(defvar message-header-format-alist\r
-  `((Newsgroups)\r
-    (To . message-fill-address)\r
-    (Cc . message-fill-address)\r
-    (Subject)\r
-    (In-Reply-To)\r
-    (Fcc)\r
-    (Bcc)\r
-    (Date)\r
-    (Organization)\r
-    (Distribution)\r
-    (Lines)\r
-    (Expires)\r
-    (Message-ID)\r
-    (References . message-shorten-references)\r
-    (User-Agent))\r
-  "Alist used for formatting headers.")\r
-\r
-(eval-and-compile\r
-  (autoload 'message-setup-toolbar "messagexmas")\r
-  (autoload 'mh-new-draft-name "mh-comp")\r
-  (autoload 'mh-send-letter "mh-comp")\r
-  (autoload 'gnus-point-at-eol "gnus-util")\r
-  (autoload 'gnus-point-at-bol "gnus-util")\r
-  (autoload 'gnus-output-to-mail "gnus-util")\r
-  (autoload 'mail-abbrev-in-expansion-header-p "mailabbrev")\r
-  (autoload 'nndraft-request-associate-buffer "nndraft")\r
-  (autoload 'nndraft-request-expire-articles "nndraft")\r
-  (autoload 'gnus-open-server "gnus-int")\r
-  (autoload 'gnus-request-post "gnus-int")\r
-  (autoload 'gnus-copy-article-buffer "gnus-msg")\r
-  (autoload 'gnus-alive-p "gnus-util")\r
-  (autoload 'rmail-output "rmail"))\r
-\r
-\f\r
-\r
-;;;\r
-;;; Utility functions.\r
-;;;\r
-(defun message-eval-parameter (parameter)\r
-  (condition-case ()\r
-      (if (symbolp parameter)\r
-         (if (functionp parameter)\r
-             (funcall parameter)\r
-           (eval parameter))\r
-       parameter)\r
-    (error nil)))\r
-\r
-(defsubst message-get-parameter (key &optional alist)\r
-  (unless alist\r
-    (setq alist message-parameter-alist))\r
-  (cdr (assq key alist)))\r
-\r
-(defmacro message-get-parameter-with-eval (key &optional alist)\r
-  `(message-eval-parameter (message-get-parameter ,key ,alist)))\r
-\r
-(defmacro message-y-or-n-p (question show &rest text)\r
-  "Ask QUESTION, displaying the rest of the arguments in a temp. buffer if SHOW"\r
-  `(message-talkative-question 'y-or-n-p ,question ,show ,@text))\r
-\r
-;; Delete the current line (and the next N lines.);\r
-(defmacro message-delete-line (&optional n)\r
-  `(delete-region (progn (beginning-of-line) (point))\r
-                 (progn (forward-line ,(or n 1)) (point))))\r
-\r
-(defun message-tokenize-header (header &optional separator)\r
-  "Split HEADER into a list of header elements.\r
-\",\" is used as the separator."\r
-  (if (not header)\r
-      nil\r
-    (let ((regexp (format "[%s]+" (or separator ",")))\r
-         (beg 1)\r
-         (first t)\r
-         quoted elems paren)\r
-      (save-excursion\r
-       (message-set-work-buffer)\r
-       (insert header)\r
-       (goto-char (point-min))\r
-       (while (not (eobp))\r
-         (if first\r
-             (setq first nil)\r
-           (forward-char 1))\r
-         (cond ((and (> (point) beg)\r
-                     (or (eobp)\r
-                         (and (looking-at regexp)\r
-                              (not quoted)\r
-                              (not paren))))\r
-                (push (buffer-substring beg (point)) elems)\r
-                (setq beg (match-end 0)))\r
-               ((eq (char-after) ?\")\r
-                (setq quoted (not quoted)))\r
-               ((and (eq (char-after) ?\()\r
-                     (not quoted))\r
-                (setq paren t))\r
-               ((and (eq (char-after) ?\))\r
-                     (not quoted))\r
-                (setq paren nil))))\r
-       (nreverse elems)))))\r
-\r
-(defun message-mail-file-mbox-p (file)\r
-  "Say whether FILE looks like a Unix mbox file."\r
-  (when (and (file-exists-p file)\r
-            (file-readable-p file)\r
-            (file-regular-p file))\r
-    (with-temp-buffer\r
-      (nnheader-insert-file-contents file)\r
-      (goto-char (point-min))\r
-      (looking-at message-unix-mail-delimiter))))\r
-\r
-(defun message-fetch-field (header &optional not-all)\r
-  "The same as `mail-fetch-field', only remove all newlines."\r
-  (let* ((inhibit-point-motion-hooks t)\r
-        (value (mail-fetch-field header nil (not not-all))))\r
-    (when value\r
-      (while (string-match "\n[\t ]+" value)\r
-       (setq value (replace-match " " t t value)))\r
-      ;; We remove all text props.delete-region\r
-      (format "%s" value))))\r
-\r
-(defun message-narrow-to-field ()\r
-  "Narrow the buffer to the header on the current line."\r
-  (beginning-of-line)\r
-  (narrow-to-region\r
-   (point)\r
-   (progn\r
-     (forward-line 1)\r
-     (if (re-search-forward "^[^ \n\t]" nil t)\r
-        (progn\r
-          (beginning-of-line)\r
-          (point))\r
-       (point-max))))\r
-  (goto-char (point-min)))\r
-\r
-(defun message-add-header (&rest headers)\r
-  "Add the HEADERS to the message header, skipping those already present."\r
-  (while headers\r
-    (let (hclean)\r
-      (unless (string-match "^\\([^:]+\\):[ \t]*[^ \t]" (car headers))\r
-       (error "Invalid header `%s'" (car headers)))\r
-      (setq hclean (match-string 1 (car headers)))\r
-    (save-restriction\r
-      (message-narrow-to-headers)\r
-      (unless (re-search-forward (concat "^" (regexp-quote hclean) ":") nil t)\r
-       (insert (car headers) ?\n))))\r
-    (setq headers (cdr headers))))\r
-\r
-(defun message-fetch-reply-field (header)\r
-  "Fetch FIELD from the message we're replying to."\r
-  (let ((buffer (message-eval-parameter message-reply-buffer)))\r
-    (when (and buffer\r
-              (buffer-name buffer))\r
-      (save-excursion\r
-       (set-buffer buffer)\r
-       (message-fetch-field header)))))\r
-\r
-(defun message-set-work-buffer ()\r
-  (if (get-buffer " *message work*")\r
-      (progn\r
-       (set-buffer " *message work*")\r
-       (erase-buffer))\r
-    (set-buffer (get-buffer-create " *message work*"))\r
-    (kill-all-local-variables)))\r
-\r
-(defun message-functionp (form)\r
-  "Return non-nil if FORM is funcallable."\r
-  (or (and (symbolp form) (fboundp form))\r
-      (and (listp form) (eq (car form) 'lambda))\r
-      (byte-code-function-p form)))\r
-\r
-(defun message-strip-subject-re (subject)\r
-  "Remove \"Re:\" from subject lines."\r
-  (if (string-match message-subject-re-regexp subject)\r
-      (substring subject (match-end 0))\r
-    subject))\r
-\r
-(defun message-remove-header (header &optional is-regexp first reverse)\r
-  "Remove HEADER in the narrowed buffer.\r
-If REGEXP, HEADER is a regular expression.\r
-If FIRST, only remove the first instance of the header.\r
-Return the number of headers removed."\r
-  (goto-char (point-min))\r
-  (let ((regexp (if is-regexp header (concat "^" (regexp-quote header) ":")))\r
-       (number 0)\r
-       (case-fold-search t)\r
-       last)\r
-    (while (and (not (eobp))\r
-               (not last))\r
-      (if (if reverse\r
-             (not (looking-at regexp))\r
-           (looking-at regexp))\r
-         (progn\r
-           (incf number)\r
-           (when first\r
-             (setq last t))\r
-           (delete-region\r
-            (point)\r
-            ;; There might be a continuation header, so we have to search\r
-            ;; until we find a new non-continuation line.\r
-            (progn\r
-              (forward-line 1)\r
-              (if (re-search-forward "^[^ \t]" nil t)\r
-                  (goto-char (match-beginning 0))\r
-                (point-max)))))\r
-       (forward-line 1)\r
-       (if (re-search-forward "^[^ \t]" nil t)\r
-           (goto-char (match-beginning 0))\r
-         (goto-char (point-max)))))\r
-    number))\r
-\r
-(defun message-remove-first-header (header)\r
-  "Remove the first instance of HEADER if there is more than one."\r
-  (let ((count 0)\r
-       (regexp (concat "^" (regexp-quote header) ":")))\r
-    (save-excursion\r
-      (goto-char (point-min))\r
-      (while (re-search-forward regexp nil t)\r
-       (incf count)))\r
-    (while (> count 1)\r
-      (message-remove-header header nil t)\r
-      (decf count))))\r
-\r
-(defun message-narrow-to-headers ()\r
-  "Narrow the buffer to the head of the message."\r
-  (widen)\r
-  (narrow-to-region\r
-   (goto-char (point-min))\r
-   (if (re-search-forward\r
-       (concat "^" (regexp-quote mail-header-separator) "\n") nil t)\r
-       (match-beginning 0)\r
-     (point-max)))\r
-  (goto-char (point-min)))\r
-\r
-(defun message-narrow-to-head ()\r
-  "Narrow the buffer to the head of the message.\r
-Point is left at the beginning of the narrowed-to region."\r
-  (widen)\r
-  (narrow-to-region\r
-   (goto-char (point-min))\r
-   (if (search-forward "\n\n" nil 1)\r
-       (1- (point))\r
-     (point-max)))\r
-  (goto-char (point-min)))\r
-\r
-(defun message-narrow-to-headers-or-head ()\r
-  "Narrow the buffer to the head of the message."\r
-  (widen)\r
-  (narrow-to-region\r
-   (goto-char (point-min))\r
-   (cond\r
-    ((re-search-forward\r
-      (concat "^" (regexp-quote mail-header-separator) "\n") nil t)\r
-     (match-beginning 0))\r
-    ((search-forward "\n\n" nil t)\r
-     (1- (point)))\r
-    (t\r
-     (point-max))))\r
-  (goto-char (point-min)))\r
-\r
-(defun message-news-p ()\r
-  "Say whether the current buffer contains a news message."\r
-  (and (not message-this-is-mail)\r
-       (or message-this-is-news\r
-          (save-excursion\r
-            (save-restriction\r
-              (message-narrow-to-headers)\r
-              (and (message-fetch-field "newsgroups")\r
-                   (not (message-fetch-field "posted-to"))))))))\r
-\r
-(defun message-mail-p ()\r
-  "Say whether the current buffer contains a mail message."\r
-  (and (not message-this-is-news)\r
-       (or message-this-is-mail\r
-          (save-excursion\r
-            (save-restriction\r
-              (message-narrow-to-headers)\r
-              (or (message-fetch-field "to")\r
-                  (message-fetch-field "cc")\r
-                  (message-fetch-field "bcc")))))))\r
-\r
-(defun message-next-header ()\r
-  "Go to the beginning of the next header."\r
-  (beginning-of-line)\r
-  (or (eobp) (forward-char 1))\r
-  (not (if (re-search-forward "^[^ \t]" nil t)\r
-          (beginning-of-line)\r
-        (goto-char (point-max)))))\r
-\r
-(defun message-sort-headers-1 ()\r
-  "Sort the buffer as headers using `message-rank' text props."\r
-  (goto-char (point-min))\r
-  (sort-subr\r
-   nil 'message-next-header\r
-   (lambda ()\r
-     (message-next-header)\r
-     (unless (bobp)\r
-       (forward-char -1)))\r
-   (lambda ()\r
-     (or (get-text-property (point) 'message-rank)\r
-        10000))))\r
-\r
-(defun message-sort-headers ()\r
-  "Sort the headers of the current message according to `message-header-format-alist'."\r
-  (interactive)\r
-  (save-excursion\r
-    (save-restriction\r
-      (let ((max (1+ (length message-header-format-alist)))\r
-           rank)\r
-       (message-narrow-to-headers)\r
-       (while (re-search-forward "^[^ \n]+:" nil t)\r
-         (put-text-property\r
-          (match-beginning 0) (1+ (match-beginning 0))\r
-          'message-rank\r
-          (if (setq rank (length (memq (assq (intern (buffer-substring\r
-                                                      (match-beginning 0)\r
-                                                      (1- (match-end 0))))\r
-                                             message-header-format-alist)\r
-                                       message-header-format-alist)))\r
-              (- max rank)\r
-            (1+ max)))))\r
-      (message-sort-headers-1))))\r
-\r
-\f\r
-\r
-;;;\r
-;;; Message mode\r
-;;;\r
-\r
-;;; Set up keymap.\r
-\r
-(defvar message-mode-map nil)\r
-\r
-(unless message-mode-map\r
-  (setq message-mode-map (make-keymap))\r
-  (set-keymap-parent message-mode-map text-mode-map)\r
-  (define-key message-mode-map "\C-c?" 'describe-mode)\r
-\r
-  (define-key message-mode-map "\C-c\C-f\C-t" 'message-goto-to)\r
-  (define-key message-mode-map "\C-c\C-f\C-b" 'message-goto-bcc)\r
-  (define-key message-mode-map "\C-c\C-f\C-w" 'message-goto-fcc)\r
-  (define-key message-mode-map "\C-c\C-f\C-c" 'message-goto-cc)\r
-  (define-key message-mode-map "\C-c\C-f\C-s" 'message-goto-subject)\r
-  ;; (define-key message-mode-map "\C-c\C-f\C-r" 'message-goto-reply-to)\r
-  (define-key message-mode-map "\C-c\C-f\C-r" 'message-goto-mail-reply-to)\r
-  (define-key message-mode-map "\C-c\C-f\C-m" 'message-goto-mail-followup-to)\r
-  (define-key message-mode-map "\C-c\C-f\C-n" 'message-goto-newsgroups)\r
-  (define-key message-mode-map "\C-c\C-f\C-d" 'message-goto-distribution)\r
-  (define-key message-mode-map "\C-c\C-f\C-f" 'message-goto-followup-to)\r
-  (define-key message-mode-map "\C-c\C-f\C-k" 'message-goto-keywords)\r
-  (define-key message-mode-map "\C-c\C-f\C-u" 'message-goto-summary)\r
-  (define-key message-mode-map "\C-c\C-b" 'message-goto-body)\r
-  (define-key message-mode-map "\C-c\C-i" 'message-goto-signature)\r
-\r
-  (define-key message-mode-map "\C-c\C-t" 'message-insert-to)\r
-  (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups)\r
-\r
-  (define-key message-mode-map "\C-c\C-y" 'message-yank-original)\r
-  (define-key message-mode-map "\C-c\C-q" 'message-fill-yanked-message)\r
-  (define-key message-mode-map "\C-c\C-w" 'message-insert-signature)\r
-  (define-key message-mode-map "\C-c\M-h" 'message-insert-headers)\r
-  (define-key message-mode-map "\C-c\C-r" 'message-caesar-buffer-body)\r
-  (define-key message-mode-map "\C-c\C-o" 'message-sort-headers)\r
-  (define-key message-mode-map "\C-c\M-r" 'message-rename-buffer)\r
-\r
-  (define-key message-mode-map "\C-c\C-c" 'message-send-and-exit)\r
-  (define-key message-mode-map "\C-c\C-s" 'message-send)\r
-  (define-key message-mode-map "\C-c\C-k" 'message-kill-buffer)\r
-  (define-key message-mode-map "\C-c\C-d" 'message-dont-send)\r
-\r
-  (define-key message-mode-map "\C-c\C-e" 'message-elide-region)\r
-  (define-key message-mode-map "\C-c\C-v" 'message-delete-not-region)\r
-  (define-key message-mode-map "\C-c\C-z" 'message-kill-to-signature)\r
-  (define-key message-mode-map "\M-\r" 'message-newline-and-reformat)\r
-\r
-  (define-key message-mode-map "\t" 'message-tab)\r
-\r
-  (define-key message-mode-map "\C-x\C-s" 'message-save-drafts)\r
-  (define-key message-mode-map "\C-xk" 'message-mimic-kill-buffer))\r
-\r
-(easy-menu-define\r
- message-mode-menu message-mode-map "Message Menu."\r
- '("Message"\r
-   ["Sort Headers" message-sort-headers t]\r
-   ["Yank Original" message-yank-original t]\r
-   ["Fill Yanked Message" message-fill-yanked-message t]\r
-   ["Insert Signature" message-insert-signature t]\r
-   ["Caesar (rot13) Message" message-caesar-buffer-body t]\r
-   ["Caesar (rot13) Region" message-caesar-region (mark t)]\r
-   ["Elide Region" message-elide-region (mark t)]\r
-   ["Delete Outside Region" message-delete-not-region (mark t)]\r
-   ["Kill To Signature" message-kill-to-signature t]\r
-   ["Newline and Reformat" message-newline-and-reformat t]\r
-   ["Rename buffer" message-rename-buffer t]\r
-   ["Spellcheck" ispell-message t]\r
-   "----"\r
-   ["Send Message" message-send-and-exit t]\r
-   ["Abort Message" message-dont-send t]\r
-   ["Kill Message" message-kill-buffer t]))\r
-\r
-(easy-menu-define\r
- message-mode-field-menu message-mode-map ""\r
- '("Field"\r
-   ["Fetch To" message-insert-to t]\r
-   ["Fetch Newsgroups" message-insert-newsgroups t]\r
-   "----"\r
-   ["To" message-goto-to t]\r
-   ["Subject" message-goto-subject t]\r
-   ["Cc" message-goto-cc t]\r
-   ["Reply-To" message-goto-reply-to t]\r
-   ["Mail-Reply-To" message-goto-mail-reply-to t]\r
-   ["Mail-Followup-To" message-goto-mail-followup-to t]\r
-   ["Mail-Copies-To" message-goto-mail-copies-to t]\r
-   ["Summary" message-goto-summary t]\r
-   ["Keywords" message-goto-keywords t]\r
-   ["Newsgroups" message-goto-newsgroups t]\r
-   ["Followup-To" message-goto-followup-to t]\r
-   ["Distribution" message-goto-distribution t]\r
-   ["Body" message-goto-body t]\r
-   ["Signature" message-goto-signature t]))\r
-\r
-(defvar facemenu-add-face-function)\r
-(defvar facemenu-remove-face-function)\r
-\r
-;;;###autoload\r
-(defun message-mode ()\r
-  "Major mode for editing mail and news to be sent.\r
-Like Text Mode but with these additional commands:\r
-C-c C-s  message-send (send the message)    C-c C-c  message-send-and-exit\r
-C-c C-f  move to a header field (and create it if there isn't):\r
-        C-c C-f C-t  move to To        C-c C-f C-s  move to Subject\r
-        C-c C-f C-c  move to Cc        C-c C-f C-b  move to Bcc\r
-        C-c C-f C-w  move to Fcc       C-c C-f C-r  move to Reply-To\r
-        C-c C-f C-u  move to Summary   C-c C-f C-n  move to Newsgroups\r
-        C-c C-f C-k  move to Keywords  C-c C-f C-d  move to Distribution\r
-        C-c C-f C-m  move to Mail-Followup-To\r
-        C-c C-f C-f  move to Followup-To\r
-C-c C-t  message-insert-to (add a To header to a news followup)\r
-C-c C-n  message-insert-newsgroups (add a Newsgroup header to a news reply)\r
-C-c C-b  message-goto-body (move to beginning of message text).\r
-C-c C-i  message-goto-signature (move to the beginning of the signature).\r
-C-c C-w  message-insert-signature (insert `message-signature-file' file).\r
-C-c C-y  message-yank-original (insert current message, if any).\r
-C-c C-q  message-fill-yanked-message (fill what was yanked).\r
-C-c C-e  message-elide-region (elide the text between point and mark).\r
-C-c C-v  message-delete-not-region (remove the text outside the region).\r
-C-c C-z  message-kill-to-signature (kill the text up to the signature).\r
-C-c C-r  message-caesar-buffer-body (rot13 the message body)."\r
-  (interactive)\r
-  (kill-all-local-variables)\r
-  (set (make-local-variable 'message-reply-buffer) nil)\r
-  (make-local-variable 'message-send-actions)\r
-  (make-local-variable 'message-exit-actions)\r
-  (make-local-variable 'message-kill-actions)\r
-  (make-local-variable 'message-postpone-actions)\r
-  (make-local-variable 'message-draft-article)\r
-  (make-local-hook 'kill-buffer-hook)\r
-  (set-syntax-table message-mode-syntax-table)\r
-  (use-local-map message-mode-map)\r
-  (setq local-abbrev-table message-mode-abbrev-table)\r
-  (setq major-mode 'message-mode)\r
-  (setq mode-name "Message")\r
-  (setq buffer-offer-save t)\r
-  (make-local-variable 'facemenu-add-face-function)\r
-  (make-local-variable 'facemenu-remove-face-function)\r
-  (setq facemenu-add-face-function\r
-       (lambda (face end)\r
-         (let ((face-fun (cdr (assq face message-face-alist))))\r
-           (if face-fun\r
-               (funcall face-fun (point) end)\r
-             (error "Face %s not configured for %s mode" face mode-name)))\r
-         "")\r
-       facemenu-remove-face-function t)\r
-  (make-local-variable 'paragraph-separate)\r
-  (make-local-variable 'paragraph-start)\r
-  ;; `-- ' precedes the signature.  `-----' appears at the start of the\r
-  ;; lines that delimit forwarded messages.\r
-  ;; Lines containing just >= 3 dashes, perhaps after whitespace,\r
-  ;; are also sometimes used and should be separators.\r
-  (setq paragraph-start\r
-       (concat (regexp-quote mail-header-separator)\r
-               "$\\|[ \t]*[a-z0-9A-Z]*>+[ \t]*$\\|[ \t]*$\\|"\r
-               "-- $\\|---+$\\|"\r
-               page-delimiter\r
-               ;;!!! Uhm... shurely this can't be right?\r
-               "[> " (regexp-quote message-yank-prefix) "]+$"))\r
-  (setq paragraph-separate paragraph-start)\r
-  (make-local-variable 'message-reply-headers)\r
-  (setq message-reply-headers nil)\r
-  (make-local-variable 'message-user-agent)\r
-  (make-local-variable 'message-post-method)\r
-  (set (make-local-variable 'message-sent-message-via) nil)\r
-  (set (make-local-variable 'message-checksum) nil)\r
-  (make-local-variable 'message-parameter-alist)\r
-  (setq message-parameter-alist\r
-       (copy-sequence message-startup-parameter-alist))\r
-  ;;(when (fboundp 'mail-hist-define-keys)\r
-  ;;  (mail-hist-define-keys))\r
-  (when (string-match "XEmacs\\|Lucid" emacs-version)\r
-    (message-setup-toolbar))\r
-  (easy-menu-add message-mode-menu message-mode-map)\r
-  (easy-menu-add message-mode-field-menu message-mode-map)\r
-  ;; Allow mail alias things.\r
-  (when (eq message-mail-alias-type 'abbrev)\r
-    (if (fboundp 'mail-abbrevs-setup)\r
-       (mail-abbrevs-setup)\r
-      (mail-aliases-setup)))\r
-  (message-set-auto-save-file-name)\r
-  (unless (string-match "XEmacs" emacs-version)\r
-    (set (make-local-variable 'font-lock-defaults)\r
-        '(message-font-lock-keywords t)))\r
-  (make-local-variable 'adaptive-fill-regexp)\r
-  (setq adaptive-fill-regexp\r
-       (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|" adaptive-fill-regexp))\r
-  (unless (boundp 'adaptive-fill-first-line-regexp)\r
-    (setq adaptive-fill-first-line-regexp nil))\r
-  (make-local-variable 'adaptive-fill-first-line-regexp)\r
-  (setq adaptive-fill-first-line-regexp\r
-       (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|"\r
-               adaptive-fill-first-line-regexp))\r
-  (run-hooks 'text-mode-hook 'message-mode-hook))\r
-\r
-\f\r
-\r
-;;;\r
-;;; Message mode commands\r
-;;;\r
-\r
-;;; Movement commands\r
-\r
-(defun message-goto-to ()\r
-  "Move point to the To header."\r
-  (interactive)\r
-  (message-position-on-field "To"))\r
-\r
-(defun message-goto-subject ()\r
-  "Move point to the Subject header."\r
-  (interactive)\r
-  (message-position-on-field "Subject"))\r
-\r
-(defun message-goto-cc ()\r
-  "Move point to the Cc header."\r
-  (interactive)\r
-  (message-position-on-field "Cc" "To"))\r
-\r
-(defun message-goto-bcc ()\r
-  "Move point to the Bcc  header."\r
-  (interactive)\r
-  (message-position-on-field "Bcc" "Cc" "To"))\r
-\r
-(defun message-goto-fcc ()\r
-  "Move point to the Fcc header."\r
-  (interactive)\r
-  (message-position-on-field "Fcc" "To" "Newsgroups"))\r
-\r
-(defun message-goto-reply-to ()\r
-  "Move point to the Reply-To header."\r
-  (interactive)\r
-  (message-position-on-field "Reply-To" "Subject"))\r
-\r
-(defun message-goto-mail-reply-to ()\r
-  "Move point to the Mail-Reply-To header."\r
-  (interactive)\r
-  (message-position-on-field "Mail-Reply-To" "Subject"))\r
-\r
-(defun message-goto-mail-followup-to ()\r
-  "Move point to the Mail-Followup-To header."\r
-  (interactive)\r
-  (message-position-on-field "Mail-Followup-To" "Subject"))\r
-\r
-(defun message-goto-mail-copies-to ()\r
-  "Move point to the Mail-Copies-To header."\r
-  (interactive)\r
-  (message-position-on-field "Mail-Copies-To" "Subject"))\r
-\r
-(defun message-goto-newsgroups ()\r
-  "Move point to the Newsgroups header."\r
-  (interactive)\r
-  (message-position-on-field "Newsgroups"))\r
-\r
-(defun message-goto-distribution ()\r
-  "Move point to the Distribution header."\r
-  (interactive)\r
-  (message-position-on-field "Distribution"))\r
-\r
-(defun message-goto-followup-to ()\r
-  "Move point to the Followup-To header."\r
-  (interactive)\r
-  (message-position-on-field "Followup-To" "Newsgroups"))\r
-\r
-(defun message-goto-keywords ()\r
-  "Move point to the Keywords header."\r
-  (interactive)\r
-  (message-position-on-field "Keywords" "Subject"))\r
-\r
-(defun message-goto-summary ()\r
-  "Move point to the Summary header."\r
-  (interactive)\r
-  (message-position-on-field "Summary" "Subject"))\r
-\r
-(defun message-goto-body ()\r
-  "Move point to the beginning of the message body."\r
-  (interactive)\r
-  (if (looking-at "[ \t]*\n") (expand-abbrev))\r
-  (goto-char (point-min))\r
-  (search-forward (concat "\n" mail-header-separator "\n") nil t))\r
-\r
-(defun message-goto-eoh ()\r
-  "Move point to the end of the headers."\r
-  (interactive)\r
-  (message-goto-body)\r
-  (forward-line -2))\r
-\r
-(defun message-goto-signature ()\r
-  "Move point to the beginning of the message signature.\r
-If there is no signature in the article, go to the end and\r
-return nil."\r
-  (interactive)\r
-  (goto-char (point-min))\r
-  (if (re-search-forward message-signature-separator nil t)\r
-      (forward-line 1)\r
-    (goto-char (point-max))\r
-    nil))\r
-\r
-\f\r
-\r
-(defun message-insert-to (&optional force)\r
-  "Insert a To header that points to the author of the article being replied to.\r
-If the original author requested not to be sent mail, the function signals\r
-an error.\r
-With the prefix argument FORCE, insert the header anyway."\r
-  (interactive "P")\r
-  (let ((co (message-fetch-reply-field "mail-copies-to")))\r
-    (when (and (null force)\r
-              co\r
-              (or (equal (downcase co) "never")\r
-                  (equal (downcase co) "nobody")))\r
-      (error "The user has requested not to have copies sent via mail")))\r
-  (when (and (message-position-on-field "To")\r
-            (mail-fetch-field "to")\r
-            (not (string-match "\\` *\\'" (mail-fetch-field "to"))))\r
-    (insert ", "))\r
-  (insert (or (message-fetch-reply-field "reply-to")\r
-             (message-fetch-reply-field "from") "")))\r
-\r
-(defun message-insert-newsgroups ()\r
-  "Insert the Newsgroups header from the article being replied to."\r
-  (interactive)\r
-  (when (and (message-position-on-field "Newsgroups")\r
-            (mail-fetch-field "newsgroups")\r
-            (not (string-match "\\` *\\'" (mail-fetch-field "newsgroups"))))\r
-    (insert ","))\r
-  (insert (or (message-fetch-reply-field "newsgroups") "")))\r
-\r
-\f\r
-\r
-;;; Various commands\r
-\r
-(defun message-delete-not-region (beg end)\r
-  "Delete everything in the body of the current message that is outside of the region."\r
-  (interactive "r")\r
-  (save-excursion\r
-    (goto-char end)\r
-    (delete-region (point) (if (not (message-goto-signature))\r
-                              (point)\r
-                            (forward-line -2)\r
-                            (point)))\r
-    (insert "\n")\r
-    (goto-char beg)\r
-    (delete-region beg (progn (message-goto-body)\r
-                             (forward-line 2)\r
-                             (point))))\r
-  (when (message-goto-signature)\r
-    (forward-line -2)))\r
-\r
-(defun message-kill-to-signature ()\r
-  "Deletes all text up to the signature."\r
-  (interactive)\r
-  (let ((point (point)))\r
-    (message-goto-signature)\r
-    (unless (eobp)\r
-      (forward-line -2))\r
-    (kill-region point (point))\r
-    (unless (bolp)\r
-      (insert "\n"))))\r
-\r
-(defun message-newline-and-reformat ()\r
-  "Insert four newlines, and then reformat if inside quoted text."\r
-  (interactive)\r
-  (let ((point (point))\r
-       quoted)\r
-    (save-excursion\r
-      (beginning-of-line)\r
-      (setq quoted (looking-at (regexp-quote message-yank-prefix))))\r
-    (insert "\n\n\n\n")\r
-    (when quoted\r
-      (insert message-yank-prefix))\r
-    (fill-paragraph nil)\r
-    (goto-char point)\r
-    (forward-line 2)))\r
-\r
-(defun message-insert-signature (&optional force)\r
-  "Insert a signature.  See documentation for the `message-signature' variable."\r
-  (interactive (list 0))\r
-  (let* ((signature\r
-         (cond\r
-          ((and (null message-signature)\r
-                (eq force 0))\r
-           (save-excursion\r
-             (goto-char (point-max))\r
-             (not (re-search-backward message-signature-separator nil t))))\r
-          ((and (null message-signature)\r
-                force)\r
-           t)\r
-          ((message-functionp message-signature)\r
-           (funcall message-signature))\r
-          ((listp message-signature)\r
-           (eval message-signature))\r
-          (t message-signature)))\r
-        (signature\r
-         (cond ((stringp signature)\r
-                signature)\r
-               ((and (eq t signature)\r
-                     message-signature-file\r
-                     (file-exists-p message-signature-file))\r
-                signature))))\r
-    (when signature\r
-      (goto-char (point-max))\r
-      ;; Insert the signature.\r
-      (unless (bolp)\r
-       (insert "\n"))\r
-      (insert "\n-- \n")\r
-      (if (eq signature t)\r
-         (insert-file-contents message-signature-file)\r
-       (insert signature))\r
-      (goto-char (point-max))\r
-      (or (bolp) (insert "\n")))))\r
-\r
-(defun message-elide-region (b e)\r
-  "Elide the text between point and mark.\r
-An ellipsis (from `message-elide-elipsis') will be inserted where the\r
-text was killed."\r
-  (interactive "r")\r
-  (kill-region b e)\r
-  (unless (bolp)\r
-    (insert "\n"))\r
-  (insert message-elide-elipsis))\r
-\r
-(defvar message-caesar-translation-table nil)\r
-\r
-(defun message-caesar-region (b e &optional n)\r
-  "Caesar rotation of region by N, default 13, for decrypting netnews."\r
-  (interactive\r
-   (list\r
-    (min (point) (or (mark t) (point)))\r
-    (max (point) (or (mark t) (point)))\r
-    (when current-prefix-arg\r
-      (prefix-numeric-value current-prefix-arg))))\r
-\r
-  (setq n (if (numberp n) (mod n 26) 13)) ;canonize N\r
-  (unless (or (zerop n)                        ; no action needed for a rot of 0\r
-             (= b e))                  ; no region to rotate\r
-    ;; We build the table, if necessary.\r
-    (when (or (not message-caesar-translation-table)\r
-             (/= (aref message-caesar-translation-table ?a) (+ ?a n)))\r
-       (setq message-caesar-translation-table\r
-             (message-make-caesar-translation-table n)))\r
-    ;; Then we translate the region.  Do it this way to retain\r
-    ;; text properties.\r
-    (while (< b e)\r
-      (when (< (char-after b) 255)\r
-       (subst-char-in-region\r
-        b (1+ b) (char-after b)\r
-        (aref message-caesar-translation-table (char-after b))))\r
-      (incf b))))\r
-\r
-(defun message-make-caesar-translation-table (n)\r
-  "Create a rot table with offset N."\r
-  (let ((i -1)\r
-       (table (make-string 256 0)))\r
-    (while (< (incf i) 256)\r
-      (aset table i i))\r
-    (concat\r
-     (substring table 0 ?A)\r
-     (substring table (+ ?A n) (+ ?A n (- 26 n)))\r
-     (substring table ?A (+ ?A n))\r
-     (substring table (+ ?A 26) ?a)\r
-     (substring table (+ ?a n) (+ ?a n (- 26 n)))\r
-     (substring table ?a (+ ?a n))\r
-     (substring table (+ ?a 26) 255))))\r
-\r
-(defun message-caesar-buffer-body (&optional rotnum)\r
-  "Caesar rotates all letters in the current buffer by 13 places.\r
-Used to encode/decode possiblyun offensive messages (commonly in net.jokes).\r
-With prefix arg, specifies the number of places to rotate each letter forward.\r
-Mail and USENET news headers are not rotated."\r
-  (interactive (if current-prefix-arg\r
-                  (list (prefix-numeric-value current-prefix-arg))\r
-                (list nil)))\r
-  (save-excursion\r
-    (save-restriction\r
-      (when (message-goto-body)\r
-       (narrow-to-region (point) (point-max)))\r
-      (message-caesar-region (point-min) (point-max) rotnum))))\r
-\r
-(defun message-pipe-buffer-body (program)\r
-  "Pipe the message body in the current buffer through PROGRAM."\r
-  (save-excursion\r
-    (save-restriction\r
-      (when (message-goto-body)\r
-        (narrow-to-region (point) (point-max)))\r
-      (let ((body (buffer-substring (point-min) (point-max))))\r
-        (unless (equal 0 (call-process-region\r
-                           (point-min) (point-max) program t t))\r
-            (insert body)\r
-            (message "%s failed." program))))))\r
-\r
-(defun message-rename-buffer (&optional enter-string)\r
-  "Rename the *message* buffer to \"*message* RECIPIENT\".\r
-If the function is run with a prefix, it will ask for a new buffer\r
-name, rather than giving an automatic name."\r
-  (interactive "Pbuffer name: ")\r
-  (save-excursion\r
-    (save-restriction\r
-      (goto-char (point-min))\r
-      (narrow-to-region (point)\r
-                       (search-forward mail-header-separator nil 'end))\r
-      (let* ((mail-to (or\r
-                      (if (message-news-p) (message-fetch-field "Newsgroups")\r
-                        (message-fetch-field "To"))\r
-                      ""))\r
-            (mail-trimmed-to\r
-             (if (string-match "," mail-to)\r
-                 (concat (substring mail-to 0 (match-beginning 0)) ", ...")\r
-               mail-to))\r
-            (name-default (concat "*message* " mail-trimmed-to))\r
-            (name (if enter-string\r
-                      (read-string "New buffer name: " name-default)\r
-                    name-default)))\r
-       (rename-buffer name t)))))\r
-\r
-(defun message-fill-yanked-message (&optional justifyp)\r
-  "Fill the paragraphs of a message yanked into this one.\r
-Numeric argument means justify as well."\r
-  (interactive "P")\r
-  (save-excursion\r
-    (goto-char (point-min))\r
-    (search-forward (concat "\n" mail-header-separator "\n") nil t)\r
-    (let ((fill-prefix message-yank-prefix))\r
-      (fill-individual-paragraphs (point) (point-max) justifyp t))))\r
-\r
-(defun message-indent-citation ()\r
-  "Modify text just inserted from a message to be cited.\r
-The inserted text should be the region.\r
-When this function returns, the region is again around the modified text.\r
-\r
-Normally, indent each nonblank line `message-indentation-spaces' spaces.\r
-However, if `message-yank-prefix' is non-nil, insert that prefix on each line."\r
-  (let ((start (point)))\r
-    ;; Remove unwanted headers.\r
-    (when message-ignored-cited-headers\r
-      (let (all-removed)\r
-       (save-restriction\r
-         (narrow-to-region\r
-          (goto-char start)\r
-          (if (search-forward "\n\n" nil t)\r
-              (1- (point))\r
-            (point)))\r
-         (message-remove-header message-ignored-cited-headers t)\r
-         (when (= (point-min) (point-max))\r
-           (setq all-removed t))\r
-         (goto-char (point-max)))\r
-       (if all-removed\r
-           (goto-char start)\r
-         (forward-line 1))))\r
-    ;; Delete blank lines at the start of the buffer.\r
-    (while (and (point-min)\r
-               (eolp)\r
-               (not (eobp)))\r
-      (message-delete-line))\r
-    ;; Delete blank lines at the end of the buffer.\r
-    (goto-char (point-max))\r
-    (unless (eolp)\r
-      (insert "\n"))\r
-    (while (and (zerop (forward-line -1))\r
-               (looking-at "$"))\r
-      (message-delete-line))\r
-    ;; Do the indentation.\r
-    (if (null message-yank-prefix)\r
-       (indent-rigidly start (mark t) message-indentation-spaces)\r
-      (save-excursion\r
-       (goto-char start)\r
-       (while (< (point) (mark t))\r
-         (insert message-yank-prefix)\r
-         (forward-line 1))))\r
-    (goto-char start)))\r
-\r
-(defvar gnus-article-copy)\r
-(defun message-yank-original (&optional arg)\r
-  "Insert the message being replied to, if any.\r
-Puts point before the text and mark after.\r
-Normally indents each nonblank line ARG spaces (default 3).  However,\r
-if `message-yank-prefix' is non-nil, insert that prefix on each line.\r
-\r
-This function uses `message-cite-function' to do the actual citing.\r
-\r
-Just \\[universal-argument] as argument means don't indent, insert no\r
-prefix, and don't delete any headers.\r
-\r
-In addition, if `message-yank-add-new-references' is non-nil and this\r
-command is called interactively, new IDs from the yanked article will\r
-be added to \"References\" field."\r
-  (interactive "P")\r
-  (let ((modified (buffer-modified-p))\r
-       (buffer (message-eval-parameter message-reply-buffer))\r
-       refs references)\r
-    (when (and buffer\r
-              message-cite-function)\r
-      (delete-windows-on buffer t)\r
-      (insert-buffer buffer) ; mark will be set at the end of article.\r
-\r
-      ;; Add new IDs to References field.\r
-      (when (and message-yank-add-new-references (interactive-p))\r
-       (save-excursion\r
-         (save-restriction\r
-           (narrow-to-region (point) (mark t))\r
-           (message-narrow-to-head)\r
-           (setq refs (concat (or (message-fetch-field "References") "")\r
-                              " "\r
-                              (or (message-fetch-field "Message-ID") "")))\r
-           (unless (string-match "^ +$" refs)\r
-             (widen)\r
-             (message-narrow-to-headers)\r
-             (setq references (message-fetch-field "References"))\r
-             (when references\r
-               (setq references (split-string references)))\r
-             (mapcar\r
-              (lambda (ref)\r
-                (or (zerop (length ref))\r
-                    (member ref references)\r
-                    (setq references (append references (list ref)))))\r
-              (split-string refs))\r
-             (when references\r
-               (goto-char (point-min))\r
-               (let ((case-fold-search t))\r
-                 (if (re-search-forward "^References:\\([\t ]+.+\n\\)+" nil t)\r
-                     (replace-match "")\r
-                   (goto-char (point-max))))\r
-               (mail-header-format\r
-                (list (or (assq 'References message-header-format-alist)\r
-                          '(References . message-shorten-references)))\r
-                (list (cons 'References\r
-                            (mapconcat 'identity references " "))))\r
-               (backward-delete-char 1))))))\r
-\r
-      (funcall message-cite-function)\r
-      (message-exchange-point-and-mark)\r
-      (unless (bolp)\r
-       (insert ?\n))\r
-      (unless modified\r
-       (setq message-checksum (message-checksum))))))\r
-\r
-(defun message-cite-original-without-signature ()\r
-  "Cite function in the standard Message manner."\r
-  (let ((start (point))\r
-       (end (mark t))\r
-       (functions\r
-        (when message-indent-citation-function\r
-          (if (listp message-indent-citation-function)\r
-              message-indent-citation-function\r
-            (list message-indent-citation-function)))))\r
-    (goto-char end)\r
-    (when (re-search-backward message-signature-separator start t)\r
-      ;; Also peel off any blank lines before the signature.\r
-      (forward-line -1)\r
-      (while (looking-at "^[ \t]*$")\r
-       (forward-line -1))\r
-      (forward-line 1)\r
-      (delete-region (point) end))\r
-    (goto-char start)\r
-    (while functions\r
-      (funcall (pop functions)))\r
-    (when message-citation-line-function\r
-      (unless (bolp)\r
-       (insert "\n"))\r
-      (funcall message-citation-line-function))))\r
-\r
-(defvar mail-citation-hook) ;Compiler directive\r
-(defun message-cite-original ()\r
-  "Cite function in the standard Message manner."\r
-  (if (and (boundp 'mail-citation-hook)\r
-          mail-citation-hook)\r
-      (run-hooks 'mail-citation-hook)\r
-    (let ((start (point))\r
-         (end (mark t))\r
-         (functions\r
-          (when message-indent-citation-function\r
-            (if (listp message-indent-citation-function)\r
-                message-indent-citation-function\r
-              (list message-indent-citation-function)))))\r
-      (goto-char start)\r
-      (while functions\r
-       (funcall (pop functions)))\r
-      (when message-citation-line-function\r
-       (unless (bolp)\r
-         (insert "\n"))\r
-       (funcall message-citation-line-function)))))\r
-\r
-(defun message-insert-citation-line ()\r
-  "Function that inserts a simple citation line."\r
-  (when message-reply-headers\r
-    (insert (mail-header-from message-reply-headers) " writes:\n\n")))\r
-\r
-(defun message-position-on-field (header &rest afters)\r
-  (let ((case-fold-search t))\r
-    (save-restriction\r
-      (narrow-to-region\r
-       (goto-char (point-min))\r
-       (progn\r
-        (re-search-forward\r
-         (concat "^" (regexp-quote mail-header-separator) "$"))\r
-        (match-beginning 0)))\r
-      (goto-char (point-min))\r
-      (if (re-search-forward (concat "^" (regexp-quote header) ":") nil t)\r
-         (progn\r
-           (re-search-forward "^[^ \t]" nil 'move)\r
-           (beginning-of-line)\r
-           (skip-chars-backward "\n")\r
-           t)\r
-       (while (and afters\r
-                   (not (re-search-forward\r
-                         (concat "^" (regexp-quote (car afters)) ":")\r
-                         nil t)))\r
-         (pop afters))\r
-       (when afters\r
-         (re-search-forward "^[^ \t]" nil 'move)\r
-         (beginning-of-line))\r
-       (insert header ": \n")\r
-       (forward-char -1)\r
-       nil))))\r
-\r
-(defun message-remove-signature ()\r
-  "Remove the signature from the text between point and mark.\r
-The text will also be indented the normal way."\r
-  (save-excursion\r
-    (let ((start (point))\r
-         mark)\r
-      (if (not (re-search-forward message-signature-separator (mark t) t))\r
-         ;; No signature here, so we just indent the cited text.\r
-         (message-indent-citation)\r
-       ;; Find the last non-empty line.\r
-       (forward-line -1)\r
-       (while (looking-at "[ \t]*$")\r
-         (forward-line -1))\r
-       (forward-line 1)\r
-       (setq mark (set-marker (make-marker) (point)))\r
-       (goto-char start)\r
-       (message-indent-citation)\r
-       ;; Enable undoing the deletion.\r
-       (undo-boundary)\r
-       (delete-region mark (mark t))\r
-       (set-marker mark nil)))))\r
-\r
-\f\r
-\r
-;;;\r
-;;; Sending messages\r
-;;;\r
-\r
-;; Avoid byte-compile warning.\r
-(defvar message-encoding-buffer nil)\r
-(defvar message-edit-buffer nil)\r
-(defvar message-mime-mode nil)\r
-\r
-(defun message-send-and-exit (&optional arg)\r
-  "Send message like `message-send', then, if no errors, exit from mail buffer."\r
-  (interactive "P")\r
-  (let ((buf (current-buffer))\r
-       (actions message-exit-actions)\r
-       (frame (selected-frame))\r
-       (org-frame message-original-frame))\r
-    (when (and (message-send arg)\r
-              (buffer-name buf))\r
-      (if message-kill-buffer-on-exit\r
-         (kill-buffer buf)\r
-       (bury-buffer buf)\r
-       (when (eq buf (current-buffer))\r
-         (message-bury buf)))\r
-      (message-do-actions actions)\r
-      (message-delete-frame frame org-frame)\r
-      t)))\r
-\r
-(defun message-dont-send ()\r
-  "Don't send the message you have been editing."\r
-  (interactive)\r
-  (message-save-drafts)\r
-  (let ((actions message-postpone-actions)\r
-       (frame (selected-frame))\r
-       (org-frame message-original-frame))\r
-    (message-bury (current-buffer))\r
-    (message-do-actions actions)\r
-    (message-delete-frame frame org-frame)))\r
-\r
-(defun message-kill-buffer ()\r
-  "Kill the current buffer."\r
-  (interactive)\r
-  (when (or (not (buffer-modified-p))\r
-           (eq t message-kill-buffer-query-function)\r
-           (funcall message-kill-buffer-query-function\r
-                    "The buffer modified; kill anyway? "))\r
-    (let ((actions message-kill-actions)\r
-         (frame (selected-frame))\r
-         (org-frame message-original-frame))\r
-      (setq buffer-file-name nil)\r
-      (kill-buffer (current-buffer))\r
-      (message-do-actions actions)\r
-      (message-delete-frame frame org-frame)))\r
-  (message ""))\r
-\r
-(defun message-mimic-kill-buffer ()\r
-  "Kill the current buffer with query."\r
-  (interactive)\r
-  (unless (eq 'message-mode major-mode)\r
-    (error "%s must be invoked from a message buffer." this-command))\r
-  (let ((command this-command)\r
-       (bufname (read-buffer (format "Kill buffer: (default %s) "\r
-                                     (buffer-name)))))\r
-    (if (or (not bufname)\r
-           (string-equal bufname "")\r
-           (string-equal bufname (buffer-name)))\r
-       (message-kill-buffer)\r
-      (message "%s must be invoked only for the current buffer." command))))\r
-\r
-(defun message-delete-frame (frame org-frame)\r
-  "Delete frame for editing message."\r
-  (when (and (or (and (featurep 'xemacs)\r
-                     (not (eq 'tty (device-type))))\r
-                window-system\r
-                (>= emacs-major-version 20))\r
-            (or (and (eq message-delete-frame-on-exit t)\r
-                     (select-frame frame)\r
-                     (or (eq frame org-frame)\r
-                         (prog1\r
-                             (y-or-n-p "Delete this frame?")\r
-                           (message ""))))\r
-                (and (eq message-delete-frame-on-exit 'ask)\r
-                     (select-frame frame)\r
-                     (prog1\r
-                         (y-or-n-p "Delete this frame?")\r
-                       (message "")))))\r
-    (delete-frame frame)))\r
-\r
-(defun message-bury (buffer)\r
-  "Bury this mail buffer."\r
-  (let ((newbuf (other-buffer buffer)))\r
-    (bury-buffer buffer)\r
-    (if (and (fboundp 'frame-parameters)\r
-            (cdr (assq 'dedicated (frame-parameters)))\r
-            (not (null (delq (selected-frame) (visible-frame-list)))))\r
-       (delete-frame (selected-frame))\r
-      (switch-to-buffer newbuf))))\r
-\r
-(defun message-send (&optional arg)\r
-  "Send the message in the current buffer.\r
-If `message-interactive' is non-nil, wait for success indication\r
-or error messages, and inform user.\r
-Otherwise any failure is reported in a message back to\r
-the user from the mailer."\r
-  (interactive "P")\r
-  ;; Disabled test.\r
-  (when (or (buffer-modified-p)\r
-           (message-check-element 'unchanged)\r
-           (y-or-n-p "No changes in the buffer; really send? "))\r
-    ;; Make it possible to undo the coming changes.\r
-    (undo-boundary)\r
-    (let ((inhibit-read-only t))\r
-      (put-text-property (point-min) (point-max) 'read-only nil))\r
-    (run-hooks 'message-send-hook)\r
-    (message "Sending...")\r
-    (let ((message-encoding-buffer\r
-          (message-generate-new-buffer-clone-locals " message encoding"))\r
-         (message-edit-buffer (current-buffer))\r
-         (message-mime-mode mime-edit-mode-flag)\r
-         (alist message-send-method-alist)\r
-         (success t)\r
-         elem sent)\r
-      (save-excursion\r
-       (set-buffer message-encoding-buffer)\r
-       (erase-buffer)\r
-       (insert-buffer message-edit-buffer)\r
-       (funcall message-encode-function)\r
-       (message-fix-before-sending)\r
-       (while (and success\r
-                   (setq elem (pop alist)))\r
-         (when (and (or (not (funcall (cadr elem)))\r
-                        (and (or (not (memq (car elem)\r
-                                            message-sent-message-via))\r
-                                 (y-or-n-p\r
-                                  (format\r
-                                   "Already sent message via %s; resend? "\r
-                                   (car elem))))\r
-                             (setq success (funcall (caddr elem) arg)))))\r
-           (setq sent t))))\r
-      (when (and success sent)\r
-       (message-do-fcc)\r
-       ;;(when (fboundp 'mail-hist-put-headers-into-history)\r
-       ;; (mail-hist-put-headers-into-history))\r
-       (save-excursion\r
-         (run-hooks 'message-sent-hook))\r
-       (message "Sending...done")\r
-       ;; Mark the buffer as unmodified and delete autosave.\r
-       (set-buffer-modified-p nil)\r
-       (delete-auto-save-file-if-necessary t)\r
-       (message-disassociate-draft)\r
-       ;; Delete other mail buffers and stuff.\r
-       (message-do-send-housekeeping)\r
-       (message-do-actions message-send-actions)\r
-       ;; Return success.\r
-       t))))\r
-\r
-(defun message-send-via-mail (arg)\r
-  "Send the current message via mail."\r
-  (message-send-mail arg))\r
-\r
-(defun message-send-via-news (arg)\r
-  "Send the current message via news."\r
-  (message-send-news arg))\r
-\r
-(defmacro message-check (type &rest forms)\r
-  "Eval FORMS if TYPE is to be checked."\r
-  `(or (message-check-element ,type)\r
-       (save-excursion\r
-        ,@forms)))\r
-\r
-(put 'message-check 'lisp-indent-function 1)\r
-(put 'message-check 'edebug-form-spec '(form body))\r
-\r
-(defun message-fix-before-sending ()\r
-  "Do various things to make the message nice before sending it."\r
-  ;; Make sure there's a newline at the end of the message.\r
-  (goto-char (point-max))\r
-  (unless (bolp)\r
-    (insert "\n"))\r
-  ;; Delete all invisible text.\r
-  (message-check 'invisible-text\r
-    (when (text-property-any (point-min) (point-max) 'invisible t)\r
-      (put-text-property (point-min) (point-max) 'invisible nil)\r
-      (unless (yes-or-no-p "Invisible text found and made visible; continue posting? ")\r
-       (error "Invisible text found and made visible")))))\r
-\r
-(defun message-add-action (action &rest types)\r
-  "Add ACTION to be performed when doing an exit of type TYPES."\r
-  (let (var)\r
-    (while types\r
-      (set (setq var (intern (format "message-%s-actions" (pop types))))\r
-          (nconc (symbol-value var) (list action))))))\r
-\r
-(defun message-do-actions (actions)\r
-  "Perform all actions in ACTIONS."\r
-  ;; Now perform actions on successful sending.\r
-  (while actions\r
-    (ignore-errors\r
-      (cond\r
-       ;; A simple function.\r
-       ((message-functionp (car actions))\r
-       (funcall (car actions)))\r
-       ;; Something to be evaled.\r
-       (t\r
-       (eval (car actions)))))\r
-    (pop actions)))\r
-\r
-(defsubst message-maybe-split-and-send-mail ()\r
-  "Split a message if necessary, and send it via mail.\r
-Returns nil if sending succeeded, returns any string if sending failed.\r
-This sub function is for exclusive use of `message-send-mail'."\r
-  (let ((mime-edit-split-ignored-field-regexp\r
-        mime-edit-split-ignored-field-regexp)\r
-       (case-fold-search t)\r
-       failure)\r
-    (while (string-match "Message-ID" mime-edit-split-ignored-field-regexp)\r
-      (setq mime-edit-split-ignored-field-regexp\r
-           (concat (substring mime-edit-split-ignored-field-regexp\r
-                              0 (match-beginning 0))\r
-                   "Hey_MIME-Edit,_there_is_an_inviolable_Message_ID"\r
-                   "_so_don't_rape_it!"\r
-                   (substring mime-edit-split-ignored-field-regexp\r
-                              (match-end 0)))))\r
-    (setq failure\r
-         (or\r
-          (catch 'message-sending-mail-failure\r
-            (mime-edit-maybe-split-and-send\r
-             (function\r
-              (lambda ()\r
-                (interactive)\r
-                (save-restriction\r
-                  (std11-narrow-to-header mail-header-separator)\r
-                  (goto-char (point-min))\r
-                  (when (re-search-forward "^Message-ID:" nil t)\r
-                    (delete-region (match-end 0) (std11-field-end))\r
-                    (insert " " (message-make-message-id))))\r
-                (condition-case err\r
-                    (funcall message-send-mail-function)\r
-                  (error\r
-                   (throw 'message-sending-mail-failure err))))))\r
-            nil)\r
-          (condition-case err\r
-              (progn\r
-                (funcall message-send-mail-function)\r
-                nil)\r
-            (error err))))\r
-    (when failure\r
-      (if (eq 'error (car failure))\r
-         (cadr failure)\r
-       (prin1-to-string failure)))))\r
-\r
-(defun message-send-mail (&optional arg)\r
-  (require 'mail-utils)\r
-  (let ((tembuf (message-generate-new-buffer-clone-locals " message temp"))\r
-       (case-fold-search nil)\r
-       (news (message-news-p))\r
-       failure)\r
-    (save-restriction\r
-      (message-narrow-to-headers)\r
-      ;; Insert some headers.\r
-      (let ((message-deletable-headers\r
-            (if news nil message-deletable-headers)))\r
-       (message-generate-headers message-required-mail-headers))\r
-      ;; Let the user do all of the above.\r
-      (run-hooks 'message-header-hook))\r
-    (if (not (message-check-mail-syntax))\r
-       (progn\r
-         (message "")\r
-         nil)\r
-      (unwind-protect\r
-         (save-excursion\r
-           (set-buffer tembuf)\r
-           (erase-buffer)\r
-           (insert-buffer message-encoding-buffer)\r
-           ;; Remove some headers.\r
-           (save-restriction\r
-             (message-narrow-to-headers)\r
-             ;; Remove some headers.\r
-             (message-remove-header message-ignored-mail-headers t))\r
-           (goto-char (point-max))\r
-           ;; require one newline at the end.\r
-           (or (= (preceding-char) ?\n)\r
-               (insert ?\n))\r
-           (when (and news\r
-                      (or (message-fetch-field "cc")\r
-                          (message-fetch-field "to")))\r
-             (message-insert-courtesy-copy))\r
-           (setq failure (message-maybe-split-and-send-mail)))\r
-       (kill-buffer tembuf))\r
-      (set-buffer message-edit-buffer)\r
-      (if failure\r
-         (progn\r
-           (message "Couldn't send message via mail: %s" failure)\r
-           nil)\r
-       (push 'mail message-sent-message-via)))))\r
-\r
-(defun message-send-mail-with-sendmail ()\r
-  "Send off the prepared buffer with sendmail."\r
-  (let ((errbuf (if message-interactive\r
-                   (generate-new-buffer " sendmail errors")\r
-                 0))\r
-       resend-to-addresses delimline)\r
-    (let ((case-fold-search t))\r
-      (save-restriction\r
-       (message-narrow-to-headers)\r
-       (setq resend-to-addresses (message-fetch-field "resent-to")))\r
-      ;; Change header-delimiter to be what sendmail expects.\r
-      (goto-char (point-min))\r
-      (re-search-forward\r
-       (concat "^" (regexp-quote mail-header-separator) "\n"))\r
-      (replace-match "\n")\r
-      (backward-char 1)\r
-      (setq delimline (point-marker))\r
-      (run-hooks 'message-send-mail-hook)\r
-      ;; Insert an extra newline if we need it to work around\r
-      ;; Sun's bug that swallows newlines.\r
-      (goto-char (1+ delimline))\r
-      (when (eval message-mailer-swallows-blank-line)\r
-       (newline))\r
-      (when message-interactive\r
-       (save-excursion\r
-         (set-buffer errbuf)\r
-         (erase-buffer))))\r
-    (let ((default-directory "/"))\r
-      (as-binary-process\r
-       (apply 'call-process-region\r
-             (append (list (point-min) (point-max)\r
-                           (if (boundp 'sendmail-program)\r
-                               sendmail-program\r
-                             "/usr/lib/sendmail")\r
-                           nil errbuf nil "-oi")\r
-                     ;; Always specify who from,\r
-                     ;; since some systems have broken sendmails.\r
-                     ;; But some systems are more broken with -f, so\r
-                     ;; we'll let users override this.\r
-                     (if (null message-sendmail-f-is-evil)\r
-                         (list "-f" (user-login-name)))\r
-                     ;; These mean "report errors by mail"\r
-                     ;; and "deliver in background".\r
-                     (if (null message-interactive) '("-oem" "-odb"))\r
-                     ;; Get the addresses from the message\r
-                     ;; unless this is a resend.\r
-                     ;; We must not do that for a resend\r
-                     ;; because we would find the original addresses.\r
-                     ;; For a resend, include the specific addresses.\r
-                     (if resend-to-addresses\r
-                         (list resend-to-addresses)\r
-                       '("-t"))))))\r
-    (when message-interactive\r
-      (save-excursion\r
-       (set-buffer errbuf)\r
-       (goto-char (point-min))\r
-       (while (re-search-forward "\n\n* *" nil t)\r
-         (replace-match "; "))\r
-       (if (not (zerop (buffer-size)))\r
-           (error "Sending...failed to %s"\r
-                  (buffer-substring (point-min) (point-max)))))\r
-      (when (bufferp errbuf)\r
-       (kill-buffer errbuf)))))\r
-\r
-(defun message-send-mail-with-qmail ()\r
-  "Pass the prepared message buffer to qmail-inject.\r
-Refer to the documentation for the variable `message-send-mail-function'\r
-to find out how to use this."\r
-  ;; replace the header delimiter with a blank line\r
-  (goto-char (point-min))\r
-  (re-search-forward\r
-   (concat "^" (regexp-quote mail-header-separator) "\n"))\r
-  (replace-match "\n")\r
-  (backward-char 1)\r
-  (run-hooks 'message-send-mail-hook)\r
-  ;; send the message\r
-  (case\r
-      (as-binary-process\r
-       (apply\r
-       'call-process-region 1 (point-max) message-qmail-inject-program\r
-       nil nil nil\r
-       ;; qmail-inject's default behaviour is to look for addresses on the\r
-       ;; command line; if there're none, it scans the headers.\r
-       ;; yes, it does The Right Thing w.r.t. Resent-To and it's kin.\r
-       ;;\r
-       ;; in general, ALL of qmail-inject's defaults are perfect for simply\r
-       ;; reading a formatted (i. e., at least a To: or Resent-To header)\r
-       ;; message from stdin.\r
-       ;;\r
-       ;; qmail also has the advantage of not having been raped by\r
-       ;; various vendors, so we don't have to allow for that, either --\r
-       ;; compare this with message-send-mail-with-sendmail and weep\r
-       ;; for sendmail's lost innocence.\r
-       ;;\r
-       ;; all this is way cool coz it lets us keep the arguments entirely\r
-       ;; free for -inject-arguments -- a big win for the user and for us\r
-       ;; since we don't have to play that double-guessing game and the user\r
-       ;; gets full control (no gestapo'ish -f's, for instance).  --sj\r
-       message-qmail-inject-args))\r
-    ;; qmail-inject doesn't say anything on it's stdout/stderr,\r
-    ;; we have to look at the retval instead\r
-    (0 nil)\r
-    (1   (error "qmail-inject reported permanent failure"))\r
-    (111 (error "qmail-inject reported transient failure"))\r
-    ;; should never happen\r
-    (t   (error "qmail-inject reported unknown failure"))))\r
-\r
-(defun message-send-mail-with-mh ()\r
-  "Send the prepared message buffer with mh."\r
-  (let ((mh-previous-window-config nil)\r
-       (name (mh-new-draft-name)))\r
-    (setq buffer-file-name name)\r
-    ;; MH wants to generate these headers itself.\r
-    (when message-mh-deletable-headers\r
-      (let ((headers message-mh-deletable-headers))\r
-       (while headers\r
-         (goto-char (point-min))\r
-         (and (re-search-forward\r
-               (concat "^" (symbol-name (car headers)) ": *") nil t)\r
-              (message-delete-line))\r
-         (pop headers))))\r
-    (run-hooks 'message-send-mail-hook)\r
-    ;; Pass it on to mh.\r
-    (mh-send-letter)))\r
-\r
-(defun message-send-mail-with-smtp ()\r
-  "Send off the prepared buffer with SMTP."\r
-  (require 'smtp) ; XXX\r
-  (let ((case-fold-search t)\r
-       recipients)\r
-    (save-restriction\r
-      (message-narrow-to-headers)\r
-      (setq recipients\r
-           ;; XXX: Should be replaced by better one.\r
-           (smtp-deduce-address-list (current-buffer)\r
-                                     (point-min) (point-max)))\r
-      ;; Remove BCC lines.\r
-      (message-remove-header "bcc"))\r
-    ;; replace the header delimiter with a blank line.\r
-    (goto-char (point-min))\r
-    (re-search-forward\r
-     (concat "^" (regexp-quote mail-header-separator) "\n"))\r
-    (replace-match "\n")\r
-    (backward-char 1)\r
-    (run-hooks 'message-send-mail-hook)\r
-    (if recipients\r
-       (let ((result (smtp-via-smtp user-mail-address\r
-                                    recipients\r
-                                    (current-buffer))))\r
-         (unless (eq result t)\r
-           (error "Sending failed; " result)))\r
-      (error "Sending failed; no recipients"))))\r
-\r
-(defsubst message-maybe-split-and-send-news (method)\r
-  "Split a message if necessary, and send it via news.\r
-Returns nil if sending succeeded, returns t if sending failed.\r
-This sub function is for exclusive use of `message-send-news'."\r
-  (let ((mime-edit-split-ignored-field-regexp\r
-        mime-edit-split-ignored-field-regexp)\r
-       (case-fold-search t))\r
-    (while (string-match "Message-ID" mime-edit-split-ignored-field-regexp)\r
-      (setq mime-edit-split-ignored-field-regexp\r
-           (concat (substring mime-edit-split-ignored-field-regexp\r
-                              0 (match-beginning 0))\r
-                   "Hey_MIME-Edit,_there_is_an_inviolable_Message_ID"\r
-                   "_so_don't_rape_it!"\r
-                   (substring mime-edit-split-ignored-field-regexp\r
-                              (match-end 0)))))\r
-    (or\r
-     (catch 'message-sending-news-failure\r
-       (mime-edit-maybe-split-and-send\r
-       (function\r
-        (lambda ()\r
-          (interactive)\r
-          (save-restriction\r
-            (std11-narrow-to-header mail-header-separator)\r
-            (goto-char (point-min))\r
-            (when (re-search-forward "^Message-ID:" nil t)\r
-              (delete-region (match-end 0) (std11-field-end))\r
-              (insert " " (message-make-message-id))))\r
-          (unless (funcall message-send-news-function method)\r
-            (throw 'message-sending-news-failure t)))))\r
-       nil)\r
-     (not (funcall message-send-news-function method)))))\r
-\r
-(defun message-send-news (&optional arg)\r
-  (let ((tembuf (message-generate-new-buffer-clone-locals " *message temp*"))\r
-       (case-fold-search nil)\r
-       (method (if (message-functionp message-post-method)\r
-                   (funcall message-post-method arg)\r
-                 message-post-method))\r
-       (message-syntax-checks\r
-        (if arg\r
-            (cons '(existing-newsgroups . disabled)\r
-                  message-syntax-checks)\r
-          message-syntax-checks))\r
-       result)\r
-    (save-restriction\r
-      (message-narrow-to-headers)\r
-      ;; Insert some headers.\r
-      (message-generate-headers message-required-news-headers)\r
-      ;; Let the user do all of the above.\r
-      (run-hooks 'message-header-hook))\r
-    (message-cleanup-headers)\r
-    (if (not (message-check-news-syntax))\r
-       nil\r
-      (unwind-protect\r
-         (save-excursion\r
-           (set-buffer tembuf)\r
-           (buffer-disable-undo)\r
-           (erase-buffer)\r
-           (insert-buffer message-encoding-buffer)\r
-           ;; Remove some headers.\r
-           (save-restriction\r
-             (message-narrow-to-headers)\r
-             ;; Remove some headers.\r
-             (message-remove-header message-ignored-news-headers t))\r
-           (goto-char (point-max))\r
-           ;; require one newline at the end.\r
-           (or (= (preceding-char) ?\n)\r
-               (insert ?\n))\r
-           (setq result (message-maybe-split-and-send-news method)))\r
-       (kill-buffer tembuf))\r
-      (set-buffer message-edit-buffer)\r
-      (if result\r
-         (progn\r
-           (message "Couldn't send message via news: %s"\r
-                    (nnheader-get-report (car method)))\r
-           nil)\r
-       (push 'news message-sent-message-via)))))\r
-\r
-;; 1997-09-29 by MORIOKA Tomohiko\r
-(defun message-send-news-with-gnus (method)\r
-  (let ((case-fold-search t))\r
-    ;; Remove the delimiter.\r
-    (goto-char (point-min))\r
-    (re-search-forward\r
-     (concat "^" (regexp-quote mail-header-separator) "\n"))\r
-    (replace-match "\n")\r
-    (backward-char 1)\r
-    (run-hooks 'message-send-news-hook)\r
-    ;;(require (car method))\r
-    ;;(funcall (intern (format "%s-open-server" (car method)))\r
-    ;;(cadr method) (cddr method))\r
-    ;;(setq result\r
-    ;;   (funcall (intern (format "%s-request-post" (car method)))\r
-    ;;            (cadr method)))\r
-    (gnus-open-server method)\r
-    (gnus-request-post method)\r
-    ))\r
-\r
-;;;\r
-;;; Header generation & syntax checking.\r
-;;;\r
-\r
-(defun message-check-element (type)\r
-  "Returns non-nil if this type is not to be checked."\r
-  (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me)\r
-      t\r
-    (let ((able (assq type message-syntax-checks)))\r
-      (and (consp able)\r
-          (eq (cdr able) 'disabled)))))\r
-\r
-(defun message-check-news-syntax ()\r
-  "Check the syntax of the message."\r
-  (save-excursion\r
-    (save-restriction\r
-      (widen)\r
-      (and\r
-       ;; We narrow to the headers and check them first.\r
-       (save-excursion\r
-        (save-restriction\r
-          (message-narrow-to-headers)\r
-          (message-check-news-header-syntax)))\r
-       ;; Check the body.\r
-       (save-excursion\r
-        (set-buffer message-edit-buffer)\r
-        (message-check-news-body-syntax))))))\r
-\r
-(defun message-check-news-header-syntax ()\r
-  (and\r
-   ;; Check the Subject header.\r
-   (message-check 'subject\r
-     (let* ((case-fold-search t)\r
-           (subject (message-fetch-field "subject")))\r
-       (or\r
-       (and subject\r
-            (not (string-match "\\`[ \t]*\\'" subject)))\r
-       (ignore\r
-        (message\r
-         "The subject field is empty or missing.  Posting is denied.")))))\r
-   ;; Check for commands in Subject.\r
-   (message-check 'subject-cmsg\r
-     (if (string-match "^cmsg " (message-fetch-field "subject"))\r
-        (y-or-n-p\r
-         "The control code \"cmsg\" is in the subject.  Really post? ")\r
-       t))\r
-   ;; Check for multiple identical headers.\r
-   (message-check 'multiple-headers\r
-     (let (found)\r
-       (while (and (not found)\r
-                  (re-search-forward "^[^ \t:]+: " nil t))\r
-        (save-excursion\r
-          (or (re-search-forward\r
-               (concat "^"\r
-                       (regexp-quote\r
-                        (setq found\r
-                              (buffer-substring\r
-                               (match-beginning 0) (- (match-end 0) 2))))\r
-                       ":")\r
-               nil t)\r
-              (setq found nil))))\r
-       (if found\r
-          (y-or-n-p (format "Multiple %s headers.  Really post? " found))\r
-        t)))\r
-   ;; Check for Version and Sendsys.\r
-   (message-check 'sendsys\r
-     (if (re-search-forward "^Sendsys:\\|^Version:" nil t)\r
-        (y-or-n-p\r
-         (format "The article contains a %s command.  Really post? "\r
-                 (buffer-substring (match-beginning 0)\r
-                                   (1- (match-end 0)))))\r
-       t))\r
-   ;; See whether we can shorten Followup-To.\r
-   (message-check 'shorten-followup-to\r
-     (let ((newsgroups (message-fetch-field "newsgroups"))\r
-          (followup-to (message-fetch-field "followup-to"))\r
-          to)\r
-       (when (and newsgroups\r
-                 (string-match "," newsgroups)\r
-                 (not followup-to)\r
-                 (not\r
-                  (zerop\r
-                   (length\r
-                    (setq to (completing-read\r
-                              "Followups to: (default all groups) "\r
-                              (mapcar (lambda (g) (list g))\r
-                                      (cons "poster"\r
-                                            (message-tokenize-header\r
-                                             newsgroups)))))))))\r
-        (goto-char (point-min))\r
-        (insert "Followup-To: " to "\n"))\r
-       t))\r
-   ;; Check "Shoot me".\r
-   (message-check 'shoot\r
-     (if (re-search-forward\r
-         "Message-ID.*.i-did-not-set--mail-host-address--so-shoot-me" nil t)\r
-        (y-or-n-p "You appear to have a misconfigured system.  Really post? ")\r
-       t))\r
-   ;; Check for Approved.\r
-   (message-check 'approved\r
-     (if (re-search-forward "^Approved:" nil t)\r
-        (y-or-n-p "The article contains an Approved header.  Really post? ")\r
-       t))\r
-   ;; Check the Message-ID header.\r
-   (message-check 'message-id\r
-     (let* ((case-fold-search t)\r
-           (message-id (message-fetch-field "message-id" t)))\r
-       (or (not message-id)\r
-          ;; Is there an @ in the ID?\r
-          (and (string-match "@" message-id)\r
-               ;; Is there a dot in the ID?\r
-               (string-match "@[^.]*\\." message-id)\r
-               ;; Does the ID end with a dot?\r
-               (not (string-match "\\.>" message-id)))\r
-          (y-or-n-p\r
-           (format "The Message-ID looks strange: \"%s\".  Really post? "\r
-                   message-id)))))\r
-   ;; Check the Newsgroups & Followup-To headers.\r
-   (message-check 'existing-newsgroups\r
-     (let* ((case-fold-search t)\r
-           (newsgroups (message-fetch-field "newsgroups"))\r
-           (followup-to (message-fetch-field "followup-to"))\r
-           (groups (message-tokenize-header\r
-                    (if followup-to\r
-                        (concat newsgroups "," followup-to)\r
-                      newsgroups)))\r
-           (hashtb (and (boundp 'gnus-active-hashtb)\r
-                        gnus-active-hashtb))\r
-           errors)\r
-       (if (or (not hashtb)\r
-              (not (boundp 'gnus-read-active-file))\r
-              (not gnus-read-active-file)\r
-              (eq gnus-read-active-file 'some))\r
-          t\r
-        (while groups\r
-          (when (and (not (boundp (intern (car groups) hashtb)))\r
-                     (not (equal (car groups) "poster")))\r
-            (push (car groups) errors))\r
-          (pop groups))\r
-        (if (not errors)\r
-            t\r
-          (y-or-n-p\r
-           (format\r
-            "Really post to %s unknown group%s: %s "\r
-            (if (= (length errors) 1) "this" "these")\r
-            (if (= (length errors) 1) "" "s")\r
-            (mapconcat 'identity errors ", ")))))))\r
-   ;; Check the Newsgroups & Followup-To headers for syntax errors.\r
-   (message-check 'valid-newsgroups\r
-     (let ((case-fold-search t)\r
-          (headers '("Newsgroups" "Followup-To"))\r
-          header error)\r
-       (while (and headers (not error))\r
-        (when (setq header (mail-fetch-field (car headers)))\r
-          (if (or\r
-               (not\r
-                (string-match\r
-                 "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'"\r
-                 header))\r
-               (memq\r
-                nil (mapcar\r
-                     (lambda (g)\r
-                       (not (string-match "\\.\\'\\|\\.\\." g)))\r
-                     (message-tokenize-header header ","))))\r
-              (setq error t)))\r
-        (unless error\r
-          (pop headers)))\r
-       (if (not error)\r
-          t\r
-        (y-or-n-p\r
-         (format "The %s header looks odd: \"%s\".  Really post? "\r
-                 (car headers) header)))))\r
-   (message-check 'repeated-newsgroups\r
-     (let ((case-fold-search t)\r
-          (headers '("Newsgroups" "Followup-To"))\r
-          header error groups group)\r
-       (while (and headers\r
-                  (not error))\r
-        (when (setq header (mail-fetch-field (pop headers)))\r
-          (setq groups (message-tokenize-header header ","))\r
-          (while (setq group (pop groups))\r
-            (when (member group groups)\r
-              (setq error group\r
-                    groups nil)))))\r
-       (if (not error)\r
-          t\r
-        (y-or-n-p\r
-         (format "Group %s is repeated in headers.  Really post? " error)))))\r
-   ;; Check the From header.\r
-   (message-check 'from\r
-     (let* ((case-fold-search t)\r
-           (from (message-fetch-field "from"))\r
-           (ad (nth 1 (std11-extract-address-components from))))\r
-       (cond\r
-       ((not from)\r
-        (message "There is no From line.  Posting is denied.")\r
-        nil)\r
-       ((or (not (string-match "@[^\\.]*\\." ad)) ;larsi@ifi\r
-            (string-match "\\.\\." ad) ;larsi@ifi..uio\r
-            (string-match "@\\." ad)   ;larsi@.ifi.uio\r
-            (string-match "\\.$" ad)   ;larsi@ifi.uio.\r
-            (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio\r
-            (string-match "(.*).*(.*)" from)) ;(lars) (lars)\r
-        (message\r
-         "Denied posting -- the From looks strange: \"%s\"." from)\r
-        nil)\r
-       (t t))))))\r
-\r
-(defun message-check-news-body-syntax ()\r
-  (and\r
-   ;; Check for long lines.\r
-   (message-check 'long-lines\r
-     (goto-char (point-min))\r
-     (re-search-forward\r
-      (concat "^" (regexp-quote mail-header-separator) "$"))\r
-     (while (and\r
-            (progn\r
-              (end-of-line)\r
-              (< (current-column) 80))\r
-            (zerop (forward-line 1))))\r
-     (or (bolp)\r
-        (eobp)\r
-        (y-or-n-p\r
-         "You have lines longer than 79 characters.  Really post? ")))\r
-   ;; Check whether the article is empty.\r
-   (message-check 'empty\r
-     (goto-char (point-min))\r
-     (re-search-forward\r
-      (concat "^" (regexp-quote mail-header-separator) "$"))\r
-     (forward-line 1)\r
-     (let ((b (point)))\r
-       (goto-char (point-max))\r
-       (re-search-backward message-signature-separator nil t)\r
-       (beginning-of-line)\r
-       (or (re-search-backward "[^ \n\t]" b t)\r
-          (y-or-n-p "Empty article.  Really post? "))))\r
-   ;; Check for control characters.\r
-   (message-check 'control-chars\r
-     (if (re-search-forward "[\000-\007\013\015-\032\034-\037\200-\237]" nil t)\r
-        (y-or-n-p\r
-         "The article contains control characters.  Really post? ")\r
-       t))\r
-   ;; Check 8bit characters.\r
-   (message-check '8bit\r
-     (message-check-8bit))\r
-   ;; Check excessive size.\r
-   (message-check 'size\r
-     (if (> (buffer-size) 60000)\r
-        (y-or-n-p\r
-         (format "The article is %d octets long.  Really post? "\r
-                 (buffer-size)))\r
-       t))\r
-   ;; Check whether any new text has been added.\r
-   (message-check 'new-text\r
-     (or\r
-      (not message-checksum)\r
-      (not (eq (message-checksum) message-checksum))\r
-      (y-or-n-p\r
-       "It looks like no new text has been added.  Really post? ")))\r
-   ;; Check the length of the signature.\r
-   (message-check 'signature\r
-     (goto-char (point-max))\r
-     (if (or (not (re-search-backward message-signature-separator nil t))\r
-            (search-forward message-forward-end-separator nil t))\r
-        t\r
-       (if (> (count-lines (point) (point-max)) 5)\r
-          (y-or-n-p\r
-           (format\r
-            "Your .sig is %d lines; it should be max 4.  Really post? "\r
-            (1- (count-lines (point) (point-max)))))\r
-        t)))))\r
-\r
-(defun message-check-mail-syntax ()\r
-  "Check the syntax of the message."\r
-  (save-excursion\r
-    (save-restriction\r
-      (widen)\r
-      (and\r
-       ;; We narrow to the headers and check them first.\r
-       (save-excursion\r
-        (save-restriction\r
-          (message-narrow-to-headers)\r
-          (message-check-mail-header-syntax)))\r
-       ;; Check the body.\r
-       (save-excursion\r
-        (set-buffer message-edit-buffer)\r
-        (message-check-mail-body-syntax))))))\r
-\r
-(defun message-check-mail-header-syntax ()\r
-  t)\r
-\r
-(defun message-check-mail-body-syntax ()\r
-  (and\r
-   ;; Check 8bit characters.\r
-   (message-check '8bit\r
-     (message-check-8bit)\r
-     )))\r
-\r
-(defun message-check-8bit ()\r
-  "Check the article contains 8bit characters."\r
-  (save-excursion\r
-    (set-buffer message-encoding-buffer)\r
-    (message-narrow-to-headers)\r
-    (let* ((case-fold-search t)\r
-          (field-value (message-fetch-field "content-transfer-encoding")))\r
-      (if (and field-value\r
-              (member (downcase field-value) message-8bit-encoding-list))\r
-         t\r
-       (widen)\r
-       (set-buffer (get-buffer-create " message syntax"))\r
-       (erase-buffer)\r
-       (goto-char (point-min))\r
-       (set-buffer-multibyte nil)\r
-       (insert-buffer message-encoding-buffer)\r
-       (goto-char (point-min))\r
-       (if (re-search-forward "[^\x00-\x7f]" nil t)\r
-           (y-or-n-p\r
-            "The article contains 8bit characters.  Really post? ")\r
-         t)))))\r
-\r
-(defun message-checksum ()\r
-  "Return a \"checksum\" for the current buffer."\r
-  (let ((sum 0))\r
-    (save-excursion\r
-      (goto-char (point-min))\r
-      (re-search-forward\r
-       (concat "^" (regexp-quote mail-header-separator) "$"))\r
-      (while (not (eobp))\r
-       (when (not (looking-at "[ \t\n]"))\r
-         (setq sum (logxor (ash sum 1) (if (natnump sum) 0 1)\r
-                           (char-after))))\r
-       (forward-char 1)))\r
-    sum))\r
-\r
-(defun message-do-fcc ()\r
-  "Process Fcc headers in the current buffer."\r
-  (let ((case-fold-search t)\r
-       (coding-system-for-write 'raw-text)\r
-       list file)\r
-    (save-excursion\r
-      (set-buffer (get-buffer-create " *message temp*"))\r
-      (erase-buffer)\r
-      (insert-buffer-substring message-encoding-buffer)\r
-      (save-restriction\r
-       (message-narrow-to-headers)\r
-       (while (setq file (message-fetch-field "fcc"))\r
-         (push file list)\r
-         (message-remove-header "fcc" nil t)))\r
-      (goto-char (point-min))\r
-      (re-search-forward (concat "^" (regexp-quote mail-header-separator) "$"))\r
-      (replace-match "" t t)\r
-      ;; Process FCC operations.\r
-      (while list\r
-       (setq file (pop list))\r
-       (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file)\r
-           ;; Pipe the article to the program in question.\r
-           (call-process-region (point-min) (point-max) shell-file-name\r
-                                nil nil nil shell-command-switch\r
-                                (match-string 1 file))\r
-         ;; Save the article.\r
-         (setq file (expand-file-name file))\r
-         (unless (file-exists-p (file-name-directory file))\r
-           (make-directory (file-name-directory file) t))\r
-         (if (and message-fcc-handler-function\r
-                  (not (eq message-fcc-handler-function 'rmail-output)))\r
-             (funcall message-fcc-handler-function file)\r
-           (if (and (file-readable-p file) (mail-file-babyl-p file))\r
-               (rmail-output file 1 nil t)\r
-             (let ((mail-use-rfc822 t))\r
-               (rmail-output file 1 t t))))))\r
-      (kill-buffer (current-buffer)))))\r
-\r
-(defun message-output (filename)\r
-  "Append this article to Unix/babyl mail file.."\r
-  (if (and (file-readable-p filename)\r
-          (mail-file-babyl-p filename))\r
-      (rmail-output-to-rmail-file filename t)\r
-    (gnus-output-to-mail filename t)))\r
-\r
-(defun message-cleanup-headers ()\r
-  "Do various automatic cleanups of the headers."\r
-  ;; Remove empty lines in the header.\r
-  (save-restriction\r
-    (message-narrow-to-headers)\r
-    ;; Remove blank lines.\r
-    (while (re-search-forward "^[ \t]*\n" nil t)\r
-      (replace-match "" t t))\r
-\r
-    ;; Correct Newsgroups and Followup-To headers:  Change sequence of\r
-    ;; spaces to comma and eliminate spaces around commas.  Eliminate\r
-    ;; embedded line breaks.\r
-    (goto-char (point-min))\r
-    (while (re-search-forward "^\\(Newsgroups\\|Followup-To\\): +" nil t)\r
-      (save-restriction\r
-       (narrow-to-region\r
-        (point)\r
-        (if (re-search-forward "^[^ \t]" nil t)\r
-            (match-beginning 0)\r
-          (forward-line 1)\r
-          (point)))\r
-       (goto-char (point-min))\r
-       (while (re-search-forward "\n[ \t]+" nil t)\r
-         (replace-match " " t t))      ;No line breaks (too confusing)\r
-       (goto-char (point-min))\r
-       (while (re-search-forward "[ \t\n]*,[ \t\n]*\\|[ \t]+" nil t)\r
-         (replace-match "," t t))\r
-       (goto-char (point-min))\r
-       ;; Remove trailing commas.\r
-       (when (re-search-forward ",+$" nil t)\r
-         (replace-match "" t t))))))\r
-\r
-(defun message-make-date (&optional now)\r
-  "Make a valid data header.\r
-If NOW, use that time instead."\r
-  (let* ((now (or now (current-time)))\r
-        (zone (nth 8 (decode-time now)))\r
-        (sign "+"))\r
-    (when (< zone 0)\r
-      (setq sign "-")\r
-      (setq zone (- zone)))\r
-    (concat\r
-     (format-time-string "%d" now)\r
-     ;; The month name of the %b spec is locale-specific.  Pfff.\r
-     (format " %s "\r
-            (capitalize (car (rassoc (nth 4 (decode-time now))\r
-                                     parse-time-months))))\r
-     (format-time-string "%Y %H:%M:%S " now)\r
-     ;; We do all of this because XEmacs doesn't have the %z spec.\r
-     (format "%s%02d%02d" sign (/ zone 3600) (% zone 3600)))))\r
-\r
-(defun message-make-followup-subject (subject)\r
-  "Make a followup Subject."\r
-  (cond\r
-   ((and (eq message-use-subject-re 'guess)\r
-         (string-match message-subject-encoded-re-regexp subject))\r
-    subject)\r
-   (message-use-subject-re\r
-    (concat "Re: " (message-strip-subject-re subject)))\r
-   (t subject)))\r
-\r
-(defun message-make-message-id ()\r
-  "Make a unique Message-ID."\r
-  (concat "<" (message-unique-id)\r
-         (let ((psubject (save-excursion (message-fetch-field "subject")))\r
-               (psupersedes\r
-                (save-excursion (message-fetch-field "supersedes"))))\r
-           (if (or\r
-                (and message-reply-headers\r
-                     (mail-header-references message-reply-headers)\r
-                     (mail-header-subject message-reply-headers)\r
-                     psubject\r
-                     (mail-header-subject message-reply-headers)\r
-                     (not (string=\r
-                           (message-strip-subject-re\r
-                            (mail-header-subject message-reply-headers))\r
-                           (message-strip-subject-re psubject))))\r
-                (and psupersedes\r
-                     (string-match "_-_@" psupersedes)))\r
-               "_-_" ""))\r
-         "@" (message-make-fqdn) ">"))\r
-\r
-(defvar message-unique-id-char nil)\r
-\r
-;; If you ever change this function, make sure the new version\r
-;; cannot generate IDs that the old version could.\r
-;; You might for example insert a "." somewhere (not next to another dot\r
-;; or string boundary), or modify the "fsf" string.\r
-(defun message-unique-id ()\r
-  ;; Don't use microseconds from (current-time), they may be unsupported.\r
-  ;; Instead we use this randomly inited counter.\r
-  (setq message-unique-id-char\r
-       (% (1+ (or message-unique-id-char (logand (random t) (1- (lsh 1 20)))))\r
-          ;; (current-time) returns 16-bit ints,\r
-          ;; and 2^16*25 just fits into 4 digits i base 36.\r
-          (* 25 25)))\r
-  (let ((tm (current-time)))\r
-    (concat\r
-     (if (memq system-type '(ms-dos emx vax-vms))\r
-        (let ((user (downcase (user-login-name))))\r
-          (while (string-match "[^a-z0-9_]" user)\r
-            (aset user (match-beginning 0) ?_))\r
-          user)\r
-       (message-number-base36 (user-uid) -1))\r
-     (message-number-base36 (+ (car   tm)\r
-                              (lsh (% message-unique-id-char 25) 16)) 4)\r
-     (message-number-base36 (+ (nth 1 tm)\r
-                              (lsh (/ message-unique-id-char 25) 16)) 4)\r
-     ;; Append the newsreader name, because while the generated\r
-     ;; ID is unique to this newsreader, other newsreaders might\r
-     ;; otherwise generate the same ID via another algorithm.\r
-     ".fsf")))\r
-\r
-(defun message-number-base36 (num len)\r
-  (if (if (< len 0)\r
-         (<= num 0)\r
-       (= len 0))\r
-      ""\r
-    (concat (message-number-base36 (/ num 36) (1- len))\r
-           (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210"\r
-                                 (% num 36))))))\r
-\r
-(defun message-make-organization ()\r
-  "Make an Organization header."\r
-  (let* ((organization\r
-         (when message-user-organization\r
-               (if (message-functionp message-user-organization)\r
-                   (funcall message-user-organization)\r
-                 message-user-organization))))\r
-    (save-excursion\r
-      (message-set-work-buffer)\r
-      (cond ((stringp organization)\r
-            (insert organization))\r
-           ((and (eq t organization)\r
-                 message-user-organization-file\r
-                 (file-exists-p message-user-organization-file))\r
-            (insert-file-contents message-user-organization-file)))\r
-      (goto-char (point-min))\r
-      (while (re-search-forward "[\t\n]+" nil t)\r
-       (replace-match "" t t))\r
-      (unless (zerop (buffer-size))\r
-       (buffer-string)))))\r
-\r
-(defun message-make-lines ()\r
-  "Count the number of lines and return numeric string."\r
-  (save-excursion\r
-    (save-restriction\r
-      (widen)\r
-      (goto-char (point-min))\r
-      (re-search-forward\r
-       (concat "^" (regexp-quote mail-header-separator) "$"))\r
-      (forward-line 1)\r
-      (int-to-string (count-lines (point) (point-max))))))\r
-\r
-(defun message-make-in-reply-to ()\r
-  "Return the In-Reply-To header for this message."\r
-  (when message-reply-headers\r
-    (let ((mid (mail-header-message-id message-reply-headers))\r
-         (from (mail-header-from message-reply-headers))\r
-         (date (mail-header-date message-reply-headers)))\r
-      (when mid\r
-       (concat mid\r
-               (when from\r
-                 (let ((pair (std11-extract-address-components from)))\r
-                   (concat "\n ("\r
-                           (or (car pair) (cadr pair))\r
-                           "'s message of \""\r
-                           (if (or (not date) (string= date ""))\r
-                               "(unknown date)" date)\r
-                           "\")"))))))))\r
-\r
-(defun message-make-distribution ()\r
-  "Make a Distribution header."\r
-  (let ((orig-distribution (message-fetch-reply-field "distribution")))\r
-    (cond ((message-functionp message-distribution-function)\r
-          (funcall message-distribution-function))\r
-         (t orig-distribution))))\r
-\r
-(defun message-make-expires ()\r
-  "Return an Expires header based on `message-expires'."\r
-  (let ((current (current-time))\r
-       (future (* 1.0 message-expires 60 60 24)))\r
-    ;; Add the future to current.\r
-    (setcar current (+ (car current) (round (/ future (expt 2 16)))))\r
-    (setcar (cdr current) (+ (nth 1 current) (% (round future) (expt 2 16))))\r
-    (message-make-date current)))\r
-\r
-(defun message-make-path ()\r
-  "Return uucp path."\r
-  (let ((login-name (user-login-name)))\r
-    (cond ((null message-user-path)\r
-          (concat (system-name) "!" login-name))\r
-         ((stringp message-user-path)\r
-          ;; Support GENERICPATH.  Suggested by vixie@decwrl.dec.com.\r
-          (concat message-user-path "!" login-name))\r
-         (t login-name))))\r
-\r
-(defun message-make-from ()\r
-  "Make a From header."\r
-  (let* ((style message-from-style)\r
-        (login (message-make-address))\r
-        (fullname\r
-         (or (and (boundp 'user-full-name)\r
-                  user-full-name)\r
-             (user-full-name))))\r
-    (when (string= fullname "&")\r
-      (setq fullname (user-login-name)))\r
-    (save-excursion\r
-      (message-set-work-buffer)\r
-      (cond\r
-       ((or (null style)\r
-           (equal fullname ""))\r
-       (insert login))\r
-       ((or (eq style 'angles)\r
-           (and (not (eq style 'parens))\r
-                ;; Use angles if no quoting is needed, or if parens would\r
-                ;; need quoting too.\r
-                (or (not (string-match "[^- !#-'*+/-9=?A-Z^-~]" fullname))\r
-                    (let ((tmp (concat fullname nil)))\r
-                      (while (string-match "([^()]*)" tmp)\r
-                        (aset tmp (match-beginning 0) ?-)\r
-                        (aset tmp (1- (match-end 0)) ?-))\r
-                      (string-match "[\\()]" tmp)))))\r
-       (insert fullname)\r
-       (goto-char (point-min))\r
-       ;; Look for a character that cannot appear unquoted\r
-       ;; according to RFC 822.\r
-       (when (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" nil 1)\r
-         ;; Quote fullname, escaping specials.\r
-         (goto-char (point-min))\r
-         (insert "\"")\r
-         (while (re-search-forward "[\"\\]" nil 1)\r
-           (replace-match "\\\\\\&" t))\r
-         (insert "\""))\r
-       (insert " <" login ">"))\r
-       (t                              ; 'parens or default\r
-       (insert login " (")\r
-       (let ((fullname-start (point)))\r
-         (insert fullname)\r
-         (goto-char fullname-start)\r
-         ;; RFC 822 says \ and nonmatching parentheses\r
-         ;; must be escaped in comments.\r
-         ;; Escape every instance of ()\ ...\r
-         (while (re-search-forward "[()\\]" nil 1)\r
-           (replace-match "\\\\\\&" t))\r
-         ;; ... then undo escaping of matching parentheses,\r
-         ;; including matching nested parentheses.\r
-         (goto-char fullname-start)\r
-         (while (re-search-forward\r
-                 "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)"\r
-                 nil 1)\r
-           (replace-match "\\1(\\3)" t)\r
-           (goto-char fullname-start)))\r
-       (insert ")")))\r
-      (buffer-string))))\r
-\r
-(defun message-make-sender ()\r
-  "Return the \"real\" user address.\r
-This function tries to ignore all user modifications, and\r
-give as trustworthy answer as possible."\r
-  (concat (user-login-name) "@" (system-name)))\r
-\r
-(defun message-make-address ()\r
-  "Make the address of the user."\r
-  (or (message-user-mail-address)\r
-      (concat (user-login-name) "@" (message-make-domain))))\r
-\r
-(defun message-user-mail-address ()\r
-  "Return the pertinent part of `user-mail-address'."\r
-  (when user-mail-address\r
-    (if (string-match " " user-mail-address)\r
-       (nth 1 (std11-extract-address-components user-mail-address))\r
-      user-mail-address)))\r
-\r
-(defun message-make-fqdn ()\r
-  "Return user's fully qualified domain name."\r
-  (let ((system-name (system-name))\r
-       (user-mail (message-user-mail-address)))\r
-    (cond\r
-     ((string-match "[^.]\\.[^.]" system-name)\r
-      ;; `system-name' returned the right result.\r
-      system-name)\r
-     ;; Try `mail-host-address'.\r
-     ((and (boundp 'mail-host-address)\r
-          (stringp mail-host-address)\r
-          (string-match "\\." mail-host-address))\r
-      mail-host-address)\r
-     ;; We try `user-mail-address' as a backup.\r
-     ((and user-mail\r
-          (string-match "\\." user-mail)\r
-          (string-match "@\\(.*\\)\\'" user-mail))\r
-      (match-string 1 user-mail))\r
-     ;; Default to this bogus thing.\r
-     (t\r
-      (concat system-name ".i-did-not-set--mail-host-address--so-shoot-me")))))\r
-\r
-(defun message-make-host-name ()\r
-  "Return the name of the host."\r
-  (let ((fqdn (message-make-fqdn)))\r
-    (string-match "^[^.]+\\." fqdn)\r
-    (substring fqdn 0 (1- (match-end 0)))))\r
-\r
-(defun message-make-domain ()\r
-  "Return the domain name."\r
-  (or mail-host-address\r
-      (message-make-fqdn)))\r
-\r
-;; Dummy to avoid byte-compile warning.\r
-(defvar mule-version)\r
-(defvar emacs-beta-version)\r
-(defvar xemacs-codename)\r
-(defvar gnus-inviolable-extended-version)\r
-\r
-(defun message-make-user-agent ()\r
-  "Return user-agent info if the value `message-user-agent' is non-nil. If the\r
-\"User-Agent\" field has already exist, it's value will be added in the return\r
-string."\r
-  (when message-user-agent\r
-    (save-excursion\r
-      (goto-char (point-min))\r
-      (let ((case-fold-search t)\r
-           user-agent start p end)\r
-       (if (re-search-forward "^User-Agent:[\t ]*" nil t)\r
-           (progn\r
-             (setq start (match-beginning 0)\r
-                   p (match-end 0)\r
-                   end (std11-field-end)\r
-                   user-agent (buffer-substring-no-properties p end))\r
-             (delete-region start (1+ end))\r
-             (concat message-user-agent " " user-agent))\r
-         message-user-agent)))))\r
-\r
-(defun message-generate-headers (headers)\r
-  "Prepare article HEADERS.\r
-Headers already prepared in the buffer are not modified."\r
-  (save-restriction\r
-    (message-narrow-to-headers)\r
-    (let* ((Date (message-make-date))\r
-          (Message-ID (message-make-message-id))\r
-          (Organization (message-make-organization))\r
-          (From (message-make-from))\r
-          (Path (message-make-path))\r
-          (Subject nil)\r
-          (Newsgroups nil)\r
-          (In-Reply-To (message-make-in-reply-to))\r
-          (To nil)\r
-          (Distribution (message-make-distribution))\r
-          (Lines (message-make-lines))\r
-          (User-Agent (message-make-user-agent))\r
-          (Expires (message-make-expires))\r
-          (case-fold-search t)\r
-          header value elem)\r
-      ;; First we remove any old generated headers.\r
-      (let ((headers message-deletable-headers))\r
-       (unless (buffer-modified-p)\r
-         (setq headers (delq 'Message-ID (copy-sequence headers))))\r
-       (while headers\r
-         (goto-char (point-min))\r
-         (and (re-search-forward\r
-               (concat "^" (symbol-name (car headers)) ": *") nil t)\r
-              (get-text-property (1+ (match-beginning 0)) 'message-deletable)\r
-              (message-delete-line))\r
-         (pop headers)))\r
-      ;; Go through all the required headers and see if they are in the\r
-      ;; articles already.  If they are not, or are empty, they are\r
-      ;; inserted automatically - except for Subject, Newsgroups and\r
-      ;; Distribution.\r
-      (while headers\r
-       (goto-char (point-min))\r
-       (setq elem (pop headers))\r
-       (if (consp elem)\r
-           (if (eq (car elem) 'optional)\r
-               (setq header (cdr elem))\r
-             (setq header (car elem)))\r
-         (setq header elem))\r
-       (when (or (not (re-search-forward\r
-                       (concat "^"\r
-                               (regexp-quote\r
-                                (downcase\r
-                                 (if (stringp header)\r
-                                     header\r
-                                   (symbol-name header))))\r
-                               ":")\r
-                       nil t))\r
-                 (progn\r
-                   ;; The header was found.  We insert a space after the\r
-                   ;; colon, if there is none.\r
-                   (if (/= (char-after) ? ) (insert " ") (forward-char 1))\r
-                   ;; Find out whether the header is empty...\r
-                   (looking-at "[ \t]*$")))\r
-         ;; So we find out what value we should insert.\r
-         (setq value\r
-               (cond\r
-                ((and (consp elem) (eq (car elem) 'optional))\r
-                 ;; This is an optional header.  If the cdr of this\r
-                 ;; is something that is nil, then we do not insert\r
-                 ;; this header.\r
-                 (setq header (cdr elem))\r
-                 (or (and (fboundp (cdr elem)) (funcall (cdr elem)))\r
-                     (and (boundp (cdr elem)) (symbol-value (cdr elem)))))\r
-                ((consp elem)\r
-                 ;; The element is a cons.  Either the cdr is a\r
-                 ;; string to be inserted verbatim, or it is a\r
-                 ;; function, and we insert the value returned from\r
-                 ;; this function.\r
-                 (or (and (stringp (cdr elem)) (cdr elem))\r
-                     (and (fboundp (cdr elem)) (funcall (cdr elem)))))\r
-                ((and (boundp header) (symbol-value header))\r
-                 ;; The element is a symbol.  We insert the value\r
-                 ;; of this symbol, if any.\r
-                 (symbol-value header))\r
-                (t\r
-                 ;; We couldn't generate a value for this header,\r
-                 ;; so we just ask the user.\r
-                 (read-from-minibuffer\r
-                  (format "Empty header for %s; enter value: " header)))))\r
-         ;; Finally insert the header.\r
-         (when (and value\r
-                    (not (equal value "")))\r
-           (save-excursion\r
-             (if (bolp)\r
-                 (progn\r
-                   ;; This header didn't exist, so we insert it.\r
-                   (goto-char (point-max))\r
-                   (insert (if (stringp header) header (symbol-name header))\r
-                           ": " value "\n")\r
-                   (forward-line -1))\r
-               ;; The value of this header was empty, so we clear\r
-               ;; totally and insert the new value.\r
-               (delete-region (point) (gnus-point-at-eol))\r
-               (insert value))\r
-             ;; Add the deletable property to the headers that require it.\r
-             (and (memq header message-deletable-headers)\r
-                  (progn (beginning-of-line) (looking-at "[^:]+: "))\r
-                  (add-text-properties\r
-                   (point) (match-end 0)\r
-                   '(message-deletable t face italic) (current-buffer)))))))\r
-      ;; Insert new Sender if the From is strange.\r
-      (let ((from (message-fetch-field "from"))\r
-           (sender (message-fetch-field "sender"))\r
-           (secure-sender (message-make-sender)))\r
-       (when (and from\r
-                  (not (message-check-element 'sender))\r
-                  (not (string=\r
-                        (downcase\r
-                         (cadr (std11-extract-address-components from)))\r
-                        (downcase secure-sender)))\r
-                  (or (null sender)\r
-                      (not\r
-                       (string=\r
-                        (downcase\r
-                         (cadr (std11-extract-address-components sender)))\r
-                        (downcase secure-sender)))))\r
-         (goto-char (point-min))\r
-         ;; Rename any old Sender headers to Original-Sender.\r
-         (when (re-search-forward "^\\(Original-\\)*Sender:" nil t)\r
-           (beginning-of-line)\r
-           (insert "Original-")\r
-           (beginning-of-line))\r
-         (when (or (message-news-p)\r
-                   (string-match "@.+\\.." secure-sender))\r
-           (insert "Sender: " secure-sender "\n")))))))\r
-\r
-(defun message-insert-courtesy-copy ()\r
-  "Insert a courtesy message in mail copies of combined messages."\r
-  (let (newsgroups)\r
-    (save-excursion\r
-      (save-restriction\r
-       (message-narrow-to-headers)\r
-       (when (setq newsgroups (message-fetch-field "newsgroups"))\r
-         (goto-char (point-max))\r
-         (insert "Posted-To: " newsgroups "\n")))\r
-      (forward-line 1)\r
-      (when message-courtesy-message\r
-       (cond\r
-        ((string-match "%s" message-courtesy-message)\r
-         (insert (format message-courtesy-message newsgroups)))\r
-        (t\r
-         (insert message-courtesy-message)))))))\r
-\r
-;;;\r
-;;; Setting up a message buffer\r
-;;;\r
-\r
-(defun message-fill-address (header value)\r
-  (save-restriction\r
-    (narrow-to-region (point) (point))\r
-    (insert (capitalize (symbol-name header))\r
-           ": "\r
-           (if (consp value) (car value) value)\r
-           "\n")\r
-    (narrow-to-region (point-min) (1- (point-max)))\r
-    (let (quoted last)\r
-      (goto-char (point-min))\r
-      (while (not (eobp))\r
-       (skip-chars-forward "^,\"" (point-max))\r
-       (if (or (eq (char-after) ?,)\r
-               (eobp))\r
-           (when (not quoted)\r
-             (if (and (> (current-column) 78)\r
-                      last)\r
-                  (save-excursion\r
-                    (goto-char last)\r
-                   (looking-at "[ \t]*")\r
-                    (replace-match "\n " t t)))\r
-              (setq last (1+ (point))))\r
-         (setq quoted (not quoted)))\r
-       (unless (eobp)\r
-         (forward-char 1))))\r
-    (goto-char (point-max))\r
-    (widen)\r
-    (forward-line 1)))\r
-\r
-(defun message-fill-references (header value)\r
-  (insert (capitalize (symbol-name header))\r
-         ": "\r
-         (std11-fill-msg-id-list-string\r
-         (if (consp value) (car value) value))\r
-         "\n"))\r
-\r
-(defun message-fill-header (header value)\r
-  (let ((begin (point))\r
-       (fill-column 78)\r
-       (fill-prefix " "))\r
-    (insert (capitalize (symbol-name header))\r
-           ": "\r
-           (if (consp value) (car value) value)\r
-           "\n")\r
-    (save-restriction\r
-      (narrow-to-region begin (point))\r
-      (fill-region-as-paragraph begin (point))\r
-      ;; Tapdance around looong Message-IDs.\r
-      (forward-line -1)\r
-      (when (looking-at "[ \t]*$")\r
-       (message-delete-line))\r
-      (goto-char begin)\r
-      (re-search-forward ":" nil t)\r
-      (when (looking-at "\n[ \t]+")\r
-       (replace-match " " t t))\r
-      (goto-char (point-max)))))\r
-\r
-(defun message-shorten-references (header references)\r
-  "Limit REFERENCES to be shorter than 988 characters."\r
-  (let ((max 988)\r
-       (cut 4)\r
-       refs)\r
-    (with-temp-buffer\r
-      (insert references)\r
-      (goto-char (point-min))\r
-      (while (re-search-forward "<[^>]+>" nil t)\r
-       (push (match-string 0) refs))\r
-      (setq refs (nreverse refs))\r
-      (while (> (length (mapconcat 'identity refs " ")) max)\r
-       (when (< (length refs) (1+ cut))\r
-         (decf cut))\r
-       (setcdr (nthcdr cut refs) (cddr (nthcdr cut refs)))))\r
-    (insert (capitalize (symbol-name header)) ": "\r
-           (mapconcat 'identity refs " ") "\n")))\r
-\r
-(defun message-position-point ()\r
-  "Move point to where the user probably wants to find it."\r
-  (message-narrow-to-headers)\r
-  (cond\r
-   ((re-search-forward "^[^:]+:[ \t]*$" nil t)\r
-    (search-backward ":" )\r
-    (widen)\r
-    (forward-char 1)\r
-    (if (eq (char-after) ? )\r
-       (forward-char 1)\r
-      (insert " ")))\r
-   (t\r
-    (goto-char (point-max))\r
-    (widen)\r
-    (forward-line 1)\r
-    (unless (looking-at "$")\r
-      (forward-line 2)))\r
-   (sit-for 0)))\r
-\r
-(defun message-buffer-name (type &optional to group)\r
-  "Return a new (unique) buffer name based on TYPE and TO."\r
-  (cond\r
-   ;; Generate a new buffer name The Message Way.\r
-   ((eq message-generate-new-buffers 'unique)\r
-    (generate-new-buffer-name\r
-     (concat "*" type\r
-            (if to\r
-                (concat " to "\r
-                        (or (car (std11-extract-address-components to))\r
-                            to) "")\r
-              "")\r
-            (if (and group (not (string= group ""))) (concat " on " group) "")\r
-            "*")))\r
-   ;; Check whether `message-generate-new-buffers' is a function,\r
-   ;; and if so, call it.\r
-   ((message-functionp message-generate-new-buffers)\r
-    (funcall message-generate-new-buffers type to group))\r
-   ((eq message-generate-new-buffers 'unsent)\r
-    (generate-new-buffer-name\r
-     (concat "*unsent " type\r
-            (if to\r
-                (concat " to "\r
-                        (or (car (mail-extract-address-components to))\r
-                            to) "")\r
-              "")\r
-            (if (and group (not (string= group ""))) (concat " on " group) "")\r
-            "*")))\r
-   ;; Use standard name.\r
-   (t\r
-    (format "*%s message*" type))))\r
-\r
-(defun message-pop-to-buffer (name)\r
-  "Pop to buffer NAME, and warn if it already exists and is modified."\r
-  (let ((pop-up-frames pop-up-frames)\r
-       (special-display-buffer-names special-display-buffer-names)\r
-       (special-display-regexps special-display-regexps)\r
-       (same-window-buffer-names same-window-buffer-names)\r
-       (same-window-regexps same-window-regexps)\r
-       (buffer (get-buffer name))\r
-       (cur (current-buffer)))\r
-    (if (or (and (featurep 'xemacs)\r
-                (not (eq 'tty (device-type))))\r
-           window-system\r
-           (>= emacs-major-version 20))\r
-       (when message-use-multi-frames\r
-         (setq pop-up-frames t\r
-               special-display-buffer-names nil\r
-               special-display-regexps nil\r
-               same-window-buffer-names nil\r
-               same-window-regexps nil))\r
-      (setq pop-up-frames nil))\r
-    (if (and buffer\r
-            (buffer-name buffer))\r
-       (progn\r
-         (set-buffer (pop-to-buffer buffer))\r
-         (when (and (buffer-modified-p)\r
-                    (not (y-or-n-p\r
-                          "Message already being composed; erase? ")))\r
-           (error "Message being composed")))\r
-      (set-buffer (pop-to-buffer name)))\r
-    (erase-buffer)\r
-    (message-mode)\r
-    (when pop-up-frames\r
-      (make-local-variable 'message-original-frame)\r
-      (setq message-original-frame (selected-frame)))))\r
-\r
-(defun message-do-send-housekeeping ()\r
-  "Kill old message buffers."\r
-  ;; We might have sent this buffer already.  Delete it from the\r
-  ;; list of buffers.\r
-  (setq message-buffer-list (delq (current-buffer) message-buffer-list))\r
-  (while (and message-max-buffers\r
-              message-buffer-list\r
-             (>= (length message-buffer-list) message-max-buffers))\r
-    ;; Kill the oldest buffer -- unless it has been changed.\r
-    (let ((buffer (pop message-buffer-list)))\r
-      (when (and (buffer-name buffer)\r
-                (not (buffer-modified-p buffer)))\r
-       (kill-buffer buffer))))\r
-  ;; Rename the buffer.\r
-  (if message-send-rename-function\r
-      (funcall message-send-rename-function)\r
-    (when (string-match "\\`\\*\\(unsent \\)?" (buffer-name))\r
-      (rename-buffer\r
-       (concat "*sent " (substring (buffer-name) (match-end 0))) t)))\r
-  ;; Push the current buffer onto the list.\r
-  (when message-max-buffers\r
-    (setq message-buffer-list\r
-         (nconc message-buffer-list (list (current-buffer))))))\r
-\r
-(defvar mc-modes-alist)\r
-(defun message-setup (headers &optional replybuffer actions)\r
-  (when (and (boundp 'mc-modes-alist)\r
-            (not (assq 'message-mode mc-modes-alist)))\r
-    (push '(message-mode (encrypt . mc-encrypt-message)\r
-                        (sign . mc-sign-message))\r
-         mc-modes-alist))\r
-  (when actions\r
-    (setq message-send-actions actions))\r
-  (setq message-reply-buffer\r
-       (or (message-get-parameter 'reply-buffer)\r
-           replybuffer))\r
-  (goto-char (point-min))\r
-  ;; Insert all the headers.\r
-  (mail-header-format\r
-   (let ((h headers)\r
-        (alist message-header-format-alist))\r
-     (while h\r
-       (unless (assq (caar h) message-header-format-alist)\r
-        (push (list (caar h)) alist))\r
-       (pop h))\r
-     alist)\r
-   headers)\r
-  (delete-region (point) (progn (forward-line -1) (point)))\r
-  (when message-default-headers\r
-    (insert message-default-headers)\r
-    (or (bolp) (insert ?\n)))\r
-  (put-text-property\r
-   (point)\r
-   (progn\r
-     (insert mail-header-separator "\n")\r
-     (1- (point)))\r
-   'read-only nil)\r
-  (forward-line -1)\r
-  (when (message-news-p)\r
-    (when message-default-news-headers\r
-      (insert message-default-news-headers)\r
-      (or (bolp) (insert ?\n)))\r
-    (when message-generate-headers-first\r
-      (message-generate-headers\r
-       (delq 'Lines\r
-            (delq 'Subject\r
-                  (copy-sequence message-required-news-headers))))))\r
-  (when (message-mail-p)\r
-    (when message-default-mail-headers\r
-      (insert message-default-mail-headers)\r
-      (or (bolp) (insert ?\n)))\r
-    (when message-generate-headers-first\r
-      (message-generate-headers\r
-       (delq 'Lines\r
-            (delq 'Subject\r
-                  (copy-sequence message-required-mail-headers))))))\r
-  (run-hooks 'message-signature-setup-hook)\r
-  (message-insert-signature)\r
-  (save-restriction\r
-    (message-narrow-to-headers)\r
-    (run-hooks 'message-header-setup-hook))\r
-  (set-buffer-modified-p nil)\r
-  (setq buffer-undo-list nil)\r
-  (run-hooks 'message-setup-hook)\r
-  (message-position-point)\r
-  (undo-boundary))\r
-\r
-(defun message-set-auto-save-file-name ()\r
-  "Associate the message buffer with a file in the drafts directory."\r
-  (when message-auto-save-directory\r
-    (if (gnus-alive-p)\r
-       (setq message-draft-article\r
-             (nndraft-request-associate-buffer "drafts"))\r
-      (setq buffer-file-name (expand-file-name "*message*"\r
-                                              message-auto-save-directory))\r
-      (setq buffer-auto-save-file-name (make-auto-save-file-name)))\r
-    (clear-visited-file-modtime)\r
-    (setq buffer-file-coding-system message-draft-coding-system)))\r
-\r
-(defun message-disassociate-draft ()\r
-  "Disassociate the message buffer from the drafts directory."\r
-  (when message-draft-article\r
-    (nndraft-request-expire-articles\r
-     (list message-draft-article) "drafts" nil t)))\r
-\r
-(defun message-insert-headers ()\r
-  "Generate the headers for the article."\r
-  (interactive)\r
-  (save-excursion\r
-    (save-restriction\r
-      (message-narrow-to-headers)\r
-      (when (message-news-p)\r
-       (message-generate-headers\r
-        (delq 'Lines\r
-              (delq 'Subject\r
-                    (copy-sequence message-required-news-headers)))))\r
-      (when (message-mail-p)\r
-       (message-generate-headers\r
-        (delq 'Lines\r
-              (delq 'Subject\r
-                    (copy-sequence message-required-mail-headers))))))))\r
-\r
-\f\r
-\r
-;;;\r
-;;; Commands for interfacing with message\r
-;;;\r
-\r
-;;;###autoload\r
-(defun message-mail (&optional to subject\r
-                              other-headers continue switch-function\r
-                              yank-action send-actions)\r
-  "Start editing a mail message to be sent.\r
-OTHER-HEADERS is an alist of header/value pairs."\r
-  (interactive)\r
-  (let ((message-this-is-mail t))\r
-    (message-pop-to-buffer (message-buffer-name "mail" to))\r
-    (message-setup\r
-     (nconc\r
-      `((To . ,(or to "")) (Subject . ,(or subject "")))\r
-      (when other-headers other-headers)))))\r
-\r
-;;;###autoload\r
-(defun message-news (&optional newsgroups subject)\r
-  "Start editing a news article to be sent."\r
-  (interactive)\r
-  (let ((message-this-is-news t))\r
-    (message-pop-to-buffer (message-buffer-name "news" nil newsgroups))\r
-    (message-setup `((Newsgroups . ,(or newsgroups ""))\r
-                    (Subject . ,(or subject ""))))))\r
-\r
-;;;###autoload\r
-(defun message-reply (&optional to-address wide)\r
-  "Start editing a reply to the article in the current buffer."\r
-  (interactive)\r
-  (let ((cur (current-buffer))\r
-       from subject date to cc\r
-       references message-id follow-to\r
-       (inhibit-point-motion-hooks t)\r
-       mct never-mct mft mrt gnus-warning)\r
-    (save-restriction\r
-      (message-narrow-to-head)\r
-      ;; Allow customizations to have their say.\r
-      (if (not wide)\r
-         ;; This is a regular reply.\r
-         (if (message-functionp message-reply-to-function)\r
-             (setq follow-to (funcall message-reply-to-function)))\r
-       ;; This is a followup.\r
-       (if (message-functionp message-wide-reply-to-function)\r
-           (save-excursion\r
-             (setq follow-to\r
-                   (funcall message-wide-reply-to-function)))))\r
-      ;; Find all relevant headers we need.\r
-      (setq from (message-fetch-field "from")\r
-           date (message-fetch-field "date" t)\r
-           subject (or (message-fetch-field "subject") "none")\r
-           references (message-fetch-field "references")\r
-           message-id (message-fetch-field "message-id" t)\r
-           to (message-fetch-field "to")\r
-           cc (message-fetch-field "cc")\r
-           mct (when (and wide message-use-mail-copies-to)\r
-                 (message-fetch-field "mail-copies-to"))\r
-           mft (when (and wide message-use-mail-followup-to)\r
-                 (message-fetch-field "mail-followup-to"))\r
-           mrt (when message-use-mail-reply-to\r
-                 (or (message-fetch-field "mail-reply-to")\r
-                     (message-fetch-field "reply-to")))\r
-           gnus-warning (message-fetch-field "gnus-warning"))\r
-      (when (and gnus-warning (string-match "<[^>]+>" gnus-warning))\r
-       (setq message-id (match-string 0 gnus-warning)))\r
-      ;; Remove any (buggy) Re:'s that are present and make a\r
-      ;; proper one.\r
-      (setq subject (message-make-followup-subject subject))\r
-      (widen))\r
-\r
-    ;; Handle special values of Mail-Copies-To.\r
-    (when mct\r
-      (cond\r
-       ((and (or (equal (downcase mct) "never")\r
-                (equal (downcase mct) "nobody"))\r
-            (or (not (eq message-use-mail-copies-to 'ask))\r
-                (message-y-or-n-p\r
-                 (concat "Obey Mail-Copies-To: never? ") t "\\r
-You should normally obey the Mail-Copies-To: header.\r
-\r
-       `Mail-Copies-To: never'\r
-directs you not to send your response to the author.")))\r
-       (setq never-mct t)\r
-       (setq mct nil))\r
-       ((and (or (equal (downcase mct) "always")\r
-                (equal (downcase mct) "poster"))\r
-            (or (not (eq message-use-mail-copies-to 'ask))\r
-                (message-y-or-n-p\r
-                 (concat "Obey Mail-Copies-To: always? ") t "\\r
-You should normally obey the Mail-Copies-To: header.\r
-\r
-       `Mail-Copies-To: always'\r
-sends a copy of your response to the author.")))\r
-       (setq mct (or mrt from)))\r
-       ((and (eq message-use-mail-copies-to 'ask)\r
-            (not\r
-             (message-y-or-n-p\r
-              (concat "Obey Mail-Copies-To: " mct " ? ") t "\\r
-You should normally obey the Mail-Copies-To: header.\r
-\r
-       `Mail-Copies-To: " mct "'\r
-sends a copy of your response to " (if (string-match "," mct)\r
-                                      "the specified addresses"\r
-                                    "that address") ".")))\r
-       (setq mct nil))\r
-       ))\r
-\r
-    (unless follow-to\r
-      (cond\r
-       (to-address (setq follow-to (list (cons 'To to-address))))\r
-       ((not wide) (setq follow-to (list (cons 'To (or mrt from)))))\r
-       ;; Handle Mail-Followup-To.\r
-       ((and mft\r
-            (or (not (eq message-use-mail-followup-to 'ask))\r
-                (message-y-or-n-p\r
-                 (concat "Obey Mail-Followup-To: " mft "? ") t "\\r
-You should normally obey the Mail-Followup-To: header.\r
-\r
-       `Mail-Followup-To: " mft "'\r
-directs your response to " (if (string-match "," mft)\r
-                              "the specified addresses"\r
-                            "that address only") ".\r
-\r
-A typical situation where Mail-Followup-To is used is when the author thinks\r
-that further discussion should take place only in "\r
-                 (if (string-match "," mft)\r
-                     "the specified mailing lists"\r
-                   "that mailing list") ".")))\r
-       (setq follow-to (list (cons 'To mft)))\r
-       (when mct\r
-         (push (cons 'Cc mct) follow-to)))\r
-       (t\r
-       (let (ccalist)\r
-         (save-excursion\r
-           (message-set-work-buffer)\r
-           (unless never-mct\r
-             (insert (or mrt from "")))\r
-           (insert (if to (concat (if (bolp) "" ", ") to "") ""))\r
-           (insert (if mct (concat (if (bolp) "" ", ") mct) ""))\r
-           (insert (if cc (concat (if (bolp) "" ", ") cc) ""))\r
-           (goto-char (point-min))\r
-           (while (re-search-forward "[ \t]+" nil t)\r
-             (replace-match " " t t))\r
-           ;; Remove addresses that match `rmail-dont-reply-to-names'.\r
-           (insert (prog1 (rmail-dont-reply-to (buffer-string))\r
-                     (erase-buffer)))\r
-           (goto-char (point-min))\r
-           ;; Perhaps Mail-Copies-To: never removed the only address?\r
-           (when (eobp)\r
-             (insert (or mrt from "")))\r
-           (setq ccalist\r
-                 (mapcar\r
-                  (lambda (addr)\r
-                    (cons (mail-strip-quoted-names addr) addr))\r
-                  (message-tokenize-header (buffer-string))))\r
-           (let ((s ccalist))\r
-             (while s\r
-               (setq ccalist (delq (assoc (car (pop s)) s) ccalist)))))\r
-         (setq follow-to (list (cons 'To (cdr (pop ccalist)))))\r
-         (when ccalist\r
-           (let ((ccs (cons 'Cc (mapconcat\r
-                                 (lambda (addr) (cdr addr)) ccalist ", "))))\r
-             (when (string-match "^ +" (cdr ccs))\r
-               (setcdr ccs (substring (cdr ccs) (match-end 0))))\r
-             (push ccs follow-to)))))))\r
-\r
-    (message-pop-to-buffer (message-buffer-name\r
-                           (if wide "wide reply" "reply") from\r
-                           (if wide to-address nil)))\r
-\r
-    (setq message-reply-headers\r
-         (make-full-mail-header-from-decoded-header\r
-          0 subject from date message-id references 0 0 ""))\r
-\r
-    (message-setup\r
-     `((Subject . ,subject)\r
-       ,@follow-to\r
-       ,@(if (or references message-id)\r
-            `((References . ,(concat (or references "") (and references " ")\r
-                                     (or message-id ""))))))\r
-     cur)))\r
-\r
-;;;###autoload\r
-(defun message-wide-reply (&optional to-address)\r
-  "Make a \"wide\" reply to the message in the current buffer."\r
-  (interactive)\r
-  (message-reply to-address t))\r
-\r
-;;;###autoload\r
-(defun message-followup (&optional to-newsgroups)\r
-  "Follow up to the message in the current buffer.\r
-If TO-NEWSGROUPS, use that as the new Newsgroups line."\r
-  (interactive)\r
-  (let ((cur (current-buffer))\r
-       from subject date mct\r
-       references message-id follow-to\r
-       (inhibit-point-motion-hooks t)\r
-       (message-this-is-news t)\r
-       followup-to distribution newsgroups gnus-warning posted-to mft mrt)\r
-    (save-restriction\r
-      (message-narrow-to-head)\r
-      (when (message-functionp message-followup-to-function)\r
-       (setq follow-to\r
-             (funcall message-followup-to-function)))\r
-      (setq from (message-fetch-field "from")\r
-           date (message-fetch-field "date" t)\r
-           subject (or (message-fetch-field "subject") "none")\r
-           references (message-fetch-field "references")\r
-           message-id (message-fetch-field "message-id" t)\r
-           followup-to (when message-use-followup-to\r
-                         (message-fetch-field "followup-to"))\r
-           distribution (message-fetch-field "distribution")\r
-           newsgroups (message-fetch-field "newsgroups")\r
-           posted-to (message-fetch-field "posted-to")\r
-           mct (when message-use-mail-copies-to\r
-                 (message-fetch-field "mail-copies-to"))\r
-           mft (when message-use-mail-followup-to\r
-                 (message-fetch-field "mail-followup-to"))\r
-           mrt (when message-use-mail-reply-to\r
-                 (or (message-fetch-field "mail-reply-to")\r
-                     (message-fetch-field "reply-to")))\r
-           gnus-warning (message-fetch-field "gnus-warning"))\r
-      (when (and gnus-warning (string-match "<[^>]+>" gnus-warning))\r
-       (setq message-id (match-string 0 gnus-warning)))\r
-      ;; Remove bogus distribution.\r
-      (when (and (stringp distribution)\r
-                (let ((case-fold-search t))\r
-                  (string-match "world" distribution)))\r
-       (setq distribution nil))\r
-      ;; Remove any (buggy) Re:'s that are present and make a\r
-      ;; proper one.\r
-      (setq subject (message-make-followup-subject subject))\r
-      (widen))\r
-\r
-    ;; Handle special values of Mail-Copies-To.\r
-    (when mct\r
-      (cond\r
-       ((and (or (equal (downcase mct) "never")\r
-                (equal (downcase mct) "nobody"))\r
-            (or (not (eq message-use-mail-copies-to 'ask))\r
-                (message-y-or-n-p\r
-                 (concat "Obey Mail-Copies-To: never? ") t "\\r
-You should normally obey the Mail-Copies-To: header.\r
-\r
-       `Mail-Copies-To: never'\r
-directs you not to send your response to the author.")))\r
-       (setq mct nil))\r
-       ((and (or (equal (downcase mct) "always")\r
-                (equal (downcase mct) "poster"))\r
-            (or (not (eq message-use-mail-copies-to 'ask))\r
-                (message-y-or-n-p\r
-                 (concat "Obey Mail-Copies-To: always? ") t "\\r
-You should normally obey the Mail-Copies-To: header.\r
-\r
-       `Mail-Copies-To: always'\r
-sends a copy of your response to the author.")))\r
-       (setq mct (or mrt from)))\r
-       ((and (eq message-use-mail-copies-to 'ask)\r
-            (not\r
-             (message-y-or-n-p\r
-              (concat "Obey Mail-Copies-To: " mct " ? ") t "\\r
-You should normally obey the Mail-Copies-To: header.\r
-\r
-       `Mail-Copies-To: " mct "'\r
-sends a copy of your response to " (if (string-match "," mct)\r
-                                      "the specified addresses"\r
-                                    "that address") ".")))\r
-       (setq mct nil))\r
-       ))\r
-\r
-    (unless follow-to\r
-      (cond\r
-       (to-newsgroups (setq follow-to (list (cons 'Newsgroups to-newsgroups))))\r
-       ;; Handle Followup-To.\r
-       (followup-to\r
-       (cond\r
-        ((equal (downcase followup-to) "poster")\r
-         (if (or (eq message-use-followup-to 'use)\r
-                 (message-y-or-n-p "Obey Followup-To: poster? " t "\\r
-You should normally obey the Followup-To: header.\r
-\r
-       `Followup-To: poster'\r
-sends your response via e-mail instead of news.\r
-\r
-A typical situation where `Followup-To: poster' is used is when the author\r
-does not read the newsgroup, so he wouldn't see any replies sent to it."))\r
-             (setq message-this-is-news nil\r
-                   distribution nil\r
-                   follow-to (list (cons 'To (or mrt from ""))))\r
-           (setq follow-to (list (cons 'Newsgroups newsgroups)))))\r
-        (t\r
-         (if (or (equal followup-to newsgroups)\r
-                 (not (eq message-use-followup-to 'ask))\r
-                 (message-y-or-n-p\r
-                  (concat "Obey Followup-To: " followup-to "? ") t "\\r
-You should normally obey the Followup-To: header.\r
-\r
-       `Followup-To: " followup-to "'\r
-directs your response to " (if (string-match "," followup-to)\r
-                              "the specified newsgroups"\r
-                            "that newsgroup only") ".\r
-\r
-If a message is posted to several newsgroups, Followup-To is often\r
-used to direct the following discussion to one newsgroup only,\r
-because discussions that are spread over several newsgroup tend to\r
-be fragmented and very difficult to follow.\r
-\r
-Also, some source/announcement newsgroups are not indented for discussion;\r
-responses here are directed to other newsgroups."))\r
-             (setq follow-to (list (cons 'Newsgroups followup-to)))\r
-           (setq follow-to (list (cons 'Newsgroups newsgroups)))))))\r
-       ;; Handle Mail-Followup-To, followup via e-mail.\r
-       ((and mft\r
-            (or (not (eq message-use-mail-followup-to 'ask))\r
-                (message-y-or-n-p\r
-                 (concat "Obey Mail-Followup-To: " mft "? ") t "\\r
-You should normally obey the Mail-Followup-To: header.\r
-\r
-       `Mail-Followup-To: " mft "'\r
-directs your response to " (if (string-match "," mft)\r
-                              "the specified addresses"\r
-                            "that address only") " instead of news.\r
-\r
-A typical situation where Mail-Followup-To is used is when the author thinks\r
-that further discussion should take place only in "\r
-                            (if (string-match "," mft)\r
-                                "the specified mailing lists"\r
-                              "that mailing list") ".")))\r
-       (setq message-this-is-news nil\r
-             distribution nil\r
-             follow-to (list (cons 'To mft))))\r
-       (posted-to (setq follow-to (list (cons 'Newsgroups posted-to))))\r
-       (t\r
-       (setq follow-to (list (cons 'Newsgroups newsgroups))))))\r
-\r
-    (message-pop-to-buffer (message-buffer-name "followup" from newsgroups))\r
-\r
-    (setq message-reply-headers\r
-         (make-full-mail-header-from-decoded-header\r
-          0 subject from date message-id references 0 0 ""))\r
-\r
-    (message-setup\r
-     `((Subject . ,subject)\r
-       ,@follow-to\r
-       ,@(and mct (list (cons 'Cc mct)))\r
-       ,@(and distribution (list (cons 'Distribution distribution)))\r
-       ,@(if (or references message-id)\r
-            `((References . ,(concat (or references "") (and references " ")\r
-                                     (or message-id ""))))))\r
-     cur)))\r
-\r
-;;;###autoload\r
-(defun message-cancel-news ()\r
-  "Cancel an article you posted."\r
-  (interactive)\r
-  (unless (message-news-p)\r
-    (error "This is not a news article; canceling is impossible"))\r
-  (when (yes-or-no-p "Do you really want to cancel this article? ")\r
-    (let (from newsgroups message-id distribution buf sender)\r
-      (save-excursion\r
-       ;; Get header info. from original article.\r
-       (save-restriction\r
-         (message-narrow-to-head)\r
-         (setq from (message-fetch-field "from")\r
-               sender (message-fetch-field "sender")\r
-               newsgroups (message-fetch-field "newsgroups")\r
-               message-id (message-fetch-field "message-id" t)\r
-               distribution (message-fetch-field "distribution")))\r
-       ;; Make sure that this article was written by the user.\r
-       (unless (or (and sender\r
-                        (string-equal\r
-                         (downcase sender)\r
-                         (downcase (message-make-sender))))\r
-                   (string-equal\r
-                    (downcase (cadr (std11-extract-address-components\r
-                                     from)))\r
-                    (downcase (cadr (std11-extract-address-components\r
-                                     (message-make-from))))))\r
-         (error "This article is not yours"))\r
-       ;; Make control message.\r
-       (setq buf (set-buffer (get-buffer-create " *message cancel*")))\r
-       (erase-buffer)\r
-       (insert "Newsgroups: " newsgroups "\n"\r
-               "From: " (message-make-from) "\n"\r
-               "Subject: cmsg cancel " message-id "\n"\r
-               "Control: cancel " message-id "\n"\r
-               (if distribution\r
-                   (concat "Distribution: " distribution "\n")\r
-                 "")\r
-               mail-header-separator "\n"\r
-               message-cancel-message)\r
-       (run-hooks 'message-cancel-hook)\r
-       (message "Canceling your article...")\r
-       (if (let ((message-syntax-checks\r
-                  'dont-check-for-anything-just-trust-me)\r
-                 (message-encoding-buffer (current-buffer))\r
-                 (message-edit-buffer (current-buffer)))\r
-             (message-send-news))\r
-           (message "Canceling your article...done"))\r
-       (kill-buffer buf)))))\r
-\r
-(defun message-supersede-setup-for-mime-edit ()\r
-  (set (make-local-variable 'message-setup-hook) nil)\r
-  (mime-edit-again))\r
-\r
-;;;###autoload\r
-(defun message-supersede ()\r
-  "Start composing a message to supersede the current message.\r
-This is done simply by taking the old article and adding a Supersedes\r
-header line with the old Message-ID."\r
-  (interactive)\r
-  (let ((cur (current-buffer))\r
-       (sender (message-fetch-field "sender"))\r
-       (from (message-fetch-field "from")))\r
-    ;; Check whether the user owns the article that is to be superseded.\r
-    (unless (or (and sender\r
-                    (string-equal\r
-                     (downcase sender)\r
-                     (downcase (message-make-sender))))\r
-               (string-equal\r
-                (downcase (cadr (std11-extract-address-components from)))\r
-                (downcase (cadr (std11-extract-address-components\r
-                                 (message-make-from))))))\r
-      (error "This article is not yours"))\r
-    ;; Get a normal message buffer.\r
-    (message-pop-to-buffer (message-buffer-name "supersede"))\r
-    (insert-buffer-substring cur)\r
-    (message-narrow-to-head)\r
-    ;; Remove unwanted headers.\r
-    (when message-ignored-supersedes-headers\r
-      (message-remove-header message-ignored-supersedes-headers t))\r
-    (goto-char (point-min))\r
-    (if (not (re-search-forward "^Message-ID: " nil t))\r
-       (error "No Message-ID in this article")\r
-      (replace-match "Supersedes: " t t))\r
-    (goto-char (point-max))\r
-    (insert mail-header-separator)\r
-    (widen)\r
-    (when message-supersede-setup-function\r
-      (funcall message-supersede-setup-function))\r
-    (run-hooks 'message-supersede-setup-hook)\r
-    (goto-char (point-min))\r
-    (search-forward (concat "\n" mail-header-separator "\n") nil t)))\r
-\r
-;;;###autoload\r
-(defun message-recover ()\r
-  "Reread contents of current buffer from its last auto-save file."\r
-  (interactive)\r
-  (let ((file-name (make-auto-save-file-name)))\r
-    (cond ((save-window-excursion\r
-            (if (not (eq system-type 'vax-vms))\r
-                (with-output-to-temp-buffer "*Directory*"\r
-                  (buffer-disable-undo standard-output)\r
-                  (let ((default-directory "/"))\r
-                    (call-process\r
-                     "ls" nil standard-output nil "-l" file-name))))\r
-            (yes-or-no-p (format "Recover auto save file %s? " file-name)))\r
-          (let ((buffer-read-only nil))\r
-            (erase-buffer)\r
-            (insert-file-contents file-name nil)))\r
-         (t (error "message-recover cancelled")))))\r
-\r
-;;; Washing Subject:\r
-\r
-(defun message-wash-subject (subject)\r
-  "Remove junk like \"Re:\", \"(fwd)\", etc. that was added to the subject by previous forwarders, replyers, etc."\r
-  (with-temp-buffer\r
-    (insert-string subject)\r
-    (goto-char (point-min))\r
-    ;; strip Re/Fwd stuff off the beginning\r
-    (while (re-search-forward\r
-           "\\([Rr][Ee]:\\|[Ff][Ww][Dd]\\(\\[[0-9]*\\]\\)?:\\|[Ff][Ww]:\\)" nil t)\r
-      (replace-match ""))\r
-\r
-    ;; and gnus-style forwards [foo@bar.com] subject\r
-    (goto-char (point-min))\r
-    (while (re-search-forward "\\[[^ \t]*\\(@\\|\\.\\)[^ \t]*\\]" nil t)\r
-      (replace-match ""))\r
-\r
-    ;; and off the end\r
-    (goto-char (point-max))\r
-    (while (re-search-backward "([Ff][Ww][Dd])" nil t)\r
-      (replace-match ""))\r
-\r
-    ;; and finally, any whitespace that was left-over\r
-    (goto-char (point-min))\r
-    (while (re-search-forward "^[ \t]+" nil t)\r
-      (replace-match ""))\r
-    (goto-char (point-max))\r
-    (while (re-search-backward "[ \t]+$" nil t)\r
-      (replace-match ""))\r
-\r
-    (buffer-string)))\r
-\r
-;;; Forwarding messages.\r
-\r
-(defun message-forward-subject-author-subject (subject)\r
-  "Generate a subject for a forwarded message.\r
-The form is: [Source] Subject, where if the original message was mail,\r
-Source is the sender, and if the original message was news, Source is\r
-the list of newsgroups is was posted to."\r
-  (concat "["\r
-         (or (message-fetch-field\r
-              (if (message-news-p) "newsgroups" "from"))\r
-             "(nowhere)")\r
-         "] " subject))\r
-\r
-(defun message-forward-subject-fwd (subject)\r
-  "Generate a subject for a forwarded message.\r
-The form is: Fwd: Subject, where Subject is the original subject of\r
-the message."\r
-  (concat "Fwd: " subject))\r
-\r
-(defun message-make-forward-subject ()\r
-  "Return a Subject header suitable for the message in the current buffer."\r
-  (save-excursion\r
-    (save-restriction\r
-      (current-buffer)\r
-      (message-narrow-to-head)\r
-      (let ((funcs message-make-forward-subject-function)\r
-           (subject (if message-wash-forwarded-subjects\r
-                        (message-wash-subject\r
-                         (or (nnheader-decode-subject\r
-                              (message-fetch-field "Subject"))\r
-                             ""))\r
-                      (or (nnheader-decode-subject\r
-                           (message-fetch-field "Subject"))\r
-                          ""))))\r
-       ;; Make sure funcs is a list.\r
-       (and funcs\r
-            (not (listp funcs))\r
-            (setq funcs (list funcs)))\r
-       ;; Apply funcs in order, passing subject generated by previous\r
-       ;; func to the next one.\r
-       (while funcs\r
-         (when (message-functionp (car funcs))\r
-           (setq subject (funcall (car funcs) subject)))\r
-         (setq funcs (cdr funcs)))\r
-       subject))))\r
-\r
-;;;###autoload\r
-(defun message-forward (&optional news)\r
-  "Forward the current message via mail.\r
-Optional NEWS will use news to forward instead of mail."\r
-  (interactive "P")\r
-  (let ((cur (current-buffer))\r
-       (subject (message-make-forward-subject))\r
-       art-beg)\r
-    (if news (message-news nil subject) (message-mail nil subject))\r
-    ;; Put point where we want it before inserting the forwarded\r
-    ;; message.\r
-    (if message-signature-before-forwarded-message\r
-       (goto-char (point-max))\r
-      (message-goto-body))\r
-    ;; Make sure we're at the start of the line.\r
-    (unless (eolp)\r
-      (insert "\n"))\r
-    ;; Narrow to the area we are to insert.\r
-    (narrow-to-region (point) (point))\r
-    ;; Insert the separators and the forwarded buffer.\r
-    (insert message-forward-start-separator)\r
-    (setq art-beg (point))\r
-    (insert-buffer-substring cur)\r
-    (goto-char (point-max))\r
-    (insert message-forward-end-separator)\r
-    (set-text-properties (point-min) (point-max) nil)\r
-    ;; Remove all unwanted headers.\r
-    (goto-char art-beg)\r
-    (narrow-to-region (point) (if (search-forward "\n\n" nil t)\r
-                                 (1- (point))\r
-                               (point)))\r
-    (goto-char (point-min))\r
-    (message-remove-header message-included-forward-headers t nil t)\r
-    (widen)\r
-    (message-position-point)))\r
-\r
-;;;###autoload\r
-(defun message-resend (address)\r
-  "Resend the current article to ADDRESS."\r
-  (interactive "sResend message to: ")\r
-  (message "Resending message to %s..." address)\r
-  (save-excursion\r
-    (let ((cur (current-buffer))\r
-         beg)\r
-      ;; We first set up a normal mail buffer.\r
-      (set-buffer (get-buffer-create " *message resend*"))\r
-      (erase-buffer)\r
-      ;; avoid to turn-on-mime-edit\r
-      (let (message-setup-hook)\r
-       (message-setup `((To . ,address)))\r
-       )\r
-      ;; Insert our usual headers.\r
-      (message-generate-headers '(From Date To))\r
-      (message-narrow-to-headers)\r
-      ;; Rename them all to "Resent-*".\r
-      (while (re-search-forward "^[A-Za-z]" nil t)\r
-       (forward-char -1)\r
-       (insert "Resent-"))\r
-      (widen)\r
-      (forward-line)\r
-      (delete-region (point) (point-max))\r
-      (setq beg (point))\r
-      ;; Insert the message to be resent.\r
-      (insert-buffer-substring cur)\r
-      (goto-char (point-min))\r
-      (search-forward "\n\n")\r
-      (forward-char -1)\r
-      (save-restriction\r
-       (narrow-to-region beg (point))\r
-       (message-remove-header message-ignored-resent-headers t)\r
-       (goto-char (point-max)))\r
-      (insert mail-header-separator)\r
-      ;; Rename all old ("Also-")Resent headers.\r
-      (while (re-search-backward "^\\(Also-\\)*Resent-" beg t)\r
-       (beginning-of-line)\r
-       (insert "Also-"))\r
-      ;; Quote any "From " lines at the beginning.\r
-      (goto-char beg)\r
-      (when (looking-at "From ")\r
-       (replace-match "X-From-Line: "))\r
-      ;; Send it.\r
-      (let ((message-encoding-buffer (current-buffer))\r
-           (message-edit-buffer (current-buffer)))\r
-       (let (message-required-mail-headers)\r
-         (message-send-mail)))\r
-      (kill-buffer (current-buffer)))\r
-    (message "Resending message to %s...done" address)))\r
-\r
-(defun message-bounce-setup-for-mime-edit ()\r
-  (set (make-local-variable 'message-setup-hook) nil)\r
-  (mime-edit-again))\r
-\r
-;;;###autoload\r
-(defun message-bounce ()\r
-  "Re-mail the current message.\r
-This only makes sense if the current message is a bounce message than\r
-contains some mail you have written which has been bounced back to\r
-you."\r
-  (interactive)\r
-  (let ((cur (current-buffer))\r
-       boundary)\r
-    (message-pop-to-buffer (message-buffer-name "bounce"))\r
-    (insert-buffer-substring cur)\r
-    (undo-boundary)\r
-    (message-narrow-to-head)\r
-    (if (and (message-fetch-field "MIME-Version")\r
-            (setq boundary (message-fetch-field "Content-Type")))\r
-       (if (string-match "boundary=\"\\([^\"]+\\)\"" boundary)\r
-           (setq boundary (concat (match-string 1 boundary) " *\n"\r
-                                  "Content-Type: message/rfc822"))\r
-         (setq boundary nil)))\r
-    (widen)\r
-    (goto-char (point-min))\r
-    (search-forward "\n\n" nil t)\r
-    (or (and boundary\r
-            (re-search-forward boundary nil t)\r
-            (forward-line 2))\r
-       (and (re-search-forward message-unsent-separator nil t)\r
-            (forward-line 1))\r
-       (re-search-forward "^Return-Path:.*\n" nil t))\r
-    ;; We remove everything before the bounced mail.\r
-    (delete-region\r
-     (point-min)\r
-     (if (re-search-forward "^[^ \n\t]+:" nil t)\r
-        (match-beginning 0)\r
-       (point)))\r
-    (save-restriction\r
-      (message-narrow-to-head)\r
-      (message-remove-header message-ignored-bounced-headers t)\r
-      (goto-char (point-max))\r
-      (insert mail-header-separator))\r
-    (when message-bounce-setup-function\r
-      (funcall message-bounce-setup-function))\r
-    (run-hooks 'message-bounce-setup-hook)\r
-    (message-position-point)))\r
-\r
-;;;\r
-;;; Interactive entry points for new message buffers.\r
-;;;\r
-\r
-;;;###autoload\r
-(defun message-mail-other-window (&optional to subject)\r
-  "Like `message-mail' command, but display mail buffer in another window."\r
-  (interactive)\r
-  (let ((pop-up-windows t)\r
-       (special-display-buffer-names nil)\r
-       (special-display-regexps nil)\r
-       (same-window-buffer-names nil)\r
-       (same-window-regexps nil))\r
-    (message-pop-to-buffer (message-buffer-name "mail" to)))\r
-  (let ((message-this-is-mail t))\r
-    (message-setup `((To . ,(or to "")) (Subject . ,(or subject ""))))))\r
-\r
-;;;###autoload\r
-(defun message-mail-other-frame (&optional to subject)\r
-  "Like `message-mail' command, but display mail buffer in another frame."\r
-  (interactive)\r
-  (let ((pop-up-frames t)\r
-       (special-display-buffer-names nil)\r
-       (special-display-regexps nil)\r
-       (same-window-buffer-names nil)\r
-       (same-window-regexps nil))\r
-    (message-pop-to-buffer (message-buffer-name "mail" to)))\r
-  (let ((message-this-is-mail t))\r
-    (message-setup `((To . ,(or to "")) (Subject . ,(or subject ""))))))\r
-\r
-;;;###autoload\r
-(defun message-news-other-window (&optional newsgroups subject)\r
-  "Start editing a news article to be sent."\r
-  (interactive)\r
-  (let ((pop-up-windows t)\r
-       (special-display-buffer-names nil)\r
-       (special-display-regexps nil)\r
-       (same-window-buffer-names nil)\r
-       (same-window-regexps nil))\r
-    (message-pop-to-buffer (message-buffer-name "news" nil newsgroups)))\r
-  (let ((message-this-is-news t))\r
-    (message-setup `((Newsgroups . ,(or newsgroups ""))\r
-                    (Subject . ,(or subject ""))))))\r
-\r
-;;;###autoload\r
-(defun message-news-other-frame (&optional newsgroups subject)\r
-  "Start editing a news article to be sent."\r
-  (interactive)\r
-  (let ((pop-up-frames t)\r
-       (special-display-buffer-names nil)\r
-       (special-display-regexps nil)\r
-       (same-window-buffer-names nil)\r
-       (same-window-regexps nil))\r
-    (message-pop-to-buffer (message-buffer-name "news" nil newsgroups)))\r
-  (let ((message-this-is-news t))\r
-    (message-setup `((Newsgroups . ,(or newsgroups ""))\r
-                    (Subject . ,(or subject ""))))))\r
-\r
-;;; underline.el\r
-\r
-;; This code should be moved to underline.el (from which it is stolen).\r
-\r
-;;;###autoload\r
-(defun bold-region (start end)\r
-  "Bold all nonblank characters in the region.\r
-Works by overstriking characters.\r
-Called from program, takes two arguments START and END\r
-which specify the range to operate on."\r
-  (interactive "r")\r
-  (save-excursion\r
-    (let ((end1 (make-marker)))\r
-      (move-marker end1 (max start end))\r
-      (goto-char (min start end))\r
-      (while (< (point) end1)\r
-       (or (looking-at "[_\^@- ]")\r
-           (insert (char-after) "\b"))\r
-       (forward-char 1)))))\r
-\r
-;;;###autoload\r
-(defun unbold-region (start end)\r
-  "Remove all boldness (overstruck characters) in the region.\r
-Called from program, takes two arguments START and END\r
-which specify the range to operate on."\r
-  (interactive "r")\r
-  (save-excursion\r
-    (let ((end1 (make-marker)))\r
-      (move-marker end1 (max start end))\r
-      (goto-char (min start end))\r
-      (while (re-search-forward "\b" end1 t)\r
-       (if (eq (char-after) (char-after (- (point) 2)))\r
-           (delete-char -2))))))\r
-\r
-(defalias 'message-exchange-point-and-mark 'exchange-point-and-mark)\r
-\r
-;; Support for toolbar\r
-(when (string-match "XEmacs\\|Lucid" emacs-version)\r
-  (require 'messagexmas))\r
-\r
-;;; Group name completion.\r
-\r
-(defvar message-newgroups-header-regexp\r
-  "^\\(Newsgroups\\|Followup-To\\|Posted-To\\|Gcc\\):"\r
-  "Regexp that match headers that lists groups.")\r
-\r
-(defun message-tab ()\r
-  "Expand group names in Newsgroups and Followup-To headers.\r
-Do a `tab-to-tab-stop' if not in those headers."\r
-  (interactive)\r
-  (if (let ((mail-abbrev-mode-regexp message-newgroups-header-regexp))\r
-       (mail-abbrev-in-expansion-header-p))\r
-      (message-expand-group)\r
-    (tab-to-tab-stop)))\r
-\r
-(defvar gnus-active-hashtb)\r
-(defun message-expand-group ()\r
-  "Expand the group name under point."\r
-  (let* ((b (save-excursion\r
-             (save-restriction\r
-               (narrow-to-region\r
-                (save-excursion\r
-                  (beginning-of-line)\r
-                  (skip-chars-forward "^:")\r
-                  (1+ (point)))\r
-                (point))\r
-               (skip-chars-backward "^, \t\n") (point))))\r
-        (completion-ignore-case t)\r
-        (string (buffer-substring b (progn (skip-chars-forward "^,\t\n ")\r
-                                           (point))))\r
-        (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb))\r
-        (completions (all-completions string hashtb))\r
-        comp)\r
-    (delete-region b (point))\r
-    (cond\r
-     ((= (length completions) 1)\r
-      (if (string= (car completions) string)\r
-         (progn\r
-           (insert string)\r
-           (message "Only matching group"))\r
-       (insert (car completions))))\r
-     ((and (setq comp (try-completion string hashtb))\r
-          (not (string= comp string)))\r
-      (insert comp))\r
-     (t\r
-      (insert string)\r
-      (if (not comp)\r
-         (message "No matching groups")\r
-       (save-selected-window\r
-         (pop-to-buffer "*Completions*")\r
-         (buffer-disable-undo)\r
-         (let ((buffer-read-only nil))\r
-           (erase-buffer)\r
-           (let ((standard-output (current-buffer)))\r
-             (display-completion-list (sort completions 'string<)))\r
-           (goto-char (point-min))\r
-           (delete-region (point) (progn (forward-line 3) (point))))))))))\r
-\r
-;;; Help stuff.\r
-\r
-(defun message-talkative-question (ask question show &rest text)\r
-  "Call FUNCTION with argument QUESTION; optionally display TEXT... args.\r
-If SHOW is non-nil, the arguments TEXT... are displayed in a temp buffer.\r
-The following arguments may contain lists of values."\r
-  (if (and show\r
-          (setq text (message-flatten-list text)))\r
-      (save-window-excursion\r
-       (save-excursion\r
-         (with-output-to-temp-buffer " *MESSAGE information message*"\r
-           (set-buffer " *MESSAGE information message*")\r
-           (mapcar 'princ text)\r
-           (goto-char (point-min))))\r
-       (funcall ask question))\r
-    (funcall ask question)))\r
-\r
-(defun message-flatten-list (list)\r
-  "Return a new, flat list that contains all elements of LIST.\r
-\r
-\(message-flatten-list '(1 (2 3 (4 5 (6))) 7))\r
-=> (1 2 3 4 5 6 7)"\r
-  (cond ((consp list)\r
-        (apply 'append (mapcar 'message-flatten-list list)))\r
-       (list\r
-        (list list))))\r
-\r
-(defun message-generate-new-buffer-clone-locals (name &optional varstr)\r
-  "Create and return a buffer with a name based on NAME using generate-new-buffer.\r
-Then clone the local variables and values from the old buffer to the\r
-new one, cloning only the locals having a substring matching the\r
-regexp varstr."\r
-  (let ((oldbuf (current-buffer)))\r
-    (save-excursion\r
-      (set-buffer (generate-new-buffer name))\r
-      (message-clone-locals oldbuf)\r
-      (current-buffer))))\r
-\r
-(defun message-clone-locals (buffer)\r
-  "Clone the local variables from BUFFER to the current buffer."\r
-  (let ((locals (save-excursion\r
-                 (set-buffer buffer)\r
-                 (buffer-local-variables)))\r
-       (regexp\r
-        "^\\(gnus\\|nn\\|message\\|user-\\(mail-address\\|full-name\\)\\)"))\r
-    (mapcar\r
-     (lambda (local)\r
-       (when (and (consp local)\r
-                 (car local)\r
-                 (string-match regexp (symbol-name (car local))))\r
-        (ignore-errors\r
-          (set (make-local-variable (car local))\r
-               (cdr local)))))\r
-     locals)))\r
-\r
-\r
-;;; @ for MIME Edit mode\r
-;;;\r
-\r
-(defun message-maybe-encode ()\r
-  (when message-mime-mode\r
-    (run-hooks 'mime-edit-translate-hook)\r
-    (if (catch 'mime-edit-error\r
-         (save-excursion\r
-           (mime-edit-translate-body)\r
-           ))\r
-       (error "Translation error!")\r
-      )\r
-    (end-of-invisible)\r
-    (run-hooks 'mime-edit-exit-hook)\r
-    ))\r
-\r
-(defun message-mime-insert-article (&optional full-headers)\r
-  (interactive "P")\r
-  (let ((message-cite-function 'mime-edit-inserted-message-filter)\r
-       (message-reply-buffer\r
-        (message-get-parameter-with-eval 'original-buffer))\r
-       (start (point)))\r
-    (message-yank-original nil)\r
-    (save-excursion\r
-      (narrow-to-region (goto-char start)\r
-                       (if (search-forward "\n\n" nil t)\r
-                           (1- (point))\r
-                         (point-max)))\r
-      (goto-char (point-min))\r
-      (let ((message-included-forward-headers\r
-            (if full-headers "" message-included-forward-headers)))\r
-       (message-remove-header message-included-forward-headers t nil t))\r
-      (widen))))\r
-\r
-(set-alist 'mime-edit-message-inserter-alist\r
-          'message-mode (function message-mime-insert-article))\r
-\r
-;;; Miscellaneous functions\r
-\r
-;; stolen (and renamed) from nnheader.el\r
-(defun message-replace-chars-in-string (string from to)\r
-  "Replace characters in STRING from FROM to TO."\r
-  (let ((string (substring string 0))  ;Copy string.\r
-       (len (length string))\r
-       (idx 0))\r
-    ;; Replace all occurrences of FROM with TO.\r
-    (while (< idx len)\r
-      (when (= (aref string idx) from)\r
-       (aset string idx to))\r
-      (setq idx (1+ idx)))\r
-    string))\r
-\r
-;;;\r
-;;; MIME functions\r
-;;;\r
-\r
-(defun message-mime-query-file (prompt)\r
-  (let ((file (read-file-name prompt nil nil t)))\r
-    ;; Prevent some common errors.  This is inspired by similar code in\r
-    ;; VM.\r
-    (when (file-directory-p file)\r
-      (error "%s is a directory, cannot attach" file))\r
-    (unless (file-exists-p file)\r
-      (error "No such file: %s" file))\r
-    (unless (file-readable-p file)\r
-      (error "Permission denied: %s" file))\r
-    file))\r
-\r
-(defun message-mime-query-type (file)\r
-  (let* ((default (or (mm-default-file-encoding file)\r
-                     ;; Perhaps here we should check what the file\r
-                     ;; looks like, and offer text/plain if it looks\r
-                     ;; like text/plain.\r
-                     "application/octet-stream"))\r
-        (string (completing-read\r
-                 (format "Content type (default %s): " default)\r
-                 (delete-duplicates\r
-                  (mapcar (lambda (m) (list (cdr m))) mailcap-mime-extensions)\r
-                  :test 'equal))))\r
-    (if (not (equal string ""))\r
-       string\r
-      default)))\r
-\r
-(defun message-mime-query-description ()\r
-  (let ((description (read-string "One line description: ")))\r
-    (when (string-match "\\`[ \t]*\\'" description)\r
-      (setq description nil))\r
-    description))\r
-\r
-(defun message-mime-attach-file (file &optional type description)\r
-  "Attach a file to the outgoing MIME message.\r
-The file is not inserted or encoded until you send the message with\r
-`\\[message-send-and-exit]' or `\\[message-send]'.\r
-\r
-FILE is the name of the file to attach.  TYPE is its content-type, a\r
-string of the form \"type/subtype\".  DESCRIPTION is a one-line\r
-description of the attachment."\r
-  (interactive\r
-   (let* ((file (message-mime-query-file "Attach file: "))\r
-         (type (message-mime-query-type file))\r
-         (description (message-mime-query-description)))\r
-     (list file type description)))\r
-  (insert (format\r
-          "<#part type=%s filename=%s%s disposition=attachment><#/part>\n"\r
-          type (prin1-to-string file)\r
-          (if description\r
-              (format " description=%s" (prin1-to-string description))\r
-            ""))))\r
-\r
-(defun message-mime-attach-external (file &optional type description)\r
-  "Attach an external file into the buffer.\r
-FILE is an ange-ftp/efs specification of the part location.\r
-TYPE is the MIME type to use."\r
-  (interactive\r
-   (let* ((file (message-mime-query-file "Attach external file: "))\r
-         (type (message-mime-query-type file))\r
-         (description (message-mime-query-description)))\r
-     (list file type description)))\r
-  (insert (format\r
-          "<#external type=%s name=%s disposition=attachment><#/external>\n"\r
-          type (prin1-to-string file))))\r
-\r
-(defun message-encode-message-body ()\r
-  (let ((mail-parse-charset message-default-charset)\r
-       (case-fold-search t)\r
-       lines multipart-p content-type-p)\r
-    (message-goto-body)\r
-    (save-restriction\r
-      (narrow-to-region (point) (point-max))\r
-      (let ((new (mml-generate-mime)))\r
-       (when new\r
-         (delete-region (point-min) (point-max))\r
-         (insert new)\r
-         (goto-char (point-min))\r
-         (if (eq (aref new 0) ?\n)\r
-             (delete-char 1)\r
-           (search-forward "\n\n")\r
-           (setq lines (buffer-substring (point-min) (1- (point))))\r
-           (delete-region (point-min)  (point))))))\r
-    (save-restriction\r
-      (message-narrow-to-headers-or-head)\r
-      (message-remove-header "Mime-Version")\r
-      (goto-char (point-max))\r
-      (insert "Mime-Version: 1.0\n")\r
-      (when lines\r
-       (insert lines))\r
-      (setq multipart-p\r
-           (re-search-backward "^Content-Type: multipart/" nil t))\r
-      (goto-char (point-max))\r
-      (setq content-type-p\r
-           (re-search-backward "^Content-Type:" nil t)))\r
-    (save-restriction\r
-      (message-narrow-to-headers-or-head)\r
-      (message-remove-first-header "Content-Type")\r
-      (message-remove-first-header "Content-Transfer-Encoding"))\r
-    (when multipart-p\r
-      (save-restriction\r
-       (message-narrow-to-headers-or-head)\r
-       (message-remove-first-header "Content-Type")\r
-       (message-remove-first-header "Content-Transfer-Encoding"))\r
-      (message-goto-body)\r
-      (insert "This is a MIME multipart message.  If you are reading\n")\r
-      (insert "this, you shouldn't.\n"))\r
-    ;; We always make sure that the message has a Content-Type header.\r
-    ;; This is because some broken MTAs and MUAs get awfully confused\r
-    ;; when confronted with a message with a MIME-Version header and\r
-    ;; without a Content-Type header.  For instance, Solaris'\r
-    ;; /usr/bin/mail.\r
-    (unless content-type-p\r
-      (goto-char (point-min))\r
-      (re-search-forward "^MIME-Version:")\r
-      (forward-line 1)\r
-      (insert "Content-Type: text/plain; charset=us-ascii\n"))))\r
-\r
-(defvar message-save-buffer " *encoding")\r
-(defun message-save-drafts ()\r
-  (interactive)\r
-  (if (not (get-buffer message-save-buffer))\r
-      (get-buffer-create message-save-buffer))\r
-  (let ((filename buffer-file-name)\r
-       (buffer (current-buffer)))\r
-    (set-buffer message-save-buffer)\r
-    (erase-buffer)\r
-    (insert-buffer buffer)\r
-    (mime-edit-translate-buffer)\r
-    (write-region (point-min) (point-max) filename)\r
-    (set-buffer buffer)\r
-    (set-buffer-modified-p nil)))\r
-\r
-(provide 'message)\r
-\r
-(run-hooks 'message-load-hook)\r
-\r
-;;; message.el ends here\r
+;;; message.el --- composing mail and news messages
+;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+;;        Free Software Foundation, Inc.
+
+;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
+;;     MORIOKA Tomohiko <morioka@jaist.ac.jp>
+;;     Shuhei KOBAYASHI <shuhei-k@jaist.ac.jp>
+;;     Keiichi Suzuki   <kei-suzu@mail.wbs.ne.jp>
+;;     Tatsuya Ichikawa <t-ichi@po.shiojiri.ne.jp>
+;;     Katsumi Yamaoka  <yamaoka@jpl.org>
+;;     Kiyokazu SUTO    <suto@merry.xmath.ous.ac.jp>
+;; Keywords: mail, news, MIME
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This mode provides mail-sending facilities from within Emacs.  It
+;; consists mainly of large chunks of code from the sendmail.el,
+;; gnus-msg.el and rnewspost.el files.
+
+;;; Code:
+
+(eval-when-compile
+  (require 'cl)
+  (require 'smtp)
+  (defvar gnus-message-group-art)
+  (defvar gnus-list-identifiers)) ; gnus-sum is required where necessary
+(eval-and-compile
+  (if (boundp 'MULE)
+      (progn
+       (require 'base64)
+       (require 'canlock-om))
+    (require 'canlock)))
+(require 'mailheader)
+(require 'nnheader)
+;; This is apparently necessary even though things are autoloaded.
+;; Because we dynamically bind mail-abbrev-mode-regexp, we'd better
+;; require mailabbrev here.
+(if (featurep 'xemacs)
+    (require 'mail-abbrevs)
+  (require 'mailabbrev))
+(require 'mime-edit)
+(eval-when-compile (require 'static))
+
+;; Avoid byte-compile warnings.
+(eval-when-compile
+  (require 'mail-parse)
+  (require 'mml))
+
+(require 'rfc822)
+(eval-and-compile
+  (autoload 'customize-save-variable "cus-edit") ;; for Mule 2.
+  (autoload 'sha1 "sha1-el")
+  (autoload 'gnus-find-method-for-group "gnus")
+  (autoload 'nnvirtual-find-group-art "nnvirtual")
+  (autoload 'gnus-group-decoded-name "gnus-group"))
+
+(defgroup message '((user-mail-address custom-variable)
+                   (user-full-name custom-variable))
+  "Mail and news message composing."
+  :link '(custom-manual "(message)Top")
+  :group 'mail
+  :group 'news)
+
+(put 'user-mail-address 'custom-type 'string)
+(put 'user-full-name 'custom-type 'string)
+
+(defgroup message-various nil
+  "Various Message Variables"
+  :link '(custom-manual "(message)Various Message Variables")
+  :group 'message)
+
+(defgroup message-buffers nil
+  "Message Buffers"
+  :link '(custom-manual "(message)Message Buffers")
+  :group 'message)
+
+(defgroup message-sending nil
+  "Message Sending"
+  :link '(custom-manual "(message)Sending Variables")
+  :group 'message)
+
+(defgroup message-interface nil
+  "Message Interface"
+  :link '(custom-manual "(message)Interface")
+  :group 'message)
+
+(defgroup message-forwarding nil
+  "Message Forwarding"
+  :link '(custom-manual "(message)Forwarding")
+  :group 'message-interface)
+
+(defgroup message-insertion nil
+  "Message Insertion"
+  :link '(custom-manual "(message)Insertion")
+  :group 'message)
+
+(defgroup message-headers nil
+  "Message Headers"
+  :link '(custom-manual "(message)Message Headers")
+  :group 'message)
+
+(defgroup message-news nil
+  "Composing News Messages"
+  :group 'message)
+
+(defgroup message-mail nil
+  "Composing Mail Messages"
+  :group 'message)
+
+(defgroup message-faces nil
+  "Faces used for message composing."
+  :group 'message
+  :group 'faces)
+
+(defgroup message-frames nil
+  "Message frames"
+  :group 'message)
+
+(defcustom message-directory "~/Mail/"
+  "*Directory from which all other mail file variables are derived."
+  :group 'message-various
+  :type 'directory)
+
+(defcustom message-max-buffers 10
+  "*How many buffers to keep before starting to kill them off."
+  :group 'message-buffers
+  :type 'integer)
+
+(defcustom message-send-rename-function nil
+  "Function called to rename the buffer after sending it."
+  :group 'message-buffers
+  :type '(choice function (const nil)))
+
+(defcustom message-fcc-handler-function 'message-output
+  "*A function called to save outgoing articles.
+This function will be called with the name of the file to store the
+article in.  The default function is `message-output' which saves in Unix
+mailbox format."
+  :type '(radio (function-item message-output)
+               (function :tag "Other"))
+  :group 'message-sending)
+
+(defcustom message-encode-function 'message-maybe-encode
+  "*A function called to encode messages."
+  :group 'message-sending
+  :type 'function)
+
+(defcustom message-8bit-encoding-list '(8bit binary)
+  "*8bit encoding type in Content-Transfer-Encoding field."
+  :group 'message-sending
+  :type '(repeat (symbol :tag "Type")))
+
+(defcustom message-fcc-externalize-attachments nil
+  "If non-nil, attachments are included as external parts in Fcc copies."
+  :type 'boolean
+  :group 'message-sending)
+
+(defcustom message-courtesy-message
+  "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n"
+  "*This is inserted at the start of a mailed copy of a posted message.
+If the string contains the format spec \"%s\", the Newsgroups
+the article has been posted to will be inserted there.
+If this variable is nil, no such courtesy message will be added."
+  :group 'message-sending
+  :type '(radio (string :format "%t: %v\n" :size 0) (const nil)))
+
+(defcustom message-ignored-bounced-headers
+  "^\\(Received\\|Return-Path\\|Delivered-To\\):"
+  "*Regexp that matches headers to be removed in resent bounced mail."
+  :group 'message-interface
+  :type 'regexp)
+
+(defcustom message-bounce-setup-function 'message-bounce-setup-for-mime-edit
+  "Function to setup a re-sending bounced message."
+  :group 'message-sending
+  :type 'function)
+
+;;; Start of variables adopted from `message-utils.el'.
+
+(defcustom message-subject-trailing-was-query 'ask
+  ;; should it default to nil or ask?
+  "*What to do with trailing \"(was: <old subject>)\" in subject lines.
+If nil, leave the subject unchanged.  If it is the symbol `ask', query
+the user what do do.  In this case, the subject is matched against
+`message-subject-trailing-was-ask-regexp'.  If
+`message-subject-trailing-was-query' is t, always strip the trailing
+old subject.  In this case, `message-subject-trailing-was-regexp' is
+used."
+  :type '(choice (const :tag "never" nil)
+                (const :tag "always strip" t)
+                 (const ask))
+  :group 'message-various)
+
+(defcustom message-subject-trailing-was-ask-regexp
+  "[ \t]*\\([[(]+[Ww][Aa][Ss][ \t]*.*[\])]+\\)"
+  "*Regexp matching \"(was: <old subject>)\" in the subject line.
+
+The function `message-strip-subject-trailing-was' uses this regexp if
+`message-subject-trailing-was-query' is set to the symbol `ask'.  If
+the variable is t instead of `ask', use
+`message-subject-trailing-was-regexp' instead.
+
+It is okay to create some false positives here, as the user is asked."
+  :group 'message-various
+  :type 'regexp)
+
+(defcustom message-subject-trailing-was-regexp
+  "[ \t]*\\((*[Ww][Aa][Ss]:[ \t]*.*)\\)"
+  "*Regexp matching \"(was: <old subject>)\" in the subject line.
+
+If `message-subject-trailing-was-query' is set to t, the subject is
+matched against `message-subject-trailing-was-regexp' in
+`message-strip-subject-trailing-was'.  You should use a regexp creating very
+few false positives here."
+  :group 'message-various
+  :type 'regexp)
+
+;; Fixme: Why are all these things autoloaded?
+
+;;; marking inserted text
+
+;;;###autoload
+(defcustom message-mark-insert-begin
+  "--8<---------------cut here---------------start------------->8---\n"
+  "How to mark the beginning of some inserted text."
+  :type 'string
+  :group 'message-various)
+
+;;;###autoload
+(defcustom message-mark-insert-end
+  "--8<---------------cut here---------------end--------------->8---\n"
+  "How to mark the end of some inserted text."
+  :type 'string
+  :group 'message-various)
+
+;;;###autoload
+(defcustom message-archive-header
+  "X-No-Archive: Yes\n"
+  "Header to insert when you don't want your article to be archived.
+Archives \(such as groups.google.com\) respect this header."
+  :type 'string
+  :group 'message-various)
+
+;;;###autoload
+(defcustom message-archive-note
+  "X-No-Archive: Yes - save http://groups.google.com/"
+  "Note to insert why you wouldn't want this posting archived.
+If nil, don't insert any text in the body."
+  :type '(radio (string :format "%t: %v\n" :size 0)
+               (const nil))
+  :group 'message-various)
+
+;;; Crossposts and Followups
+;; inspired by JoH-followup-to by Jochem Huhman <joh  at gmx.de>
+;; new suggestions by R. Weikusat <rw at another.de>
+
+(defvar message-cross-post-old-target nil
+  "Old target for cross-posts or follow-ups.")
+(make-variable-buffer-local 'message-cross-post-old-target)
+
+;;;###autoload
+(defcustom message-cross-post-default t
+  "When non-nil `message-cross-post-followup-to' will perform a crosspost.
+If nil, `message-cross-post-followup-to' will only do a followup.  Note that
+you can explicitly override this setting by calling
+`message-cross-post-followup-to' with a prefix."
+  :type 'boolean
+  :group 'message-various)
+
+;;;###autoload
+(defcustom message-cross-post-note
+  "Crosspost & Followup-To: "
+  "Note to insert before signature to notify of xpost and follow-up."
+  :type 'string
+  :group 'message-various)
+
+;;;###autoload
+(defcustom message-followup-to-note
+  "Followup-To: "
+  "Note to insert before signature to notify of follow-up only."
+  :type 'string
+  :group 'message-various)
+
+;;;###autoload
+(defcustom message-cross-post-note-function
+  'message-cross-post-insert-note
+  "Function to use to insert note about Crosspost or Followup-To.
+The function will be called with four arguments.  The function should not only
+insert a note, but also ensure old notes are deleted.  See the documentation
+for `message-cross-post-insert-note'."
+  :type 'function
+  :group 'message-various)
+
+;;; End of variables adopted from `message-utils.el'.
+
+;;;###autoload
+(defcustom message-from-style 'default
+  "*Specifies how \"From\" headers look.
+
+If nil, they contain just the return address like:
+       king@grassland.com
+If `parens', they look like:
+       king@grassland.com (Elvis Parsley)
+If `angles', they look like:
+       Elvis Parsley <king@grassland.com>
+
+Otherwise, most addresses look like `angles', but they look like
+`parens' if `angles' would need quoting and `parens' would not."
+  :type '(choice (const :tag "simple" nil)
+                (const parens)
+                (const angles)
+                (const default))
+  :group 'message-headers)
+
+(defcustom message-insert-canlock t
+  "Whether to insert a Cancel-Lock header in news postings."
+  :version "21.3"
+  :group 'message-headers
+  :type 'boolean)
+
+(defcustom message-syntax-checks
+  (if message-insert-canlock '((sender . disabled)) nil)
+  ;; Guess this one shouldn't be easy to customize...
+  "*Controls what syntax checks should not be performed on outgoing posts.
+To disable checking of long signatures, for instance, add
+ `(signature . disabled)' to this list.
+
+Don't touch this variable unless you really know what you're doing.
+
+Checks include `subject-cmsg', `multiple-headers', `sendsys',
+`message-id', `from', `long-lines', `control-chars', `size',
+`new-text', `quoting-style', `redirected-followup', `signature',
+`approved', `sender', `empty', `empty-headers', `message-id', `from',
+`subject', `shorten-followup-to', `existing-newsgroups',
+`buffer-file-name', `unchanged', `newsgroups', `reply-to',
+`continuation-headers', `long-header-lines', `invisible-text' and
+`illegible-text'."
+  :group 'message-news
+  :type '(repeat sexp))                        ; Fixme: improve this
+
+(defcustom message-required-headers '((optional . References)
+                                     From)
+  "*Headers to be generated or prompted for when sending a message.
+Also see `message-required-news-headers' and
+`message-required-mail-headers'."
+  :group 'message-news
+  :group 'message-headers
+  :type '(repeat sexp))
+
+(defcustom message-draft-headers '(References From)
+  "*Headers to be generated when saving a draft message."
+  :group 'message-news
+  :group 'message-headers
+  :type '(repeat sexp))
+
+(defcustom message-required-news-headers
+  '(From Newsgroups Subject Date Message-ID
+        (optional . Organization)
+        (optional . User-Agent))
+  "*Headers to be generated or prompted for when posting an article.
+RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
+Message-ID.  Organization, Lines, In-Reply-To, Expires, and
+User-Agent are optional.  If don't you want message to insert some
+header, remove it from this list."
+  :group 'message-news
+  :group 'message-headers
+  :type '(repeat sexp))
+
+(defcustom message-required-mail-headers
+  '(From Subject Date (optional . In-Reply-To) Message-ID
+        (optional . User-Agent))
+  "*Headers to be generated or prompted for when mailing a message.
+It is recommended that From, Date, To, Subject and Message-ID be
+included.  Organization and User-Agent are optional."
+  :group 'message-mail
+  :group 'message-headers
+  :type '(repeat sexp))
+
+(defcustom message-deletable-headers '(Message-ID Date Lines)
+  "Headers to be deleted if they already exist and were generated by message previously."
+  :group 'message-headers
+  :type 'sexp)
+
+(defcustom message-ignored-news-headers
+  "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
+  "*Regexp of headers to be removed unconditionally before posting."
+  :group 'message-news
+  :group 'message-headers
+  :type 'regexp)
+
+(defcustom message-ignored-mail-headers
+  "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
+  "*Regexp of headers to be removed unconditionally before mailing."
+  :group 'message-mail
+  :group 'message-headers
+  :type 'regexp)
+
+(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|^X-Complaints-To:\\|^Cancel-Lock:\\|^Cancel-Key:\\|^X-Hashcash:\\|^X-Payment:"
+  "*Header lines matching this regexp will be deleted before posting.
+It's best to delete old Path and Date headers before posting to avoid
+any confusion."
+  :group 'message-interface
+  :type 'regexp)
+
+(defcustom message-supersede-setup-function
+  'message-supersede-setup-for-mime-edit
+  "Function to setup a supersede message."
+  :group 'message-sending
+  :type 'function)
+
+(defcustom message-subject-re-regexp
+  "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*"
+  "*Regexp matching \"Re: \" in the subject line."
+  :group 'message-various
+  :type 'regexp)
+
+;;; Some sender agents encode the whole subject including leading "Re: ".
+;;; And if followup agent does not decode it for some reason (e.g. unknown
+;;; charset) and just add a new "Re: " in front of the encoded-word, the
+;;; result will contain multiple "Re: "'s.
+(defcustom message-subject-encoded-re-regexp
+  (concat
+   "^[ \t]*"
+   (regexp-quote "=?")
+   "[-!#$%&'*+0-9A-Z^_`a-z{|}~]+" ; charset
+   (regexp-quote "?")
+   "\\("
+   "[Bb]" (regexp-quote "?") ; B encoding
+   "\\(\\(CQk\\|CSA\\|IAk\\|ICA\\)[Jg]\\)*" ; \([ \t][ \t][ \t]\)*
+   "\\("
+   "[Uc][km]U6" ; [Rr][Ee]:
+   "\\|"
+   "\\(C[VX]\\|I[FH]\\)J[Fl]O[g-v]" ; [ \t][Rr][Ee]:
+   "\\|"
+   "\\(CQl\\|CSB\\|IAl\\|ICB\\)[Sy][RZ]T[o-r]" ; [ \t][ \t][Rr][Ee]:
+   "\\)"
+   "\\|"
+   "[Qb]" (regexp-quote "?") ; Q encoding
+   "\\(_\\|=09\\|=20\\)*"
+   "\\([Rr]\\|=[57]2\\)\\([Ee]\\|=[46]5\\)\\(:\\|=3[Aa]\\)"
+   "\\)"
+   )
+  "*Regexp matching \"Re: \" in the subject line.
+Unlike `message-subject-re-regexp', this regexp matches \"Re: \" within
+an encoded-word."
+  :group 'message-various
+  :type 'regexp)
+
+(defcustom message-use-subject-re t
+  "*If t, remove any (buggy) \"Re: \"'s from the subject of the precursor
+and add a new \"Re: \".  If it is nil, use the subject \"as-is\".  If it
+is the symbol `guess', try to detect \"Re: \" within an encoded-word."
+  :group 'message-various
+  :type '(choice (const :tag "off" nil)
+                (const :tag "on" t)
+                (const guess)))
+
+;;;###autoload
+(defcustom message-signature-separator "^-- *$"
+  "Regexp matching the signature separator."
+  :type 'regexp
+  :group 'message-various)
+
+(defcustom message-signature-separator-for-insertion "-- \n"
+  "*Signature separator. This value will be inserted as signature separator
+when composing message. Default value is \"-- \\n\". Notice: Changing this
+value may go against RFC-1036 and draft-ietf-usefor-article-05.txt. "
+  :type 'string
+  :group 'message-insertion)
+
+(defcustom message-elide-ellipsis "\n[...]\n\n"
+  "*The string which is inserted for elided text."
+  :type 'string
+  :group 'message-various)
+
+(defcustom message-interactive t
+  "Non-nil means when sending a message wait for and display errors.
+nil means let mailer mail back a message to report errors."
+  :group 'message-sending
+  :group 'message-mail
+  :type 'boolean)
+
+(defcustom message-generate-new-buffers 'unique
+  "*Non-nil means create a new message buffer whenever `message-setup' is called.
+If this is a function, call that function with three parameters:  The type,
+the to address and the group name.  (Any of these may be nil.)  The function
+should return the new buffer name."
+  :group 'message-buffers
+  :type '(choice (const :tag "off" nil)
+                (const :tag "unique" unique)
+                (const :tag "unsent" unsent)
+                (function fun)))
+
+(defcustom message-kill-buffer-on-exit nil
+  "*Non-nil means that the message buffer will be killed after sending a message."
+  :group 'message-buffers
+  :type 'boolean)
+
+(defcustom message-kill-buffer-query-function 'yes-or-no-p
+  "*Function used to prompt user whether to kill the message buffer.  If
+it is t, the buffer will be killed unconditionally."
+  :type '(radio (function-item yes-or-no-p)
+               (function-item y-or-n-p)
+               (function-item nnheader-Y-or-n-p)
+               (function :tag "Other" t))
+  :group 'message-buffers)
+
+(defcustom message-kill-buffer-and-remove-file t
+  "*Non-nil means that the associated file will be removed before
+removing the message buffer.  However, it is treated as nil when the
+command `message-mimic-kill-buffer' is used."
+  :group 'message-buffers
+  :type 'boolean)
+
+(eval-when-compile
+  (defvar gnus-local-organization))
+(defcustom message-user-organization
+  (or (and (boundp 'gnus-local-organization)
+          (stringp gnus-local-organization)
+          gnus-local-organization)
+      (getenv "ORGANIZATION")
+      t)
+  "*String to be used as an Organization header.
+If t, use `message-user-organization-file'."
+  :group 'message-headers
+  :type '(choice string
+                (const :tag "consult file" t)))
+
+;;;###autoload
+(defcustom message-user-organization-file "/usr/lib/news/organization"
+  "*Local news organization file."
+  :type 'file
+  :group 'message-headers)
+
+(defcustom message-forward-start-separator
+  (concat (mime-make-tag "message" "rfc822") "\n")
+  "*Delimiter inserted before forwarded messages."
+  :group 'message-forwarding
+  :type 'string)
+
+(defcustom message-forward-end-separator
+  (concat (mime-make-tag "text" "plain") "\n")
+  "*Delimiter inserted after forwarded messages."
+  :group 'message-forwarding
+  :type 'string)
+
+(defcustom message-included-forward-headers
+  "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^\\(Mail-\\)?Followup-To:\\|^\\(Mail-\\)?Reply-To:\\|^Mail-Copies-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:\\|^Content-\\|^MIME-Version:"
+  "*Regexp matching headers to be included in forwarded messages."
+  :group 'message-forwarding
+  :type 'regexp)
+
+(defcustom message-make-forward-subject-function
+  #'message-forward-subject-name-subject
+  "*List of functions called to generate subject headers for forwarded messages.
+The subject generated by the previous function is passed into each
+successive function.
+
+The provided functions are:
+
+* `message-forward-subject-author-subject' Source of article (author or
+      newsgroup), in brackets followed by the subject
+* `message-forward-subject-name-subject' Source of article (name of author
+      or newsgroup), in brackets followed by the subject
+* `message-forward-subject-fwd' Subject of article with 'Fwd:' prepended
+      to it."
+  :group 'message-forwarding
+  :type '(radio (function-item message-forward-subject-author-subject)
+               (function-item message-forward-subject-fwd)
+               (function-item message-forward-subject-name-subject)
+               (repeat :tag "List of functions" function)))
+
+(defcustom message-forward-as-mime t
+  "*Non-nil means forward messages as an inline/rfc822 MIME section.
+Otherwise, directly inline the old message in the forwarded message."
+  :version "21.1"
+  :group 'message-forwarding
+  :type 'boolean)
+
+(defcustom message-forward-show-mml 'best
+  "*Non-nil means show forwarded messages as MML (decoded from MIME).
+Otherwise, forwarded messages are unchanged.
+Can also be the symbol `best' to indicate that MML should be
+used, except when it is a bad idea to use MML.  One example where
+it is a bad idea is when forwarding a signed or encrypted
+message, because converting MIME to MML would invalidate the
+digital signature."
+  :version "21.1"
+  :group 'message-forwarding
+  :type '(choice (const :tag "use MML" t)
+                (const :tag "don't use MML " nil)
+                (const :tag "use MML when appropriate" best)))
+
+(defcustom message-forward-before-signature t
+  "*Non-nil means put forwarded message before signature, else after."
+  :group 'message-forwarding
+  :type 'boolean)
+
+(defcustom message-wash-forwarded-subjects nil
+  "*Non-nil means try to remove as much cruft as possible from the subject.
+Done before generating the new subject of a forward."
+  :group 'message-forwarding
+  :type 'boolean)
+
+(defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From "
+  "*All headers that match this regexp will be deleted when resending a message."
+  :group 'message-interface
+  :type 'regexp)
+
+(defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus"
+  "*All headers that match this regexp will be deleted when forwarding a message."
+  :version "21.1"
+  :group 'message-forwarding
+  :type '(choice (const :tag "None" nil)
+                regexp))
+
+(defcustom message-ignored-cited-headers "."
+  "*Delete these headers from the messages you yank."
+  :group 'message-insertion
+  :type 'regexp)
+
+(defcustom message-cite-prefix-regexp
+  (if (string-match "[[:digit:]]" "1") ;; support POSIX?
+      "\\([ \t]*[-_.[:word:]]+>+\\|[ \t]*[]>|}+]\\)+"
+    ;; ?-, ?_ or ?. MUST NOT be in syntax entry w.
+    (let ((old-table (syntax-table))
+         non-word-constituents)
+      (set-syntax-table text-mode-syntax-table)
+      (setq non-word-constituents
+           (concat
+            (if (string-match "\\w" "-")  "" "-")
+            (if (string-match "\\w" "_")  "" "_")
+            (if (string-match "\\w" ".")  "" ".")))
+      (set-syntax-table old-table)
+      (if (equal non-word-constituents "")
+         "\\([ \t]*\\(\\w\\)+>+\\|[ \t]*[]>|}+]\\)+"
+       (concat "\\([ \t]*\\(\\w\\|["
+               non-word-constituents
+               "]\\)+>+\\|[ \t]*[]>|}+]\\)+"))))
+  "*Regexp matching the longest possible citation prefix on a line."
+  :group 'message-insertion
+  :type 'regexp)
+
+(defcustom message-cancel-message "I am canceling my own article.\n"
+  "Message to be inserted in the cancel message."
+  :group 'message-interface
+  :type 'string)
+
+;; Useful to set in site-init.el
+;;;###autoload
+(defcustom message-send-mail-function 'message-send-mail-with-sendmail
+  "Function to call to send the current buffer as mail.
+The headers should be delimited by a line whose contents match the
+variable `mail-header-separator'.
+
+Valid values include `message-send-mail-with-sendmail' (the default),
+`message-send-mail-with-mh', `message-send-mail-with-qmail',
+`message-send-mail-with-smtp', `message-smtpmail-send-it',
+`smtpmail-send-it' and `feedmail-send-it'.
+
+See also `send-mail-function'."
+  :type '(radio (function-item message-send-mail-with-sendmail)
+               (function-item message-send-mail-with-mh)
+               (function-item message-send-mail-with-qmail)
+               (function-item message-send-mail-with-smtp)
+               (function-item message-smtpmail-send-it)
+               (function-item smtpmail-send-it)
+               (function-item feedmail-send-it)
+               (function :tag "Other"))
+  :group 'message-sending
+  :group 'message-mail)
+
+;; 1997-09-29 by MORIOKA Tomohiko
+(defcustom message-send-news-function 'message-send-news-with-gnus
+  "Function to call to send the current buffer as news.
+The headers should be delimited by a line whose contents match the
+variable `mail-header-separator'."
+  :group 'message-sending
+  :group 'message-news
+  :type 'function)
+
+(defcustom message-reply-to-function nil
+  "If non-nil, function that should return a list of headers.
+This function should pick out addresses from the To, Cc, and From headers
+and respond with new To and Cc headers."
+  :group 'message-interface
+  :type '(choice function (const nil)))
+
+(defcustom message-wide-reply-to-function nil
+  "If non-nil, function that should return a list of headers.
+This function should pick out addresses from the To, Cc, and From headers
+and respond with new To and Cc headers."
+  :group 'message-interface
+  :type '(choice function (const nil)))
+
+(defcustom message-followup-to-function nil
+  "If non-nil, function that should return a list of headers.
+This function should pick out addresses from the To, Cc, and From headers
+and respond with new To and Cc headers."
+  :group 'message-interface
+  :type '(choice function (const nil)))
+
+(defcustom message-use-followup-to 'ask
+  "*Specifies what to do with Followup-To header.
+If nil, always ignore the header.  If it is t, use its value, but
+query before using the \"poster\" value.  If it is the symbol `ask',
+always query the user whether to use the value.  If it is the symbol
+`use', always use the value."
+  :group 'message-interface
+  :type '(choice (const :tag "ignore" nil)
+                (const :tag "use & query" t)
+                (const :tag "maybe" t)
+                (const :tag "always" use)
+                (const :tag "ask" ask)))
+
+(defcustom message-use-mail-copies-to 'ask
+  "*Specifies what to do with Mail-Copies-To header.
+If nil, always ignore the header.  If it is t, use its value, but
+query before using the value other than \"always\" or \"never\".
+If it is the symbol `ask', always query the user whether to use
+the value.  If it is the symbol `use', always use the value."
+  :group 'message-interface
+  :type '(choice (const :tag "ignore" nil)
+                (const :tag "maybe" t)
+                (const :tag "always" use)
+                (const :tag "ask" ask)))
+
+;;; XXX: 'ask and 'use are not implemented yet.
+(defcustom message-use-mail-reply-to 'ask
+  "*Specifies what to do with Mail-Reply-To/Reply-To header.
+If nil, always ignore the header.  If it is t or the symbol `use', use
+its value.  If it is the symbol `ask', always query the user whether to
+use the value.  Note that if \"Reply-To\" is marked as \"broken\", its value
+is never used."
+  :group 'message-interface
+  :type '(choice (const :tag "ignore" nil)
+                (const :tag "maybe" t)
+                (const :tag "always" use)
+                (const :tag "ask" ask)))
+
+(defcustom message-use-mail-followup-to 'use
+  "*Specifies what to do with Mail-Followup-To header.
+If nil, always ignore the header.  If it is the symbol `ask', always
+query the user whether to use the value.  If it is t or the symbol
+`use', always use the value."
+  :group 'message-interface
+  :type '(choice (const :tag "ignore" nil)
+                (const :tag "maybe" t)
+                (const :tag "always" use)
+                (const :tag "ask" ask)))
+
+(defcustom message-subscribed-address-functions nil
+  "*Specifies functions for determining list subscription.
+If nil, do not attempt to determine list subscription with functions.
+If non-nil, this variable contains a list of functions which return
+regular expressions to match lists.  These functions can be used in
+conjunction with `message-subscribed-regexps' and
+`message-subscribed-addresses'."
+  :group 'message-interface
+  :type '(repeat sexp))
+
+(defcustom message-subscribed-address-file nil
+  "*A file containing addresses the user is subscribed to.
+If nil, do not look at any files to determine list subscriptions.  If
+non-nil, each line of this file should be a mailing list address."
+  :group 'message-interface
+  :type '(radio (file :format "%t: %v\n" :size 0)
+               (const nil)))
+
+(defcustom message-subscribed-addresses nil
+  "*Specifies a list of addresses the user is subscribed to.
+If nil, do not use any predefined list subscriptions.  This list of
+addresses can be used in conjunction with
+`message-subscribed-address-functions' and `message-subscribed-regexps'."
+  :group 'message-interface
+  :type '(repeat string))
+
+(defcustom message-subscribed-regexps nil
+  "*Specifies a list of addresses the user is subscribed to.
+If nil, do not use any predefined list subscriptions.  This list of
+regular expressions can be used in conjunction with
+`message-subscribed-address-functions' and `message-subscribed-addresses'."
+  :group 'message-interface
+  :type '(repeat regexp))
+
+(defcustom message-allow-no-recipients 'ask
+  "Specifies what to do when there are no recipients other than Gcc/Fcc.
+If it is the symbol `always', the posting is allowed.  If it is the
+symbol `never', the posting is not allowed.  If it is the symbol
+`ask', you are prompted."
+  :group 'message-interface
+  :type '(choice (const always)
+                (const never)
+                (const ask)))
+
+(defcustom message-sendmail-f-is-evil nil
+  "*Non-nil means don't add \"-f username\" to the sendmail command line.
+Doing so would be even more evil than leaving it out."
+  :group 'message-sending
+  :type 'boolean)
+
+(defcustom message-sendmail-envelope-from nil
+  "*Envelope-from when sending mail with sendmail.
+If this is nil, use `user-mail-address'.  If it is the symbol
+`header', use the From: header of the message."
+  :type '(choice (string :tag "From name")
+                (const :tag "Use From: header from message" header)
+                (const :tag "Use `user-mail-address'" nil))
+  :group 'message-sending)
+
+;; qmail-related stuff
+(defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"
+  "Location of the qmail-inject program."
+  :group 'message-sending
+  :type 'file)
+
+(defcustom message-qmail-inject-args nil
+  "Arguments passed to qmail-inject programs.
+This should be a list of strings, one string for each argument.  It
+may also be a function.
+
+For e.g., if you wish to set the envelope sender address so that bounces
+go to the right place or to deal with listserv's usage of that address, you
+might set this variable to '(\"-f\" \"you@some.where\")."
+  :group 'message-sending
+  :type '(choice (function)
+                (repeat string)))
+
+(defvar message-cater-to-broken-inn t
+  "Non-nil means Gnus should not fold the `References' header.
+Folding `References' makes ancient versions of INN create incorrect
+NOV lines.")
+
+(eval-when-compile
+  (defvar gnus-post-method)
+  (defvar gnus-select-method))
+(defcustom message-post-method
+  (cond ((and (boundp 'gnus-post-method)
+             (listp gnus-post-method)
+             gnus-post-method)
+        gnus-post-method)
+       ((boundp 'gnus-select-method)
+        gnus-select-method)
+       (t '(nnspool "")))
+  "*Method used to post news.
+Note that when posting from inside Gnus, for instance, this
+variable isn't used."
+  :group 'message-news
+  :group 'message-sending
+  ;; This should be the `gnus-select-method' widget, but that might
+  ;; create a dependence to `gnus.el'.
+  :type 'sexp)
+
+;; FIXME: This should be a temporary workaround until someone implements a
+;; proper solution.  If a crash happens while replying, the auto-save file
+;; will *not* have a `References:' header if `message-generate-headers-first'
+;; is nil.  See: http://article.gmane.org/gmane.emacs.gnus.general/51138
+(defcustom message-generate-headers-first '(references)
+  "*If non-nil, generate all required headers before composing.
+The variables `message-required-news-headers' and
+`message-required-mail-headers' specify which headers to generate.
+This can also be a list of headers that should be generated before
+composing.
+
+Note that the variable `message-deletable-headers' specifies headers which
+are to be deleted and then re-generated before sending, so this variable
+will not have a visible effect for those headers."
+  :group 'message-headers
+  :type '(choice (const :tag "None" nil)
+                 (const :tag "References" '(references))
+                 (const :tag "All" t)
+                 (repeat (sexp :tag "Header"))))
+
+(defcustom message-setup-hook '(turn-on-mime-edit)
+  "Normal hook, run each time a new outgoing message is initialized.
+The function `message-setup' runs this hook."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-cancel-hook nil
+  "Hook run when cancelling articles."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-signature-setup-hook nil
+  "Normal hook, run each time a new outgoing message is initialized.
+It is run after the headers have been inserted and before
+the signature is inserted."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-bounce-setup-hook nil
+  "Normal hook, run each time a re-sending bounced message is initialized.
+The function `message-bounce' runs this hook."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-supersede-setup-hook nil
+  "Normal hook, run each time a supersede message is initialized.
+The function `message-supersede' runs this hook."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-mode-hook nil
+  "Hook run in message mode buffers."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-header-hook '((lambda () (mime-encode-header-in-buffer t)))
+  "Hook run in a message mode buffer narrowed to the headers."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-header-setup-hook nil
+  "Hook called narrowed to the headers when setting up a message buffer."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-minibuffer-local-map
+  (let ((map (make-sparse-keymap 'message-minibuffer-local-map)))
+    (set-keymap-parent map minibuffer-local-map)
+    map)
+  "Keymap for `message-read-from-minibuffer'.")
+
+;;;###autoload
+(defcustom message-citation-line-function 'message-insert-citation-line
+  "*Function called to insert the \"Whomever writes:\" line.
+
+Note that Gnus provides a feature where the reader can click on
+`writes:' to hide the cited text.  If you change this line too much,
+people who read your message will have to change their Gnus
+configuration.  See the variable `gnus-cite-attribution-suffix'."
+  :type 'function
+  :group 'message-insertion)
+
+;;;###autoload
+(defcustom message-yank-prefix "> "
+  "*Prefix inserted on the lines of yanked messages.
+Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
+See also `message-yank-cited-prefix'."
+  :type 'string
+  :group 'message-insertion)
+
+(defcustom message-yank-add-new-references t
+  "Non-nil means new IDs will be added to \"References\" field when an
+article is yanked by the command `message-yank-original' interactively.
+If it is a symbol `message-id-only', only an ID from \"Message-ID\" field
+is used, otherwise IDs extracted from \"References\", \"In-Reply-To\" and
+\"Message-ID\" fields are used."
+  :type '(radio (const :tag "Do not add anything" nil)
+               (const :tag "From Message-Id, References and In-Reply-To fields" t)
+               (const :tag "From only Message-Id field." message-id-only))
+  :group 'message-insertion)
+
+(defcustom message-list-references-add-position nil
+  "Integer value means position for adding to \"References\" field when
+an article is yanked by the command `message-yank-original' interactively."
+  :type '(radio (const :tag "Add to last" nil)
+               (integer :tag "Position from last ID"))
+  :group 'message-insertion)
+
+(defcustom message-yank-cited-prefix ">"
+  "*Prefix inserted on cited or empty lines of yanked messages.
+Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
+See also `message-yank-prefix'."
+  :type 'string
+  :group 'message-insertion)
+
+(defcustom message-indentation-spaces 3
+  "*Number of spaces to insert at the beginning of each cited line.
+Used by `message-yank-original' via `message-yank-cite'."
+  :group 'message-insertion
+  :type 'integer)
+
+;;;###autoload
+(defcustom message-cite-function 'message-cite-original
+  "*Function for citing an original message.
+Predefined functions include `message-cite-original' and
+`message-cite-original-without-signature'.
+Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil."
+  :type '(radio (function-item message-cite-original)
+               (function-item message-cite-original-without-signature)
+               (function-item mu-cite-original)
+               (function-item sc-cite-original)
+               (function :tag "Other"))
+  :group 'message-insertion)
+
+;;;###autoload
+(defcustom message-suspend-font-lock-when-citing nil
+  "Non-nil means suspend font-lock'ing while citing an original message.
+Some lazy demand-driven fontification tools (or Emacs itself) have a
+bug that they often miss a buffer to be fontified.  It will mostly
+occur when Emacs prompts user for any inputs in the minibuffer.
+Setting this option to non-nil may help you to avoid unpleasant errors
+even if it is an add-hoc expedient."
+  :type 'boolean
+  :group 'message-insertion)
+
+;;;###autoload
+(defcustom message-indent-citation-function 'message-indent-citation
+  "*Function for modifying a citation just inserted in the mail buffer.
+This can also be a list of functions.  Each function can find the
+citation between (point) and (mark t).  And each function should leave
+point and mark around the citation text as modified."
+  :type 'function
+  :group 'message-insertion)
+
+;;;###autoload
+(defcustom message-signature t
+  "*String to be inserted at the end of the message buffer.
+If t, the `message-signature-file' file will be inserted instead.
+If a function, the result from the function will be used instead.
+If a form, the result from the form will be used instead."
+  :type 'sexp
+  :group 'message-insertion)
+
+;;;###autoload
+(defcustom message-signature-file "~/.signature"
+  "*Name of file containing the text inserted at end of message buffer.
+Ignored if the named file doesn't exist.
+If nil, don't insert a signature."
+  :type '(choice file (const :tags "None" nil))
+  :group 'message-insertion)
+
+;;;###autoload
+(defcustom message-signature-insert-empty-line t
+  "*If non-nil, insert an empty line before the signature separator."
+  :type 'boolean
+  :group 'message-insertion)
+
+(defcustom message-distribution-function nil
+  "*Function called to return a Distribution header."
+  :group 'message-news
+  :group 'message-headers
+  :type '(choice function (const nil)))
+
+(defcustom message-expires 14
+  "Number of days before your article expires."
+  :group 'message-news
+  :group 'message-headers
+  :link '(custom-manual "(message)News Headers")
+  :type 'integer)
+
+(defcustom message-user-path nil
+  "If nil, use the NNTP server name in the Path header.
+If stringp, use this; if non-nil, use no host name (user name only)."
+  :group 'message-news
+  :group 'message-headers
+  :link '(custom-manual "(message)News Headers")
+  :type '(choice (const :tag "nntp" nil)
+                (string :tag "name")
+                (sexp :tag "none" :format "%t" t)))
+
+(defvar message-reply-buffer nil)
+(defvar message-reply-headers nil
+  "The headers of the current replied article.
+It is a vector of the following headers:
+\[number subject from date id references chars lines xref extra].")
+(defvar message-sent-message-via nil)
+(defvar message-checksum nil)
+(defvar message-send-actions nil
+  "A list of actions to be performed upon successful sending of a message.")
+(defvar message-exit-actions nil
+  "A list of actions to be performed upon exiting after sending a message.")
+(defvar message-kill-actions nil
+  "A list of actions to be performed before killing a message buffer.")
+(defvar message-postpone-actions nil
+  "A list of actions to be performed after postponing a message.")
+(defvar message-original-frame nil)
+(defvar message-parameter-alist nil)
+(defvar message-startup-parameter-alist nil)
+
+(define-widget 'message-header-lines 'text
+  "All header lines must be LFD terminated."
+  :format "%{%t%}:%n%v"
+  :valid-regexp "^\\'"
+  :error "All header lines must be newline terminated")
+
+(defcustom message-default-headers ""
+  "*A string containing header lines to be inserted in outgoing messages.
+It is inserted before you edit the message, so you can edit or delete
+these lines."
+  :group 'message-headers
+  :type 'message-header-lines)
+
+(defcustom message-default-mail-headers ""
+  "*A string of header lines to be inserted in outgoing mails."
+  :group 'message-headers
+  :group 'message-mail
+  :type 'message-header-lines)
+
+(defcustom message-default-news-headers ""
+  "*A string of header lines to be inserted in outgoing news articles."
+  :group 'message-headers
+  :group 'message-news
+  :type 'message-header-lines)
+
+;; Note: could use /usr/ucb/mail instead of sendmail;
+;; options -t, and -v if not interactive.
+(defcustom message-mailer-swallows-blank-line
+  (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)"
+                        system-configuration)
+          (file-readable-p "/etc/sendmail.cf")
+          (let ((buffer (get-buffer-create " *temp*")))
+            (unwind-protect
+                (save-excursion
+                  (set-buffer buffer)
+                  (insert-file-contents "/etc/sendmail.cf")
+                  (goto-char (point-min))
+                  (let ((case-fold-search nil))
+                    (re-search-forward "^OR\\>" nil t)))
+              (kill-buffer buffer))))
+      ;; According to RFC822, "The field-name must be composed of printable
+      ;; ASCII characters (i. e., characters that have decimal values between
+      ;; 33 and 126, except colon)", i. e., any chars except ctl chars,
+      ;; space, or colon.
+      '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))
+  "*Set this non-nil if the system's mailer runs the header and body together.
+\(This problem exists on Sunos 4 when sendmail is run in remote mode.)
+The value should be an expression to test whether the problem will
+actually occur."
+  :group 'message-sending
+  :type 'sexp)
+
+;;; XXX: This symbol is overloaded!  See below.
+(defvar message-user-agent nil
+  "String of the form of PRODUCT/VERSION.  Used for User-Agent header field.")
+
+(static-when (boundp 'MULE)
+  (require 'reporter));; `define-mail-user-agent' is here.
+
+;;;###autoload
+(define-mail-user-agent 'message-user-agent
+  'message-mail 'message-send-and-exit
+  'message-kill-buffer 'message-send-hook)
+
+(defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)
+  "If non-nil, delete the deletable headers before feeding to mh.")
+
+(defvar message-send-method-alist
+  '((news message-news-p message-send-via-news)
+    (mail message-mail-p message-send-via-mail))
+  "Alist of ways to send outgoing messages.
+Each element has the form
+
+  \(TYPE PREDICATE FUNCTION)
+
+where TYPE is a symbol that names the method; PREDICATE is a function
+called without any parameters to determine whether the message is
+a message of type TYPE; and FUNCTION is a function to be called if
+PREDICATE returns non-nil.  FUNCTION is called with one parameter --
+the prefix.")
+
+(defcustom message-mail-alias-type 'abbrev
+  "*What alias expansion type to use in Message buffers.
+The default is `abbrev', which uses mailabbrev.  nil switches
+mail aliases off."
+  :group 'message
+  :link '(custom-manual "(message)Mail Aliases")
+  :type '(choice (const :tag "Use Mailabbrev" abbrev)
+                (const :tag "No expansion" nil)))
+
+(defcustom message-auto-save-directory
+  (file-name-as-directory (nnheader-concat message-directory "drafts"))
+  "*Directory where Message auto-saves buffers if Gnus isn't running.
+If nil, Message won't auto-save."
+  :group 'message-buffers
+  :type '(choice directory (const :tag "Don't auto-save" nil)))
+
+(defcustom message-default-charset
+  (and (featurep 'xemacs) (not (featurep 'mule)) 'iso-8859-1)
+  "Default charset used in non-MULE XEmacsen."
+  :version "21.1"
+  :group 'message
+  :type 'symbol)
+
+(defcustom message-dont-reply-to-names
+  (and (boundp 'rmail-dont-reply-to-names) rmail-dont-reply-to-names)
+  "*A regexp specifying addresses to prune when doing wide replies.
+A value of nil means exclude your own user name only."
+  :version "21.1"
+  :group 'message
+  :type '(choice (const :tag "Yourself" nil)
+                regexp))
+
+(defvar message-shoot-gnksa-feet nil
+  "*A list of GNKSA feet you are allowed to shoot.
+Gnus gives you all the opportunity you could possibly want for
+shooting yourself in the foot.  Also, Gnus allows you to shoot the
+feet of Good Net-Keeping Seal of Approval.  The following are foot
+candidates:
+`empty-article'     Allow you to post an empty article;
+`quoted-text-only'  Allow you to post quoted text only;
+`multiple-copies'   Allow you to post multiple copies;
+`cancel-messages'   Allow you to cancel or supersede messages from
+                    your other email addresses.")
+
+(defsubst message-gnksa-enable-p (feature)
+  (or (not (listp message-shoot-gnksa-feet))
+      (memq feature message-shoot-gnksa-feet)))
+
+(defcustom message-hidden-headers nil
+  "Regexp of headers to be hidden when composing new messages.
+This can also be a list of regexps to match headers.  Or a list
+starting with `not' and followed by regexps."
+  :group 'message
+  :type '(repeat regexp))
+
+;;; Internal variables.
+;;; Well, not really internal.
+
+(defvar message-mode-syntax-table
+  (let ((table (copy-syntax-table text-mode-syntax-table)))
+    (modify-syntax-entry ?% ". " table)
+    (modify-syntax-entry ?> ". " table)
+    (modify-syntax-entry ?< ". " table)
+    table)
+  "Syntax table used while in Message mode.")
+
+(defface message-header-to-face
+  '((((class color)
+      (background dark))
+     (:foreground "green2" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "MidnightBlue" :bold t))
+    (t
+     (:bold t :italic t)))
+  "Face used for displaying From headers."
+  :group 'message-faces)
+
+(defface message-header-cc-face
+  '((((class color)
+      (background dark))
+     (:foreground "green4" :bold t))
+    (((class color)
+      (background light))
+     (:foreground "MidnightBlue"))
+    (t
+     (:bold t)))
+  "Face used for displaying Cc headers."
+  :group 'message-faces)
+
+(defface message-header-subject-face
+  '((((class color)
+      (background dark))
+     (:foreground "green3"))
+    (((class color)
+      (background light))
+     (:foreground "navy blue" :bold t))
+    (t
+     (:bold t)))
+  "Face used for displaying subject headers."
+  :group 'message-faces)
+
+(defface message-header-newsgroups-face
+  '((((class color)
+      (background dark))
+     (:foreground "yellow" :bold t :italic t))
+    (((class color)
+      (background light))
+     (:foreground "blue4" :bold t :italic t))
+    (t
+     (:bold t :italic t)))
+  "Face used for displaying newsgroups headers."
+  :group 'message-faces)
+
+(defface message-header-other-face
+  '((((class color)
+      (background dark))
+     (:foreground "#b00000"))
+    (((class color)
+      (background light))
+     (:foreground "steel blue"))
+    (t
+     (:bold t :italic t)))
+  "Face used for displaying newsgroups headers."
+  :group 'message-faces)
+
+(defface message-header-name-face
+  '((((class color)
+      (background dark))
+     (:foreground "DarkGreen"))
+    (((class color)
+      (background light))
+     (:foreground "cornflower blue"))
+    (t
+     (:bold t)))
+  "Face used for displaying header names."
+  :group 'message-faces)
+
+(defface message-header-xheader-face
+  '((((class color)
+      (background dark))
+     (:foreground "blue"))
+    (((class color)
+      (background light))
+     (:foreground "blue"))
+    (t
+     (:bold t)))
+  "Face used for displaying X-Header headers."
+  :group 'message-faces)
+
+(defface message-separator-face
+  '((((class color)
+      (background dark))
+     (:foreground "blue3"))
+    (((class color)
+      (background light))
+     (:foreground "brown"))
+    (t
+     (:bold t)))
+  "Face used for displaying the separator."
+  :group 'message-faces)
+
+(defface message-cited-text-face
+  '((((class color)
+      (background dark))
+     (:foreground "red"))
+    (((class color)
+      (background light))
+     (:foreground "red"))
+    (t
+     (:bold t)))
+  "Face used for displaying cited text names."
+  :group 'message-faces)
+
+(defface message-mml-face
+  '((((class color)
+      (background dark))
+     (:foreground "ForestGreen"))
+    (((class color)
+      (background light))
+     (:foreground "ForestGreen"))
+    (t
+     (:bold t)))
+  "Face used for displaying MML."
+  :group 'message-faces)
+
+(defun message-font-lock-make-header-matcher (regexp)
+  (let ((form
+        `(lambda (limit)
+           (let ((start (point)))
+             (save-restriction
+               (widen)
+               (goto-char (point-min))
+               (if (re-search-forward
+                    (concat "^" (regexp-quote mail-header-separator) "$")
+                    nil t)
+                   (setq limit (min limit (match-beginning 0))))
+               (goto-char start))
+             (and (< start limit)
+                  (re-search-forward ,regexp limit t))))))
+    (if (featurep 'bytecomp)
+       (byte-compile form)
+      form)))
+
+(defvar message-font-lock-keywords
+  (let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
+    `((,(message-font-lock-make-header-matcher
+        (concat "^\\([Tt]o:\\)" content))
+       (1 'message-header-name-face)
+       (2 'message-header-to-face nil t))
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([GBF]?[Cc][Cc]:\\|[Rr]eply-[Tt]o:\\|"
+                "[Mm]ail-[Cc]opies-[Tt]o:\\|"
+                "[Mm]ail-[Rr]eply-[Tt]o:\\|"
+                "[Mm]ail-[Ff]ollowup-[Tt]o:\\)" content))
+       (1 'message-header-name-face)
+       (2 'message-header-cc-face nil t))
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([Ss]ubject:\\)" content))
+       (1 'message-header-name-face)
+       (2 'message-header-subject-face nil t))
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content))
+       (1 'message-header-name-face)
+       (2 'message-header-newsgroups-face nil t))
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\([A-Z][^: \n\t]+:\\)" content))
+       (1 'message-header-name-face)
+       (2 'message-header-other-face nil t))
+      (,(message-font-lock-make-header-matcher
+        (concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content))
+       (1 'message-header-name-face)
+       (2 'message-header-name-face))
+      ,@(if (and mail-header-separator
+                (not (equal mail-header-separator "")))
+           `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
+              1 'message-separator-face))
+         nil)
+      ((lambda (limit)
+        (re-search-forward (concat "^\\("
+                                   message-cite-prefix-regexp
+                                   "\\).*")
+                           limit t))
+       (0 'message-cited-text-face))
+      (,mime-edit-tag-regexp
+       (0 'message-mml-face))))
+  "Additional expressions to highlight in Message mode.")
+
+;; XEmacs does it like this.  For Emacs, we have to set the
+;; `font-lock-defaults' buffer-local variable.
+(put 'message-mode 'font-lock-defaults '(message-font-lock-keywords t))
+
+(defvar message-face-alist
+  '((bold . bold-region)
+    (underline . underline-region)
+    (default . (lambda (b e)
+                (unbold-region b e)
+                (ununderline-region b e))))
+  "Alist of mail and news faces for facemenu.
+The cdr of each entry is a function for applying the face to a region.")
+
+(defcustom message-send-hook nil
+  "Hook run before sending messages.
+This hook is run quite early when sending."
+  :group 'message-various
+  :options '(ispell-message)
+  :type 'hook)
+
+(defcustom message-send-mail-hook nil
+  "Hook run before sending mail messages.
+This hook is run very late -- just before the message is sent as
+mail."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-send-news-hook nil
+  "Hook run before sending news messages.
+This hook is run very late -- just before the message is sent as
+news."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-sent-hook nil
+  "Hook run after sending messages."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-use-multi-frames nil
+  "Make new frame when sending messages."
+  :group 'message-frames
+  :type 'boolean)
+
+(defcustom message-delete-frame-on-exit nil
+  "Delete frame after sending messages."
+  :group 'message-frames
+  :type '(choice (const :tag "off" nil)
+                (const :tag "always" t)
+                (const :tag "ask" ask)))
+
+(defvar message-draft-coding-system
+  nnheader-auto-save-coding-system
+  "*Coding system to compose mail.
+If you'd like to make it possible to share draft files between XEmacs
+and Emacs, you may use `iso-2022-7bit' for this value at your own risk.
+Note that the coding-system `iso-2022-7bit' isn't suitable to all data.")
+
+(defcustom message-send-mail-partially-limit 1000000
+  "The limitation of messages sent as message/partial.
+The lower bound of message size in characters, beyond which the message
+should be sent in several parts.  If it is nil, the size is unlimited."
+  :version "21.1"
+  :group 'message-buffers
+  :type '(choice (const :tag "unlimited" nil)
+                (integer 1000000)))
+
+(defcustom message-alternative-emails nil
+  "A regexp to match the alternative email addresses.
+The first matched address (not primary one) is used in the From field."
+  :group 'message-headers
+  :type '(choice (const :tag "Always use primary" nil)
+                regexp))
+
+(defcustom message-hierarchical-addresses nil
+  "A list of hierarchical mail address definitions.
+
+Inside each entry, the first address is the \"top\" address, and
+subsequent addresses are subaddresses; this is used to indicate that
+mail sent to the first address will automatically be delivered to the
+subaddresses.  So if the first address appears in the recipient list
+for a message, the subaddresses will be removed (if present) before
+the mail is sent.  All addresses in this structure should be
+downcased."
+  :group 'message-headers
+  :type '(repeat (repeat string)))
+
+(defcustom message-mail-user-agent nil
+  "Like `mail-user-agent'.
+Except if it is nil, use Gnus native MUA; if it is t, use
+`mail-user-agent'."
+  :type '(radio (const :tag "Gnus native"
+                      :format "%t\n"
+                      nil)
+               (const :tag "`mail-user-agent'"
+                      :format "%t\n"
+                      t)
+               (function-item :tag "Default Emacs mail"
+                              :format "%t\n"
+                              sendmail-user-agent)
+               (function-item :tag "Emacs interface to MH"
+                              :format "%t\n"
+                              mh-e-user-agent)
+               (function :tag "Other"))
+  :version "21.1"
+  :group 'message)
+
+(defcustom message-wide-reply-confirm-recipients nil
+  "Whether to confirm a wide reply to multiple email recipients.
+If this variable is nil, don't ask whether to reply to all recipients.
+If this variable is non-nil, pose the question \"Reply to all
+recipients?\" before a wide reply to multiple recipients.  If the user
+answers yes, reply to all recipients as usual.  If the user answers
+no, only reply back to the author."
+  :version "21.3"
+  :group 'message-headers
+  :type 'boolean)
+
+(defcustom message-user-fqdn nil
+  "*Domain part of Messsage-Ids."
+  :group 'message-headers
+  :link '(custom-manual "(message)News Headers")
+  :type '(radio (const :format "%v  " nil)
+               (string :format "FQDN: %v\n" :size 0)))
+
+(defcustom message-use-idna (and (condition-case nil (require 'idna)
+                                  (file-error))
+                                (mm-coding-system-p 'utf-8)
+                                (executable-find idna-program)
+                                'ask)
+  "Whether to encode non-ASCII in domain names into ASCII according to IDNA."
+  :group 'message-headers
+  :type '(choice (const :tag "Ask" ask)
+                (const :tag "Never" nil)
+                (const :tag "Always" t)))
+
+;;; Internal variables.
+
+(defvar message-sending-message "Sending...")
+(defvar message-buffer-list nil)
+(defvar message-this-is-news nil)
+(defvar message-this-is-mail nil)
+(defvar message-draft-article nil)
+(defvar message-mime-part nil)
+(defvar message-posting-charset nil)
+(defvar message-inserted-headers nil)
+
+;; Byte-compiler warning
+(eval-when-compile
+  (defvar gnus-active-hashtb)
+  (defvar gnus-read-active-file))
+
+;;; Regexp matching the delimiter of messages in UNIX mail format
+;;; (UNIX From lines), minus the initial ^.  It should be a copy
+;;; of rmail.el's rmail-unix-mail-delimiter.
+(defvar message-unix-mail-delimiter
+  (let ((time-zone-regexp
+        (concat "\\([A-Z]?[A-Z]?[A-Z][A-Z]\\( DST\\)?"
+                "\\|[-+]?[0-9][0-9][0-9][0-9]"
+                "\\|"
+                "\\) *")))
+    (concat
+     "From "
+
+     ;; Many things can happen to an RFC 822 mailbox before it is put into
+     ;; a `From' line.  The leading phrase can be stripped, e.g.
+     ;; `Joe <@w.x:joe@y.z>' -> `<@w.x:joe@y.z>'.  The <> can be stripped, e.g.
+     ;; `<@x.y:joe@y.z>' -> `@x.y:joe@y.z'.  Everything starting with a CRLF
+     ;; can be removed, e.g.
+     ;;                From: joe@y.z (Joe      K
+     ;;                        User)
+     ;; can yield `From joe@y.z (Joe   K Fri Mar 22 08:11:15 1996', and
+     ;;                From: Joe User
+     ;;                        <joe@y.z>
+     ;; can yield `From Joe User Fri Mar 22 08:11:15 1996'.
+     ;; The mailbox can be removed or be replaced by white space, e.g.
+     ;;                From: "Joe User"{space}{tab}
+     ;;                        <joe@y.z>
+     ;; can yield `From {space}{tab} Fri Mar 22 08:11:15 1996',
+     ;; where {space} and {tab} represent the Ascii space and tab characters.
+     ;; We want to match the results of any of these manglings.
+     ;; The following regexp rejects names whose first characters are
+     ;; obviously bogus, but after that anything goes.
+     "\\([^\0-\b\n-\r\^?].*\\)?"
+
+     ;; The time the message was sent.
+     "\\([^\0-\r \^?]+\\) +"           ; day of the week
+     "\\([^\0-\r \^?]+\\) +"           ; month
+     "\\([0-3]?[0-9]\\) +"             ; day of month
+     "\\([0-2][0-9]:[0-5][0-9]\\(:[0-6][0-9]\\)?\\) *" ; time of day
+
+     ;; Perhaps a time zone, specified by an abbreviation, or by a
+     ;; numeric offset.
+     time-zone-regexp
+
+     ;; The year.
+     " \\([0-9][0-9]+\\) *"
+
+     ;; On some systems the time zone can appear after the year, too.
+     time-zone-regexp
+
+     ;; Old uucp cruft.
+     "\\(remote from .*\\)?"
+
+     "\n"))
+  "Regexp matching the delimiter of messages in UNIX mail format.")
+
+(defvar message-unsent-separator
+  (concat "^ *---+ +Unsent message follows +---+ *$\\|"
+         "^ *---+ +Returned message +---+ *$\\|"
+         "^Start of returned message$\\|"
+         "^ *---+ +Original message +---+ *$\\|"
+         "^ *--+ +begin message +--+ *$\\|"
+         "^ *---+ +Original message follows +---+ *$\\|"
+         "^ *---+ +Undelivered message follows +---+ *$\\|"
+         "^|? *---+ +Message text follows: +---+ *|?$")
+  "A regexp that matches the separator before the text of a failed message.")
+
+(defvar message-header-format-alist
+  `((Newsgroups)
+    (To . message-fill-address)
+    (Cc . message-fill-address)
+    (Subject)
+    (In-Reply-To)
+    (Fcc)
+    (Bcc)
+    (Date)
+    (Organization)
+    (Distribution)
+    (Lines)
+    (Expires)
+    (Message-ID)
+    (References . message-shorten-references)
+    (User-Agent))
+  "Alist used for formatting headers.")
+
+(defvar        message-options nil
+  "Some saved answers when sending message.")
+
+(defvar message-send-mail-real-function nil
+  "Internal send mail function.")
+
+(defvar message-bogus-system-names "^localhost\\."
+  "The regexp of bogus system names.")
+
+(defcustom message-valid-fqdn-regexp
+  (concat "[a-z0-9][-.a-z0-9]+\\." ;; [hostname.subdomain.]domain.
+         ;; valid TLDs:
+         "\\([a-z][a-z]" ;; two letter country TDLs
+         "\\|biz\\|com\\|edu\\|gov\\|int\\|mil\\|net\\|org"
+         "\\|aero\\|coop\\|info\\|name\\|museum"
+         "\\|arpa\\|pro\\|uucp\\|bitnet\\|bofh" ;; old style?
+         "\\)")
+  "Regular expression that matches a valid FQDN."
+  ;; see also: gnus-button-valid-fqdn-regexp
+  :group 'message-headers
+  :type 'regexp)
+
+(eval-and-compile
+  (autoload 'message-setup-toolbar "messagexmas")
+  (autoload 'mh-new-draft-name "mh-comp")
+  (autoload 'mh-send-letter "mh-comp")
+  (autoload 'gnus-point-at-eol "gnus-util")
+  (autoload 'gnus-point-at-bol "gnus-util")
+  (autoload 'gnus-output-to-rmail "gnus-util")
+  (autoload 'gnus-output-to-mail "gnus-util")
+  (autoload 'nndraft-request-associate-buffer "nndraft")
+  (autoload 'nndraft-request-expire-articles "nndraft")
+  (autoload 'gnus-open-server "gnus-int")
+  (autoload 'gnus-request-post "gnus-int")
+  (autoload 'gnus-copy-article-buffer "gnus-msg")
+  (autoload 'gnus-alive-p "gnus-util")
+  (autoload 'gnus-server-string "gnus")
+  (autoload 'gnus-group-name-charset "gnus-group")
+  (autoload 'gnus-group-name-decode "gnus-group")
+  (autoload 'gnus-groups-from-server "gnus")
+  (autoload 'rmail-output "rmailout")
+  (autoload 'gnus-delay-article "gnus-delay")
+  (autoload 'gnus-make-local-hook "gnus-util")
+  (autoload 'mu-cite-original "mu-cite"))
+
+\f
+
+;;;
+;;; Utility functions.
+;;;
+(defun message-eval-parameter (parameter)
+  (condition-case ()
+      (if (symbolp parameter)
+         (if (functionp parameter)
+             (funcall parameter)
+           (eval parameter))
+       parameter)
+    (error nil)))
+
+(defsubst message-get-parameter (key &optional alist)
+  (unless alist
+    (setq alist message-parameter-alist))
+  (cdr (assq key alist)))
+
+(defmacro message-get-parameter-with-eval (key &optional alist)
+  `(message-eval-parameter (message-get-parameter ,key ,alist)))
+
+(defmacro message-y-or-n-p (question show &rest text)
+  "Ask QUESTION, displaying remaining args in a temporary buffer if SHOW."
+  `(message-talkative-question 'y-or-n-p ,question ,show ,@text))
+
+(defmacro message-delete-line (&optional n)
+  "Delete the current line (and the next N lines)."
+  `(delete-region (progn (beginning-of-line) (point))
+                 (progn (forward-line ,(or n 1)) (point))))
+
+(defun message-mark-active-p ()
+  "Non-nil means the mark and region are currently active in this buffer."
+  mark-active)
+
+(defun message-unquote-tokens (elems)
+  "Remove double quotes (\") from strings in list ELEMS."
+  (mapcar (lambda (item)
+           (while (string-match "^\\(.*\\)\"\\(.*\\)$" item)
+             (setq item (concat (match-string 1 item)
+                                (match-string 2 item))))
+           item)
+         elems))
+
+(defun message-tokenize-header (header &optional separator)
+  "Split HEADER into a list of header elements.
+SEPARATOR is a string of characters to be used as separators.  \",\"
+is used by default."
+  (if (not header)
+      nil
+    (let ((regexp (format "[%s]+" (or separator ",")))
+         (beg 1)
+         (first t)
+         quoted elems paren)
+      (with-temp-buffer
+       (set-buffer-multibyte t)
+       (insert header)
+       (goto-char (point-min))
+       (while (not (eobp))
+         (if first
+             (setq first nil)
+           (forward-char 1))
+         (cond ((and (> (point) beg)
+                     (or (eobp)
+                         (and (looking-at regexp)
+                              (not quoted)
+                              (not paren))))
+                (push (buffer-substring beg (point)) elems)
+                (setq beg (match-end 0)))
+               ((eq (char-after) ?\")
+                (setq quoted (not quoted)))
+               ((and (eq (char-after) ?\()
+                     (not quoted))
+                (setq paren t))
+               ((and (eq (char-after) ?\))
+                     (not quoted))
+                (setq paren nil))))
+       (nreverse elems)))))
+
+(defun message-mail-file-mbox-p (file)
+  "Say whether FILE looks like a Unix mbox file."
+  (when (and (file-exists-p file)
+            (file-readable-p file)
+            (file-regular-p file))
+    (with-temp-buffer
+      (nnheader-insert-file-contents file)
+      (goto-char (point-min))
+      (looking-at message-unix-mail-delimiter))))
+
+(defun message-fetch-field (header &optional not-all)
+  "The same as `mail-fetch-field', only remove all newlines.
+The buffer is expected to be narrowed to just the header of the message;
+see `message-narrow-to-headers-or-head'."
+  (let* ((inhibit-point-motion-hooks t)
+        (case-fold-search t)
+        (value (mail-fetch-field header nil (not not-all))))
+    (when value
+      (while (string-match "\n[\t ]+" value)
+       (setq value (replace-match " " t t value)))
+      (set-text-properties 0 (length value) nil value)
+      value)))
+
+(defun message-field-value (header &optional not-all)
+  "The same as `message-fetch-field', only narrow to the headers first."
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers-or-head)
+      (message-fetch-field header not-all))))
+
+(defun message-narrow-to-field ()
+  "Narrow the buffer to the header on the current line."
+  (beginning-of-line)
+  (narrow-to-region
+   (point)
+   (progn
+     (forward-line 1)
+     (if (re-search-forward "^[^ \n\t]" nil t)
+        (progn
+          (beginning-of-line)
+          (point))
+       (point-max))))
+  (goto-char (point-min)))
+
+(defun message-add-header (&rest headers)
+  "Add the HEADERS to the message header, skipping those already present."
+  (while headers
+    (let (hclean)
+      (unless (string-match "^\\([^:]+\\):[ \t]*[^ \t]" (car headers))
+       (error "Invalid header `%s'" (car headers)))
+      (setq hclean (match-string 1 (car headers)))
+      (save-restriction
+       (message-narrow-to-headers)
+       (unless (re-search-forward (concat "^" (regexp-quote hclean) ":") nil t)
+         (goto-char (point-max))
+         (if (string-match "\n$" (car headers))
+             (insert (car headers))
+           (insert (car headers) ?\n)))))
+    (setq headers (cdr headers))))
+
+(defmacro message-with-reply-buffer (&rest forms)
+  "Evaluate FORMS in the reply buffer, if it exists."
+  `(let ((buffer (message-eval-parameter message-reply-buffer)))
+     (when (and buffer
+               (buffer-name buffer))
+       (save-excursion
+        (set-buffer buffer)
+        ,@forms))))
+
+(put 'message-with-reply-buffer 'lisp-indent-function 0)
+(put 'message-with-reply-buffer 'edebug-form-spec '(body))
+
+(defun message-fetch-reply-field (header)
+  "Fetch field HEADER from the message we're replying to."
+  (message-with-reply-buffer
+    (save-restriction
+      (mail-narrow-to-head)
+      (message-fetch-field header))))
+
+(defun message-strip-list-identifiers (subject)
+  "Remove list identifiers in `gnus-list-identifiers' from string SUBJECT."
+  (require 'gnus-sum)                  ; for gnus-list-identifiers
+  (let ((regexp (if (stringp gnus-list-identifiers)
+                   gnus-list-identifiers
+                 (mapconcat 'identity gnus-list-identifiers " *\\|"))))
+    (if (string-match (concat "\\(\\(\\(Re: +\\)?\\(" regexp
+                             " *\\)\\)+\\(Re: +\\)?\\)") subject)
+       (concat (substring subject 0 (match-beginning 1))
+               (or (match-string 3 subject)
+                   (match-string 5 subject))
+               (substring subject
+                          (match-end 1)))
+      subject)))
+
+(defun message-strip-subject-re (subject)
+  "Remove \"Re:\" from subject lines in string SUBJECT."
+  (if (string-match message-subject-re-regexp subject)
+      (substring subject (match-end 0))
+    subject))
+
+;;; Start of functions adopted from `message-utils.el'.
+
+(defun message-strip-subject-trailing-was (subject)
+  "Remove trailing \"(Was: <old subject>)\" from SUBJECT lines.
+Leading \"Re: \" is not stripped by this function.  Use the function
+`message-strip-subject-re' for this."
+  (let* ((query message-subject-trailing-was-query)
+        (new) (found))
+    (setq found
+         (string-match
+          (if (eq query 'ask)
+              message-subject-trailing-was-ask-regexp
+            message-subject-trailing-was-regexp)
+          subject))
+    (if found
+       (setq new (substring subject 0 (match-beginning 0))))
+    (if (or (not found) (eq query nil))
+       subject
+      (if (eq query 'ask)
+         (if (message-y-or-n-p
+              "Strip `(was: <old subject>)' in subject? " t
+              (concat
+               "Strip `(was: <old subject>)' in subject "
+               "and use the new one instead?\n\n"
+               "Current subject is:   \""
+               subject "\"\n\n"
+               "New subject would be: \""
+               new "\"\n\n"
+               "See the variable `message-subject-trailing-was-query' "
+               "to get rid of this query."
+               ))
+             new subject)
+       new))))
+
+;;; Suggested by Jonas Steverud  @  www.dtek.chalmers.se/~d4jonas/
+
+;;;###autoload
+(defun message-change-subject (new-subject)
+  "Ask for NEW-SUBJECT header, append (was: <Old Subject>)."
+  ;; <URL:http://www.landfield.com/usefor/drafts/draft-ietf-usefor-useage--1.02.unpaged>
+  (interactive
+   (list
+    (read-from-minibuffer "New subject: ")))
+  (cond ((and (not (or (null new-subject) ; new subject not empty
+                      (zerop (string-width new-subject))
+                      (string-match "^[ \t]*$" new-subject))))
+        (save-excursion
+          (let ((old-subject
+                 (save-restriction
+                   (message-narrow-to-headers)
+                   (message-fetch-field "Subject"))))
+            (cond ((not old-subject)
+                   (error "No current subject"))
+                  ((not (string-match
+                         (concat "^[ \t]*"
+                                 (regexp-quote new-subject)
+                                 " \t]*$")
+                         old-subject))  ; yes, it really is a new subject
+                   ;; delete eventual Re: prefix
+                   (setq old-subject
+                         (message-strip-subject-re old-subject))
+                   (message-goto-subject)
+                   (message-delete-line)
+                   (insert (concat "Subject: "
+                                   new-subject
+                                   " (was: "
+                                   old-subject ")\n")))))))))
+
+;;;###autoload
+(defun message-mark-inserted-region (beg end)
+  "Mark some region in the current article with enclosing tags.
+See `message-mark-insert-begin' and `message-mark-insert-end'."
+  (interactive "r")
+  (save-excursion
+    ;; add to the end of the region first, otherwise end would be invalid
+    (goto-char end)
+    (insert message-mark-insert-end)
+    (goto-char beg)
+    (insert message-mark-insert-begin)))
+
+;;;###autoload
+(defun message-mark-insert-file (file)
+  "Insert FILE at point, marking it with enclosing tags.
+See `message-mark-insert-begin' and `message-mark-insert-end'."
+  (interactive "fFile to insert: ")
+    ;; reverse insertion to get correct result.
+  (let ((p (point)))
+    (insert message-mark-insert-end)
+    (goto-char p)
+    (insert-file-contents file)
+    (goto-char p)
+    (insert message-mark-insert-begin)))
+
+;;;###autoload
+(defun message-add-archive-header ()
+  "Insert \"X-No-Archive: Yes\" in the header and a note in the body.
+The note can be customized using `message-archive-note'.  When called with a
+prefix argument, ask for a text to insert.  If you don't want the note in the
+body, set  `message-archive-note' to nil."
+  (interactive)
+  (if current-prefix-arg
+      (setq message-archive-note
+           (read-from-minibuffer "Reason for No-Archive: "
+                                 (cons message-archive-note 0))))
+    (save-excursion
+      (if (message-goto-signature)
+         (re-search-backward message-signature-separator))
+      (when message-archive-note
+       (insert message-archive-note)
+       (newline))
+      (message-add-header message-archive-header)
+      (message-sort-headers)))
+
+;;;###autoload
+(defun message-cross-post-followup-to-header (target-group)
+  "Mangles FollowUp-To and Newsgroups header to point to TARGET-GROUP.
+With prefix-argument just set Follow-Up, don't cross-post."
+  (interactive
+   (list ; Completion based on Gnus
+    (completing-read "Followup To: "
+                    (if (boundp 'gnus-newsrc-alist)
+                        gnus-newsrc-alist)
+                    nil nil '("poster" . 0)
+                    (if (boundp 'gnus-group-history)
+                        'gnus-group-history))))
+  (message-remove-header "Follow[Uu]p-[Tt]o" t)
+  (message-goto-newsgroups)
+  (beginning-of-line)
+  ;; if we already did a crosspost before, kill old target
+  (if (and message-cross-post-old-target
+          (re-search-forward
+           (regexp-quote (concat "," message-cross-post-old-target))
+           nil t))
+      (replace-match ""))
+  ;; unless (followup is to poster or user explicitly asked not
+  ;; to cross-post, or target-group is already in Newsgroups)
+  ;; add target-group to Newsgroups line.
+  (cond ((and (or
+              ;; def: cross-post, req:no
+              (and message-cross-post-default (not current-prefix-arg))
+              ;; def: no-cross-post, req:yes
+              (and (not message-cross-post-default) current-prefix-arg))
+             (not (string-match "poster" target-group))
+             (not (string-match (regexp-quote target-group)
+                                (message-fetch-field "Newsgroups"))))
+        (end-of-line)
+        (insert (concat "," target-group))))
+  (end-of-line) ; ensure Followup: comes after Newsgroups:
+  ;; unless new followup would be identical to Newsgroups line
+  ;; make a new Followup-To line
+  (if (not (string-match (concat "^[ \t]*"
+                                target-group
+                                "[ \t]*$")
+                        (message-fetch-field "Newsgroups")))
+      (insert (concat "\nFollowup-To: " target-group)))
+  (setq message-cross-post-old-target target-group))
+
+;;;###autoload
+(defun message-cross-post-insert-note (target-group cross-post in-old
+                                                   old-groups)
+  "Insert a in message body note about a set Followup or Crosspost.
+If there have been previous notes, delete them.  TARGET-GROUP specifies the
+group to Followup-To.  When CROSS-POST is t, insert note about
+crossposting.  IN-OLD specifies whether TARGET-GROUP is a member of
+OLD-GROUPS.  OLD-GROUPS lists the old-groups the posting would have
+been made to before the user asked for a Crosspost."
+  ;; start scanning body for previous uses
+  (message-goto-signature)
+  (let ((head (re-search-backward
+              (concat "^" mail-header-separator)
+              nil t))) ; just search in body
+    (message-goto-signature)
+    (while (re-search-backward
+           (concat "^" (regexp-quote message-cross-post-note) ".*")
+           head t)
+      (message-delete-line))
+    (message-goto-signature)
+    (while (re-search-backward
+           (concat "^" (regexp-quote message-followup-to-note) ".*")
+           head t)
+      (message-delete-line))
+    ;; insert new note
+    (if (message-goto-signature)
+       (re-search-backward message-signature-separator))
+    (if (or in-old
+           (not cross-post)
+           (string-match "^[ \t]*poster[ \t]*$" target-group))
+       (insert (concat message-followup-to-note target-group "\n"))
+      (insert (concat message-cross-post-note target-group "\n")))))
+
+;;;###autoload
+(defun message-cross-post-followup-to (target-group)
+  "Crossposts message and set Followup-To to TARGET-GROUP.
+With prefix-argument just set Follow-Up, don't cross-post."
+  (interactive
+   (list ; Completion based on Gnus
+    (completing-read "Followup To: "
+                    (if (boundp 'gnus-newsrc-alist)
+                        gnus-newsrc-alist)
+                    nil nil '("poster" . 0)
+                    (if (boundp 'gnus-group-history)
+                        'gnus-group-history))))
+  (cond ((not (or (null target-group) ; new subject not empty
+                 (zerop (string-width target-group))
+                 (string-match "^[ \t]*$" target-group)))
+        (save-excursion
+          (let* ((old-groups (message-fetch-field "Newsgroups"))
+                 (in-old (string-match
+                          (regexp-quote target-group)
+                          (or old-groups ""))))
+            ;; check whether target exactly matches old Newsgroups
+            (cond ((not old-groups)
+                   (error "No current newsgroup"))
+                  ((or (not in-old)
+                       (not (string-match
+                             (concat "^[ \t]*"
+                                     (regexp-quote target-group)
+                                     "[ \t]*$")
+                             old-groups)))
+                   ;; yes, Newsgroups line must change
+                   (message-cross-post-followup-to-header target-group)
+                   ;; insert note whether we do cross-post or followup-to
+                   (funcall message-cross-post-note-function
+                            target-group
+                            (if (or (and message-cross-post-default
+                                         (not current-prefix-arg))
+                                    (and (not message-cross-post-default)
+                                         current-prefix-arg)) t)
+                            in-old old-groups))))))))
+
+;;; Reduce To: to Cc: or Bcc: header
+
+;;;###autoload
+(defun message-reduce-to-to-cc ()
+ "Replace contents of To: header with contents of Cc: or Bcc: header."
+ (interactive)
+ (let ((cc-content
+       (save-restriction (message-narrow-to-headers)
+                         (message-fetch-field "cc")))
+       (bcc nil))
+   (if (and (not cc-content)
+           (setq cc-content
+                 (save-restriction
+                   (message-narrow-to-headers)
+                   (message-fetch-field "bcc"))))
+       (setq bcc t))
+   (cond (cc-content
+         (save-excursion
+           (message-goto-to)
+           (message-delete-line)
+           (insert (concat "To: " cc-content "\n"))
+           (save-restriction
+             (message-narrow-to-headers)
+             (message-remove-header (if bcc
+                                        "bcc"
+                                      "cc"))))))))
+
+;;; End of functions adopted from `message-utils.el'.
+
+(defun message-remove-header (header &optional is-regexp first reverse)
+  "Remove HEADER in the narrowed buffer.
+If IS-REGEXP, HEADER is a regular expression.
+If FIRST, only remove the first instance of the header.
+Return the number of headers removed."
+  (goto-char (point-min))
+  (let ((regexp (if is-regexp header (concat "^" (regexp-quote header) ":")))
+       (number 0)
+       (case-fold-search t)
+       last)
+    (while (and (not (eobp))
+               (not last))
+      (if (if reverse
+             (not (looking-at regexp))
+           (looking-at regexp))
+         (progn
+           (incf number)
+           (when first
+             (setq last t))
+           (delete-region
+            (point)
+            ;; There might be a continuation header, so we have to search
+            ;; until we find a new non-continuation line.
+            (progn
+              (forward-line 1)
+              (if (re-search-forward "^[^ \t]" nil t)
+                  (goto-char (match-beginning 0))
+                (point-max)))))
+       (forward-line 1)
+       (if (re-search-forward "^[^ \t]" nil t)
+           (goto-char (match-beginning 0))
+         (goto-char (point-max)))))
+    number))
+
+(defun message-remove-first-header (header)
+  "Remove the first instance of HEADER if there is more than one."
+  (let ((count 0)
+       (regexp (concat "^" (regexp-quote header) ":")))
+    (save-excursion
+      (goto-char (point-min))
+      (while (re-search-forward regexp nil t)
+       (incf count)))
+    (while (> count 1)
+      (message-remove-header header nil t)
+      (decf count))))
+
+(defun message-narrow-to-headers ()
+  "Narrow the buffer to the head of the message."
+  (widen)
+  (narrow-to-region
+   (goto-char (point-min))
+   (if (re-search-forward
+       (concat "^" (regexp-quote mail-header-separator) "\n") nil t)
+       (match-beginning 0)
+     (point-max)))
+  (goto-char (point-min)))
+
+(defun message-narrow-to-head-1 ()
+  "Like `message-narrow-to-head'.  Don't widen."
+  (narrow-to-region
+   (goto-char (point-min))
+   (if (search-forward "\n\n" nil 1)
+       (1- (point))
+     (point-max)))
+  (goto-char (point-min)))
+
+(defun message-narrow-to-head ()
+  "Narrow the buffer to the head of the message.
+Point is left at the beginning of the narrowed-to region."
+  (widen)
+  (message-narrow-to-head-1))
+
+(defun message-narrow-to-headers-or-head ()
+  "Narrow the buffer to the head of the message."
+  (widen)
+  (narrow-to-region
+   (goto-char (point-min))
+   (cond
+    ((re-search-forward
+      (concat "^" (regexp-quote mail-header-separator) "\n") nil t)
+     (match-beginning 0))
+    ((search-forward "\n\n" nil t)
+     (1- (point)))
+    (t
+     (point-max))))
+  (goto-char (point-min)))
+
+(defun message-news-p ()
+  "Say whether the current buffer contains a news message."
+  (and (not message-this-is-mail)
+       (or message-this-is-news
+          (save-excursion
+            (save-restriction
+              (message-narrow-to-headers)
+              (and (message-fetch-field "newsgroups")
+                   (not (message-fetch-field "posted-to"))))))))
+
+(defun message-mail-p ()
+  "Say whether the current buffer contains a mail message."
+  (and (not message-this-is-news)
+       (or message-this-is-mail
+          (save-excursion
+            (save-restriction
+              (message-narrow-to-headers)
+              (or (message-fetch-field "to")
+                  (message-fetch-field "cc")
+                  (message-fetch-field "bcc")))))))
+
+(defun message-subscribed-p ()
+  "Say whether we need to insert a MFT header."
+  (or message-subscribed-regexps
+      message-subscribed-addresses
+      message-subscribed-address-file
+      message-subscribed-address-functions))
+
+(defun message-next-header ()
+  "Go to the beginning of the next header."
+  (beginning-of-line)
+  (or (eobp) (forward-char 1))
+  (not (if (re-search-forward "^[^ \t]" nil t)
+          (beginning-of-line)
+        (goto-char (point-max)))))
+
+(defun message-sort-headers-1 ()
+  "Sort the buffer as headers using `message-rank' text props."
+  (goto-char (point-min))
+  (require 'sort)
+  (sort-subr
+   nil 'message-next-header
+   (lambda ()
+     (message-next-header)
+     (unless (bobp)
+       (forward-char -1)))
+   (lambda ()
+     (or (get-text-property (point) 'message-rank)
+        10000))))
+
+(defun message-sort-headers ()
+  "Sort the headers of the current message according to `message-header-format-alist'."
+  (interactive)
+  (save-excursion
+    (save-restriction
+      (let ((max (1+ (length message-header-format-alist)))
+           rank)
+       (message-narrow-to-headers)
+       (while (re-search-forward "^[^ \n]+:" nil t)
+         (put-text-property
+          (match-beginning 0) (1+ (match-beginning 0))
+          'message-rank
+          (if (setq rank (length (memq (assq (intern (buffer-substring
+                                                      (match-beginning 0)
+                                                      (1- (match-end 0))))
+                                             message-header-format-alist)
+                                       message-header-format-alist)))
+              (- max rank)
+            (1+ max)))))
+      (message-sort-headers-1))))
+
+\f
+
+;;;
+;;; Message mode
+;;;
+
+;;; Set up keymap.
+
+(defvar message-mode-map nil)
+
+(unless message-mode-map
+  (setq message-mode-map (make-keymap))
+  (set-keymap-parent message-mode-map text-mode-map)
+  (define-key message-mode-map "\C-c?" 'describe-mode)
+
+  (define-key message-mode-map "\C-c\C-f\C-t" 'message-goto-to)
+  (define-key message-mode-map "\C-c\C-f\C-o" 'message-goto-from)
+  (define-key message-mode-map "\C-c\C-f\C-b" 'message-goto-bcc)
+  (define-key message-mode-map "\C-c\C-f\C-w" 'message-goto-fcc)
+  (define-key message-mode-map "\C-c\C-f\C-c" 'message-goto-cc)
+  (define-key message-mode-map "\C-c\C-f\C-s" 'message-goto-subject)
+  ;; (define-key message-mode-map "\C-c\C-f\C-r" 'message-goto-reply-to)
+  (define-key message-mode-map "\C-c\C-f\C-r" 'message-goto-mail-reply-to)
+  (define-key message-mode-map "\C-c\C-f\C-m" 'message-goto-mail-followup-to)
+  (define-key message-mode-map "\C-c\C-f\C-n" 'message-goto-newsgroups)
+  (define-key message-mode-map "\C-c\C-f\C-d" 'message-goto-distribution)
+  (define-key message-mode-map "\C-c\C-f\C-f" 'message-goto-followup-to)
+  (define-key message-mode-map "\C-c\C-f\C-m" 'message-goto-mail-followup-to)
+  (define-key message-mode-map "\C-c\C-f\C-k" 'message-goto-keywords)
+  (define-key message-mode-map "\C-c\C-f\C-u" 'message-goto-summary)
+  (define-key message-mode-map "\C-c\C-f\C-i"
+    'message-insert-or-toggle-importance)
+  (define-key message-mode-map "\C-c\C-f\C-a"
+    'message-generate-unsubscribed-mail-followup-to)
+
+  ;; modify headers (and insert notes in body)
+  (define-key message-mode-map "\C-c\C-fs"    'message-change-subject)
+  ;;
+  (define-key message-mode-map "\C-c\C-fx"    'message-cross-post-followup-to)
+  ;; prefix+message-cross-post-followup-to = same w/o cross-post
+  (define-key message-mode-map "\C-c\C-ft"    'message-reduce-to-to-cc)
+  (define-key message-mode-map "\C-c\C-fa"    'message-add-archive-header)
+  ;; mark inserted text
+  (define-key message-mode-map "\C-c\M-m" 'message-mark-inserted-region)
+  (define-key message-mode-map "\C-c\M-f" 'message-mark-insert-file)
+
+  (define-key message-mode-map "\C-c\C-b" 'message-goto-body)
+  (define-key message-mode-map "\C-c\C-i" 'message-goto-signature)
+  (define-key message-mode-map "\C-c\C-fc" 'message-goto-mail-copies-to)
+
+  (define-key message-mode-map "\C-c\C-t" 'message-insert-to)
+  (define-key message-mode-map "\C-c\C-fw" 'message-insert-wide-reply)
+  (define-key message-mode-map "\C-c\C-n" 'message-insert-newsgroups)
+  (define-key message-mode-map "\C-c\C-l" 'message-to-list-only)
+
+  (define-key message-mode-map "\C-c\C-u" 'message-insert-or-toggle-importance)
+  (define-key message-mode-map "\C-c\M-n"
+    'message-insert-disposition-notification-to)
+
+  (define-key message-mode-map "\C-c\C-y" 'message-yank-original)
+  (define-key message-mode-map "\C-c\M-\C-y" 'message-yank-buffer)
+  (define-key message-mode-map "\C-c\C-q" 'message-fill-yanked-message)
+  (define-key message-mode-map "\C-c\C-w" 'message-insert-signature)
+  (define-key message-mode-map "\C-c\M-h" 'message-insert-headers)
+  (define-key message-mode-map "\C-c\C-r" 'message-caesar-buffer-body)
+  (define-key message-mode-map "\C-c\C-o" 'message-sort-headers)
+  (define-key message-mode-map "\C-c\M-r" 'message-rename-buffer)
+
+  (define-key message-mode-map "\C-c\C-c" 'message-send-and-exit)
+  (define-key message-mode-map "\C-c\C-s" 'message-send)
+  (define-key message-mode-map "\C-c\C-k" 'message-kill-buffer)
+  (define-key message-mode-map "\C-c\C-d" 'message-dont-send)
+  (define-key message-mode-map "\C-c\n" 'gnus-delay-article)
+
+  (define-key message-mode-map "\C-c\C-e" 'message-elide-region)
+  (define-key message-mode-map "\C-c\C-v" 'message-delete-not-region)
+  (define-key message-mode-map "\C-c\C-z" 'message-kill-to-signature)
+  (define-key message-mode-map "\M-\r" 'message-newline-and-reformat)
+  ;;(define-key message-mode-map "\M-q" 'message-fill-paragraph)
+  (define-key message-mode-map [remap split-line]  'message-split-line)
+
+  (define-key message-mode-map "\C-a" 'message-beginning-of-line)
+  (define-key message-mode-map "\t" 'message-tab)
+  (define-key message-mode-map "\M-;" 'comment-region)
+
+  (define-key message-mode-map "\C-xk" 'message-mimic-kill-buffer))
+
+(easy-menu-define
+ message-mode-menu message-mode-map "Message Menu."
+ `("Message"
+   ["Yank Original" message-yank-original t]
+   ["Fill Yanked Message" message-fill-yanked-message t]
+   ["Insert Signature" message-insert-signature t]
+   ["Caesar (rot13) Message" message-caesar-buffer-body t]
+   ["Caesar (rot13) Region" message-caesar-region (message-mark-active-p)]
+   ["Elide Region" message-elide-region
+    :active (message-mark-active-p)
+    ,@(if (featurep 'xemacs) nil
+       '(:help "Replace text in region with an ellipsis"))]
+   ["Delete Outside Region" message-delete-not-region
+    :active (message-mark-active-p)
+    ,@(if (featurep 'xemacs) nil
+       '(:help "Delete all quoted text outside region"))]
+   ["Kill To Signature" message-kill-to-signature t]
+   ["Newline and Reformat" message-newline-and-reformat t]
+   ["Rename buffer" message-rename-buffer t]
+   ["Spellcheck" ispell-message
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Spellcheck this message"))]
+   ["Attach file as MIME" mime-edit-insert-file
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Attach a file at point"))]
+   "----"
+   ["Insert Region Marked" message-mark-inserted-region
+    :active (message-mark-active-p)
+    ,@(if (featurep 'xemacs) nil
+       '(:help "Mark region with enclosing tags"))]
+   ["Insert File Marked..." message-mark-insert-file
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Insert file at point marked with enclosing tags"))]
+   "----"
+   ["Send Message" message-send-and-exit
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Send this message"))]
+   ["Postpone Message" message-dont-send
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "File this draft message and exit"))]
+   ["Send at Specific Time..." gnus-delay-article
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Ask, then arrange to send message at that time"))]
+   ["Kill Message" message-kill-buffer
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Delete this message without sending"))]))
+
+(easy-menu-define
+ message-mode-field-menu message-mode-map ""
+ `("Field"
+   ["To" message-goto-to t]
+   ["From" message-goto-from t]
+   ["Subject" message-goto-subject t]
+   ["Change subject..." message-change-subject t]
+   ["Cc" message-goto-cc t]
+   ["Bcc" message-goto-bcc t]
+   ["Fcc" message-goto-fcc t]
+   ["Reply-To" message-goto-reply-to t]
+   ["Flag As Important" message-insert-importance-high
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Mark this message as important"))]
+   ["Flag As Unimportant" message-insert-importance-low
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Mark this message as unimportant"))]
+   ["Request Receipt"
+    message-insert-disposition-notification-to
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Request a receipt notification"))]
+   "----"
+   ;; (typical) news stuff
+   ["Summary" message-goto-summary t]
+   ["Keywords" message-goto-keywords t]
+   ["Newsgroups" message-goto-newsgroups t]
+   ["Fetch Newsgroups" message-insert-newsgroups t]
+   ["Followup-To" message-goto-followup-to t]
+   ;; ["Followup-To (with note in body)" message-cross-post-followup-to t]
+   ["Crosspost / Followup-To..." message-cross-post-followup-to t]
+   ["Distribution" message-goto-distribution t]
+   ["X-No-Archive:" message-add-archive-header t ]
+   "----"
+   ;; (typical) mailing-lists stuff
+   ["Fetch To" message-insert-to
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Insert a To header that points to the author."))]
+   ["Fetch To and Cc" message-insert-wide-reply
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help
+         "Insert To and Cc headers as if you were doing a wide reply."))]
+   "----"
+   ["Send to list only" message-to-list-only t]
+   ["Mail-Followup-To" message-goto-mail-followup-to t]
+   ["Mail-Reply-To" message-goto-mail-reply-to t]
+   ["Mail-Copies-To" message-goto-mail-copies-to t]
+   ["Unsubscribed list post" message-generate-unsubscribed-mail-followup-to
+    ,@(if (featurep 'xemacs) '(t)
+       '(:help "Insert a reasonable `Mail-Followup-To:' header."))]
+   ["Reduce To: to Cc:" message-reduce-to-to-cc t]
+   "----"
+   ["Sort Headers" message-sort-headers t]
+   ["Encode non-ASCII domain names" message-idna-to-ascii-rhs t]
+   ["Goto Body" message-goto-body t]
+   ["Goto Signature" message-goto-signature t]))
+
+(defvar message-tool-bar-map nil)
+
+(eval-when-compile
+  (defvar facemenu-add-face-function)
+  (defvar facemenu-remove-face-function))
+
+;;; Forbidden properties
+;;
+;; We use `after-change-functions' to keep special text properties
+;; that interfer with the normal function of message mode out of the
+;; buffer.
+
+(defcustom message-strip-special-text-properties t
+  "Strip special properties from the message buffer.
+
+Emacs has a number of special text properties which can break message
+composing in various ways.  If this option is set, message will strip
+these properties from the message composition buffer.  However, some
+packages requires these properties to be present in order to work.
+If you use one of these packages, turn this option off, and hope the
+message composition doesn't break too bad."
+  :group 'message-various
+  :type 'boolean)
+
+(defconst message-forbidden-properties
+  ;; No reason this should be clutter up customize.  We make it a
+  ;; property list (rather than a list of property symbols), to be
+  ;; directly useful for `remove-text-properties'.
+  '(field nil read-only nil invisible nil intangible nil
+         mouse-face nil modification-hooks nil insert-in-front-hooks nil
+         insert-behind-hooks nil point-entered nil point-left nil)
+  ;; Other special properties:
+  ;; category, face, display: probably doesn't do any harm.
+  ;; fontified: is used by font-lock.
+  ;; syntax-table, local-map: I dunno.
+  ;; We need to add XEmacs names to the list.
+  "Property list of with properties.forbidden in message buffers.
+The values of the properties are ignored, only the property names are used.")
+
+(defun message-tamago-not-in-use-p (pos)
+  "Return t when tamago version 4 is not in use at the cursor position.
+Tamago version 4 is a popular input method for writing Japanese text.
+It uses the properties `intangible', `invisible', `modification-hooks'
+and `read-only' when translating ascii or kana text to kanji text.
+These properties are essential to work, so we should never strip them."
+  (not (and (boundp 'egg-modefull-mode)
+           (symbol-value 'egg-modefull-mode)
+           (or (memq (get-text-property pos 'intangible)
+                     '(its-part-1 its-part-2))
+               (get-text-property pos 'egg-end)
+               (get-text-property pos 'egg-lang)
+               (get-text-property pos 'egg-start)))))
+
+(defun message-strip-forbidden-properties (begin end &optional old-length)
+  "Strip forbidden properties between BEGIN and END, ignoring the third arg.
+This function is intended to be called from `after-change-functions'.
+See also `message-forbidden-properties'."
+  (when (and message-strip-special-text-properties
+            (message-tamago-not-in-use-p begin)
+            ;; Check whether the invisible MIME part is not inserted.
+            (not (text-property-any begin end 'mime-edit-invisible t)))
+    (while (not (= begin end))
+      (when (not (get-text-property begin 'message-hidden))
+       (remove-text-properties begin (1+ begin)
+                               message-forbidden-properties))
+      (incf begin))))
+
+;;;###autoload
+(define-derived-mode message-mode text-mode "Message"
+  "Major mode for editing mail and news to be sent.
+Like Text Mode but with these additional commands:\\<message-mode-map>
+C-c C-s  `message-send' (send the message)  C-c C-c  `message-send-and-exit'
+C-c C-d  Postpone sending the message       C-c C-k  Kill the message
+C-c C-f  move to a header field (and create it if there isn't):
+        C-c C-f C-t  move to To        C-c C-f C-s  move to Subject
+        C-c C-f C-c  move to Cc        C-c C-f C-b  move to Bcc
+        C-c C-f C-w  move to Fcc       C-c C-f C-r  move to Reply-To
+        C-c C-f C-u  move to Summary   C-c C-f C-n  move to Newsgroups
+        C-c C-f C-k  move to Keywords  C-c C-f C-d  move to Distribution
+         C-c C-f C-o  move to From (\"Originator\")
+        C-c C-f C-f  move to Followup-To
+        C-c C-f C-m  move to Mail-Followup-To
+        C-c C-f c    move to Mail-Copies-To
+        C-c C-f C-i  cycle through Importance values
+        C-c C-f s    change subject and append \"(was: <Old Subject>)\"
+        C-c C-f x    crossposting with FollowUp-To header and note in body
+        C-c C-f t    replace To: header with contents of Cc: or Bcc:
+        C-c C-f a    Insert X-No-Archive: header and a note in the body
+C-c C-t  `message-insert-to' (add a To header to a news followup)
+C-c C-l  `message-to-list-only' (removes all but list address in to/cc)
+C-c C-n  `message-insert-newsgroups' (add a Newsgroup header to a news reply)
+C-c C-b  `message-goto-body' (move to beginning of message text).
+C-c C-i  `message-goto-signature' (move to the beginning of the signature).
+C-c C-w  `message-insert-signature' (insert `message-signature-file' file).
+C-c C-y  `message-yank-original' (insert current message, if any).
+C-c C-q  `message-fill-yanked-message' (fill what was yanked).
+C-c C-e  `message-elide-region' (elide the text between point and mark).
+C-c C-v  `message-delete-not-region' (remove the text outside the region).
+C-c C-z  `message-kill-to-signature' (kill the text up to the signature).
+C-c C-r  `message-caesar-buffer-body' (rot13 the message body).
+C-c C-u  `message-insert-or-toggle-importance'  (insert or cycle importance).
+C-c M-n  `message-insert-disposition-notification-to'  (request receipt).
+C-c M-m  `message-mark-inserted-region' (mark region with enclosing tags).
+C-c M-f  `message-mark-insert-file' (insert file marked with enclosing tags).
+M-RET    `message-newline-and-reformat' (break the line and reformat)."
+  (setq local-abbrev-table text-mode-abbrev-table)
+  (set (make-local-variable 'message-reply-buffer) nil)
+  (set (make-local-variable 'message-inserted-headers) nil)
+  (set (make-local-variable 'message-send-actions) nil)
+  (set (make-local-variable 'message-exit-actions) nil)
+  (set (make-local-variable 'message-kill-actions) nil)
+  (set (make-local-variable 'message-postpone-actions) nil)
+  (set (make-local-variable 'message-draft-article) nil)
+  (setq buffer-offer-save t)
+  (set (make-local-variable 'facemenu-add-face-function)
+       (lambda (face end)
+        (let ((face-fun (cdr (assq face message-face-alist))))
+          (if face-fun
+              (funcall face-fun (point) end)
+            (error "Face %s not configured for %s mode" face mode-name)))
+        ""))
+  (set (make-local-variable 'facemenu-remove-face-function) t)
+  (set (make-local-variable 'message-reply-headers) nil)
+  (make-local-variable 'message-user-agent)
+  (make-local-variable 'message-post-method)
+  (set (make-local-variable 'message-sent-message-via) nil)
+  (set (make-local-variable 'message-checksum) nil)
+  (make-local-variable 'message-parameter-alist)
+  (setq message-parameter-alist
+       (copy-sequence message-startup-parameter-alist))
+  (message-setup-fill-variables)
+  (set
+   (make-local-variable 'paragraph-separate)
+   (format "\\(%s\\)\\|\\(%s\\)"
+          paragraph-separate
+          "<#!*/?\\(multipart\\|part\\|external\\|mml\\|secure\\)"))
+  ;; Allow using comment commands to add/remove quoting.
+  (set (make-local-variable 'comment-start) message-yank-prefix)
+  (if (featurep 'xemacs)
+      (message-setup-toolbar)
+    (set (make-local-variable 'font-lock-defaults)
+        '(message-font-lock-keywords t))
+    (if (boundp 'tool-bar-map)
+       (set (make-local-variable 'tool-bar-map) (message-tool-bar-map))))
+  (easy-menu-add message-mode-menu message-mode-map)
+  (easy-menu-add message-mode-field-menu message-mode-map)
+  (gnus-make-local-hook 'after-change-functions)
+  ;; Mmmm... Forbidden properties...
+  (add-hook 'after-change-functions 'message-strip-forbidden-properties
+           nil 'local)
+  ;; Allow mail alias things.
+  (when (eq message-mail-alias-type 'abbrev)
+    (if (fboundp 'mail-abbrevs-setup)
+       (mail-abbrevs-setup)
+      (if (fboundp 'mail-aliases-setup)        ; warning avoidance
+         (mail-aliases-setup))))
+  (unless buffer-file-name
+    (message-set-auto-save-file-name))
+  (set (make-local-variable 'indent-tabs-mode) nil)) ;No tabs for indentation.
+
+(defun message-setup-fill-variables ()
+  "Setup message fill variables."
+  (set (make-local-variable 'fill-paragraph-function)
+       'message-fill-paragraph)
+  (make-local-variable 'paragraph-separate)
+  (make-local-variable 'paragraph-start)
+  (make-local-variable 'adaptive-fill-regexp)
+  (unless (boundp 'adaptive-fill-first-line-regexp)
+    (setq adaptive-fill-first-line-regexp nil))
+  (make-local-variable 'adaptive-fill-first-line-regexp)
+  (let ((quote-prefix-regexp
+        ;; User should change message-cite-prefix-regexp if
+        ;; message-yank-prefix is set to an abnormal value.
+        (concat "\\(" message-cite-prefix-regexp "\\)[ \t]*")))
+    (setq paragraph-start
+         (concat
+          (regexp-quote mail-header-separator) "$\\|"
+          "[ \t]*$\\|"                 ; blank lines
+          "-- $\\|"                    ; signature delimiter
+          "---+$\\|"                   ; delimiters for forwarded messages
+          page-delimiter "$\\|"        ; spoiler warnings
+          ".*wrote:$\\|"               ; attribution lines
+          quote-prefix-regexp "$"))    ; empty lines in quoted text
+    (setq paragraph-separate paragraph-start)
+    (setq adaptive-fill-regexp
+         (concat quote-prefix-regexp "\\|" adaptive-fill-regexp))
+    (setq adaptive-fill-first-line-regexp
+         (concat quote-prefix-regexp "\\|"
+                 adaptive-fill-first-line-regexp)))
+  (make-local-variable 'auto-fill-inhibit-regexp)
+  ;;(setq auto-fill-inhibit-regexp "^[A-Z][^: \n\t]+:")
+  (setq auto-fill-inhibit-regexp nil)
+  (make-local-variable 'normal-auto-fill-function)
+  (setq normal-auto-fill-function 'message-do-auto-fill)
+  ;; KLUDGE: auto fill might already be turned on in `text-mode-hook'.
+  ;; In that case, ensure that it uses the right function.  The real
+  ;; solution would be not to use `define-derived-mode', and run
+  ;; `text-mode-hook' ourself at the end of the mode.
+  ;; -- Per Abrahamsen <abraham@dina.kvl.dk> Date: 2001-10-19.
+  (when auto-fill-function
+    (setq auto-fill-function normal-auto-fill-function)))
+
+\f
+
+;;;
+;;; Message mode commands
+;;;
+
+;;; Movement commands
+
+(defun message-goto-to ()
+  "Move point to the To header."
+  (interactive)
+  (message-position-on-field "To"))
+
+(defun message-goto-from ()
+  "Move point to the From header."
+  (interactive)
+  (message-position-on-field "From"))
+
+(defun message-goto-subject ()
+  "Move point to the Subject header."
+  (interactive)
+  (message-position-on-field "Subject"))
+
+(defun message-goto-cc ()
+  "Move point to the Cc header."
+  (interactive)
+  (message-position-on-field "Cc" "To"))
+
+(defun message-goto-bcc ()
+  "Move point to the Bcc  header."
+  (interactive)
+  (message-position-on-field "Bcc" "Cc" "To"))
+
+(defun message-goto-fcc ()
+  "Move point to the Fcc header."
+  (interactive)
+  (message-position-on-field "Fcc" "To" "Newsgroups"))
+
+(defun message-goto-reply-to ()
+  "Move point to the Reply-To header."
+  (interactive)
+  (message-position-on-field "Reply-To" "Subject"))
+
+(defun message-goto-mail-reply-to ()
+  "Move point to the Mail-Reply-To header."
+  (interactive)
+  (message-position-on-field "Mail-Reply-To" "Subject"))
+
+(defun message-goto-mail-copies-to ()
+  "Move point to the Mail-Copies-To header.  If the header is newly created,
+a string \"never\" is inserted in default."
+  (interactive)
+  (unless (message-position-on-field "Mail-Copies-To" "Subject")
+    (insert "never")
+    (backward-char 5)))
+
+(defun message-goto-newsgroups ()
+  "Move point to the Newsgroups header."
+  (interactive)
+  (message-position-on-field "Newsgroups"))
+
+(defun message-goto-distribution ()
+  "Move point to the Distribution header."
+  (interactive)
+  (message-position-on-field "Distribution"))
+
+(defun message-goto-followup-to ()
+  "Move point to the Followup-To header."
+  (interactive)
+  (message-position-on-field "Followup-To" "Newsgroups"))
+
+(defun message-goto-mail-followup-to ()
+  "Move point to the Mail-Followup-To header.  If the header is newly created
+and To field contains only one address, the address is inserted in default."
+  (interactive)
+  (unless (message-position-on-field "Mail-Followup-To" "Subject")
+    (let ((start (point))
+         addresses)
+      (save-restriction
+       (message-narrow-to-headers)
+       (setq addresses (split-string (mail-strip-quoted-names
+                                      (or (std11-fetch-field "to") ""))
+                                     "[ \f\t\n\r\v,]+"))
+       (when (eq 1 (length addresses))
+         (goto-char start)
+         (insert (car addresses))
+         (goto-char start))))))
+
+(defun message-goto-keywords ()
+  "Move point to the Keywords header."
+  (interactive)
+  (message-position-on-field "Keywords" "Subject"))
+
+(defun message-goto-summary ()
+  "Move point to the Summary header."
+  (interactive)
+  (message-position-on-field "Summary" "Subject"))
+
+(defun message-goto-body (&optional interactivep)
+  "Move point to the beginning of the message body."
+  (interactive (list t))
+  (when (and interactivep
+            (looking-at "[ \t]*\n"))
+    (expand-abbrev))
+  (goto-char (point-min))
+  (or (search-forward (concat "\n" mail-header-separator "\n") nil t)
+      (search-forward-regexp "[^:]+:\\([^\n]\\|\n[ \t]\\)+\n\n" nil t)))
+
+(defun message-goto-eoh ()
+  "Move point to the end of the headers."
+  (interactive)
+  (message-goto-body)
+  (forward-line -1))
+
+(defun message-goto-signature ()
+  "Move point to the beginning of the message signature.
+If there is no signature in the article, go to the end and
+return nil."
+  (interactive)
+  (goto-char (point-min))
+  (if (re-search-forward message-signature-separator nil t)
+      (forward-line 1)
+    (goto-char (point-max))
+    nil))
+
+(defun message-generate-unsubscribed-mail-followup-to (&optional include-cc)
+  "Insert a reasonable MFT header in a post to an unsubscribed list.
+When making original posts to a mailing list you are not subscribed to,
+you have to type in a MFT header by hand.  The contents, usually, are
+the addresses of the list and your own address.  This function inserts
+such a header automatically.  It fetches the contents of the To: header
+in the current mail buffer, and appends the current `user-mail-address'.
+
+If the optional argument INCLUDE-CC is non-nil, the addresses in the
+Cc: header are also put into the MFT."
+
+  (interactive "P")
+  (let* (cc tos)
+    (save-restriction
+      (message-narrow-to-headers)
+      (message-remove-header "Mail-Followup-To")
+      (setq cc (and include-cc (message-fetch-field "Cc")))
+      (setq tos (if cc
+                   (concat (message-fetch-field "To") "," cc)
+                 (message-fetch-field "To"))))
+    (message-goto-mail-followup-to)
+    (insert (concat tos ", " user-mail-address))))
+
+\f
+
+(defun message-insert-to (&optional force)
+  "Insert a To header that points to the author of the article being replied to.
+If the original author requested not to be sent mail, don't insert unless the
+prefix FORCE is given."
+  (interactive "P")
+  (let* ((mct (message-fetch-reply-field "mail-copies-to"))
+         (dont (and mct (or (equal (downcase mct) "never")
+                           (equal (downcase mct) "nobody"))))
+         (to (or (message-fetch-reply-field "mail-reply-to")
+                 (message-fetch-reply-field "reply-to")
+                 (message-fetch-reply-field "from"))))
+    (when (and dont to)
+      (gnus-message
+       3
+       (if force
+          "Ignoring the user request not to have copies sent via mail"
+        "Complying with the user request not to have copies sent via mail")))
+    (when (and force (not to))
+      (error "No mail address in the article"))
+    (when (and to (or force (not dont)))
+      (message-carefully-insert-headers (list (cons 'To to))))))
+
+(defun message-insert-wide-reply ()
+  "Insert To and Cc headers as if you were doing a wide reply."
+  (interactive)
+  (let ((headers (message-with-reply-buffer
+                  (message-get-reply-headers t))))
+    (message-carefully-insert-headers headers)))
+
+(defun message-carefully-insert-headers (headers)
+  (dolist (header headers)
+    (let ((header-name (symbol-name (car header))))
+      (when (and (message-position-on-field header-name)
+                (mail-fetch-field header-name)
+                (not (string-match "\\` *\\'"
+                                   (mail-fetch-field header-name))))
+       (insert ", "))
+      (insert (cdr header)))))
+
+(defun message-widen-reply ()
+  "Widen the reply to include maximum recipients."
+  (interactive)
+  (let ((follow-to
+        (and message-reply-buffer
+             (buffer-name message-reply-buffer)
+             (save-excursion
+               (set-buffer message-reply-buffer)
+               (message-get-reply-headers t)))))
+    (save-excursion
+      (save-restriction
+       (message-narrow-to-headers)
+       (dolist (elem follow-to)
+         (message-remove-header (symbol-name (car elem)))
+         (goto-char (point-min))
+         (insert (symbol-name (car elem)) ": "
+                 (cdr elem) "\n"))))))
+
+(defun message-insert-newsgroups ()
+  "Insert the Newsgroups header from the article being replied to."
+  (interactive)
+  (when (and (message-position-on-field "Newsgroups")
+            (mail-fetch-field "newsgroups")
+            (not (string-match "\\` *\\'" (mail-fetch-field "newsgroups"))))
+    (insert ","))
+  (insert (or (message-fetch-reply-field "newsgroups") "")))
+
+\f
+
+;;; Various commands
+
+(defun message-delete-not-region (beg end)
+  "Delete everything in the body of the current message outside of the region."
+  (interactive "r")
+  (let (citeprefix)
+    (save-excursion
+      (goto-char beg)
+      ;; snarf citation prefix, if appropriate
+      (unless (eq (point) (progn (beginning-of-line) (point)))
+       (when (looking-at message-cite-prefix-regexp)
+         (setq citeprefix (match-string 0))))
+      (goto-char end)
+      (delete-region (point) (if (not (message-goto-signature))
+                                (point)
+                              (forward-line -2)
+                              (point)))
+      (insert "\n")
+      (goto-char beg)
+      (delete-region beg (progn (message-goto-body)
+                               (forward-line 2)
+                               (point)))
+      (when citeprefix
+       (insert citeprefix))))
+  (when (message-goto-signature)
+    (forward-line -2)))
+
+(defun message-kill-to-signature ()
+  "Deletes all text up to the signature."
+  (interactive)
+  (let ((point (point)))
+    (message-goto-signature)
+    (unless (eobp)
+      (end-of-line -1))
+    (kill-region point (point))
+    (unless (bolp)
+      (insert "\n"))))
+
+(defun message-newline-and-reformat (&optional arg not-break)
+  "Insert four newlines, and then reformat if inside quoted text.
+Prefix arg means justify as well."
+  (interactive (list (if current-prefix-arg 'full)))
+  (let (quoted point beg end leading-space bolp)
+    (setq point (point))
+    (beginning-of-line)
+    (setq beg (point))
+    (setq bolp (= beg point))
+    ;; Find first line of the paragraph.
+    (if not-break
+       (while (and (not (eobp))
+                   (not (looking-at message-cite-prefix-regexp))
+                   (looking-at paragraph-start))
+         (forward-line 1)))
+    ;; Find the prefix
+    (when (looking-at message-cite-prefix-regexp)
+      (setq quoted (match-string 0))
+      (goto-char (match-end 0))
+      (looking-at "[ \t]*")
+      (setq leading-space (match-string 0)))
+    (if (and quoted
+            (not not-break)
+            (not bolp)
+            (< (- point beg) (length quoted)))
+       ;; break inside the cite prefix.
+       (setq quoted nil
+             end nil))
+    (if quoted
+       (progn
+         (forward-line 1)
+         (while (and (not (eobp))
+                     (not (looking-at paragraph-separate))
+                     (looking-at message-cite-prefix-regexp)
+                     (equal quoted (match-string 0)))
+           (goto-char (match-end 0))
+           (looking-at "[ \t]*")
+           (if (> (length leading-space) (length (match-string 0)))
+               (setq leading-space (match-string 0)))
+           (forward-line 1))
+         (setq end (point))
+         (goto-char beg)
+         (while (and (if (bobp) nil (forward-line -1) t)
+                     (not (looking-at paragraph-start))
+                     (looking-at message-cite-prefix-regexp)
+                     (equal quoted (match-string 0)))
+           (setq beg (point))
+           (goto-char (match-end 0))
+           (looking-at "[ \t]*")
+           (if (> (length leading-space) (length (match-string 0)))
+               (setq leading-space (match-string 0)))))
+      (while (and (not (eobp))
+                 (not (looking-at paragraph-separate))
+                 (not (looking-at message-cite-prefix-regexp)))
+       (forward-line 1))
+      (setq end (point))
+      (goto-char beg)
+      (while (and (if (bobp) nil (forward-line -1) t)
+                 (not (looking-at paragraph-start))
+                 (not (looking-at message-cite-prefix-regexp)))
+       (setq beg (point))))
+    (goto-char point)
+    (save-restriction
+      (narrow-to-region beg end)
+      (if not-break
+         (setq point nil)
+       (if bolp
+           (newline)
+         (newline)
+         (newline))
+       (setq point (point))
+       ;; (newline 2) doesn't mark both newline's as hard, so call
+       ;; newline twice. -jas
+       (newline)
+       (newline)
+       (delete-region (point) (re-search-forward "[ \t]*"))
+       (when (and quoted (not bolp))
+         (insert quoted leading-space)))
+      (undo-boundary)
+      (if quoted
+         (let* ((adaptive-fill-regexp
+                 (regexp-quote (concat quoted leading-space)))
+                (adaptive-fill-first-line-regexp
+                 adaptive-fill-regexp ))
+           (fill-paragraph arg))
+       (fill-paragraph arg))
+      (if point (goto-char point)))))
+
+(defun message-fill-paragraph (&optional arg)
+  "Like `fill-paragraph'."
+  (interactive (list (if current-prefix-arg 'full)))
+  (if (if (boundp 'filladapt-mode) filladapt-mode)
+      nil
+    (message-newline-and-reformat arg t)
+    t))
+
+;; Is it better to use `mail-header-end'?
+(defun message-point-in-header-p ()
+  "Return t if point is in the header."
+  (save-excursion
+    (let ((p (point)))
+      (goto-char (point-min))
+      (not (re-search-forward
+           (concat "^" (regexp-quote mail-header-separator) "\n")
+           p t)))))
+
+(defun message-do-auto-fill ()
+  "Like `do-auto-fill', but don't fill in message header."
+  (unless (message-point-in-header-p)
+    (do-auto-fill)))
+
+(defun message-insert-signature (&optional force)
+  "Insert a signature.  See documentation for variable `message-signature'."
+  (interactive (list 0))
+  (let* ((signature
+         (cond
+          ((and (null message-signature)
+                (eq force 0))
+           (save-excursion
+             (goto-char (point-max))
+             (not (re-search-backward message-signature-separator nil t))))
+          ((and (null message-signature)
+                force)
+           t)
+          ((functionp message-signature)
+           (funcall message-signature))
+          ((listp message-signature)
+           (eval message-signature))
+          (t message-signature)))
+        (signature
+         (cond ((stringp signature)
+                signature)
+               ((and (eq t signature)
+                     message-signature-file
+                     (file-exists-p message-signature-file))
+                signature))))
+    (when signature
+      (goto-char (point-max))
+      ;; Insert the signature.
+      (unless (bolp)
+       (insert "\n"))
+      (when message-signature-insert-empty-line
+       (insert "\n"))
+      (insert "\n" message-signature-separator-for-insertion)
+      (unless (bolp)
+       (insert "\n"))
+      (if (eq signature t)
+         (insert-file-contents message-signature-file)
+       (insert signature))
+      (goto-char (point-max))
+      (or (bolp) (insert "\n")))))
+
+(defun message-insert-importance-high ()
+  "Insert header to mark message as important."
+  (interactive)
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers)
+      (message-remove-header "Importance"))
+    (message-goto-eoh)
+    (insert "Importance: high\n")))
+
+(defun message-insert-importance-low ()
+  "Insert header to mark message as unimportant."
+  (interactive)
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers)
+      (message-remove-header "Importance"))
+    (message-goto-eoh)
+    (insert "Importance: low\n")))
+
+(defun message-insert-or-toggle-importance ()
+  "Insert a \"Importance: high\" header, or cycle through the header values.
+The three allowed values according to RFC 1327 are `high', `normal'
+and `low'."
+  (interactive)
+  (save-excursion
+    (let ((valid '("high" "normal" "low"))
+         (new "high")
+         cur)
+      (save-restriction
+       (message-narrow-to-headers)
+       (when (setq cur (message-fetch-field "Importance"))
+         (message-remove-header "Importance")
+         (setq new (cond ((string= cur "high")
+                          "low")
+                         ((string= cur "low")
+                          "normal")
+                         (t
+                          "high")))))
+      (message-goto-eoh)
+      (insert (format "Importance: %s\n" new)))))
+
+(defun message-insert-disposition-notification-to ()
+  "Request a disposition notification (return receipt) to this message.
+Note that this should not be used in newsgroups."
+  (interactive)
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers)
+      (message-remove-header "Disposition-Notification-To"))
+    (message-goto-eoh)
+    (insert (format "Disposition-Notification-To: %s\n"
+                   (or (message-field-value "Reply-to")
+                       (message-field-value "From")
+                       (message-make-from))))))
+
+(defun message-elide-region (b e)
+  "Elide the text in the region.
+An ellipsis (from `message-elide-ellipsis') will be inserted where the
+text was killed."
+  (interactive "r")
+  (kill-region b e)
+  (insert message-elide-ellipsis))
+
+(defvar message-caesar-translation-table nil)
+
+(defun message-caesar-region (b e &optional n)
+  "Caesar rotate region B to E by N, default 13, for decrypting netnews."
+  (interactive
+   (list
+    (min (point) (or (mark t) (point)))
+    (max (point) (or (mark t) (point)))
+    (when current-prefix-arg
+      (prefix-numeric-value current-prefix-arg))))
+
+  (setq n (if (numberp n) (mod n 26) 13)) ;canonize N
+  (unless (or (zerop n)                        ; no action needed for a rot of 0
+             (= b e))                  ; no region to rotate
+    ;; We build the table, if necessary.
+    (when (or (not message-caesar-translation-table)
+             (/= (aref message-caesar-translation-table ?a) (+ ?a n)))
+      (setq message-caesar-translation-table
+           (message-make-caesar-translation-table n)))
+    (translate-region b e message-caesar-translation-table)))
+
+(defun message-make-caesar-translation-table (n)
+  "Create a rot table with offset N."
+  (let ((i -1)
+       (table (make-string 256 0)))
+    (while (< (incf i) 256)
+      (aset table i i))
+    (concat
+     (substring table 0 ?A)
+     (substring table (+ ?A n) (+ ?A n (- 26 n)))
+     (substring table ?A (+ ?A n))
+     (substring table (+ ?A 26) ?a)
+     (substring table (+ ?a n) (+ ?a n (- 26 n)))
+     (substring table ?a (+ ?a n))
+     (substring table (+ ?a 26) 255))))
+
+(defun message-caesar-buffer-body (&optional rotnum)
+  "Caesar rotate all letters in the current buffer by 13 places.
+Used to encode/decode possibly offensive messages (commonly in rec.humor).
+With prefix arg, specifies the number of places to rotate each letter forward.
+Mail and USENET news headers are not rotated."
+  (interactive (if current-prefix-arg
+                  (list (prefix-numeric-value current-prefix-arg))
+                (list nil)))
+  (save-excursion
+    (save-restriction
+      (when (message-goto-body)
+       (narrow-to-region (point) (point-max)))
+      (message-caesar-region (point-min) (point-max) rotnum))))
+
+(defun message-pipe-buffer-body (program)
+  "Pipe the message body in the current buffer through PROGRAM."
+  (save-excursion
+    (save-restriction
+      (when (message-goto-body)
+       (narrow-to-region (point) (point-max)))
+      (shell-command-on-region
+       (point-min) (point-max) program nil t))))
+
+(defun message-rename-buffer (&optional enter-string)
+  "Rename the *message* buffer to \"*message* RECIPIENT\".
+If the function is run with a prefix, it will ask for a new buffer
+name, rather than giving an automatic name."
+  (interactive "Pbuffer name: ")
+  (save-excursion
+    (save-restriction
+      (goto-char (point-min))
+      (narrow-to-region (point)
+                       (search-forward mail-header-separator nil 'end))
+      (let* ((mail-to (or
+                      (if (message-news-p) (message-fetch-field "Newsgroups")
+                        (message-fetch-field "To"))
+                      ""))
+            (mail-trimmed-to
+             (if (string-match "," mail-to)
+                 (concat (substring mail-to 0 (match-beginning 0)) ", ...")
+               mail-to))
+            (name-default (concat "*message* " mail-trimmed-to))
+            (name (if enter-string
+                      (read-string "New buffer name: " name-default)
+                    name-default)))
+       (rename-buffer name t)))))
+
+(defun message-fill-yanked-message (&optional justifyp)
+  "Fill the paragraphs of a message yanked into this one.
+Numeric argument means justify as well."
+  (interactive "P")
+  (save-excursion
+    (goto-char (point-min))
+    (search-forward (concat "\n" mail-header-separator "\n") nil t)
+    (let ((fill-prefix message-yank-prefix))
+      (fill-individual-paragraphs (point) (point-max) justifyp))))
+
+(defun message-indent-citation ()
+  "Modify text just inserted from a message to be cited.
+The inserted text should be the region.
+When this function returns, the region is again around the modified text.
+
+Normally, indent each nonblank line `message-indentation-spaces' spaces.
+However, if `message-yank-prefix' is non-nil, insert that prefix on each line."
+  (let ((start (point)))
+    ;; Remove unwanted headers.
+    (when message-ignored-cited-headers
+      (let (all-removed)
+       (save-restriction
+         (narrow-to-region
+          (goto-char start)
+          (if (search-forward "\n\n" nil t)
+              (1- (point))
+            (point)))
+         (message-remove-header message-ignored-cited-headers t)
+         (when (= (point-min) (point-max))
+           (setq all-removed t))
+         (goto-char (point-max)))
+       (if all-removed
+           (goto-char start)
+         (forward-line 1))))
+    ;; Delete blank lines at the start of the buffer.
+    (while (and (point-min)
+               (eolp)
+               (not (eobp)))
+      (message-delete-line))
+    ;; Delete blank lines at the end of the buffer.
+    (goto-char (point-max))
+    (unless (bolp)
+      (insert "\n"))
+    (while (and (zerop (forward-line -1))
+               (looking-at "$"))
+      (message-delete-line))
+    ;; Do the indentation.
+    (if (null message-yank-prefix)
+       (indent-rigidly start (mark t) message-indentation-spaces)
+      (save-excursion
+       (goto-char start)
+       (while (< (point) (mark t))
+         (if (or (looking-at ">") (looking-at "^$"))
+             (insert message-yank-cited-prefix)
+           (insert message-yank-prefix))
+         (forward-line 1))))
+    (goto-char start)))
+
+(defun message-list-references (refs-list &rest refs-strs)
+  "Add `Message-ID's which appear in REFS-STRS but not in REFS-LIST,
+to REFS-LIST."
+  (let (refs ref id saved-id)
+    (when (and refs-list
+              (integerp message-list-references-add-position))
+      (let ((pos message-list-references-add-position))
+       (while (and refs-list
+                   (> pos 0))
+         (push (pop refs-list) saved-id)
+         (setq pos (1- pos)))))
+    (while refs-strs
+      (when (setq refs (pop refs-strs))
+       (setq refs (std11-parse-msg-ids (std11-lexical-analyze refs)))
+       (while refs
+         (when (eq (car (setq ref (pop refs))) 'msg-id)
+           (setq id (concat "<" (mapconcat 'cdr (cdr ref) "") ">"))
+           (or (member id refs-list)
+               (member id saved-id)
+               (push id refs-list))))))
+    (while saved-id
+      (push (pop saved-id) refs-list))
+    refs-list))
+
+(defun message-yank-original (&optional arg)
+  "Insert the message being replied to, if any.
+Puts point before the text and mark after.
+Normally indents each nonblank line ARG spaces (default 3).  However,
+if `message-yank-prefix' is non-nil, insert that prefix on each line.
+
+This function uses `message-cite-function' to do the actual citing.
+
+Just \\[universal-argument] as argument means don't indent, insert no
+prefix, and don't delete any headers.
+
+In addition, if `message-yank-add-new-references' is non-nil and this
+command is called interactively, new IDs from the yanked article will
+be added to the \"References\" field."
+  (interactive "P")
+  (let ((modified (buffer-modified-p)))
+    (when (let ((buffer (message-eval-parameter message-reply-buffer)))
+           (and buffer
+                message-cite-function
+                (prog1
+                    t
+                  (delete-windows-on buffer t)
+                  ; The mark will be set at the end of the article.
+                  (insert-buffer buffer))))
+      ;; Add new IDs to the References field.
+      (when (and message-yank-add-new-references
+                (interactive-p))
+       (let ((start (point))
+             (end (mark t))
+             refs newrefs)
+         (save-excursion
+           (save-restriction
+             (widen)
+             (setq refs (message-list-references
+                         nil
+                         (or (message-make-references)
+                             (prog2
+                                 (message-narrow-to-headers)
+                                 (message-fetch-field "References")
+                               (widen)))))
+             (narrow-to-region start end)
+             (std11-narrow-to-header)
+             (unless (equal (setq newrefs
+                                  (message-list-references
+                                   (copy-sequence refs)
+                                   (unless (eq message-yank-add-new-references
+                                               'message-id-only)
+                                     (or (message-fetch-field "References")
+                                         (message-fetch-field "In-Reply-To")))
+                                   (message-fetch-field "Message-ID")))
+                            refs)
+               ;; If the References field has been changed, we make it
+               ;; visible in the header.
+               (when message-reply-headers
+                 (mail-header-set-message-id message-reply-headers nil)
+                 (mail-header-set-references message-reply-headers nil))
+               (widen)
+               (message-narrow-to-headers)
+               (if (let ((case-fold-search t))
+                     (re-search-forward "^References:\\([\t ]+.+\n\\)+"
+                                        nil t))
+                   (replace-match "")
+                 (goto-char (point-max)))
+               (mail-header-format
+                (list (or (assq 'References message-header-format-alist)
+                          '(References . message-fill-references)))
+                (list (cons 'References (mapconcat 'identity
+                                                   (nreverse newrefs) " "))))
+               (backward-delete-char 1))))))
+      (unless arg
+       (if (and message-suspend-font-lock-when-citing
+                (boundp 'font-lock-mode)
+                (symbol-value 'font-lock-mode))
+           (unwind-protect
+               (progn
+                 (sit-for 0)
+                 (font-lock-mode 0)
+                 (funcall message-cite-function))
+             (font-lock-mode 1))
+         (funcall message-cite-function)))
+      (message-exchange-point-and-mark)
+      (unless (bolp)
+       (insert ?\n))
+      (unless modified
+       (setq message-checksum (message-checksum))))))
+
+(defun message-yank-buffer (buffer)
+  "Insert BUFFER into the current buffer and quote it."
+  (interactive "bYank buffer: ")
+  (let ((message-reply-buffer buffer))
+    (save-window-excursion
+      (message-yank-original))))
+
+(defun message-buffers ()
+  "Return a list of active message buffers."
+  (let (buffers)
+    (save-excursion
+      (dolist (buffer (buffer-list t))
+       (set-buffer buffer)
+       (when (and (eq major-mode 'message-mode)
+                  (null message-sent-message-via))
+         (push (buffer-name buffer) buffers))))
+    (nreverse buffers)))
+
+(defun message-cite-original-without-signature ()
+  "Cite function in the standard Message manner."
+  (let ((start (point))
+       (end (mark t))
+       (functions
+        (when message-indent-citation-function
+          (if (listp message-indent-citation-function)
+              message-indent-citation-function
+            (list message-indent-citation-function))))
+       (message-reply-headers (or message-reply-headers
+                                  (make-mail-header))))
+    (mail-header-set-from message-reply-headers
+                         (save-restriction
+                           (narrow-to-region
+                            (point)
+                            (if (search-forward "\n\n" nil t)
+                                (1- (point))
+                              (point-max)))
+                           (or (message-fetch-field "from")
+                               "unknown sender")))
+    ;; Allow undoing.
+    (undo-boundary)
+    (goto-char end)
+    (when (re-search-backward message-signature-separator start t)
+      ;; Also peel off any blank lines before the signature.
+      (forward-line -1)
+      (while (looking-at "^[ \t]*$")
+       (forward-line -1))
+      (forward-line 1)
+      (delete-region (point) end)
+      (unless (search-backward "\n\n" start t)
+       ;; Insert a blank line if it is peeled off.
+       (insert "\n")))
+    (goto-char start)
+    (while functions
+      (funcall (pop functions)))
+    (when message-citation-line-function
+      (unless (bolp)
+       (insert "\n"))
+      (funcall message-citation-line-function))))
+
+(eval-when-compile (defvar mail-citation-hook))                ;Compiler directive
+(defun message-cite-original ()
+  "Cite function in the standard Message manner."
+  (if (and (boundp 'mail-citation-hook)
+          mail-citation-hook)
+      (run-hooks 'mail-citation-hook)
+    (let ((start (point))
+         (end (mark t))
+         (functions
+          (when message-indent-citation-function
+            (if (listp message-indent-citation-function)
+                message-indent-citation-function
+              (list message-indent-citation-function))))
+         (message-reply-headers (or message-reply-headers
+                                    (make-mail-header))))
+      (mail-header-set-from message-reply-headers
+                           (save-restriction
+                             (narrow-to-region
+                              (point)
+                              (if (search-forward "\n\n" nil t)
+                                  (1- (point))
+                                (point-max)))
+                             (or (message-fetch-field "from")
+                                 "unknown sender")))
+      (goto-char start)
+      (while functions
+       (funcall (pop functions)))
+      (when message-citation-line-function
+       (unless (bolp)
+         (insert "\n"))
+       (funcall message-citation-line-function)))))
+
+(defun message-insert-citation-line ()
+  "Insert a simple citation line."
+  (when message-reply-headers
+    (insert (mail-header-from message-reply-headers) " writes:\n\n")))
+
+(defun message-position-on-field (header &rest afters)
+  (let ((case-fold-search t))
+    (save-restriction
+      (narrow-to-region
+       (goto-char (point-min))
+       (progn
+        (re-search-forward
+         (concat "^" (regexp-quote mail-header-separator) "$"))
+        (match-beginning 0)))
+      (goto-char (point-min))
+      (if (re-search-forward (concat "^" (regexp-quote header) ":") nil t)
+         (progn
+           (re-search-forward "^[^ \t]" nil 'move)
+           (beginning-of-line)
+           (skip-chars-backward "\n")
+           t)
+       (while (and afters
+                   (not (re-search-forward
+                         (concat "^" (regexp-quote (car afters)) ":")
+                         nil t)))
+         (pop afters))
+       (when afters
+         (re-search-forward "^[^ \t]" nil 'move)
+         (beginning-of-line))
+       (insert header ": \n")
+       (forward-char -1)
+       nil))))
+
+(defun message-remove-signature ()
+  "Remove the signature from the text between point and mark.
+The text will also be indented the normal way."
+  (save-excursion
+    (let ((start (point))
+         mark)
+      (if (not (re-search-forward message-signature-separator (mark t) t))
+         ;; No signature here, so we just indent the cited text.
+         (message-indent-citation)
+       ;; Find the last non-empty line.
+       (forward-line -1)
+       (while (looking-at "[ \t]*$")
+         (forward-line -1))
+       (forward-line 1)
+       (setq mark (set-marker (make-marker) (point)))
+       (goto-char start)
+       (message-indent-citation)
+       ;; Enable undoing the deletion.
+       (undo-boundary)
+       (delete-region mark (mark t))
+       (set-marker mark nil)))))
+
+\f
+
+;;;
+;;; Sending messages
+;;;
+
+;; Avoid byte-compile warning.
+(defvar message-encoding-buffer nil)
+(defvar message-edit-buffer nil)
+(defvar message-mime-mode nil)
+
+(defun message-send-and-exit (&optional arg)
+  "Send message like `message-send', then, if no errors, exit from mail buffer."
+  (interactive "P")
+  (let ((buf (current-buffer))
+       (actions message-exit-actions)
+       (frame (selected-frame))
+       (org-frame message-original-frame))
+    (when (and (message-send arg)
+              (buffer-name buf))
+      (if message-kill-buffer-on-exit
+         (kill-buffer buf)
+       (bury-buffer buf)
+       (when (eq buf (current-buffer))
+         (message-bury buf)))
+      (message-do-actions actions)
+      (message-delete-frame frame org-frame)
+      t)))
+
+(defun message-dont-send ()
+  "Don't send the message you have been editing.
+Instead, just auto-save the buffer and then bury it."
+  (interactive)
+  (set-buffer-modified-p t)
+  (save-buffer)
+  (let ((actions message-postpone-actions)
+       (frame (selected-frame))
+       (org-frame message-original-frame))
+    (message-bury (current-buffer))
+    (message-do-actions actions)
+    (message-delete-frame frame org-frame)))
+
+(defun message-kill-buffer ()
+  "Kill the current buffer."
+  (interactive)
+  (when (or (not (buffer-modified-p))
+           (eq t message-kill-buffer-query-function)
+           (funcall message-kill-buffer-query-function
+                    "The buffer modified; kill anyway? "))
+    (let ((actions message-kill-actions)
+         (draft-article message-draft-article)
+         (auto-save-file-name buffer-auto-save-file-name)
+         (file-name buffer-file-name)
+         (modified (buffer-modified-p))
+         (frame (selected-frame))
+         (org-frame message-original-frame))
+      (setq buffer-file-name nil)
+      (kill-buffer (current-buffer))
+      (when (and message-kill-buffer-and-remove-file
+                (or (and auto-save-file-name
+                         (file-exists-p auto-save-file-name))
+                    (and file-name
+                         (file-exists-p file-name)))
+                (yes-or-no-p (format "Remove the backup file%s? "
+                                     (if modified " too" ""))))
+       (ignore-errors
+         (delete-file auto-save-file-name))
+       (let ((message-draft-article draft-article))
+         (message-disassociate-draft)))
+      (message-do-actions actions)
+      (message-delete-frame frame org-frame)))
+  (message ""))
+
+(defun message-mimic-kill-buffer ()
+  "Kill the current buffer with query.  This is an imitation for
+`kill-buffer', but it will delete a message frame."
+  (interactive)
+  (let ((bufname (read-buffer (format "Kill buffer: (default %s) "
+                                     (buffer-name))))
+       message-kill-buffer-and-remove-file)
+    (when (or (not bufname)
+             (string-equal bufname "")
+             (string-equal bufname (buffer-name)))
+      (message-kill-buffer))))
+
+(defun message-delete-frame (frame org-frame)
+  "Delete frame for editing message."
+  (when (and (or (static-if (featurep 'xemacs)
+                    (device-on-window-system-p)
+                  window-system)
+                (>= emacs-major-version 20))
+            (or (and (eq message-delete-frame-on-exit t)
+                     (select-frame frame)
+                     (or (eq frame org-frame)
+                         (prog1
+                             (y-or-n-p "Delete this frame?")
+                           (message ""))))
+                (and (eq message-delete-frame-on-exit 'ask)
+                     (select-frame frame)
+                     (prog1
+                         (y-or-n-p "Delete this frame?")
+                       (message "")))))
+    (delete-frame frame)))
+
+(defun message-bury (buffer)
+  "Bury this mail BUFFER."
+  (let ((newbuf (other-buffer buffer)))
+    (bury-buffer buffer)
+    (if (and (fboundp 'frame-parameters)
+            (cdr (assq 'dedicated (frame-parameters)))
+            (not (null (delq (selected-frame) (visible-frame-list)))))
+       (delete-frame (selected-frame))
+      (switch-to-buffer newbuf))))
+
+(defun message-send (&optional arg)
+  "Send the message in the current buffer.
+If `message-interactive' is non-nil, wait for success indication or
+error messages, and inform user.
+Otherwise any failure is reported in a message back to the user from
+the mailer.
+The usage of ARG is defined by the instance that called Message.
+It should typically alter the sending method in some way or other."
+  (interactive "P")
+  ;; Disabled test.
+  (when (or (buffer-modified-p)
+           (message-check-element 'unchanged)
+           (y-or-n-p "No changes in the buffer; really send? "))
+    ;; Make it possible to undo the coming changes.
+    (undo-boundary)
+    (let ((inhibit-read-only t))
+      (put-text-property (point-min) (point-max) 'read-only nil))
+    (run-hooks 'message-send-hook)
+    (message-fix-before-sending)
+    (message message-sending-message)
+    (let ((message-encoding-buffer
+          (message-generate-new-buffer-clone-locals " message encoding"))
+         (message-edit-buffer (current-buffer))
+         (message-mime-mode mime-edit-mode-flag)
+         (alist message-send-method-alist)
+         (success t)
+         elem sent dont-barf-on-no-method
+         (message-options message-options))
+      (unwind-protect
+         (progn
+           (message-options-set-recipient)
+           (save-excursion
+             (set-buffer message-encoding-buffer)
+             (erase-buffer)
+             ;; ;; Avoid copying text props (except hard newlines).
+             ;; T-gnus change: copy all text props from the editing buffer
+             ;; into the encoding buffer.
+             (insert-buffer-substring message-edit-buffer)
+             (funcall message-encode-function)
+             (while (and success
+                         (setq elem (pop alist)))
+               (when (funcall (cadr elem))
+                 (when (and
+                        (or (not (memq (car elem)
+                                       message-sent-message-via))
+                            (message-fetch-field "supersedes")
+                            (if (or (message-gnksa-enable-p 'multiple-copies)
+                                    (not (eq (car elem) 'news)))
+                                (y-or-n-p
+                                 (format
+                                  "Already sent message via %s; resend? "
+                                  (car elem)))
+                              (error "Denied posting -- multiple copies")))
+                        (setq success (funcall (caddr elem) arg)))
+                   (setq sent t)))))
+           (unless
+               (or
+                sent
+                (not success)
+                (let ((fcc (message-fetch-field "Fcc"))
+                      (gcc (message-fetch-field "Gcc")))
+                  (when (or fcc gcc)
+                    (or
+                     (eq message-allow-no-recipients 'always)
+                     (and (not (eq message-allow-no-recipients 'never))
+                          (setq dont-barf-on-no-method
+                                (gnus-y-or-n-p
+                                 (format "No receiver, perform %s anyway? "
+                                         (cond ((and fcc gcc) "Fcc and Gcc")
+                                               (fcc "Fcc")
+                                               (t "Gcc"))))))))))
+             (error "No methods specified to send by"))
+           (when (or dont-barf-on-no-method
+                     (and success sent))
+             (message-do-fcc)
+             (save-excursion
+               (run-hooks 'message-sent-hook))
+             (message "Sending...done")
+             ;; Mark the buffer as unmodified and delete auto-save.
+             (set-buffer-modified-p nil)
+             (delete-auto-save-file-if-necessary t)
+             (message-disassociate-draft)
+             ;; Delete other mail buffers and stuff.
+             (message-do-send-housekeeping)
+             (message-do-actions message-send-actions)
+             ;; Return success.
+             t))
+       (kill-buffer message-encoding-buffer)))))
+
+(defun message-send-via-mail (arg)
+  "Send the current message via mail."
+  (message-send-mail arg))
+
+(defun message-send-via-news (arg)
+  "Send the current message via news."
+  (message-send-news arg))
+
+(defmacro message-check (type &rest forms)
+  "Eval FORMS if TYPE is to be checked."
+  `(or (message-check-element ,type)
+       (save-excursion
+        ,@forms)))
+
+(put 'message-check 'lisp-indent-function 1)
+(put 'message-check 'edebug-form-spec '(form body))
+
+;; Advise the function `invisible-region'.
+(let (current-load-list)
+  (eval
+   `(defadvice invisible-region (around add-mime-edit-invisible (start end)
+                                       activate)
+      "Advised by T-gnus Message.
+Add the text property `mime-edit-invisible' to an invisible text when
+the buffer's major mode is `message-mode'.  The added property will be
+used to distinguish whether the invisible text is a MIME part or not."
+      ,(if (featurep 'xemacs)
+          '(if (eq ?\n (char-after start))
+               (setq start (1+ start)))
+        '(if (eq ?\n (char-after (1- end)))
+             (setq end (1- end))))
+      (setq ad-return-value
+           (if (eq 'message-mode major-mode)
+               (add-text-properties start end
+                                    '(invisible t mime-edit-invisible t))
+             (put-text-property start end 'invisible t))))))
+
+(defun message-text-with-property (prop)
+  "Return a list of all points where the text has PROP."
+  (let ((points nil)
+       (point (point-min)))
+    (save-excursion
+      (while (< point (point-max))
+       (when (get-text-property point prop)
+         (push point points))
+       (incf point)))
+    (nreverse points)))
+
+(defun message-fix-before-sending ()
+  "Do various things to make the message nice before sending it."
+  ;; Make sure there's a newline at the end of the message.
+  (widen)
+  (goto-char (point-max))
+  (unless (bolp)
+    (insert "\n"))
+  ;; Make the hidden headers visible.
+  (let ((points (message-text-with-property 'message-hidden)))
+    (when points
+      (goto-char (car points))
+      (dolist (point points)
+       (add-text-properties point (1+ point)
+                            '(invisible nil intangible nil)))))
+  ;; Make invisible text visible except for mime parts which may be
+  ;; inserted by the MIME-Edit.
+  ;; It doesn't seem as if this is useful, since the invisible property
+  ;; is clobbered by an after-change hook anyhow.
+  (message-check 'invisible-text
+    ;; FIXME T-gnus: It should also detect invisible overlays.
+    (let (from
+         (to (point-min))
+         mime-from mime-to hidden-start)
+      (while (setq from (text-property-any to (point-max) 'invisible t))
+       (setq to (or (text-property-not-all from (point-max) 'invisible t)
+                    (point-max))
+             mime-to from)
+       (while (setq mime-from (text-property-any mime-to to
+                                                 'mime-edit-invisible t))
+         (when (> mime-from mime-to)
+           (setq hidden-start (or hidden-start mime-to))
+           (add-text-properties mime-to mime-from
+                                '(invisible nil face highlight
+                                            font-lock-face highlight)))
+         (setq mime-to (or (text-property-not-all mime-from to
+                                                  'mime-edit-invisible t)
+                           to)))
+       (when (< mime-to to)
+         (setq hidden-start (or hidden-start mime-to))
+         (add-text-properties mime-to to
+                              '(invisible nil face highlight
+                                          font-lock-face highlight))))
+      (when hidden-start
+       (goto-char hidden-start)
+       (set-window-start (selected-window) (gnus-point-at-bol))
+       (unless (yes-or-no-p
+                "Invisible text found and made visible; continue sending? ")
+         (error "Invisible text found and made visible")))))
+;; The following check is needless to T-gnus since T-gnus determines
+;; a MIME charset forcibly (even if it cannot be determined properly,
+;; the value of the `default-mime-charset-for-write' variable is used).
+;;  (message-check 'illegible-text
+;;    (let ((mm-7bit-chars "\x20-\x7f\r\n\t\x7\x8\xb\xc\x1f\x1b")
+;;       found choice)
+;;      (message-goto-body)
+;;      (skip-chars-forward mm-7bit-chars)
+;;      (while (not (eobp))
+;;     (when (let ((char (char-after)))
+;;             (or (< (mm-char-int char) 128)
+;;                 (and (mm-multibyte-p)
+;;                      (> (length (mm-find-mime-charset-region
+;;                                  (point) (point-max)))
+;;                         1))))
+;;       (message-overlay-put (message-make-overlay (point) (1+ (point)))
+;;                            'face 'highlight)
+;;       (setq found t))
+;;     (forward-char)
+;;     (skip-chars-forward mm-7bit-chars))
+;;      (when found
+;;     (setq choice
+;;           (gnus-multiple-choice
+;;            "Non-printable characters found.  Continue sending?"
+;;            '((?d "Remove non-printable characters and send")
+;;              (?r "Replace non-printable characters with dots and send")
+;;              (?i "Ignore non-printable characters and send")
+;;              (?e "Continue editing"))))
+;;     (if (eq choice ?e)
+;;       (error "Non-printable characters"))
+;;     (message-goto-body)
+;;     (skip-chars-forward mm-7bit-chars)
+;;     (while (not (eobp))
+;;       (when (let ((char (char-after)))
+;;               (or (< (mm-char-int char) 128)
+;;                   (and (mm-multibyte-p)
+;;                        ;; Fixme: Wrong for Emacs 22 and for things
+;;                        ;; like undecable utf-8.  Should at least
+;;                        ;; use find-coding-systems-region.
+;;                        (memq (char-charset char)
+;;                              '(eight-bit-control eight-bit-graphic
+;;                                                  control-1)))))
+;;         (if (eq choice ?i)
+;;             (message-kill-all-overlays)
+;;           (delete-char 1)
+;;           (when (eq choice ?r)
+;;             (insert "."))))
+;;       (forward-char)
+;;       (skip-chars-forward mm-7bit-chars)))))
+  )
+
+(defun message-add-action (action &rest types)
+  "Add ACTION to be performed when doing an exit of type TYPES."
+  (while types
+    (add-to-list (intern (format "message-%s-actions" (pop types)))
+                action)))
+
+(defun message-delete-action (action &rest types)
+  "Delete ACTION from lists of actions performed when doing an exit of type TYPES."
+  (let (var)
+    (while types
+      (set (setq var (intern (format "message-%s-actions" (pop types))))
+          (delq action (symbol-value var))))))
+
+(defun message-do-actions (actions)
+  "Perform all actions in ACTIONS."
+  ;; Now perform actions on successful sending.
+  (while actions
+    (ignore-errors
+      (cond
+       ;; A simple function.
+       ((functionp (car actions))
+       (funcall (car actions)))
+       ;; Something to be evaled.
+       (t
+       (eval (car actions)))))
+    (pop actions)))
+
+(defsubst message-maybe-split-and-send-mail ()
+  "Split a message if necessary, and send it via mail.
+Returns nil if sending succeeded, returns any string if sending failed.
+This sub function is for exclusive use of `message-send-mail'."
+  (let ((mime-edit-split-ignored-field-regexp
+        mime-edit-split-ignored-field-regexp)
+       (case-fold-search t)
+       failure)
+    (while (string-match "Message-ID" mime-edit-split-ignored-field-regexp)
+      (setq mime-edit-split-ignored-field-regexp
+           (concat (substring mime-edit-split-ignored-field-regexp
+                              0 (match-beginning 0))
+                   "Hey_MIME-Edit,_there_is_an_inviolable_Message_ID"
+                   "_so_don't_rape_it!"
+                   (substring mime-edit-split-ignored-field-regexp
+                              (match-end 0)))))
+    (setq failure
+         (or
+          (catch 'message-sending-mail-failure
+            (mime-edit-maybe-split-and-send
+             (function
+              (lambda ()
+                (interactive)
+                (save-restriction
+                  (std11-narrow-to-header mail-header-separator)
+                  (goto-char (point-min))
+                  (when (re-search-forward "^Message-ID:" nil t)
+                    (delete-region (match-end 0) (std11-field-end))
+                    (insert " " (message-make-message-id))))
+                (condition-case err
+                    (funcall (or message-send-mail-real-function
+                                 message-send-mail-function))
+                  (error
+                   (throw 'message-sending-mail-failure err))))))
+            nil)
+          (condition-case err
+              (progn
+                (funcall (or message-send-mail-real-function
+                             message-send-mail-function))
+                nil)
+            (error err))))
+    (when failure
+      (if (eq 'error (car failure))
+         (cadr failure)
+       (prin1-to-string failure)))))
+
+(defun message-send-mail-partially ()
+  "Send mail as message/partial."
+  ;; replace the header delimiter with a blank line
+  (goto-char (point-min))
+  (re-search-forward
+   (concat "^" (regexp-quote mail-header-separator) "\n"))
+  (replace-match "\n")
+  (run-hooks 'message-send-mail-hook)
+  (let ((p (goto-char (point-min)))
+       (tembuf (message-generate-new-buffer-clone-locals " message temp"))
+       (curbuf (current-buffer))
+       (id (message-make-message-id)) (n 1)
+       plist total  header required-mail-headers)
+    (while (not (eobp))
+      (if (< (point-max) (+ p message-send-mail-partially-limit))
+         (goto-char (point-max))
+       (goto-char (+ p message-send-mail-partially-limit))
+       (beginning-of-line)
+       (if (<= (point) p) (forward-line 1))) ;; In case of bad message.
+      (push p plist)
+      (setq p (point)))
+    (setq total (length plist))
+    (push (point-max) plist)
+    (setq plist (nreverse plist))
+    (unwind-protect
+       (save-excursion
+         (setq p (pop plist))
+         (while plist
+           (set-buffer curbuf)
+           (copy-to-buffer tembuf p (car plist))
+           (set-buffer tembuf)
+           (goto-char (point-min))
+           (if header
+               (progn
+                 (goto-char (point-min))
+                 (narrow-to-region (point) (point))
+                 (insert header))
+             (message-goto-eoh)
+             (setq header (buffer-substring (point-min) (point)))
+             (goto-char (point-min))
+             (narrow-to-region (point) (point))
+             (insert header)
+             (message-remove-header "Mime-Version")
+             (message-remove-header "Content-Type")
+             (message-remove-header "Content-Transfer-Encoding")
+             (message-remove-header "Message-ID")
+             (message-remove-header "Lines")
+             (goto-char (point-max))
+             (insert "Mime-Version: 1.0\n")
+             (setq header (buffer-string)))
+           (goto-char (point-max))
+           (insert (format "Content-Type: message/partial; id=\"%s\"; number=%d; total=%d\n\n"
+                           id n total))
+           (forward-char -1)
+           (let ((mail-header-separator ""))
+             (when (memq 'Message-ID message-required-mail-headers)
+               (insert "Message-ID: " (message-make-message-id) "\n"))
+             (when (memq 'Lines message-required-mail-headers)
+               (insert "Lines: " (message-make-lines) "\n"))
+             (message-goto-subject)
+             (end-of-line)
+             (insert (format " (%d/%d)" n total))
+             (widen)
+             (mm-with-unibyte-current-buffer
+               (funcall (or message-send-mail-real-function
+                            message-send-mail-function))))
+           (setq n (+ n 1))
+           (setq p (pop plist))
+           (erase-buffer)))
+      (kill-buffer tembuf))))
+
+(defun message-send-mail (&optional arg)
+  (require 'mail-utils)
+  (let* ((tembuf (message-generate-new-buffer-clone-locals " message temp"))
+        (case-fold-search nil)
+        (news (message-news-p))
+        (message-this-is-mail t)
+        (headers message-required-mail-headers)
+        failure)
+    (save-restriction
+      (message-narrow-to-headers)
+      ;; Generate the Mail-Followup-To header if the header is not there...
+      (if (and (message-subscribed-p)
+              (not (mail-fetch-field "mail-followup-to")))
+         (setq headers
+               (cons
+                (cons "Mail-Followup-To" (message-make-mail-followup-to))
+                message-required-mail-headers))
+       ;; otherwise, delete the MFT header if the field is empty
+       (when (equal "" (mail-fetch-field "mail-followup-to"))
+         (message-remove-header "^Mail-Followup-To:")))
+      ;; Insert some headers.
+      (let ((message-deletable-headers
+            (if news nil message-deletable-headers)))
+       (message-generate-headers headers))
+      ;; Let the user do all of the above.
+      (run-hooks 'message-header-hook))
+    (if (not (message-check-mail-syntax))
+       (progn
+         (message "")
+         nil)
+      (unwind-protect
+         (save-excursion
+           (set-buffer tembuf)
+           (erase-buffer)
+           ;; ;; Avoid copying text props (except hard newlines).
+           ;; T-gnus change: copy all text props from the editing buffer
+           ;; into the encoding buffer.
+           (insert-buffer-substring message-encoding-buffer)
+           ;; Remove some headers.
+           (save-restriction
+             (message-narrow-to-headers)
+;; We Semi-gnus people have no use for it.
+;;           ;; We (re)generate the Lines header.
+;;           (when (memq 'Lines message-required-mail-headers)
+;;             (message-generate-headers '(Lines)))
+             (message-remove-header message-ignored-mail-headers t))
+           (goto-char (point-max))
+           ;; require one newline at the end.
+           (or (= (preceding-char) ?\n)
+               (insert ?\n))
+           (message-cleanup-headers)
+           ;; FIXME: we're inserting the courtesy copy after encoding.
+           ;; This is wrong if the courtesy copy string contains
+           ;; non-ASCII characters. -- jh
+           (when
+               (save-restriction
+                 (message-narrow-to-headers)
+                 (and news
+                      (or (message-fetch-field "cc")
+                          (message-fetch-field "bcc")
+                          (message-fetch-field "to"))
+                      (let ((content-type (mime-read-Content-Type)))
+                        (and
+                         (or
+                          (not content-type)
+                          (and
+                           (eq 'text (cdr (assq 'type content-type)))
+                           (eq 'plain (cdr (assq 'subtype content-type)))))
+                         (not
+                          (string= "base64"
+                                   (mime-read-Content-Transfer-Encoding)))))))
+             (message-insert-courtesy-copy))
+           (setq failure (message-maybe-split-and-send-mail)))
+       (kill-buffer tembuf))
+      (set-buffer message-edit-buffer)
+      (if failure
+         (progn
+           (message "Couldn't send message via mail: %s" failure)
+           nil)
+       (push 'mail message-sent-message-via)))))
+
+(defun message-send-mail-with-sendmail ()
+  "Send off the prepared buffer with sendmail."
+  (let ((errbuf (if message-interactive
+                   (message-generate-new-buffer-clone-locals
+                    " sendmail errors")
+                 0))
+       resend-to-addresses delimline)
+    (unwind-protect
+       (progn
+         (let ((case-fold-search t))
+           (save-restriction
+             (message-narrow-to-headers)
+             (setq resend-to-addresses (message-fetch-field "resent-to")))
+           ;; Change header-delimiter to be what sendmail expects.
+           (goto-char (point-min))
+           (re-search-forward
+            (concat "^" (regexp-quote mail-header-separator) "\n"))
+           (replace-match "\n")
+           (backward-char 1)
+           (setq delimline (point-marker))
+           (run-hooks 'message-send-mail-hook)
+           ;; Insert an extra newline if we need it to work around
+           ;; Sun's bug that swallows newlines.
+           (goto-char (1+ delimline))
+           (when (eval message-mailer-swallows-blank-line)
+             (newline))
+           (when message-interactive
+             (save-excursion
+               (set-buffer errbuf)
+               (erase-buffer))))
+         (let* ((default-directory "/")
+                (cpr (as-binary-process
+                      (apply
+                       'call-process-region
+                       (append
+                        (list (point-min) (point-max)
+                              (if (boundp 'sendmail-program)
+                                  sendmail-program
+                                "/usr/lib/sendmail")
+                              nil errbuf nil "-oi")
+                        ;; Always specify who from,
+                        ;; since some systems have broken sendmails.
+                        ;; But some systems are more broken with -f, so
+                        ;; we'll let users override this.
+                        (if (null message-sendmail-f-is-evil)
+                            (list "-f" (message-sendmail-envelope-from)))
+                        ;; These mean "report errors by mail"
+                        ;; and "deliver in background".
+                        (if (null message-interactive) '("-oem" "-odb"))
+                        ;; Get the addresses from the message
+                        ;; unless this is a resend.
+                        ;; We must not do that for a resend
+                        ;; because we would find the original addresses.
+                        ;; For a resend, include the specific addresses.
+                        (if resend-to-addresses
+                            (list resend-to-addresses)
+                          '("-t")))))))
+           (unless (or (null cpr) (and (numberp cpr) (zerop cpr)))
+             (error "Sending...failed with exit value %d" cpr)))
+         (when message-interactive
+           (save-excursion
+             (set-buffer errbuf)
+             (goto-char (point-min))
+             (while (re-search-forward "\n\n* *" nil t)
+               (replace-match "; "))
+             (if (not (zerop (buffer-size)))
+                 (error "Sending...failed to %s"
+                        (buffer-string))))))
+      (when (bufferp errbuf)
+       (kill-buffer errbuf)))))
+
+(defun message-send-mail-with-qmail ()
+  "Pass the prepared message buffer to qmail-inject.
+Refer to the documentation for the variable `message-send-mail-function'
+to find out how to use this."
+  ;; replace the header delimiter with a blank line
+  (goto-char (point-min))
+  (re-search-forward
+   (concat "^" (regexp-quote mail-header-separator) "\n"))
+  (replace-match "\n")
+  (backward-char 1)
+  (run-hooks 'message-send-mail-hook)
+  ;; send the message
+  (case
+      (as-binary-process
+       (apply
+       'call-process-region 1 (point-max) message-qmail-inject-program
+       nil nil nil
+       ;; qmail-inject's default behaviour is to look for addresses on the
+       ;; command line; if there're none, it scans the headers.
+       ;; yes, it does The Right Thing w.r.t. Resent-To and it's kin.
+       ;;
+       ;; in general, ALL of qmail-inject's defaults are perfect for simply
+       ;; reading a formatted (i. e., at least a To: or Resent-To header)
+       ;; message from stdin.
+       ;;
+       ;; qmail also has the advantage of not having been raped by
+       ;; various vendors, so we don't have to allow for that, either --
+       ;; compare this with message-send-mail-with-sendmail and weep
+       ;; for sendmail's lost innocence.
+       ;;
+       ;; all this is way cool coz it lets us keep the arguments entirely
+       ;; free for -inject-arguments -- a big win for the user and for us
+       ;; since we don't have to play that double-guessing game and the user
+       ;; gets full control (no gestapo'ish -f's, for instance).  --sj
+       (if (functionp message-qmail-inject-args)
+           (funcall message-qmail-inject-args)
+         message-qmail-inject-args)))
+    ;; qmail-inject doesn't say anything on it's stdout/stderr,
+    ;; we have to look at the retval instead
+    (0 nil)
+    (100 (error "qmail-inject reported permanent failure"))
+    (111 (error "qmail-inject reported transient failure"))
+    ;; should never happen
+    (t   (error "qmail-inject reported unknown failure"))))
+
+(defun message-send-mail-with-mh ()
+  "Send the prepared message buffer with mh."
+  (let ((mh-previous-window-config nil)
+       (name (mh-new-draft-name)))
+    (setq buffer-file-name name)
+    ;; MH wants to generate these headers itself.
+    (when message-mh-deletable-headers
+      (let ((headers message-mh-deletable-headers))
+       (while headers
+         (goto-char (point-min))
+         (and (re-search-forward
+               (concat "^" (symbol-name (car headers)) ": *") nil t)
+              (message-delete-line))
+         (pop headers))))
+    (run-hooks 'message-send-mail-hook)
+    ;; Pass it on to mh.
+    (mh-send-letter)))
+
+(defun message-send-mail-with-smtp ()
+  "Send off the prepared buffer with SMTP."
+  (require 'smtp) ; XXX
+  (let ((case-fold-search t)
+       recipients)
+    (save-restriction
+      (message-narrow-to-headers)
+      (setq recipients
+           ;; XXX: Should be replaced by better one.
+           (smtp-deduce-address-list (current-buffer)
+                                     (point-min) (point-max)))
+      ;; Remove BCC lines.
+      (message-remove-header "bcc"))
+    ;; replace the header delimiter with a blank line.
+    (goto-char (point-min))
+    (re-search-forward
+     (concat "^" (regexp-quote mail-header-separator) "\n"))
+    (replace-match "\n")
+    (backward-char 1)
+    (run-hooks 'message-send-mail-hook)
+    (if recipients
+       (smtp-send-buffer user-mail-address recipients (current-buffer))
+      (error "Sending failed; no recipients"))))
+
+(defsubst message-maybe-split-and-send-news (method)
+  "Split a message if necessary, and send it via news.
+Returns nil if sending succeeded, returns t if sending failed.
+This sub function is for exclusive use of `message-send-news'."
+  (let ((mime-edit-split-ignored-field-regexp
+        mime-edit-split-ignored-field-regexp)
+       (case-fold-search t))
+    (while (string-match "Message-ID" mime-edit-split-ignored-field-regexp)
+      (setq mime-edit-split-ignored-field-regexp
+           (concat (substring mime-edit-split-ignored-field-regexp
+                              0 (match-beginning 0))
+                   "Hey_MIME-Edit,_there_is_an_inviolable_Message_ID"
+                   "_so_don't_rape_it!"
+                   (substring mime-edit-split-ignored-field-regexp
+                              (match-end 0)))))
+    (or
+     (catch 'message-sending-news-failure
+       (mime-edit-maybe-split-and-send
+       (function
+        (lambda ()
+          (interactive)
+          (save-restriction
+            (std11-narrow-to-header mail-header-separator)
+            (goto-char (point-min))
+            (when (re-search-forward "^Message-ID:" nil t)
+              (delete-region (match-end 0) (std11-field-end))
+              (insert " " (message-make-message-id))))
+          (unless (funcall message-send-news-function method)
+            (throw 'message-sending-news-failure t)))))
+       nil)
+     (not (funcall message-send-news-function method)))))
+
+(defun message-smtpmail-send-it ()
+  "Send the prepared message buffer with `smtpmail-send-it'.
+This only differs from `smtpmail-send-it' that this command evaluates
+`message-send-mail-hook' just before sending a message.  It is useful
+if your ISP requires the POP-before-SMTP authentication.  See the
+documentation for the function `mail-source-touch-pop'."
+  (run-hooks 'message-send-mail-hook)
+  (smtpmail-send-it))
+
+(defun message-canlock-generate ()
+  "Return a string that is non-trivial to guess.
+Do not use this for anything important, it is cryptographically weak."
+  (let (sha1-maximum-internal-length)
+    (sha1 (concat (message-unique-id)
+                 (format "%x%x%x" (random) (random t) (random))
+                 (prin1-to-string (recent-keys))
+                 (prin1-to-string (garbage-collect))))))
+
+(defun message-canlock-password ()
+  "The password used by message for cancel locks.
+This is the value of `canlock-password', if that option is non-nil.
+Otherwise, generate and save a value for `canlock-password' first."
+  (unless canlock-password
+    (customize-save-variable 'canlock-password (message-canlock-generate))
+    (setq canlock-password-for-verify canlock-password))
+  canlock-password)
+
+(defun message-insert-canlock ()
+  (when message-insert-canlock
+    (message-canlock-password)
+    (canlock-insert-header)))
+
+(defun message-send-news (&optional arg)
+  (let* ((tembuf (message-generate-new-buffer-clone-locals " *message temp*"))
+        (case-fold-search nil)
+        (method (if (functionp message-post-method)
+                    (funcall message-post-method arg)
+                  message-post-method))
+        (newsgroups-field (save-restriction
+                            (message-narrow-to-headers-or-head)
+                            (message-fetch-field "Newsgroups")))
+        (followup-field (save-restriction
+                          (message-narrow-to-headers-or-head)
+                          (message-fetch-field "Followup-To")))
+        ;; BUG: We really need to get the charset for each name in the
+        ;; Newsgroups and Followup-To lines to allow crossposting
+        ;; between group namess with incompatible character sets.
+        ;; -- Per Abrahamsen <abraham@dina.kvl.dk> 2001-10-08.
+        (group-field-charset
+         (gnus-group-name-charset method newsgroups-field))
+        (followup-field-charset
+         (gnus-group-name-charset method (or followup-field "")))
+        (mime-field-encoding-method-alist
+         (append (when group-field-charset
+                   (list (cons "Newsgroups" group-field-charset)))
+                 (when followup-field-charset
+                   (list (cons "Followup-To" followup-field-charset)))
+                 mime-field-encoding-method-alist))
+        (message-syntax-checks
+         (if (and arg
+                  (listp message-syntax-checks))
+             (cons '(existing-newsgroups . disabled)
+                   message-syntax-checks)
+           message-syntax-checks))
+        (message-this-is-news t)
+        result)
+    (save-restriction
+      (message-narrow-to-headers)
+      ;; Insert some headers.
+      (message-generate-headers message-required-news-headers)
+      (message-insert-canlock)
+      ;; Let the user do all of the above.
+      (run-hooks 'message-header-hook))
+    ;; Note: This check will be disabled by the ".*" default value for
+    ;; gnus-group-name-charset-group-alist. -- Pa 2001-10-07.
+    (when (and group-field-charset
+              (listp message-syntax-checks))
+      (setq message-syntax-checks
+           (cons '(valid-newsgroups . disabled)
+                 message-syntax-checks)))
+    (message-cleanup-headers)
+    (if (not (let ((message-post-method method))
+              (message-check-news-syntax)))
+       nil
+      (unwind-protect
+         (save-excursion
+           (set-buffer tembuf)
+           (buffer-disable-undo)
+           (erase-buffer)
+           (insert-buffer-substring message-encoding-buffer)
+           ;; Remove some headers.
+           (save-restriction
+             (message-narrow-to-headers)
+;; We Semi-gnus people have no use for it.
+;;           ;; We (re)generate the Lines header.
+;;           (when (memq 'Lines message-required-mail-headers)
+;;             (message-generate-headers '(Lines)))
+             ;; Remove some headers.
+             (message-remove-header message-ignored-news-headers t))
+           (goto-char (point-max))
+           ;; require one newline at the end.
+           (or (= (preceding-char) ?\n)
+               (insert ?\n))
+           (setq result (message-maybe-split-and-send-news method)))
+       (kill-buffer tembuf))
+      (set-buffer message-edit-buffer)
+      (if result
+         (progn
+           (message "Couldn't send message via news: %s"
+                    (nnheader-get-report (car method)))
+           nil)
+       (push 'news message-sent-message-via)))))
+
+;; 1997-09-29 by MORIOKA Tomohiko
+(defun message-send-news-with-gnus (method)
+  (let ((case-fold-search t))
+    ;; Remove the delimiter.
+    (goto-char (point-min))
+    (re-search-forward
+     (concat "^" (regexp-quote mail-header-separator) "\n"))
+    (replace-match "\n")
+    (backward-char 1)
+    (run-hooks 'message-send-news-hook)
+    (gnus-open-server method)
+    (message "Sending news via %s..." (gnus-server-string method))
+    (gnus-request-post method)
+    ))
+
+;;;
+;;; Header generation & syntax checking.
+;;;
+
+(defun message-check-element (type)
+  "Return non-nil if this TYPE is not to be checked."
+  (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me)
+      t
+    (let ((able (assq type message-syntax-checks)))
+      (and (consp able)
+          (eq (cdr able) 'disabled)))))
+
+(defun message-check-news-syntax ()
+  "Check the syntax of the message."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (and
+       ;; We narrow to the headers and check them first.
+       (save-excursion
+        (save-restriction
+          (message-narrow-to-headers)
+          (message-check-news-header-syntax)))
+       ;; Check the body.
+       (save-excursion
+        (set-buffer message-edit-buffer)
+        (message-check-news-body-syntax))))))
+
+(defun message-check-news-header-syntax ()
+  (and
+   ;; Check Newsgroups header.
+   (message-check 'newsgroups
+     (let ((group (message-fetch-field "newsgroups")))
+       (or
+       (and group
+            (not (string-match "\\`[ \t]*\\'" group)))
+       (ignore
+        (message
+         "The newsgroups field is empty or missing.  Posting is denied.")))))
+   ;; Check the Subject header.
+   (message-check 'subject
+     (let* ((case-fold-search t)
+           (subject (message-fetch-field "subject")))
+       (or
+       (and subject
+            (not (string-match "\\`[ \t]*\\'" subject)))
+       (ignore
+        (message
+         "The subject field is empty or missing.  Posting is denied.")))))
+   ;; Check for commands in Subject.
+   (message-check 'subject-cmsg
+     (if (string-match "^cmsg " (message-fetch-field "subject"))
+        (y-or-n-p
+         "The control code \"cmsg\" is in the subject.  Really post? ")
+       t))
+   ;; Check long header lines.
+   (message-check 'long-header-lines
+     (let ((start (point))
+          (header nil)
+          (length 0)
+          found)
+       (while (and (not found)
+                  (re-search-forward "^\\([^ \t:]+\\): " nil t))
+        (if (> (- (point) (match-beginning 0)) 998)
+            (setq found t
+                  length (- (point) (match-beginning 0)))
+          (setq header (match-string-no-properties 1)))
+        (setq start (match-beginning 0))
+        (forward-line 1))
+       (if found
+          (y-or-n-p (format "Your %s header is too long (%d).  Really post? "
+                            header length))
+        t)))
+   ;; Check for multiple identical headers.
+   (message-check 'multiple-headers
+     (let (found)
+       (while (and (not found)
+                  (re-search-forward "^[^ \t:]+: " nil t))
+        (save-excursion
+          (or (re-search-forward
+               (concat "^"
+                       (regexp-quote
+                        (setq found
+                              (buffer-substring
+                               (match-beginning 0) (- (match-end 0) 2))))
+                       ":")
+               nil t)
+              (setq found nil))))
+       (if found
+          (y-or-n-p (format "Multiple %s headers.  Really post? " found))
+        t)))
+   ;; Check for Version and Sendsys.
+   (message-check 'sendsys
+     (if (re-search-forward "^Sendsys:\\|^Version:" nil t)
+        (y-or-n-p
+         (format "The article contains a %s command.  Really post? "
+                 (buffer-substring (match-beginning 0)
+                                   (1- (match-end 0)))))
+       t))
+   ;; See whether we can shorten Followup-To.
+   (message-check 'shorten-followup-to
+     (let ((newsgroups (message-fetch-field "newsgroups"))
+          (followup-to (message-fetch-field "followup-to"))
+          to)
+       (when (and newsgroups
+                 (string-match "," newsgroups)
+                 (not followup-to)
+                 (not
+                  (zerop
+                   (length
+                    (setq to (completing-read
+                              "Followups to (default: no Followup-To header) "
+                              (mapcar #'list
+                                      (cons "poster"
+                                            (message-tokenize-header
+                                             newsgroups)))))))))
+        (goto-char (point-min))
+        (insert "Followup-To: " to "\n"))
+       t))
+   ;; Check "Shoot me".
+   (message-check 'shoot
+     (if (re-search-forward
+         "Message-ID.*.i-did-not-set--mail-host-address--so-tickle-me" nil t)
+        (y-or-n-p "You appear to have a misconfigured system.  Really post? ")
+       t))
+   ;; Check for Approved.
+   (message-check 'approved
+     (if (re-search-forward "^Approved:" nil t)
+        (y-or-n-p "The article contains an Approved header.  Really post? ")
+       t))
+   ;; Check the Message-ID header.
+   (message-check 'message-id
+     (let* ((case-fold-search t)
+           (message-id (message-fetch-field "message-id" t)))
+       (or (not message-id)
+          ;; Is there an @ in the ID?
+          (and (string-match "@" message-id)
+               ;; Is there a dot in the ID?
+               (string-match "@[^.]*\\." message-id)
+               ;; Does the ID end with a dot?
+               (not (string-match "\\.>" message-id)))
+          (y-or-n-p
+           (format "The Message-ID looks strange: \"%s\".  Really post? "
+                   message-id)))))
+   ;; Check the Newsgroups & Followup-To headers.
+   (message-check 'existing-newsgroups
+     (let* ((case-fold-search t)
+           (newsgroups (message-fetch-field "newsgroups"))
+           (followup-to (message-fetch-field "followup-to"))
+           (groups (message-tokenize-header
+                    (if followup-to
+                        (concat newsgroups "," followup-to)
+                      newsgroups)))
+           (post-method (if (functionp message-post-method)
+                            (funcall message-post-method)
+                          message-post-method))
+           ;; KLUDGE to handle nnvirtual groups.  Doing this right
+           ;; would probably involve a new nnoo function.
+           ;; -- Per Abrahamsen <abraham@dina.kvl.dk>, 2001-10-17.
+           (method (if (and (consp post-method)
+                            (eq (car post-method) 'nnvirtual)
+                            gnus-message-group-art)
+                       (let ((group (car (nnvirtual-find-group-art
+                                          (car gnus-message-group-art)
+                                          (cdr gnus-message-group-art)))))
+                         (gnus-find-method-for-group group))
+                     post-method))
+           (known-groups
+            (mapcar (lambda (n)
+                      (gnus-group-name-decode
+                       (gnus-group-real-name n)
+                       (gnus-group-name-charset method n)))
+                    (gnus-groups-from-server method)))
+           errors)
+       (while groups
+        (when (and (not (equal (car groups) "poster"))
+                   (not (member (car groups) known-groups))
+                   (not (member (car groups) errors)))
+          (push (car groups) errors))
+        (pop groups))
+       (cond
+       ;; Gnus is not running.
+       ((or (not (and (boundp 'gnus-active-hashtb)
+                      gnus-active-hashtb))
+            (not (boundp 'gnus-read-active-file)))
+        t)
+       ;; We don't have all the group names.
+       ((and (or (not gnus-read-active-file)
+                 (eq gnus-read-active-file 'some))
+             errors)
+        (y-or-n-p
+         (format
+          "Really use %s possibly unknown group%s: %s? "
+          (if (= (length errors) 1) "this" "these")
+          (if (= (length errors) 1) "" "s")
+          (mapconcat 'identity errors ", "))))
+       ;; There were no errors.
+       ((not errors)
+        t)
+       ;; There are unknown groups.
+       (t
+        (y-or-n-p
+         (format
+          "Really post to %s unknown group%s: %s? "
+          (if (= (length errors) 1) "this" "these")
+          (if (= (length errors) 1) "" "s")
+          (mapconcat 'identity errors ", ")))))))
+   ;; Check continuation headers.
+   (message-check 'continuation-headers
+     (goto-char (point-min))
+     (let ((do-posting t))
+       (while (re-search-forward "^[^ \t\n][^:\n]*$" nil t)
+        (if (y-or-n-p "Fix continuation lines? ")
+            (progn
+              (goto-char (match-beginning 0))
+              (insert " "))
+          (unless (y-or-n-p "Send anyway? ")
+            (setq do-posting nil))))
+       do-posting))
+   ;; Check the Newsgroups & Followup-To headers for syntax errors.
+   (message-check 'valid-newsgroups
+     (let ((case-fold-search t)
+          (headers '("Newsgroups" "Followup-To"))
+          header error)
+       (while (and headers (not error))
+        (when (setq header (mail-fetch-field (car headers)))
+          (if (or
+               (not
+                (string-match
+                 "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'"
+                 header))
+               (memq
+                nil (mapcar
+                     (lambda (g)
+                       (not (string-match "\\.\\'\\|\\.\\." g)))
+                     (message-tokenize-header header ","))))
+              (setq error t)))
+        (unless error
+          (pop headers)))
+       (if (not error)
+          t
+        (y-or-n-p
+         (format "The %s header looks odd: \"%s\".  Really post? "
+                 (car headers) header)))))
+   (message-check 'repeated-newsgroups
+     (let ((case-fold-search t)
+          (headers '("Newsgroups" "Followup-To"))
+          header error groups group)
+       (while (and headers
+                  (not error))
+        (when (setq header (mail-fetch-field (pop headers)))
+          (setq groups (message-tokenize-header header ","))
+          (while (setq group (pop groups))
+            (when (member group groups)
+              (setq error group
+                    groups nil)))))
+       (if (not error)
+          t
+        (y-or-n-p
+         (format "Group %s is repeated in headers.  Really post? " error)))))
+   ;; Check the From header.
+   (message-check 'from
+     (let* ((case-fold-search t)
+           (from (message-fetch-field "from"))
+           ad)
+       (cond
+       ((not from)
+        (message "There is no From line.  Posting is denied.")
+        nil)
+       ((or (not (string-match
+                  "@[^\\.]*\\."
+                  (setq ad (nth 1 (std11-extract-address-components
+                                   from))))) ;larsi@ifi
+            (string-match "\\.\\." ad) ;larsi@ifi..uio
+            (string-match "@\\." ad)   ;larsi@.ifi.uio
+            (string-match "\\.$" ad)   ;larsi@ifi.uio.
+            (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio
+            (string-match "(.*).*(.*)" from)) ;(lars) (lars)
+        (message
+         "Denied posting -- the From looks strange: \"%s\"." from)
+        nil)
+       ((let ((addresses (rfc822-addresses from)))
+          (while (and addresses
+                      (not (eq (string-to-char (car addresses)) ?\()))
+            (setq addresses (cdr addresses)))
+          addresses)
+        (message
+         "Denied posting -- bad From address: \"%s\"." from)
+        nil)
+       (t t))))
+   ;; Check the Reply-To header.
+   (message-check 'reply-to
+     (let* ((case-fold-search t)
+           (reply-to (message-fetch-field "reply-to"))
+           ad)
+       (cond
+       ((not reply-to)
+        t)
+       ((string-match "," reply-to)
+        (y-or-n-p
+         (format "Multiple Reply-To addresses: \"%s\". Really post? "
+                 reply-to)))
+       ((or (not (string-match
+                  "@[^\\.]*\\."
+                  (setq ad (nth 1 (std11-extract-address-components
+                                   reply-to))))) ;larsi@ifi
+            (string-match "\\.\\." ad) ;larsi@ifi..uio
+            (string-match "@\\." ad)   ;larsi@.ifi.uio
+            (string-match "\\.$" ad)   ;larsi@ifi.uio.
+            (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio
+            (string-match "(.*).*(.*)" reply-to)) ;(lars) (lars)
+        (y-or-n-p
+         (format
+          "The Reply-To looks strange: \"%s\". Really post? "
+          reply-to)))
+       (t t))))))
+
+(defun message-check-news-body-syntax ()
+  (and
+   ;; Check for long lines.
+   (message-check 'long-lines
+     (goto-char (point-min))
+     (re-search-forward
+      (concat "^" (regexp-quote mail-header-separator) "$"))
+     (forward-line 1)
+     (while (and
+            (or (looking-at
+                 mime-edit-tag-regexp)
+                (let ((p (point)))
+                  (end-of-line)
+                  (< (- (point) p) 80)))
+            (zerop (forward-line 1))))
+     (or (bolp)
+        (eobp)
+        (y-or-n-p
+         "You have lines longer than 79 characters.  Really post? ")))
+   ;; Check whether the article is empty.
+   (message-check 'empty
+     (goto-char (point-min))
+     (re-search-forward
+      (concat "^" (regexp-quote mail-header-separator) "$"))
+     (forward-line 1)
+     (let ((b (point)))
+       (goto-char (point-max))
+       (re-search-backward message-signature-separator nil t)
+       (beginning-of-line)
+       (or (re-search-backward "[^ \n\t]" b t)
+          (if (message-gnksa-enable-p 'empty-article)
+              (y-or-n-p "Empty article.  Really post? ")
+            (message "Denied posting -- Empty article.")
+            nil))))
+   ;; Check for control characters.
+   (message-check 'control-chars
+     (if (re-search-forward "[\000-\007\013\015-\032\034-\037\200-\237]" nil t)
+        (y-or-n-p
+         "The article contains control characters.  Really post? ")
+       t))
+   ;; Check 8bit characters.
+   (message-check '8bit
+     (message-check-8bit))
+   ;; Check excessive size.
+   (message-check 'size
+     (if (> (buffer-size) 60000)
+        (y-or-n-p
+         (format "The article is %d octets long.  Really post? "
+                 (buffer-size)))
+       t))
+   ;; Check whether any new text has been added.
+   (message-check 'new-text
+     (or
+      (not message-checksum)
+      (not (eq (message-checksum) message-checksum))
+      (if (message-gnksa-enable-p 'quoted-text-only)
+         (y-or-n-p
+          "It looks like no new text has been added.  Really post? ")
+       (message "Denied posting -- no new text has been added.")
+       nil)))
+   ;; Check the length of the signature.
+   (message-check 'signature
+     (goto-char (point-max))
+     (if (> (count-lines (point) (point-max)) 5)
+        (y-or-n-p
+         (format
+          "Your .sig is %d lines; it should be max 4.  Really post? "
+          (1- (count-lines (point) (point-max)))))
+       t))
+   ;; Ensure that text follows last quoted portion.
+   (message-check 'quoting-style
+     (goto-char (point-max))
+     (let ((no-problem t))
+       (when (search-backward-regexp "^>[^\n]*\n" nil t)
+        (setq no-problem (search-forward-regexp "^[ \t]*[^>\n]" nil t)))
+       (if no-problem
+          t
+        (if (message-gnksa-enable-p 'quoted-text-only)
+            (y-or-n-p "Your text should follow quoted text.  Really post? ")
+          ;; Ensure that
+          (goto-char (point-min))
+          (re-search-forward
+           (concat "^" (regexp-quote mail-header-separator) "$"))
+          (if (search-forward-regexp "^[ \t]*[^>\n]" nil t)
+              (y-or-n-p "Your text should follow quoted text.  Really post? ")
+            (message "Denied posting -- only quoted text.")
+            nil)))))))
+
+(defun message-check-mail-syntax ()
+  "Check the syntax of the message."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (and
+       ;; We narrow to the headers and check them first.
+       (save-excursion
+        (save-restriction
+          (message-narrow-to-headers)
+          (message-check-mail-header-syntax)))
+       ;; Check the body.
+       (save-excursion
+        (set-buffer message-edit-buffer)
+        (message-check-mail-body-syntax))))))
+
+(defun message-check-mail-header-syntax ()
+  t)
+
+(defun message-check-mail-body-syntax ()
+  (and
+   ;; Check 8bit characters.
+   (message-check '8bit
+     (message-check-8bit)
+     )))
+
+(defun message-check-8bit ()
+  "Check the article contains 8bit characters."
+  (save-excursion
+    (set-buffer message-encoding-buffer)
+    (message-narrow-to-headers)
+    (let* ((case-fold-search t)
+          (field-value (message-fetch-field "content-transfer-encoding")))
+      (if (and field-value
+              (member (downcase field-value) message-8bit-encoding-list))
+         t
+       (widen)
+       (set-buffer (get-buffer-create " message syntax"))
+       (erase-buffer)
+       (goto-char (point-min))
+       (set-buffer-multibyte nil)
+       (insert-buffer-substring message-encoding-buffer)
+       (goto-char (point-min))
+       (if (re-search-forward "[^\x00-\x7f]" nil t)
+           (y-or-n-p
+            "The article contains 8bit characters.  Really post? ")
+         t)))))
+
+(defun message-checksum ()
+  "Return a \"checksum\" for the current buffer."
+  (let ((sum 0))
+    (save-excursion
+      (goto-char (point-min))
+      (re-search-forward
+       (concat "^" (regexp-quote mail-header-separator) "$"))
+      (while (not (eobp))
+       (when (not (looking-at "[ \t\n]"))
+         (setq sum (logxor (ash sum 1) (if (natnump sum) 0 1)
+                           (char-after))))
+       (forward-char 1)))
+    sum))
+
+(defun message-do-fcc ()
+  "Process Fcc headers in the current buffer."
+  (let ((case-fold-search t)
+       (coding-system-for-write 'raw-text)
+       (output-coding-system 'raw-text)
+       list file
+       (mml-externalize-attachments message-fcc-externalize-attachments))
+    (save-excursion
+      (save-restriction
+       (message-narrow-to-headers)
+       (setq file (message-fetch-field "fcc" t)))
+      (when file
+       (set-buffer (get-buffer-create " *message temp*"))
+       (erase-buffer)
+       (insert-buffer-substring message-encoding-buffer)
+       (save-restriction
+         (message-narrow-to-headers)
+         (while (setq file (message-fetch-field "fcc"))
+           (push file list)
+           (message-remove-header "fcc" nil t)))
+       (goto-char (point-min))
+       (when (re-search-forward
+              (concat "^" (regexp-quote mail-header-separator) "$")
+              nil t)
+         (replace-match "" t t))
+       ;; Process FCC operations.
+       (while list
+         (setq file (pop list))
+         (if (string-match "^[ \t]*|[ \t]*\\(.*\\)[ \t]*$" file)
+             ;; Pipe the article to the program in question.
+             (call-process-region (point-min) (point-max) shell-file-name
+                                  nil nil nil shell-command-switch
+                                  (match-string 1 file))
+           ;; Save the article.
+           (setq file (expand-file-name file))
+           (unless (file-exists-p (file-name-directory file))
+             (make-directory (file-name-directory file) t))
+           (if (and message-fcc-handler-function
+                    (not (eq message-fcc-handler-function 'rmail-output)))
+               (funcall message-fcc-handler-function file)
+             (if (and (file-readable-p file) (mail-file-babyl-p file))
+                 (rmail-output file 1 nil t)
+               (let ((mail-use-rfc822 t))
+                 (rmail-output file 1 t t))))))
+       (kill-buffer (current-buffer))))))
+
+(defun message-output (filename)
+  "Append this article to Unix/babyl mail file FILENAME."
+  (if (and (file-readable-p filename)
+          (mail-file-babyl-p filename))
+      (gnus-output-to-rmail filename t)
+    (gnus-output-to-mail filename t)))
+
+(defun message-cleanup-headers ()
+  "Do various automatic cleanups of the headers."
+  ;; Remove empty lines in the header.
+  (save-restriction
+    (message-narrow-to-headers)
+    ;; Remove blank lines.
+    (while (re-search-forward "^[ \t]*\n" nil t)
+      (replace-match "" t t))
+
+    ;; Correct Newsgroups and Followup-To headers:  Change sequence of
+    ;; spaces to comma and eliminate spaces around commas.  Eliminate
+    ;; embedded line breaks.
+    (goto-char (point-min))
+    (while (re-search-forward "^\\(Newsgroups\\|Followup-To\\): +" nil t)
+      (save-restriction
+       (narrow-to-region
+        (point)
+        (if (re-search-forward "^[^ \t]" nil t)
+            (match-beginning 0)
+          (forward-line 1)
+          (point)))
+       (goto-char (point-min))
+       (while (re-search-forward "\n[ \t]+" nil t)
+         (replace-match " " t t))      ;No line breaks (too confusing)
+       (goto-char (point-min))
+       (while (re-search-forward "[ \t\n]*,[ \t\n]*\\|[ \t]+" nil t)
+         (replace-match "," t t))
+       (goto-char (point-min))
+       ;; Remove trailing commas.
+       (when (re-search-forward ",+$" nil t)
+         (replace-match "" t t))))))
+
+(defun message-make-date (&optional now)
+  "Make a valid data header.
+If NOW, use that time instead."
+  (let* ((now (or now (current-time)))
+        (zone (nth 8 (decode-time now)))
+        (sign "+"))
+    (when (< zone 0)
+      (setq sign "-")
+      (setq zone (- zone)))
+    (concat
+     ;; The day name of the %a spec is locale-specific.  Pfff.
+     (format "%s, " (capitalize (car (rassoc (nth 6 (decode-time now))
+                                            parse-time-weekdays))))
+     (format-time-string "%d" now)
+     ;; The month name of the %b spec is locale-specific.  Pfff.
+     (format " %s "
+            (capitalize (car (rassoc (nth 4 (decode-time now))
+                                     parse-time-months))))
+     (format-time-string "%Y %H:%M:%S " now)
+     ;; We do all of this because XEmacs doesn't have the %z spec.
+     (format "%s%02d%02d" sign (/ zone 3600) (/ (% zone 3600) 60)))))
+
+(defun message-make-followup-subject (subject)
+  "Make a followup Subject."
+  (cond
+   ((and (eq message-use-subject-re 'guess)
+        (string-match message-subject-encoded-re-regexp subject))
+    subject)
+   (message-use-subject-re
+    (concat "Re: " (message-strip-subject-re subject)))
+   (t subject)))
+
+(defun message-make-message-id ()
+  "Make a unique Message-ID."
+  (concat "<" (message-unique-id)
+         (let ((psubject (save-excursion (message-fetch-field "subject")))
+               (psupersedes
+                (save-excursion (message-fetch-field "supersedes"))))
+           (if (or
+                (and message-reply-headers
+                     (mail-header-references message-reply-headers)
+                     (mail-header-subject message-reply-headers)
+                     psubject
+                     (not (string=
+                           (message-strip-subject-re
+                            (mail-header-subject message-reply-headers))
+                           (message-strip-subject-re psubject))))
+                (and psupersedes
+                     (string-match "_-_@" psupersedes)))
+               "_-_" ""))
+         "@" (message-make-fqdn) ">"))
+
+(defvar message-unique-id-char nil)
+
+;; If you ever change this function, make sure the new version
+;; cannot generate IDs that the old version could.
+;; You might for example insert a "." somewhere (not next to another dot
+;; or string boundary), or modify the "fsf" string.
+(defun message-unique-id ()
+  ;; Don't use microseconds from (current-time), they may be unsupported.
+  ;; Instead we use this randomly inited counter.
+  (setq message-unique-id-char
+       (% (1+ (or message-unique-id-char (logand (random t) (1- (lsh 1 20)))))
+          ;; (current-time) returns 16-bit ints,
+          ;; and 2^16*25 just fits into 4 digits i base 36.
+          (* 25 25)))
+  (let ((tm (current-time)))
+    (concat
+     (if (memq system-type '(ms-dos emx vax-vms))
+        (let ((user (downcase (user-login-name))))
+          (while (string-match "[^a-z0-9_]" user)
+            (aset user (match-beginning 0) ?_))
+          user)
+       (message-number-base36 (user-uid) -1))
+     (message-number-base36 (+ (car tm)
+                              (lsh (% message-unique-id-char 25) 16)) 4)
+     (message-number-base36 (+ (nth 1 tm)
+                              (lsh (/ message-unique-id-char 25) 16)) 4)
+     ;; Append a given name, because while the generated ID is unique
+     ;; to this newsreader, other newsreaders might otherwise generate
+     ;; the same ID via another algorithm.
+     ".fsf")))
+
+(defun message-number-base36 (num len)
+  (if (if (< len 0)
+         (<= num 0)
+       (= len 0))
+      ""
+    (concat (message-number-base36 (/ num 36) (1- len))
+           (char-to-string (aref "zyxwvutsrqponmlkjihgfedcba9876543210"
+                                 (% num 36))))))
+
+(defun message-make-organization ()
+  "Make an Organization header."
+  (let* ((organization
+         (when message-user-organization
+           (if (functionp message-user-organization)
+               (funcall message-user-organization)
+             message-user-organization))))
+    (with-temp-buffer
+      (set-buffer-multibyte t)
+      (cond ((stringp organization)
+            (insert organization))
+           ((and (eq t organization)
+                 message-user-organization-file
+                 (file-exists-p message-user-organization-file))
+            (insert-file-contents message-user-organization-file)))
+      (goto-char (point-min))
+      (while (re-search-forward "[\t\n]+" nil t)
+       (replace-match "" t t))
+      (unless (zerop (buffer-size))
+       (buffer-string)))))
+
+(defun message-make-lines ()
+  "Count the number of lines and return numeric string."
+  (save-excursion
+    (save-restriction
+      (widen)
+      (message-goto-body)
+      (int-to-string (count-lines (point) (point-max))))))
+
+(defun message-make-references ()
+  "Return the References header for this message."
+  (when message-reply-headers
+    (let ((message-id (mail-header-message-id message-reply-headers))
+         (references (mail-header-references message-reply-headers))
+         new-references)
+      (if (or references message-id)
+         (concat (or references "") (and references " ")
+                 (or message-id ""))
+       nil))))
+
+(defun message-make-in-reply-to ()
+  "Return the In-Reply-To header for this message."
+  (when message-reply-headers
+    (let ((from (mail-header-from message-reply-headers))
+         (date (mail-header-date message-reply-headers))
+         (msg-id (mail-header-message-id message-reply-headers)))
+      (when from
+       (let ((name (std11-extract-address-components from)))
+         (concat msg-id (if msg-id " (")
+                 (or (car name)
+                     (nth 1 name))
+                 "'s message of \""
+                 (if (or (not date) (string= date ""))
+                     "(unknown date)" date)
+                 "\"" (if msg-id ")")))))))
+
+(defun message-make-distribution ()
+  "Make a Distribution header."
+  (let ((orig-distribution (message-fetch-reply-field "distribution")))
+    (cond ((functionp message-distribution-function)
+          (funcall message-distribution-function))
+         (t orig-distribution))))
+
+(defun message-make-expires ()
+  "Return an Expires header based on `message-expires'."
+  (let ((current (current-time))
+       (future (* 1.0 message-expires 60 60 24)))
+    ;; Add the future to current.
+    (setcar current (+ (car current) (round (/ future (expt 2 16)))))
+    (setcar (cdr current) (+ (nth 1 current) (% (round future) (expt 2 16))))
+    (message-make-date current)))
+
+(defun message-make-path ()
+  "Return uucp path."
+  (let ((login-name (user-login-name)))
+    (cond ((null message-user-path)
+          (concat (system-name) "!" login-name))
+         ((stringp message-user-path)
+          ;; Support GENERICPATH.  Suggested by vixie@decwrl.dec.com.
+          (concat message-user-path "!" login-name))
+         (t login-name))))
+
+(defun message-make-from ()
+  "Make a From header."
+  (let* ((style message-from-style)
+        (login (message-make-address))
+        (fullname
+         (or (and (boundp 'user-full-name)
+                  user-full-name)
+             (user-full-name))))
+    (when (string= fullname "&")
+      (setq fullname (user-login-name)))
+    (with-temp-buffer
+      (set-buffer-multibyte t)
+      (cond
+       ((or (null style)
+           (equal fullname ""))
+       (insert login))
+       ((or (eq style 'angles)
+           (and (not (eq style 'parens))
+                ;; Use angles if no quoting is needed, or if parens would
+                ;; need quoting too.
+                (or (not (string-match "[^- !#-'*+/-9=?A-Z^-~]" fullname))
+                    (let ((tmp (concat fullname nil)))
+                      (while (string-match "([^()]*)" tmp)
+                        (aset tmp (match-beginning 0) ?-)
+                        (aset tmp (1- (match-end 0)) ?-))
+                      (string-match "[\\()]" tmp)))))
+       (insert fullname)
+       (goto-char (point-min))
+       ;; Look for a character that cannot appear unquoted
+       ;; according to RFC 822.
+       (when (re-search-forward "[^- !#-'*+/-9=?A-Z^-~]" nil 1)
+         ;; Quote fullname, escaping specials.
+         (goto-char (point-min))
+         (insert "\"")
+         (while (re-search-forward "[\"\\]" nil 1)
+           (replace-match "\\\\\\&" t))
+         (insert "\""))
+       (insert " <" login ">"))
+       (t                              ; 'parens or default
+       (insert login " (")
+       (let ((fullname-start (point)))
+         (insert fullname)
+         (goto-char fullname-start)
+         ;; RFC 822 says \ and nonmatching parentheses
+         ;; must be escaped in comments.
+         ;; Escape every instance of ()\ ...
+         (while (re-search-forward "[()\\]" nil 1)
+           (replace-match "\\\\\\&" t))
+         ;; ... then undo escaping of matching parentheses,
+         ;; including matching nested parentheses.
+         (goto-char fullname-start)
+         (while (re-search-forward
+                 "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)"
+                 nil 1)
+           (replace-match "\\1(\\3)" t)
+           (goto-char fullname-start)))
+       (insert ")")))
+      (buffer-string))))
+
+(defun message-make-sender ()
+  "Return the \"real\" user address.
+This function tries to ignore all user modifications, and
+give as trustworthy answer as possible."
+  (concat (user-login-name) "@" (system-name)))
+
+(defun message-make-address ()
+  "Make the address of the user."
+  (or (message-user-mail-address)
+      (concat (user-login-name) "@" (message-make-domain))))
+
+(defun message-user-mail-address ()
+  "Return the pertinent part of `user-mail-address'."
+  (when (and user-mail-address
+            (string-match "@.*\\." user-mail-address))
+    (if (string-match " " user-mail-address)
+       (nth 1 (std11-extract-address-components user-mail-address))
+      user-mail-address)))
+
+(defun message-sendmail-envelope-from ()
+  "Return the envelope from."
+  (cond ((eq message-sendmail-envelope-from 'header)
+        (nth 1 (std11-extract-address-components
+                (message-fetch-field "from"))))
+       ((stringp message-sendmail-envelope-from)
+        message-sendmail-envelope-from)
+       (t
+        (message-make-address))))
+
+(defun message-make-fqdn ()
+  "Return user's fully qualified domain name."
+  (let* ((system-name (system-name))
+        (user-mail (message-user-mail-address))
+        (user-domain
+         (if (and user-mail
+                  (string-match "@\\(.*\\)\\'" user-mail))
+             (match-string 1 user-mail)))
+        (case-fold-search t))
+    (cond
+     ((and message-user-fqdn
+          (stringp message-user-fqdn)
+          (string-match message-valid-fqdn-regexp message-user-fqdn)
+          (not (string-match message-bogus-system-names message-user-fqdn)))
+      message-user-fqdn)
+     ;; `message-user-fqdn' seems to be valid
+     ((and (string-match message-valid-fqdn-regexp system-name)
+          (not (string-match message-bogus-system-names system-name)))
+      ;; `system-name' returned the right result.
+      system-name)
+     ;; Try `mail-host-address'.
+     ((and (boundp 'mail-host-address)
+          (stringp mail-host-address)
+          (string-match message-valid-fqdn-regexp mail-host-address)
+          (not (string-match message-bogus-system-names mail-host-address)))
+      mail-host-address)
+     ;; We try `user-mail-address' as a backup.
+     ((and user-domain
+          (stringp user-domain)
+          (string-match message-valid-fqdn-regexp user-domain)
+          (not (string-match message-bogus-system-names user-domain)))
+      user-domain)
+     ;; Default to this bogus thing.
+     (t
+      (concat system-name
+             ".i-did-not-set--mail-host-address--so-tickle-me")))))
+
+(defun message-make-host-name ()
+  "Return the name of the host."
+  (let ((fqdn (message-make-fqdn)))
+    (string-match "^[^.]+\\." fqdn)
+    (substring fqdn 0 (1- (match-end 0)))))
+
+(defun message-make-domain ()
+  "Return the domain name."
+  (or mail-host-address
+      (message-make-fqdn)))
+
+(defun message-to-list-only ()
+  "Send a message to the list only.
+Remove all addresses but the list address from To and Cc headers."
+  (interactive)
+  (let ((listaddr (message-make-mail-followup-to t)))
+    (when listaddr
+      (save-excursion
+       (message-remove-header "to")
+       (message-remove-header "cc")
+       (message-position-on-field "To" "X-Draft-From")
+       (insert listaddr)))))
+
+(defun message-make-mail-followup-to (&optional only-show-subscribed)
+  "Return the Mail-Followup-To header.
+If passed the optional argument ONLY-SHOW-SUBSCRIBED only return the
+subscribed address (and not the additional To and Cc header contents)."
+  (let* ((case-fold-search t)
+        (to (message-fetch-field "To"))
+        (cc (message-fetch-field "cc"))
+        (msg-recipients (concat to (and to cc ", ") cc))
+        (recipients
+         (mapcar 'mail-strip-quoted-names
+                 (message-tokenize-header msg-recipients)))
+        (file-regexps
+         (if message-subscribed-address-file
+             (let (begin end item re)
+               (save-excursion
+                 (with-temp-buffer
+                   (insert-file-contents message-subscribed-address-file)
+                   (while (not (eobp))
+                     (setq begin (point))
+                     (forward-line 1)
+                     (setq end (point))
+                     (if (bolp) (setq end (1- end)))
+                     (setq item (regexp-quote (buffer-substring begin end)))
+                     (if re (setq re (concat re "\\|" item))
+                       (setq re (concat "\\`\\(" item))))
+                   (and re (list (concat re "\\)\\'"))))))))
+        (mft-regexps (apply 'append message-subscribed-regexps
+                            (mapcar 'regexp-quote
+                                    message-subscribed-addresses)
+                            file-regexps
+                            (mapcar 'funcall
+                                    message-subscribed-address-functions))))
+    (save-match-data
+      (let ((subscribed-lists nil)
+           (list
+            (loop for recipient in recipients
+              when (loop for regexp in mft-regexps
+                     when (string-match regexp recipient) return t)
+              return recipient)))
+       (when list
+         (if only-show-subscribed
+             list
+           msg-recipients))))))
+
+;; Dummy to avoid byte-compile warning.
+(defvar mule-version)
+(defvar emacs-beta-version)
+(defvar xemacs-codename)
+(defvar gnus-inviolable-extended-version)
+
+(defun message-make-user-agent ()
+  "Return user-agent info if the value `message-user-agent' is non-nil. If the
+\"User-Agent\" field has already exist, remove it."
+  (when message-user-agent
+    (save-excursion
+      (goto-char (point-min))
+      (let ((case-fold-search t))
+       (when (re-search-forward "^User-Agent:[\t ]*" nil t)
+         (delete-region (match-beginning 0) (1+ (std11-field-end)))))))
+  message-user-agent)
+
+(defun message-idna-inside-rhs-p ()
+  "Return t iff point is inside a RHS (heuristically).
+Only works properly if header contains mailbox-list or address-list.
+I.e., calling it on a Subject: header is useless."
+  (save-restriction
+    (narrow-to-region (save-excursion (or (re-search-backward "^[^ \t]" nil t)
+                                         (point-min)))
+                     (save-excursion (or (re-search-forward "^[^ \t]" nil t)
+                                         (point-max))))
+    (if (re-search-backward "[\\\n\r\t ]"
+                           (save-excursion (search-backward "@" nil t)) t)
+       ;; whitespace between @ and point
+       nil
+      (let ((dquote 1) (paren 1))
+       (while (save-excursion (re-search-backward "[^\\]\"" nil t dquote))
+         (incf dquote))
+       (while (save-excursion (re-search-backward "[^\\]\(" nil t paren))
+         (incf paren))
+       (and (= (% dquote 2) 1) (= (% paren 2) 1))))))
+
+(autoload 'idna-to-ascii "idna")
+
+(defun message-idna-to-ascii-rhs-1 (header)
+  "Interactively potentially IDNA encode domain names in HEADER."
+  (let (rhs ace start startpos endpos ovl)
+    (goto-char (point-min))
+    (while (re-search-forward (concat "^" header) nil t)
+      (while (re-search-forward "@\\([^ \t\r\n>,]+\\)"
+                               (or (save-excursion
+                                     (re-search-forward "^[^ \t]" nil t))
+                                   (point-max))
+                               t)
+       (setq rhs (match-string-no-properties 1)
+             startpos (match-beginning 1)
+             endpos (match-end 1))
+       (when (save-match-data
+               (and (message-idna-inside-rhs-p)
+                    (setq ace (idna-to-ascii rhs))
+                    (not (string= rhs ace))
+                    (if (eq message-use-idna 'ask)
+                        (unwind-protect
+                            (progn
+                              (setq ovl (message-make-overlay startpos
+                                                              endpos))
+                              (message-overlay-put ovl 'face 'highlight)
+                              (y-or-n-p
+                               (format "Replace with `%s'? " ace)))
+                          (message "")
+                          (message-delete-overlay ovl))
+                      message-use-idna)))
+         (replace-match (concat "@" ace)))))))
+
+(defun message-idna-to-ascii-rhs ()
+  "Possibly IDNA encode non-ASCII domain names in From:, To: and Cc: headers.
+See `message-idna-encode'."
+  (interactive)
+  (when message-use-idna
+    (save-excursion
+      (save-restriction
+       (message-narrow-to-head)
+       (message-idna-to-ascii-rhs-1 "From")
+       (message-idna-to-ascii-rhs-1 "To")
+       (message-idna-to-ascii-rhs-1 "Cc")))))
+
+(defun message-generate-headers (headers)
+  "Prepare article HEADERS.
+Headers already prepared in the buffer are not modified."
+  (setq headers (append headers message-required-headers))
+  (save-restriction
+    (message-narrow-to-headers)
+    (let* ((Date (message-make-date))
+          (Message-ID (message-make-message-id))
+          (Organization (message-make-organization))
+          (From (message-make-from))
+          (Path (message-make-path))
+          (Subject nil)
+          (Newsgroups nil)
+          (In-Reply-To (message-make-in-reply-to))
+          (References (message-make-references))
+          (To nil)
+          (Distribution (message-make-distribution))
+          (Lines (message-make-lines))
+          (User-Agent (message-make-user-agent))
+          (Expires (message-make-expires))
+          (case-fold-search t)
+          (optionalp nil)
+          header value elem header-string)
+      ;; First we remove any old generated headers.
+      (let ((headers message-deletable-headers))
+       (unless (buffer-modified-p)
+         (setq headers (delq 'Message-ID (copy-sequence headers))))
+       (while headers
+         (goto-char (point-min))
+         (and (re-search-forward
+               (concat "^" (symbol-name (car headers)) ": *") nil t)
+              (get-text-property (1+ (match-beginning 0)) 'message-deletable)
+              (message-delete-line))
+         (pop headers)))
+      ;; Go through all the required headers and see if they are in the
+      ;; articles already.  If they are not, or are empty, they are
+      ;; inserted automatically - except for Subject, Newsgroups and
+      ;; Distribution.
+      (while headers
+       (goto-char (point-min))
+       (setq elem (pop headers))
+       (if (consp elem)
+           (if (eq (car elem) 'optional)
+               (setq header (cdr elem)
+                     optionalp t)
+             (setq header (car elem)))
+         (setq header elem))
+       (setq header-string  (if (stringp header)
+                                header
+                              (symbol-name header)))
+       (when (or (not (re-search-forward
+                       (concat "^"
+                               (regexp-quote (downcase header-string))
+                               ":")
+                       nil t))
+                 (progn
+                   ;; The header was found.  We insert a space after the
+                   ;; colon, if there is none.
+                   (if (/= (char-after) ? ) (insert " ") (forward-char 1))
+                   ;; Find out whether the header is empty.
+                   (looking-at "[ \t]*\n[^ \t]")))
+         ;; So we find out what value we should insert.
+         (setq value
+               (cond
+                ((and (consp elem)
+                      (eq (car elem) 'optional)
+                      (not (member header-string message-inserted-headers)))
+                 ;; This is an optional header.  If the cdr of this
+                 ;; is something that is nil, then we do not insert
+                 ;; this header.
+                 (setq header (cdr elem))
+                 (or (and (functionp (cdr elem))
+                          (funcall (cdr elem)))
+                     (and (boundp (cdr elem))
+                          (symbol-value (cdr elem)))))
+                ((consp elem)
+                 ;; The element is a cons.  Either the cdr is a
+                 ;; string to be inserted verbatim, or it is a
+                 ;; function, and we insert the value returned from
+                 ;; this function.
+                 (or (and (stringp (cdr elem))
+                          (cdr elem))
+                     (and (functionp (cdr elem))
+                          (funcall (cdr elem)))))
+                ((and (boundp header)
+                      (symbol-value header))
+                 ;; The element is a symbol.  We insert the value
+                 ;; of this symbol, if any.
+                 (symbol-value header))
+                ((not (message-check-element header))
+                 ;; We couldn't generate a value for this header,
+                 ;; so we just ask the user.
+                 (read-from-minibuffer
+                  (format "Empty header for %s; enter value: " header)))))
+         ;; Finally insert the header.
+         (when (and value
+                    (not (equal value "")))
+           (save-excursion
+             (if (bolp)
+                 (progn
+                   ;; This header didn't exist, so we insert it.
+                   (goto-char (point-max))
+                   (let ((formatter
+                          (cdr (assq header message-header-format-alist))))
+                     (if formatter
+                         (funcall formatter header value)
+                       (insert header-string ": " value))
+                     ;; We check whether the value was ended by a
+                     ;; newline.  If now, we insert one.
+                     (unless (bolp)
+                       (insert "\n"))
+                     (forward-line -1)))
+               ;; The value of this header was empty, so we clear
+               ;; totally and insert the new value.
+               (delete-region (point) (gnus-point-at-eol))
+               ;; If the header is optional, and the header was
+               ;; empty, we can't insert it anyway.
+               (unless optionalp
+                 (push header-string message-inserted-headers)
+                 (insert value)
+                 (when (bolp)
+                   (delete-char -1))))
+             ;; Add the deletable property to the headers that require it.
+             (and (memq header message-deletable-headers)
+                  (progn (beginning-of-line) (looking-at "[^:]+: "))
+                  (add-text-properties
+                   (point) (match-end 0)
+                   '(message-deletable t face italic) (current-buffer)))))))
+      ;; Insert new Sender if the From is strange.
+      (let ((from (message-fetch-field "from"))
+           (sender (message-fetch-field "sender"))
+           (secure-sender (message-make-sender)))
+       (when (and from
+                  (not (message-check-element 'sender))
+                  (not (string=
+                        (downcase
+                         (cadr (std11-extract-address-components from)))
+                        (downcase secure-sender)))
+                  (or (null sender)
+                      (not
+                       (string=
+                        (downcase
+                         (cadr (std11-extract-address-components sender)))
+                        (downcase secure-sender)))))
+         (goto-char (point-min))
+         ;; Rename any old Sender headers to Original-Sender.
+         (when (re-search-forward "^\\(Original-\\)*Sender:" nil t)
+           (beginning-of-line)
+           (insert "Original-")
+           (beginning-of-line))
+         (when (or (message-news-p)
+                   (string-match "@.+\\.." secure-sender))
+           (insert "Sender: " secure-sender "\n"))))
+      ;; Check for IDNA
+      (message-idna-to-ascii-rhs))))
+
+(defun message-insert-courtesy-copy ()
+  "Insert a courtesy message in mail copies of combined messages."
+  (let (newsgroups)
+    (save-excursion
+      (save-restriction
+       (message-narrow-to-headers)
+       (when (setq newsgroups (message-fetch-field "newsgroups"))
+         (goto-char (point-max))
+         (insert "Posted-To: " newsgroups "\n")))
+      (forward-line 1)
+      (when message-courtesy-message
+       (cond
+        ((string-match "%s" message-courtesy-message)
+         (insert (format message-courtesy-message newsgroups)))
+        (t
+         (insert message-courtesy-message)))))))
+
+;;;
+;;; Setting up a message buffer
+;;;
+
+(defun message-fill-address (header value)
+  (save-restriction
+    (narrow-to-region (point) (point))
+    (insert (capitalize (symbol-name header))
+           ": "
+           (if (consp value) (car value) value)
+           "\n")
+    (narrow-to-region (point-min) (1- (point-max)))
+    (let (quoted last)
+      (goto-char (point-min))
+      (while (not (eobp))
+       (skip-chars-forward "^,\"" (point-max))
+       (if (or (eq (char-after) ?,)
+               (eobp))
+           (when (not quoted)
+             (if (and (> (current-column) 78)
+                      last)
+                 (save-excursion
+                   (goto-char last)
+                   (looking-at "[ \t]*")
+                   (replace-match "\n " t t)))
+             (setq last (1+ (point))))
+         (setq quoted (not quoted)))
+       (unless (eobp)
+         (forward-char 1))))
+    (goto-char (point-max))
+    (widen)
+    (forward-line 1)))
+
+(defun message-fill-references (header value)
+  (insert (capitalize (symbol-name header))
+         ": "
+         (std11-fill-msg-id-list-string
+          (if (consp value) (car value) value))
+         "\n"))
+
+(defun message-split-line ()
+  "Split current line, moving portion beyond point vertically down.
+If the current line has `message-yank-prefix', insert it on the new line."
+  (interactive "*")
+  (condition-case nil
+      (split-line message-yank-prefix) ;; Emacs 21.3.50+ supports arg.
+    (error
+     (split-line))))
+     
+
+(defun message-fill-header (header value)
+  (let ((begin (point))
+       (fill-column 78)
+       (fill-prefix " "))
+    (insert (capitalize (symbol-name header))
+           ": "
+           (if (consp value) (car value) value)
+           "\n")
+    (save-restriction
+      (narrow-to-region begin (point))
+      (fill-region-as-paragraph begin (point))
+      ;; Tapdance around looong Message-IDs.
+      (forward-line -1)
+      (when (looking-at "[ \t]*$")
+       (message-delete-line))
+      (goto-char begin)
+      (re-search-forward ":" nil t)
+      (when (looking-at "\n[ \t]+")
+       (replace-match " " t t))
+      (goto-char (point-max)))))
+
+(defun message-shorten-1 (list cut surplus)
+  "Cut SURPLUS elements out of LIST, beginning with CUTth one."
+  (setcdr (nthcdr (- cut 2) list)
+         (nthcdr (+ (- cut 2) surplus 1) list)))
+
+(defun message-shorten-references (header references)
+  "Trim REFERENCES to be 21 Message-ID long or less, and fold them.
+If folding is disallowed, also check that the REFERENCES are less
+than 988 characters long, and if they are not, trim them until they are."
+  (let ((maxcount 21)
+       (count 0)
+       (cut 2)
+       refs)
+    (with-temp-buffer
+      (insert references)
+      (goto-char (point-min))
+      ;; Cons a list of valid references.
+      (while (re-search-forward "<[^>]+>" nil t)
+       (push (match-string 0) refs))
+      (setq refs (nreverse refs)
+           count (length refs)))
+
+    ;; If the list has more than MAXCOUNT elements, trim it by
+    ;; removing the CUTth element and the required number of
+    ;; elements that follow.
+    (when (> count maxcount)
+      (let ((surplus (- count maxcount)))
+       (message-shorten-1 refs cut surplus)
+       (decf count surplus)))
+
+    ;; If folding is disallowed, make sure the total length (including
+    ;; the spaces between) will be less than MAXSIZE characters.
+    ;;
+    ;; Only disallow folding for News messages. At this point the headers
+    ;; have not been generated, thus we use message-this-is-news directly.
+    (when (and message-this-is-news message-cater-to-broken-inn)
+      (let ((maxsize 988)
+           (totalsize (+ (apply #'+ (mapcar #'length refs))
+                         (1- count)))
+           (surplus 0)
+           (ptr (nthcdr (1- cut) refs)))
+       ;; Decide how many elements to cut off...
+       (while (> totalsize maxsize)
+         (decf totalsize (1+ (length (car ptr))))
+         (incf surplus)
+         (setq ptr (cdr ptr)))
+       ;; ...and do it.
+       (when (> surplus 0)
+         (message-shorten-1 refs cut surplus))))
+
+    ;; Finally, collect the references back into a string and insert
+    ;; it into the buffer.
+    (let ((refstring (mapconcat #'identity refs " ")))
+      (if (and message-this-is-news message-cater-to-broken-inn)
+         (insert (capitalize (symbol-name header)) ": "
+                 refstring "\n")
+       (message-fill-header header refstring)))))
+
+(defun message-position-point ()
+  "Move point to where the user probably wants to find it."
+  (message-narrow-to-headers)
+  (cond
+   ((re-search-forward "^[^:]+:[ \t]*$" nil t)
+    (search-backward ":" )
+    (widen)
+    (forward-char 1)
+    (if (eq (char-after) ? )
+       (forward-char 1)
+      (insert " ")))
+   (t
+    (goto-char (point-max))
+    (widen)
+    (forward-line 1)
+    (unless (looking-at "$")
+      (forward-line 2)))
+   (sit-for 0)))
+
+(defcustom message-beginning-of-line t
+  "Whether \\<message-mode-map>\\[message-beginning-of-line]\
+ goes to beginning of header values."
+  :group 'message-buffers
+  :type 'boolean)
+
+(defun message-beginning-of-line (&optional n)
+  "Move point to beginning of header value or to beginning of line.
+The prefix argument N is passed directly to `beginning-of-line'.
+
+This command is identical to `beginning-of-line' if point is
+outside the message header or if the option `message-beginning-of-line'
+is nil.
+
+If point is in the message header and on a (non-continued) header
+line, move point to the beginning of the header value.  If point
+is already there, move point to beginning of line.  Therefore,
+repeated calls will toggle point between beginning of field and
+beginning of line."
+  (interactive "p")
+  (let ((zrs 'zmacs-region-stays))
+    (when (and (interactive-p) (boundp zrs))
+      (set zrs t)))
+  (if (and message-beginning-of-line
+          (message-point-in-header-p))
+      (let* ((here (point))
+            (bol (progn (beginning-of-line n) (point)))
+            (eol (gnus-point-at-eol))
+            (eoh (re-search-forward ": *" eol t)))
+       (if (or (not eoh) (equal here eoh))
+           (goto-char bol)
+         (goto-char eoh)))
+    (beginning-of-line n)))
+
+(defun message-buffer-name (type &optional to group)
+  "Return a new (unique) buffer name based on TYPE and TO."
+  (cond
+   ;; Generate a new buffer name The Message Way.
+   ((eq message-generate-new-buffers 'unique)
+    (generate-new-buffer-name
+     (concat "*" type
+            (if to
+                (concat " to "
+                        (or (car (std11-extract-address-components to))
+                            to) "")
+              "")
+            (if (and group (not (string= group ""))) (concat " on " group) "")
+            "*")))
+   ;; Check whether `message-generate-new-buffers' is a function,
+   ;; and if so, call it.
+   ((functionp message-generate-new-buffers)
+    (funcall message-generate-new-buffers type to group))
+   ((eq message-generate-new-buffers 'unsent)
+    (generate-new-buffer-name
+     (concat "*unsent " type
+            (if to
+                (concat " to "
+                        (or (car (std11-extract-address-components to))
+                            to) "")
+              "")
+            (if (and group (not (string= group ""))) (concat " on " group) "")
+            "*")))
+   ;; Use standard name.
+   (t
+    (format "*%s message*" type))))
+
+(defmacro message-pop-to-buffer-1 (buffer)
+  `(if pop-up-frames
+       (let (special-display-buffer-names
+            special-display-regexps
+            same-window-buffer-names
+            same-window-regexps)
+        (pop-to-buffer ,buffer))
+     (pop-to-buffer ,buffer)))
+
+(defun message-pop-to-buffer (name)
+  "Pop to buffer NAME, and warn if it already exists and is modified."
+  (let ((buffer (get-buffer name))
+       (pop-up-frames (and (or (static-if (featurep 'xemacs)
+                                   (device-on-window-system-p)
+                                 window-system)
+                               (>= emacs-major-version 20))
+                           message-use-multi-frames)))
+    (if (and buffer
+            (buffer-name buffer))
+       (progn
+         (message-pop-to-buffer-1 buffer)
+         (when (and (buffer-modified-p)
+                    (not (y-or-n-p
+                          "Message already being composed; erase? ")))
+           (error "Message being composed")))
+      (message-pop-to-buffer-1 name))
+    (erase-buffer)
+    (message-mode)
+    (when pop-up-frames
+      (set (make-local-variable 'message-original-frame) (selected-frame)))))
+
+(defun message-do-send-housekeeping ()
+  "Kill old message buffers."
+  ;; We might have sent this buffer already.  Delete it from the
+  ;; list of buffers.
+  (setq message-buffer-list (delq (current-buffer) message-buffer-list))
+  (while (and message-max-buffers
+             message-buffer-list
+             (>= (length message-buffer-list) message-max-buffers))
+    ;; Kill the oldest buffer -- unless it has been changed.
+    (let ((buffer (pop message-buffer-list)))
+      (when (and (buffer-name buffer)
+                (not (buffer-modified-p buffer)))
+       (kill-buffer buffer))))
+  ;; Rename the buffer.
+  (if message-send-rename-function
+      (funcall message-send-rename-function)
+    ;; Note: mail-abbrevs of XEmacs renames buffer name behind Gnus.
+    (when (string-match
+          "\\`\\*\\(sent \\|unsent \\)?\\(.+\\)\\*[^\\*]*\\|\\`mail to "
+          (buffer-name))
+      (let ((name (match-string 2 (buffer-name)))
+           to group)
+       (if (not (or (null name)
+                    (string-equal name "mail")
+                    (string-equal name "posting")))
+           (setq name (concat "*sent " name "*"))
+         (message-narrow-to-headers)
+         (setq to (message-fetch-field "to"))
+         (setq group (message-fetch-field "newsgroups"))
+         (widen)
+         (setq name
+               (cond
+                (to (concat "*sent mail to "
+                            (or (car (std11-extract-address-components to))
+                                to) "*"))
+                ((and group (not (string= group "")))
+                 (concat "*sent posting on " group "*"))
+                (t "*sent mail*"))))
+       (unless (string-equal name (buffer-name))
+         (rename-buffer name t)))))
+  ;; Push the current buffer onto the list.
+  (when message-max-buffers
+    (setq message-buffer-list
+         (nconc message-buffer-list (list (current-buffer))))))
+
+(defun message-mail-user-agent ()
+  (let ((mua (cond
+             ((not message-mail-user-agent) nil)
+             ((eq message-mail-user-agent t) mail-user-agent)
+             (t message-mail-user-agent))))
+    (if (memq mua '(message-user-agent gnus-user-agent))
+       nil
+      mua)))
+
+(defun message-setup (headers &optional replybuffer actions switch-function)
+  (let ((mua (message-mail-user-agent))
+       subject to field yank-action)
+    (if (not (and message-this-is-mail mua))
+       (message-setup-1 headers replybuffer actions)
+      (if replybuffer
+         (setq yank-action (list 'insert-buffer replybuffer)))
+      (setq headers (copy-sequence headers))
+      (setq field (assq 'Subject headers))
+      (when field
+       (setq subject (cdr field))
+       (setq headers (delq field headers)))
+      (setq field (assq 'To headers))
+      (when field
+       (setq to (cdr field))
+       (setq headers (delq field headers)))
+      (let ((mail-user-agent mua))
+       (compose-mail to subject
+                     (mapcar (lambda (item)
+                               (cons
+                                (format "%s" (car item))
+                                (cdr item)))
+                             headers)
+                     nil switch-function yank-action actions)))))
+
+(defun message-headers-to-generate (headers included-headers excluded-headers)
+  "Return a list that includes all headers from HEADERS.
+If INCLUDED-HEADERS is a list, just include those headers.  If if is
+t, include all headers.  In any case, headers from EXCLUDED-HEADERS
+are not included."
+  (let ((result nil)
+       header-name)
+    (dolist (header headers)
+      (setq header-name (cond
+                        ((and (consp header)
+                              (eq (car header) 'optional))
+                         ;; On the form (optional . Header)
+                         (cdr header))
+                        ((consp header)
+                         ;; On the form (Header . function)
+                         (car header))
+                        (t
+                         ;; Just a Header.
+                         header)))
+      (when (and (not (memq header-name excluded-headers))
+                (or (eq included-headers t)
+                    (memq header-name included-headers)))
+       (push header result)))
+    (nreverse result)))
+
+(defun message-setup-1 (headers &optional replybuffer actions)
+  (dolist (action actions)
+    (condition-case nil
+       (add-to-list 'message-send-actions
+                    `(apply ',(car action) ',(cdr action)))))
+  (setq message-reply-buffer
+       (or (message-get-parameter 'reply-buffer)
+           replybuffer))
+  (goto-char (point-min))
+  ;; Insert all the headers.
+  (mail-header-format
+   (let ((h headers)
+        (alist message-header-format-alist))
+     (while h
+       (unless (assq (caar h) message-header-format-alist)
+        (push (list (caar h)) alist))
+       (pop h))
+     alist)
+   headers)
+  (delete-region (point) (progn (forward-line -1) (point)))
+  (when message-default-headers
+    (insert message-default-headers)
+    (or (bolp) (insert ?\n)))
+  (put-text-property
+   (point)
+   (progn
+     (insert mail-header-separator "\n")
+     (1- (point)))
+   'read-only nil)
+  (forward-line -1)
+  (when (message-news-p)
+    (when message-default-news-headers
+      (insert message-default-news-headers)
+      (or (bolp) (insert ?\n)))
+    (when message-generate-headers-first
+      (message-generate-headers
+       (message-headers-to-generate
+       (append message-required-news-headers
+               message-required-headers)
+       message-generate-headers-first
+       '(Lines Subject)))))
+  (when (message-mail-p)
+    (when message-default-mail-headers
+      (insert message-default-mail-headers)
+      (or (bolp) (insert ?\n)))
+    (save-restriction
+      (message-narrow-to-headers)
+      (if (and replybuffer
+              message-alternative-emails)
+         (message-use-alternative-email-as-from)))
+    (when message-generate-headers-first
+      (message-generate-headers
+       (message-headers-to-generate
+       (append message-required-mail-headers
+               message-required-headers)
+       message-generate-headers-first
+       '(Lines Subject)))))
+  (run-hooks 'message-signature-setup-hook)
+  (message-insert-signature)
+  (save-restriction
+    (message-narrow-to-headers)
+    (run-hooks 'message-header-setup-hook))
+  (set-buffer-modified-p nil)
+  (setq buffer-undo-list nil)
+  (run-hooks 'message-setup-hook)
+  (message-position-point)
+  (undo-boundary))
+
+(defun message-set-auto-save-file-name ()
+  "Associate the message buffer with a file in the drafts directory."
+  (when message-auto-save-directory
+    (unless (file-directory-p
+            (directory-file-name message-auto-save-directory))
+      (make-directory message-auto-save-directory t))
+    (if (gnus-alive-p)
+       (setq message-draft-article
+             (nndraft-request-associate-buffer "drafts"))
+      (setq buffer-file-name (expand-file-name
+                             (if (memq system-type
+                                       '(ms-dos ms-windows windows-nt
+                                                cygwin cygwin32 win32 w32
+                                                mswindows))
+                                 "message"
+                               "*message*")
+                             message-auto-save-directory))
+      (setq buffer-auto-save-file-name (make-auto-save-file-name)))
+    (clear-visited-file-modtime)
+    (static-if (boundp 'MULE)
+       (set-file-coding-system message-draft-coding-system)
+      (setq buffer-file-coding-system message-draft-coding-system))))
+
+(defun message-disassociate-draft ()
+  "Disassociate the message buffer from the drafts directory."
+  (when message-draft-article
+    (nndraft-request-expire-articles
+     (list message-draft-article) "drafts" nil t)))
+
+(defun message-insert-headers ()
+  "Generate the headers for the article."
+  (interactive)
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-headers)
+      (when (message-news-p)
+       (message-generate-headers
+        (delq 'Lines
+              (delq 'Subject
+                    (copy-sequence message-required-news-headers)))))
+      (when (message-mail-p)
+       (message-generate-headers
+        (delq 'Lines
+              (delq 'Subject
+                    (copy-sequence message-required-mail-headers))))))))
+
+\f
+
+;;;
+;;; Commands for interfacing with message
+;;;
+
+;;;###autoload
+(defun message-mail (&optional to subject
+                              other-headers continue switch-function
+                              yank-action send-actions)
+  "Start editing a mail message to be sent.
+OTHER-HEADERS is an alist of header/value pairs."
+  (interactive)
+  (let ((message-this-is-mail t) replybuffer)
+    (unless (message-mail-user-agent)
+      (message-pop-to-buffer (message-buffer-name "mail" to)))
+    ;; FIXME: message-mail should do something if YANK-ACTION is not
+    ;; insert-buffer.
+    (and (consp yank-action) (eq (car yank-action) 'insert-buffer)
+        (setq replybuffer (nth 1 yank-action)))
+    (message-setup
+     (nconc
+      `((To . ,(or to "")) (Subject . ,(or subject "")))
+      (when other-headers other-headers))
+     replybuffer send-actions)
+    ;; FIXME: Should return nil if failure.
+    t))
+
+;;;###autoload
+(defun message-news (&optional newsgroups subject)
+  "Start editing a news article to be sent."
+  (interactive)
+  (let ((message-this-is-news t))
+    (message-pop-to-buffer (message-buffer-name "posting" nil newsgroups))
+    (message-setup `((Newsgroups . ,(or newsgroups ""))
+                    (Subject . ,(or subject ""))))))
+
+(defun message-get-reply-headers (wide &optional to-address address-headers)
+  (let (follow-to mct never-mct to cc author mft recipients)
+    ;; Find all relevant headers we need.
+    (let ((mrt (when message-use-mail-reply-to
+                (message-fetch-field "mail-reply-to")))
+         (reply-to (message-fetch-field "reply-to")))
+      (setq to (message-fetch-field "to")
+           cc (message-fetch-field "cc")
+           mct (when message-use-mail-copies-to
+                 (message-fetch-field "mail-copies-to"))
+           author (or mrt
+                      reply-to
+                      (message-fetch-field "from")
+                      "")
+           mft (when (and (not (or to-address mrt reply-to))
+                          message-use-mail-followup-to)
+                 (message-fetch-field "mail-followup-to"))))
+
+    (save-match-data
+      ;; Handle special values of Mail-Copies-To.
+      (when mct
+       (cond ((or (equal (downcase mct) "never")
+                  (equal (downcase mct) "nobody"))
+              (when (or (not (eq message-use-mail-copies-to 'ask))
+                        (message-y-or-n-p
+                         (concat "Obey Mail-Copies-To: never? ") t "\
+You should normally obey the Mail-Copies-To: header.
+
+       `Mail-Copies-To: " mct "'
+directs you not to send your response to the author."))
+                (setq never-mct t))
+              (setq mct nil))
+             ((or (equal (downcase mct) "always")
+                  (equal (downcase mct) "poster"))
+              (if (or (not (eq message-use-mail-copies-to 'ask))
+                      (message-y-or-n-p
+                       (concat "Obey Mail-Copies-To: always? ") t "\
+You should normally obey the Mail-Copies-To: header.
+
+       `Mail-Copies-To: " mct "'
+sends a copy of your response to the author."))
+                  (setq mct author)
+                (setq mct nil)))
+             ((and (eq message-use-mail-copies-to 'ask)
+                   (not (message-y-or-n-p
+                         (concat "Obey Mail-Copies-To: " mct " ? ") t "\
+You should normally obey the Mail-Copies-To: header.
+
+       `Mail-Copies-To: " mct "'
+sends a copy of your response to " (if (string-match "," mct)
+                                      "the specified addresses"
+                                    "that address") ".")))
+              (setq mct nil))))
+
+      ;; Build (textual) list of new recipient addresses.
+      (cond
+       ((not wide)
+       (setq recipients (concat ", " author)))
+       (address-headers
+       (dolist (header address-headers)
+         (let ((value (message-fetch-field header)))
+           (when value
+             (setq recipients (concat recipients ", " value))))))
+       ((and mft
+            (string-match "[^ \t,]" mft)
+            (or (not (eq message-use-mail-followup-to 'ask))
+                (message-y-or-n-p "Obey Mail-Followup-To? " t "\
+You should normally obey the Mail-Followup-To: header.  In this
+article, it has the value of
+
+" mft "
+
+which directs your response to " (if (string-match "," mft)
+                                    "the specified addresses"
+                                  "that address only") ".
+
+Most commonly, Mail-Followup-To is used by a mailing list poster to
+express that responses should be sent to just the list, and not the
+poster as well.
+
+If a message is posted to several mailing lists, Mail-Followup-To may
+also be used to direct the following discussion to one list only,
+because discussions that are spread over several lists tend to be
+fragmented and very difficult to follow.
+
+Also, some source/announcement lists are not intended for discussion;
+responses here are directed to other addresses.")))
+       (setq recipients (concat ", " mft)))
+       (to-address
+       (setq recipients (concat ", " to-address))
+       ;; If the author explicitly asked for a copy, we don't deny it to them.
+       (if mct (setq recipients (concat recipients ", " mct))))
+       (t
+       (setq recipients (if never-mct "" (concat ", " author)))
+       (if to  (setq recipients (concat recipients ", " to)))
+       (if cc  (setq recipients (concat recipients ", " cc)))
+       (if mct (setq recipients (concat recipients ", " mct)))))
+      (if (>= (length recipients) 2)
+         ;; Strip the leading ", ".
+         (setq recipients (substring recipients 2)))
+      ;; Squeeze whitespace.
+      (while (string-match "[ \t][ \t]+" recipients)
+       (setq recipients (replace-match " " t t recipients)))
+      ;; Remove addresses that match `rmail-dont-reply-to-names'.
+      (let ((rmail-dont-reply-to-names message-dont-reply-to-names))
+       (setq recipients (rmail-dont-reply-to recipients)))
+      ;; Perhaps "Mail-Copies-To: never" removed the only address?
+      (if (string-equal recipients "")
+         (setq recipients author))
+      ;; Convert string to a list of (("foo@bar" . "Name <Foo@BAR>") ...).
+      (setq recipients
+           (mapcar
+            (lambda (addr)
+              (cons (downcase (mail-strip-quoted-names addr)) addr))
+            (message-tokenize-header recipients)))
+      ;; Remove first duplicates.  (Why not all duplicates?  Is this a bug?)
+      (let ((s recipients))
+       (while s
+         (setq recipients (delq (assoc (car (pop s)) s) recipients))))
+
+      ;; Remove hierarchical lists that are contained within each other,
+      ;; if message-hierarchical-addresses is defined.
+      (when message-hierarchical-addresses
+       (let ((plain-addrs (mapcar 'car recipients))
+             subaddrs recip)
+         (while plain-addrs
+           (setq subaddrs (assoc (car plain-addrs)
+                                 message-hierarchical-addresses)
+                 plain-addrs (cdr plain-addrs))
+           (when subaddrs
+             (setq subaddrs (cdr subaddrs))
+             (while subaddrs
+               (setq recip (assoc (car subaddrs) recipients)
+                     subaddrs (cdr subaddrs))
+               (if recip
+                   (setq recipients (delq recip recipients))))))))
+
+      ;; Build the header alist.  Allow the user to be asked whether
+      ;; or not to reply to all recipients in a wide reply.
+      (setq follow-to (list (cons 'To (cdr (pop recipients)))))
+      (when (and recipients
+                (or (not message-wide-reply-confirm-recipients)
+                    (y-or-n-p "Reply to all recipients? ")))
+       (setq recipients (mapconcat
+                         (lambda (addr) (cdr addr)) recipients ", "))
+       (if (string-match "^ +" recipients)
+           (setq recipients (substring recipients (match-end 0))))
+       (push (cons 'Cc recipients) follow-to)))
+    follow-to))
+
+;;;###autoload
+(defun message-reply (&optional to-address wide)
+  "Start editing a reply to the article in the current buffer."
+  (interactive)
+  (require 'gnus-sum)                  ; for gnus-list-identifiers
+  (let ((cur (current-buffer))
+       from subject date
+       references message-id follow-to
+       (inhibit-point-motion-hooks t)
+       (message-this-is-mail t)
+       gnus-warning in-reply-to)
+    (save-restriction
+      (message-narrow-to-head-1)
+      ;; Allow customizations to have their say.
+      (if (not wide)
+         ;; This is a regular reply.
+         (when (functionp message-reply-to-function)
+           (save-excursion
+             (setq follow-to (funcall message-reply-to-function))))
+       ;; This is a followup.
+       (when (functionp message-wide-reply-to-function)
+         (save-excursion
+           (setq follow-to
+                 (funcall message-wide-reply-to-function)))))
+      (setq message-id (message-fetch-field "message-id" t)
+           references (message-fetch-field "references")
+           date (message-fetch-field "date")
+           from (message-fetch-field "from")
+           subject (or (message-fetch-field "subject") "none"))
+      (when gnus-list-identifiers
+       (setq subject (message-strip-list-identifiers subject)))
+      (setq subject (message-make-followup-subject subject))
+      (when message-subject-trailing-was-query
+       (setq subject (message-strip-subject-trailing-was subject)))
+
+      (when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
+                (string-match "<[^>]+>" gnus-warning))
+       (setq message-id (match-string 0 gnus-warning)))
+
+      (unless follow-to
+       (setq follow-to (message-get-reply-headers wide to-address)))
+
+      ;; Get the references from "In-Reply-To" field if there were
+      ;; no references and "In-Reply-To" field looks promising.
+      (unless references
+       (when (and (setq in-reply-to (message-fetch-field "in-reply-to"))
+                  (string-match "<[^>]+>" in-reply-to))
+         (setq references (match-string 0 in-reply-to)))))
+
+    (unless (message-mail-user-agent)
+      (message-pop-to-buffer
+       (message-buffer-name
+       (if wide "wide reply" "reply") from
+       (if wide to-address nil))))
+
+    (setq message-reply-headers
+         (make-full-mail-header-from-decoded-header
+          0 subject from date message-id references 0 0 ""))
+
+    (message-setup
+     `((Subject . ,subject)
+       ,@follow-to)
+     cur)))
+
+;;;###autoload
+(defun message-wide-reply (&optional to-address)
+  "Make a \"wide\" reply to the message in the current buffer."
+  (interactive)
+  (message-reply to-address t))
+
+;;;###autoload
+(defun message-followup (&optional to-newsgroups)
+  "Follow up to the message in the current buffer.
+If TO-NEWSGROUPS, use that as the new Newsgroups line."
+  (interactive)
+  (require 'gnus-sum)                  ; for gnus-list-identifiers
+  (let ((cur (current-buffer))
+       from subject date reply-to mrt mct mft
+       references message-id follow-to
+       (inhibit-point-motion-hooks t)
+       (message-this-is-news t)
+       followup-to distribution newsgroups gnus-warning posted-to)
+    (save-restriction
+      (message-narrow-to-head)
+      (when (functionp message-followup-to-function)
+       (setq follow-to
+             (funcall message-followup-to-function)))
+      (setq from (message-fetch-field "from")
+           date (message-fetch-field "date")
+           subject (or (message-fetch-field "subject") "none")
+           references (message-fetch-field "references")
+           message-id (message-fetch-field "message-id" t)
+           followup-to (message-fetch-field "followup-to")
+           newsgroups (message-fetch-field "newsgroups")
+           posted-to (message-fetch-field "posted-to")
+           reply-to (message-fetch-field "reply-to")
+           mrt (when message-use-mail-reply-to
+                 (message-fetch-field "mail-reply-to"))
+           distribution (message-fetch-field "distribution")
+           mct (when message-use-mail-copies-to
+                 (message-fetch-field "mail-copies-to"))
+           mft (when message-use-mail-followup-to
+                 (message-fetch-field "mail-followup-to")))
+      (when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
+                (string-match "<[^>]+>" gnus-warning))
+       (setq message-id (match-string 0 gnus-warning)))
+      ;; Remove bogus distribution.
+      (when (and (stringp distribution)
+                (let ((case-fold-search t))
+                  (string-match "world" distribution)))
+       (setq distribution nil))
+      (if gnus-list-identifiers
+         (setq subject (message-strip-list-identifiers subject)))
+      (setq subject (message-make-followup-subject subject))
+      (when message-subject-trailing-was-query
+       (setq subject (message-strip-subject-trailing-was subject)))
+      (widen))
+
+    ;; Handle special values of Mail-Copies-To.
+    (when mct
+      (cond
+       ((and (or (equal (downcase mct) "never")
+                (equal (downcase mct) "nobody")))
+       (setq mct nil))
+       ((and (or (equal (downcase mct) "always")
+                (equal (downcase mct) "poster")))
+       (if (or (not (eq message-use-mail-copies-to 'ask))
+               (message-y-or-n-p
+                (concat "Obey Mail-Copies-To: always? ") t "\
+You should normally obey the Mail-Copies-To: header.
+
+       `Mail-Copies-To: " mct "'
+sends a copy of your response to the author."))
+           (setq mct (or mrt reply-to from))
+         (setq mct nil)))
+       ((and (eq message-use-mail-copies-to 'ask)
+            (not
+             (message-y-or-n-p
+              (concat "Obey Mail-Copies-To: " mct " ? ") t "\
+You should normally obey the Mail-Copies-To: header.
+
+       `Mail-Copies-To: " mct "'
+sends a copy of your response to " (if (string-match "," mct)
+                                      "the specified addresses"
+                                    "that address") ".")))
+       (setq mct nil))))
+
+    (unless follow-to
+      (cond
+       (to-newsgroups (setq follow-to (list (cons 'Newsgroups to-newsgroups))))
+       ;; Handle Followup-To.
+       (followup-to
+       (cond
+        ((equal (downcase followup-to) "poster")
+         (if (or (and followup-to (eq message-use-followup-to 'use))
+                 (message-y-or-n-p "Obey Followup-To: poster? " t "\
+You should normally obey the Followup-To: header.
+
+       `Followup-To: poster'
+sends your response via e-mail instead of news.
+
+A typical situation where `Followup-To: poster' is used is when the author
+does not read the newsgroup, so he wouldn't see any replies sent to it."))
+             (setq message-this-is-news nil
+                   distribution nil
+                   follow-to (list (cons 'To (or mrt reply-to from ""))))
+           (setq follow-to (list (cons 'Newsgroups newsgroups)))))
+        (t
+         (if (or (equal followup-to newsgroups)
+                 (not (and followup-to (eq message-use-followup-to 'ask)))
+                 (message-y-or-n-p
+                  (concat "Obey Followup-To: " followup-to "? ") t "\
+You should normally obey the Followup-To: header.
+
+       `Followup-To: " followup-to "'
+directs your response to " (if (string-match "," followup-to)
+                              "the specified newsgroups"
+                            "that newsgroup only") ".
+
+If a message is posted to several newsgroups, Followup-To is often
+used to direct the following discussion to one newsgroup only,
+because discussions that are spread over several newsgroup tend to
+be fragmented and very difficult to follow.
+
+Also, some source/announcement newsgroups are not intended for discussion;
+responses here are directed to other newsgroups."))
+             (setq follow-to (list (cons 'Newsgroups followup-to)))
+           (setq follow-to (list (cons 'Newsgroups newsgroups)))))))
+       ;; Handle Mail-Followup-To, followup via e-mail.
+       ((and mft
+            (or (not (eq message-use-mail-followup-to 'ask))
+                (message-y-or-n-p
+                 (concat "Obey Mail-Followup-To: " mft "? ") t "\
+You should normally obey the Mail-Followup-To: header.
+
+       `Mail-Followup-To: " mft "'
+directs your response to " (if (string-match "," mft)
+                              "the specified addresses"
+                            "that address only") " instead of news.
+
+A typical situation where Mail-Followup-To is used is when the author thinks
+that further discussion should take place only in "
+                            (if (string-match "," mft)
+                                "the specified mailing lists"
+                              "that mailing list") ".")))
+       (setq message-this-is-news nil
+             distribution nil
+             follow-to (list (cons 'To mft))))
+       (posted-to (setq follow-to (list (cons 'Newsgroups posted-to))))
+       (t
+       (setq follow-to (list (cons 'Newsgroups newsgroups))))))
+
+    (message-pop-to-buffer (message-buffer-name "followup" from newsgroups))
+
+    (setq message-reply-headers
+         (make-full-mail-header-from-decoded-header
+          0 subject from date message-id references 0 0 ""))
+
+    (message-setup
+     `((Subject . ,subject)
+       ,@follow-to
+       ,@(and mct (list (cons 'Cc mct)))
+       ,@(and distribution (list (cons 'Distribution distribution))))
+     cur)))
+
+(defun message-is-yours-p ()
+  "Non-nil means current article is yours.
+If you have added 'cancel-messages to 'message-shoot-gnksa-feet', all articles
+are yours except those that have Cancel-Lock header not belonging to you.
+Instead of shooting GNKSA feet, you should modify 'message-alternative-emails'
+regexp to match all of yours addresses."
+  ;; Canlock-logic as suggested by Per Abrahamsen
+  ;; <abraham@dina.kvl.dk>
+  ;;
+  ;; IF article has cancel-lock THEN
+  ;;   IF we can verify it THEN
+  ;;     issue cancel
+  ;;   ELSE
+  ;;     error: cancellock: article is not yours
+  ;; ELSE
+  ;;   Use old rules, comparing sender...
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-head-1)
+      (if (message-fetch-field "Cancel-Lock")
+         (if (null (canlock-verify))
+             t
+           (error "Failed to verify Cancel-lock: This article is not yours"))
+       (let (sender from)
+         (or
+          (message-gnksa-enable-p 'cancel-messages)
+          (and (setq sender (message-fetch-field "sender"))
+               (string-equal (downcase sender)
+                             (downcase (message-make-sender))))
+          ;; Email address in From field equals to our address
+          (and (setq from (message-fetch-field "from"))
+               (string-equal
+                (downcase (cadr (std11-extract-address-components from)))
+                (downcase (cadr (std11-extract-address-components
+                                 (message-make-from))))))
+          ;; Email address in From field matches
+          ;; 'message-alternative-emails' regexp
+          (and from
+               message-alternative-emails
+               (string-match
+                message-alternative-emails
+                (cadr (std11-extract-address-components from))))))))))
+
+;;;###autoload
+(defun message-cancel-news (&optional arg)
+  "Cancel an article you posted.
+If ARG, allow editing of the cancellation message."
+  (interactive "P")
+  (unless (message-news-p)
+    (error "This is not a news article; canceling is impossible"))
+  (let (from newsgroups message-id distribution buf)
+    (save-excursion
+      ;; Get header info from original article.
+      (save-restriction
+       (message-narrow-to-head-1)
+       (setq from (message-fetch-field "from")
+             newsgroups (message-fetch-field "newsgroups")
+             message-id (message-fetch-field "message-id" t)
+             distribution (message-fetch-field "distribution")))
+      ;; Make sure that this article was written by the user.
+      (unless (message-is-yours-p)
+       (error "This article is not yours"))
+      (when (yes-or-no-p "Do you really want to cancel this article? ")
+       ;; Make control message.
+       (if arg
+           (message-news)
+         (setq buf (set-buffer (get-buffer-create " *message cancel*"))))
+       (erase-buffer)
+       (insert "Newsgroups: " newsgroups "\n"
+               "From: " from "\n"
+               "Subject: cmsg cancel " message-id "\n"
+               "Control: cancel " message-id "\n"
+               (if distribution
+                   (concat "Distribution: " distribution "\n")
+                 "")
+               mail-header-separator "\n"
+               message-cancel-message)
+       (run-hooks 'message-cancel-hook)
+       (unless arg
+         (message "Canceling your article...")
+         (if (let ((message-syntax-checks
+                    'dont-check-for-anything-just-trust-me)
+                   (message-encoding-buffer (current-buffer))
+                   (message-edit-buffer (current-buffer)))
+               (message-send-news))
+             (message "Canceling your article...done"))
+         (kill-buffer buf))))))
+
+(defun message-supersede-setup-for-mime-edit ()
+  (set (make-local-variable 'message-setup-hook) nil)
+  (mime-edit-again))
+
+;;;###autoload
+(defun message-supersede ()
+  "Start composing a message to supersede the current message.
+This is done simply by taking the old article and adding a Supersedes
+header line with the old Message-ID."
+  (interactive)
+  (let ((cur (current-buffer)))
+    ;; Check whether the user owns the article that is to be superseded.
+    (unless (message-is-yours-p)
+      (error "This article is not yours"))
+    ;; Get a normal message buffer.
+    (message-pop-to-buffer (message-buffer-name "supersede"))
+    (insert-buffer-substring cur)
+    (message-narrow-to-head-1)
+    ;; Remove unwanted headers.
+    (when message-ignored-supersedes-headers
+      (message-remove-header message-ignored-supersedes-headers t))
+    (goto-char (point-min))
+    (if (not (re-search-forward "^Message-ID: " nil t))
+       (error "No Message-ID in this article")
+      (replace-match "Supersedes: " t t))
+    (goto-char (point-max))
+    (insert mail-header-separator)
+    (widen)
+    (when message-supersede-setup-function
+      (funcall message-supersede-setup-function))
+    (run-hooks 'message-supersede-setup-hook)
+    (goto-char (point-min))
+    (search-forward (concat "\n" mail-header-separator "\n") nil t)))
+
+;;;###autoload
+(defun message-recover ()
+  "Reread contents of current buffer from its last auto-save file."
+  (interactive)
+  (let ((file-name (make-auto-save-file-name)))
+    (cond ((save-window-excursion
+            (if (not (eq system-type 'vax-vms))
+                (with-output-to-temp-buffer "*Directory*"
+                  (with-current-buffer standard-output
+                    (fundamental-mode)) ; for Emacs 20.4+
+                  (buffer-disable-undo standard-output)
+                  (let ((default-directory "/"))
+                    (call-process
+                     "ls" nil standard-output nil "-l" file-name))))
+            (yes-or-no-p (format "Recover auto save file %s? " file-name)))
+          (let ((buffer-read-only nil))
+            (erase-buffer)
+            (insert-file-contents file-name nil)))
+         (t (error "message-recover cancelled")))))
+
+;;; Washing Subject:
+
+(defun message-wash-subject (subject)
+  "Remove junk like \"Re:\", \"(fwd)\", etc. added to subject string SUBJECT.
+Previous forwarders, replyers, etc. may add it."
+  (with-temp-buffer
+    (insert subject)
+    (goto-char (point-min))
+    ;; strip Re/Fwd stuff off the beginning
+    (while (re-search-forward
+           "\\([Rr][Ee]:\\|[Ff][Ww][Dd]\\(\\[[0-9]*\\]\\)?:\\|[Ff][Ww]:\\)" nil t)
+      (replace-match ""))
+
+    ;; and gnus-style forwards [foo@bar.com] subject
+    (goto-char (point-min))
+    (while (re-search-forward "\\[[^ \t]*\\(@\\|\\.\\)[^ \t]*\\]" nil t)
+      (replace-match ""))
+
+    ;; and off the end
+    (goto-char (point-max))
+    (while (re-search-backward "([Ff][Ww][Dd])" nil t)
+      (replace-match ""))
+
+    ;; and finally, any whitespace that was left-over
+    (goto-char (point-min))
+    (while (re-search-forward "^[ \t]+" nil t)
+      (replace-match ""))
+    (goto-char (point-max))
+    (while (re-search-backward "[ \t]+$" nil t)
+      (replace-match ""))
+
+    (buffer-string)))
+
+;;; Forwarding messages.
+
+(defvar message-forward-decoded-p nil
+  "Non-nil means the original message is decoded.")
+
+(defun message-forward-subject-name-subject (subject)
+  "Generate a SUBJECT for a forwarded message.
+The form is: [Source] Subject, where if the original message was mail,
+Source is the name of the sender, and if the original message was
+news, Source is the list of newsgroups is was posted to."
+  (concat "["
+         (let ((group (message-fetch-field "newsgroups"))
+               from)
+           (if group
+               (gnus-group-decoded-name group)
+             (or (and (setq from (message-fetch-field "from"))
+                      (car (std11-extract-address-components 
+                            (nnheader-decode-from from))))
+                 "(nowhere)")))
+         "] " subject))
+
+(defun message-forward-subject-author-subject (subject)
+  "Generate a SUBJECT for a forwarded message.
+The form is: [Source] Subject, where if the original message was mail,
+Source is the sender, and if the original message was news, Source is
+the list of newsgroups is was posted to."
+  (concat "["
+         (let ((group (message-fetch-field "newsgroups"))
+               from)
+           (if group
+               (gnus-group-decoded-name group)
+             (if (setq from (message-fetch-field "from"))
+                 (nnheader-decode-from from)
+               "(nowhere)")))
+         "] " subject))
+
+(defun message-forward-subject-fwd (subject)
+  "Generate a SUBJECT for a forwarded message.
+The form is: Fwd: Subject, where Subject is the original subject of
+the message."
+  (if (string-match "^Fwd: " subject)
+      subject
+    (concat "Fwd: " subject)))
+
+(defun message-make-forward-subject ()
+  "Return a Subject header suitable for the message in the current buffer."
+  (save-excursion
+    (save-restriction
+      (message-narrow-to-head-1)
+      (let ((funcs message-make-forward-subject-function)
+           (subject (message-fetch-field "Subject")))
+       (setq subject
+             (if subject
+                 (if message-forward-decoded-p
+                     subject
+                   (nnheader-decode-subject subject))
+               ""))
+       (if message-wash-forwarded-subjects
+           (setq subject (message-wash-subject subject)))
+       ;; Make sure funcs is a list.
+       (and funcs
+            (not (listp funcs))
+            (setq funcs (list funcs)))
+       ;; Apply funcs in order, passing subject generated by previous
+       ;; func to the next one.
+       (while funcs
+         (when (functionp (car funcs))
+           (setq subject (funcall (car funcs) subject)))
+         (setq funcs (cdr funcs)))
+       subject))))
+
+;;;###autoload
+(defun message-forward (&optional news)
+  "Forward the current message via mail.
+Optional NEWS will use news to forward instead of mail."
+  (interactive "P")
+  (let ((cur (current-buffer))
+       (subject (message-make-forward-subject)))
+    (if news
+       (message-news nil subject)
+      (message-mail nil subject))
+    (message-forward-make-body cur)))
+
+(defun message-forward-make-body-plain (forward-buffer)
+  (insert
+   "\n-------------------- Start of forwarded message --------------------\n")
+  (let ((b (point)) e)
+    (insert
+     (with-temp-buffer
+       (mm-disable-multibyte)
+       (insert
+       (with-current-buffer forward-buffer
+         (mm-with-unibyte-current-buffer (buffer-string))))
+       (mm-enable-multibyte)
+       (mime-to-mml)
+       (goto-char (point-min))
+       (when (looking-at "From ")
+        (replace-match "X-From-Line: "))
+       (buffer-string)))
+    (setq e (point))
+    (insert
+     "\n-------------------- End of forwarded message --------------------\n")
+    (when (and (not current-prefix-arg)
+              message-forward-ignored-headers)
+      (save-restriction
+       (narrow-to-region b e)
+       (goto-char b)
+       (narrow-to-region (point)
+                         (or (search-forward "\n\n" nil t) (point)))
+       (message-remove-header message-forward-ignored-headers t)))))
+
+(defun message-forward-make-body-mime (forward-buffer)
+  (insert "\n\n<#part type=message/rfc822 disposition=inline raw=t>\n")
+  (let ((b (point)) e)
+    (save-restriction
+      (narrow-to-region (point) (point))
+      (mml-insert-buffer forward-buffer)
+      (goto-char (point-min))
+      (when (looking-at "From ")
+       (replace-match "X-From-Line: "))
+      (goto-char (point-max)))
+    (setq e (point))
+    (insert "<#/part>\n")))
+
+(defun message-forward-make-body-mml (forward-buffer)
+  (insert "\n\n<#mml type=message/rfc822 disposition=inline>\n")
+  (let ((b (point)) e)
+    (if (not message-forward-decoded-p)
+       (insert
+        (with-temp-buffer
+          (mm-disable-multibyte)
+          (insert
+           (with-current-buffer forward-buffer
+             (mm-with-unibyte-current-buffer (buffer-string))))
+          (mm-enable-multibyte)
+          (mime-to-mml)
+          (goto-char (point-min))
+          (when (looking-at "From ")
+            (replace-match "X-From-Line: "))
+          (buffer-string)))
+      (save-restriction
+       (narrow-to-region (point) (point))
+       (mml-insert-buffer forward-buffer)
+       (goto-char (point-min))
+       (when (looking-at "From ")
+         (replace-match "X-From-Line: "))
+       (goto-char (point-max))))
+    (setq e (point))
+    (insert "<#/mml>\n")
+    (when (and (not current-prefix-arg)
+              message-forward-ignored-headers)
+      (save-restriction
+       (narrow-to-region b e)
+       (goto-char b)
+       (narrow-to-region (point)
+                         (or (search-forward "\n\n" nil t) (point)))
+       (message-remove-header message-forward-ignored-headers t)))))
+
+(defun message-forward-make-body-digest-plain (forward-buffer)
+  (insert
+   "\n-------------------- Start of forwarded message --------------------\n")
+  (let ((b (point)) e)
+    (mml-insert-buffer forward-buffer)
+    (setq e (point))
+    (insert
+     "\n-------------------- End of forwarded message --------------------\n")))
+
+(defun message-forward-make-body-digest-mime (forward-buffer)
+  (insert "\n<#multipart type=digest>\n")
+  (let ((b (point)) e)
+    (insert-buffer-substring forward-buffer)
+    (setq e (point))
+    (insert "<#/multipart>\n")
+    (save-restriction
+      (narrow-to-region b e)
+      (goto-char b)
+      (narrow-to-region (point)
+                       (or (search-forward "\n\n" nil t) (point)))
+      (delete-region (point-min) (point-max)))))
+
+(defun message-forward-make-body-digest (forward-buffer)
+  (if message-forward-as-mime
+      (message-forward-make-body-digest-mime forward-buffer)
+    (message-forward-make-body-digest-plain forward-buffer)))
+
+;;;###autoload
+(defun message-forward-make-body (forward-buffer)
+  ;; Put point where we want it before inserting the forwarded
+  ;; message.
+  ;; Note that this function definition for T-gnus is totally different
+  ;; from the original Gnus."
+  (if message-forward-before-signature
+      (message-goto-body)
+    (goto-char (point-max)))
+  ;; Make sure we're at the start of the line.
+  (unless (bolp)
+    (insert "\n"))
+  ;; Narrow to the area we are to insert.
+  (narrow-to-region (point) (point))
+  ;; Insert the separators and the forwarded buffer.
+  (insert message-forward-start-separator)
+  (let ((art-beg (point)))
+    (insert-buffer-substring forward-buffer)
+    (goto-char (point-max))
+    (insert message-forward-end-separator)
+    (set-text-properties (point-min) (point-max) nil)
+    ;; Remove all unwanted headers.
+    (goto-char art-beg)
+    (narrow-to-region (point) (if (search-forward "\n\n" nil t)
+                                 (1- (point))
+                               (point)))
+    (goto-char (point-min))
+    (message-remove-header message-included-forward-headers t nil t)
+    (widen)
+    (message-position-point)))
+
+;;;###autoload
+(defun message-forward-rmail-make-body (forward-buffer)
+  (save-window-excursion
+    (set-buffer forward-buffer)
+    ;; Rmail doesn't have rmail-msg-restore-non-pruned-header in Emacs
+    ;; 20.  FIXIT, or we drop support for rmail in Emacs 20.
+    (if (rmail-msg-is-pruned)
+       (rmail-msg-restore-non-pruned-header)))
+  (message-forward-make-body forward-buffer))
+
+(eval-when-compile (defvar rmail-enable-mime-composing))
+
+;; Fixme: Should have defcustom.
+;;;###autoload
+(defun message-insinuate-rmail ()
+  "Let RMAIL use message to forward."
+  (interactive)
+  (setq rmail-enable-mime-composing t)
+  (setq rmail-insert-mime-forwarded-message-function
+       'message-forward-rmail-make-body))
+
+;;;###autoload
+(defun message-resend (address)
+  "Resend the current article to ADDRESS."
+  (interactive
+   (list (message-read-from-minibuffer "Resend message to: ")))
+  (message "Resending message to %s..." address)
+  (save-excursion
+    (let ((cur (current-buffer))
+         beg)
+      ;; We first set up a normal mail buffer.
+      (unless (message-mail-user-agent)
+       (set-buffer (get-buffer-create " *message resend*"))
+       (erase-buffer))
+      (let ((message-this-is-mail t)
+           message-setup-hook)
+       (message-setup `((To . ,address))))
+      ;; Insert our usual headers.
+      (message-generate-headers '(From Date To Message-ID))
+      (message-narrow-to-headers)
+      ;; Remove X-Draft-From header etc.
+      (message-remove-header message-ignored-mail-headers t)
+      ;; Rename them all to "Resent-*".
+      (goto-char (point-min))
+      (while (re-search-forward "^[A-Za-z]" nil t)
+       (forward-char -1)
+       (insert "Resent-"))
+      (widen)
+      (forward-line)
+      (delete-region (point) (point-max))
+      (setq beg (point))
+      ;; Insert the message to be resent.
+      (insert-buffer-substring cur)
+      (goto-char (point-min))
+      (search-forward "\n\n")
+      (forward-char -1)
+      (save-restriction
+       (narrow-to-region beg (point))
+       (message-remove-header message-ignored-resent-headers t)
+       (goto-char (point-max)))
+      (insert mail-header-separator)
+      ;; Rename all old ("Also-")Resent headers.
+      (while (re-search-backward "^\\(Also-\\)*Resent-" beg t)
+       (beginning-of-line)
+       (insert "Also-"))
+      ;; Quote any "From " lines at the beginning.
+      (goto-char beg)
+      (when (looking-at "From ")
+       (replace-match "X-From-Line: "))
+      ;; Send it.
+      (let ((message-encoding-buffer (current-buffer))
+           (message-edit-buffer (current-buffer))
+           message-required-mail-headers)
+       (message-send-mail))
+      (kill-buffer (current-buffer)))
+    (message "Resending message to %s...done" address)))
+
+(defun message-bounce-setup-for-mime-edit ()
+  (set (make-local-variable 'message-setup-hook) nil)
+  (mime-edit-again))
+
+;;;###autoload
+(defun message-bounce ()
+  "Re-mail the current message.
+This only makes sense if the current message is a bounce message that
+contains some mail you have written which has been bounced back to
+you."
+  (interactive)
+  (let ((cur (current-buffer))
+       mime-boundary boundary)
+    (message-pop-to-buffer (message-buffer-name "bounce"))
+    (insert-buffer-substring cur)
+    (undo-boundary)
+    (message-narrow-to-head)
+    (if (and (message-fetch-field "MIME-Version")
+            (setq mime-boundary (message-fetch-field "Content-Type")))
+       (if (string-match "boundary=\"\\([^\"]+\\)\"" mime-boundary)
+           (setq mime-boundary (concat (regexp-quote
+                                        (match-string 1 mime-boundary))
+                                       " *\nContent-Type: message/rfc822"))
+         (setq mime-boundary nil)))
+    (widen)
+    (goto-char (point-min))
+    (re-search-forward "\n\n+" nil t)
+    (setq boundary (point))
+    ;; We remove everything before the bounced mail.
+    (if (or (and mime-boundary
+                (re-search-forward mime-boundary nil t)
+                (forward-line 1))
+           (re-search-forward message-unsent-separator nil t)
+           (progn
+             (search-forward "\n\n" nil 'move)
+             (re-search-backward "^Return-Path:.*\n" boundary t)))
+       (progn
+         (forward-line 1)
+         (delete-region (point-min)
+                        (if (re-search-forward "^[^ \n\t]+:" nil t)
+                            (match-beginning 0)
+                          (point))))
+      (when (re-search-backward "^.?From .*\n" nil t)
+       (delete-region (match-beginning 0) (match-end 0))))
+    (save-restriction
+      (message-narrow-to-head-1)
+      (message-remove-header message-ignored-bounced-headers t)
+      (goto-char (point-max))
+      (insert mail-header-separator))
+    (when message-bounce-setup-function
+      (funcall message-bounce-setup-function))
+    (run-hooks 'message-bounce-setup-hook)
+    (message-position-point)))
+
+;;;
+;;; Interactive entry points for new message buffers.
+;;;
+
+;;;###autoload
+(defun message-mail-other-window (&optional to subject)
+  "Like `message-mail' command, but display mail buffer in another window."
+  (interactive)
+  (unless (message-mail-user-agent)
+    (let ((pop-up-windows t)
+         (special-display-buffer-names nil)
+         (special-display-regexps nil)
+         (same-window-buffer-names nil)
+         (same-window-regexps nil))
+      (message-pop-to-buffer (message-buffer-name "mail" to))))
+  (let ((message-this-is-mail t))
+    (message-setup `((To . ,(or to "")) (Subject . ,(or subject "")))
+                  nil nil 'switch-to-buffer-other-window)))
+
+;;;###autoload
+(defun message-mail-other-frame (&optional to subject)
+  "Like `message-mail' command, but display mail buffer in another frame."
+  (interactive)
+  (unless (message-mail-user-agent)
+    (let ((pop-up-frames t)
+         (special-display-buffer-names nil)
+         (special-display-regexps nil)
+         (same-window-buffer-names nil)
+         (same-window-regexps nil))
+      (message-pop-to-buffer (message-buffer-name "mail" to))))
+  (let ((message-this-is-mail t))
+    (message-setup `((To . ,(or to "")) (Subject . ,(or subject "")))
+                  nil nil 'switch-to-buffer-other-frame)))
+
+;;;###autoload
+(defun message-news-other-window (&optional newsgroups subject)
+  "Start editing a news article to be sent."
+  (interactive)
+  (let ((pop-up-windows t)
+       (special-display-buffer-names nil)
+       (special-display-regexps nil)
+       (same-window-buffer-names nil)
+       (same-window-regexps nil))
+    (message-pop-to-buffer (message-buffer-name "posting" nil newsgroups)))
+  (let ((message-this-is-news t))
+    (message-setup `((Newsgroups . ,(or newsgroups ""))
+                    (Subject . ,(or subject ""))))))
+
+;;;###autoload
+(defun message-news-other-frame (&optional newsgroups subject)
+  "Start editing a news article to be sent."
+  (interactive)
+  (let ((pop-up-frames t)
+       (special-display-buffer-names nil)
+       (special-display-regexps nil)
+       (same-window-buffer-names nil)
+       (same-window-regexps nil))
+    (message-pop-to-buffer (message-buffer-name "posting" nil newsgroups)))
+  (let ((message-this-is-news t))
+    (message-setup `((Newsgroups . ,(or newsgroups ""))
+                    (Subject . ,(or subject ""))))))
+
+;;; underline.el
+
+;; This code should be moved to underline.el (from which it is stolen).
+
+;;;###autoload
+(defun bold-region (start end)
+  "Bold all nonblank characters in the region.
+Works by overstriking characters.
+Called from program, takes two arguments START and END
+which specify the range to operate on."
+  (interactive "r")
+  (save-excursion
+    (let ((end1 (make-marker)))
+      (move-marker end1 (max start end))
+      (goto-char (min start end))
+      (while (< (point) end1)
+       (or (looking-at "[_\^@- ]")
+           (insert (char-after) "\b"))
+       (forward-char 1)))))
+
+;;;###autoload
+(defun unbold-region (start end)
+  "Remove all boldness (overstruck characters) in the region.
+Called from program, takes two arguments START and END
+which specify the range to operate on."
+  (interactive "r")
+  (save-excursion
+    (let ((end1 (make-marker)))
+      (move-marker end1 (max start end))
+      (goto-char (min start end))
+      (while (re-search-forward "\b" end1 t)
+       (if (eq (char-after) (char-after (- (point) 2)))
+           (delete-char -2))))))
+
+(defalias 'message-exchange-point-and-mark 'exchange-point-and-mark)
+(defalias 'message-make-overlay 'make-overlay)
+(defalias 'message-delete-overlay 'delete-overlay)
+(defalias 'message-overlay-put 'overlay-put)
+(defun message-kill-all-overlays ()
+  (if (featurep 'xemacs)
+      (map-extents (lambda (extent ignore) (delete-extent extent)))
+    (mapcar #'delete-overlay (overlays-in (point-min) (point-max)))))
+
+;; Support for toolbar
+(eval-when-compile
+  (defvar tool-bar-map)
+  (defvar tool-bar-mode))
+
+(defun message-tool-bar-local-item-from-menu (command icon in-map &optional from-map &rest props)
+  ;; We need to make tool bar entries in local keymaps with
+  ;; `tool-bar-local-item-from-menu' in Emacs > 21.3
+  (if (fboundp 'tool-bar-local-item-from-menu)
+      ;; This is for Emacs 21.3
+      (tool-bar-local-item-from-menu command icon in-map from-map props)
+    (tool-bar-add-item-from-menu command icon from-map props)))
+
+(defun message-tool-bar-map ()
+  (or message-tool-bar-map
+      (setq message-tool-bar-map
+           (and
+            (condition-case nil (require 'tool-bar) (error nil))
+            (fboundp 'tool-bar-add-item-from-menu)
+            tool-bar-mode
+            (let ((tool-bar-map (copy-keymap tool-bar-map))
+                  (load-path (mm-image-load-path)))
+              ;; Zap some items which aren't so relevant and take
+              ;; up space.
+              (dolist (key '(print-buffer kill-buffer save-buffer
+                                          write-file dired open-file))
+                (define-key tool-bar-map (vector key) nil))
+              (message-tool-bar-local-item-from-menu
+               'message-send-and-exit "mail_send" tool-bar-map message-mode-map)
+              (message-tool-bar-local-item-from-menu
+               'message-kill-buffer "close" tool-bar-map message-mode-map)
+              (message-tool-bar-local-item-from-menu
+               'message-dont-send "cancel" tool-bar-map message-mode-map)
+;;            (message-tool-bar-local-item-from-menu
+;;             'mime-edit-insert-file "attach"
+;;             tool-bar-map mime-edit-mode-map)
+              (message-tool-bar-local-item-from-menu
+               'ispell-message "spell" tool-bar-map message-mode-map)
+;;            (message-tool-bar-local-item-from-menu
+;;             'mime-edit-preview-message "preview"
+;;             tool-bar-map mime-edit-mode-map)
+              (message-tool-bar-local-item-from-menu
+               'message-insert-importance-high "important"
+               tool-bar-map message-mode-map)
+              (message-tool-bar-local-item-from-menu
+               'message-insert-importance-low "unimportant"
+               tool-bar-map message-mode-map)
+              (message-tool-bar-local-item-from-menu
+               'message-insert-disposition-notification-to "receipt"
+               tool-bar-map message-mode-map)
+              tool-bar-map)))))
+
+;;; Group name completion.
+
+(defcustom message-newgroups-header-regexp
+  "^\\(Newsgroups\\|Followup-To\\|Posted-To\\|Gcc\\):"
+  "Regexp that match headers that lists groups."
+  :group 'message
+  :type 'regexp)
+
+(defcustom message-completion-alist
+  (list (cons message-newgroups-header-regexp 'message-expand-group)
+       '("^\\(Resent-\\)?\\(To\\|B?Cc\\):" . message-expand-name)
+       '("^\\(Reply-To\\|From\\|Mail-Followup-To\\|Mail-Copies-To\\):"
+         . message-expand-name)
+       '("^\\(Disposition-Notification-To\\|Return-Receipt-To\\):"
+         . message-expand-name))
+  "Alist of (RE . FUN).  Use FUN for completion on header lines matching RE."
+  :group 'message
+  :type '(alist :key-type regexp :value-type function))
+
+(defcustom message-expand-name-function
+  (if (fboundp 'bbdb-complete-name)
+      'bbdb-complete-name
+    (if (fboundp 'lsdb-complete-name)
+       'lsdb-complete-name
+      'expand-abbrev))
+  "*A function called to expand addresses in field body."
+  :group 'message
+  :type 'function)
+
+(defcustom message-tab-body-function nil
+  "*Function to execute when `message-tab' (TAB) is executed in the body.
+If nil, the function bound in `text-mode-map' or `global-map' is executed."
+  :group 'message
+  :type 'function)
+
+(defun message-tab ()
+  "Complete names according to `message-completion-alist'.
+Execute function specified by `message-tab-body-function' when not in
+those headers."
+  (interactive)
+  (let ((alist message-completion-alist))
+    (while (and alist
+               (let ((mail-abbrev-mode-regexp (caar alist)))
+                 (not (mail-abbrev-in-expansion-header-p))))
+      (setq alist (cdr alist)))
+    (funcall (or (cdar alist) message-tab-body-function
+                (lookup-key text-mode-map "\t")
+                (lookup-key global-map "\t")
+                'indent-relative))))
+
+(defun message-expand-group ()
+  "Expand the group name under point."
+  (let* ((b (save-excursion
+             (save-restriction
+               (narrow-to-region
+                (save-excursion
+                  (beginning-of-line)
+                  (skip-chars-forward "^:")
+                  (1+ (point)))
+                (point))
+               (skip-chars-backward "^, \t\n") (point))))
+        (completion-ignore-case t)
+        (string (buffer-substring b (progn (skip-chars-forward "^,\t\n ")
+                                           (point))))
+        (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb))
+        (completions (all-completions string hashtb))
+        comp)
+    (delete-region b (point))
+    (cond
+     ((= (length completions) 1)
+      (if (string= (car completions) string)
+         (progn
+           (insert string)
+           (message "Only matching group"))
+       (insert (car completions))))
+     ((and (setq comp (try-completion string hashtb))
+          (not (string= comp string)))
+      (insert comp))
+     (t
+      (insert string)
+      (if (not comp)
+         (message "No matching groups")
+       (save-selected-window
+         (pop-to-buffer "*Completions*")
+         (buffer-disable-undo)
+         (let ((buffer-read-only nil))
+           (erase-buffer)
+           (let ((standard-output (current-buffer)))
+             (display-completion-list (sort completions 'string<)))
+           (goto-char (point-min))
+           (delete-region (point) (progn (forward-line 3) (point))))))))))
+
+(defun message-expand-name ()
+  (funcall message-expand-name-function))
+
+;;; Help stuff.
+
+(defun message-talkative-question (ask question show &rest text)
+  "Call FUNCTION with argument QUESTION; optionally display TEXT... args.
+If SHOW is non-nil, the arguments TEXT... are displayed in a temp buffer.
+The following arguments may contain lists of values."
+  (if (and show
+          (setq text (message-flatten-list text)))
+      (save-window-excursion
+       (save-excursion
+         (with-output-to-temp-buffer " *MESSAGE information message*"
+           (set-buffer " *MESSAGE information message*")
+           (fundamental-mode)          ; for Emacs 20.4+
+           (mapcar 'princ text)
+           (goto-char (point-min))))
+       (funcall ask question))
+    (funcall ask question)))
+
+(defun message-flatten-list (list)
+  "Return a new, flat list that contains all elements of LIST.
+
+\(message-flatten-list '(1 (2 3 (4 5 (6))) 7))
+=> (1 2 3 4 5 6 7)"
+  (cond ((consp list)
+        (apply 'append (mapcar 'message-flatten-list list)))
+       (list
+        (list list))))
+
+(defun message-generate-new-buffer-clone-locals (name &optional varstr)
+  "Create and return a buffer with name based on NAME using `generate-new-buffer'.
+Then clone the local variables and values from the old buffer to the
+new one, cloning only the locals having a substring matching the
+regexp VARSTR."
+  (let ((oldbuf (current-buffer)))
+    (save-excursion
+      (set-buffer (generate-new-buffer name))
+      (message-clone-locals oldbuf varstr)
+      (current-buffer))))
+
+(defun message-clone-locals (buffer &optional varstr)
+  "Clone the local variables from BUFFER to the current buffer."
+  (let ((locals (save-excursion
+                 (set-buffer buffer)
+                 (buffer-local-variables)))
+       (regexp
+        "^\\(gnus\\|nn\\|message\\|user-\\(mail-address\\|full-name\\)\\)"))
+    (mapcar
+     (lambda (local)
+       (when (and (consp local)
+                 (car local)
+                 (string-match regexp (symbol-name (car local)))
+                 (or (null varstr)
+                     (string-match varstr (symbol-name (car local)))))
+        (ignore-errors
+          (set (make-local-variable (car local))
+               (cdr local)))))
+     locals)))
+
+;;; @ for MIME Edit mode
+;;;
+
+(defun message-maybe-encode ()
+  (when message-mime-mode
+    ;; Inherit the buffer local variable `mime-edit-pgp-processing'.
+    (let ((pgp-processing (with-current-buffer message-edit-buffer
+                           mime-edit-pgp-processing)))
+      (setq mime-edit-pgp-processing pgp-processing))
+    (run-hooks 'mime-edit-translate-hook)
+    (if (catch 'mime-edit-error
+         (save-excursion
+           (mime-edit-pgp-enclose-buffer)
+           (mime-edit-translate-body)))
+       (error "Translation error!"))
+    (run-hooks 'mime-edit-exit-hook)))
+
+(defun message-mime-insert-article (&optional full-headers)
+  (interactive "P")
+  (let ((message-cite-function 'mime-edit-inserted-message-filter)
+       (message-reply-buffer
+        (message-get-parameter-with-eval 'original-buffer))
+       (start (point)))
+    (message-yank-original nil)
+    (save-excursion
+      (narrow-to-region (goto-char start)
+                       (if (search-forward "\n\n" nil t)
+                           (1- (point))
+                         (point-max)))
+      (goto-char (point-min))
+      (let ((message-included-forward-headers
+            (if full-headers "" message-included-forward-headers)))
+       (message-remove-header message-included-forward-headers t nil t))
+      (widen))))
+
+(set-alist 'mime-edit-message-inserter-alist
+          'message-mode (function message-mime-insert-article))
+
+;;;
+;;; MIME functions
+;;;
+
+(defvar message-inhibit-body-encoding t)
+
+(defun message-encode-message-body ()
+  (unless message-inhibit-body-encoding
+    (let ((mail-parse-charset (or mail-parse-charset
+                                 message-default-charset))
+         (case-fold-search t)
+         lines content-type-p)
+      (message-goto-body)
+      (save-restriction
+       (narrow-to-region (point) (point-max))
+       (let ((new (mml-generate-mime)))
+         (when new
+           (delete-region (point-min) (point-max))
+           (insert new)
+           (goto-char (point-min))
+           (if (eq (aref new 0) ?\n)
+               (delete-char 1)
+             (search-forward "\n\n")
+             (setq lines (buffer-substring (point-min) (1- (point))))
+             (delete-region (point-min) (point))))))
+      (save-restriction
+       (message-narrow-to-headers-or-head)
+       (message-remove-header "Mime-Version")
+       (goto-char (point-max))
+       (insert "MIME-Version: 1.0\n")
+       (when lines
+         (insert lines))
+       (setq content-type-p
+             (or mml-boundary
+                 (re-search-backward "^Content-Type:" nil t))))
+      (save-restriction
+       (message-narrow-to-headers-or-head)
+       (message-remove-first-header "Content-Type")
+       (message-remove-first-header "Content-Transfer-Encoding"))
+      ;; We always make sure that the message has a Content-Type
+      ;; header.  This is because some broken MTAs and MUAs get
+      ;; awfully confused when confronted with a message with a
+      ;; MIME-Version header and without a Content-Type header.  For
+      ;; instance, Solaris' /usr/bin/mail.
+      (unless content-type-p
+       (goto-char (point-min))
+       ;; For unknown reason, MIME-Version doesn't exist.
+       (when (re-search-forward "^MIME-Version:" nil t)
+         (forward-line 1)
+         (insert "Content-Type: text/plain; charset=us-ascii\n"))))))
+
+(defun message-read-from-minibuffer (prompt &optional initial-contents)
+  "Read from the minibuffer while providing abbrev expansion."
+  (if (fboundp 'mail-abbrevs-setup)
+      (let ((mail-abbrev-mode-regexp "")
+           (minibuffer-setup-hook 'mail-abbrevs-setup)
+           (minibuffer-local-map message-minibuffer-local-map))
+       (read-from-minibuffer prompt initial-contents))
+    (let ((minibuffer-setup-hook 'mail-abbrev-minibuffer-setup-hook)
+         (minibuffer-local-map message-minibuffer-local-map))
+      (read-string prompt initial-contents))))
+
+(defun message-use-alternative-email-as-from ()
+  (require 'mail-utils)
+  (let* ((fields '("To" "Cc"))
+        (emails
+         (split-string
+          (mail-strip-quoted-names
+           (mapconcat 'message-fetch-reply-field fields ","))
+          "[ \f\t\n\r\v,]+"))
+        email)
+    (while emails
+      (if (string-match message-alternative-emails (car emails))
+         (setq email (car emails)
+               emails nil))
+      (pop emails))
+    (unless (or (not email) (equal email user-mail-address))
+      (goto-char (point-max))
+      (insert "From: " email "\n"))))
+
+(defun message-options-get (symbol)
+  (cdr (assq symbol message-options)))
+
+(defun message-options-set (symbol value)
+  (let ((the-cons (assq symbol message-options)))
+    (if the-cons
+       (if value
+           (setcdr the-cons value)
+         (setq message-options (delq the-cons message-options)))
+      (and value
+          (push (cons symbol value) message-options))))
+  value)
+
+(defun message-options-set-recipient ()
+  (save-restriction
+    (message-narrow-to-headers-or-head)
+    (message-options-set 'message-sender
+                        (mail-strip-quoted-names
+                         (message-fetch-field "from")))
+    (message-options-set 'message-recipients
+                        (mail-strip-quoted-names
+                         (let ((to (message-fetch-field "to"))
+                               (cc (message-fetch-field "cc"))
+                               (bcc (message-fetch-field "bcc")))
+                           (concat
+                            (or to "")
+                            (if (and to cc) ", ")
+                            (or cc "")
+                            (if (and (or to cc) bcc) ", ")
+                            (or bcc "")))))))
+
+(defun message-hide-headers ()
+  "Hide headers based on the `message-hidden-headers' variable."
+  (let ((regexps (if (stringp message-hidden-headers)
+                    (list message-hidden-headers)
+                  message-hidden-headers))
+       (inhibit-point-motion-hooks t)
+       (after-change-functions nil))
+    (when regexps
+      (save-excursion
+       (save-restriction
+         (message-narrow-to-headers)
+         (goto-char (point-min))
+         (while (not (eobp))
+           (if (not (message-hide-header-p regexps))
+               (message-next-header)
+             (let ((begin (point)))
+               (message-next-header)
+               (add-text-properties
+                begin (point)
+                '(invisible t message-hidden t))))))))))
+
+(defun message-hide-header-p (regexps)
+  (let ((result nil)
+       (reverse nil))
+    (when (eq (car regexps) 'not)
+      (setq reverse t)
+      (pop regexps))
+    (dolist (regexp regexps)
+      (setq result (or result (looking-at regexp))))
+    (if reverse
+       (not result)
+      result)))
+
+(when (featurep 'xemacs)
+  (require 'messagexmas)
+  (message-xmas-redefine))
+
+(provide 'message)
+
+(run-hooks 'message-load-hook)
+
+;; Local Variables:
+;; coding: iso-8859-1
+;; End:
+
+;;; message.el ends here