Sync up with Pterodactyl Gnus v0.92.
[elisp/gnus.git-] / lisp / message.el
index 7e4bbdb..99e645d 100644 (file)
@@ -2,7 +2,13 @@
 ;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
 ;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
-;; Keywords: mail, news
+;;     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.
 
 
 ;; This file is part of GNU Emacs.
 
 
 ;;; Code:
 
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
+(eval-when-compile
+  (require 'cl)
+  (require 'smtp)
+  )
 
 (require 'mailheader)
 (require 'nnheader)
 
 (require 'mailheader)
 (require 'nnheader)
 (if (string-match "XEmacs\\|Lucid" emacs-version)
     (require 'mail-abbrevs)
   (require 'mailabbrev))
 (if (string-match "XEmacs\\|Lucid" emacs-version)
     (require 'mail-abbrevs)
   (require 'mailabbrev))
-(require 'mail-parse)
-(require 'mm-bodies)
-(require 'mm-encode)
-(require 'mml)
+(require 'mime-edit)
+
+;; Avoid byte-compile warnings.
+(eval-when-compile
+  (require 'mail-parse)
+  (require 'mm-bodies)
+  (require 'mm-encode)
+  (require 'mml)
+  )
 
 (defgroup message '((user-mail-address custom-variable)
                    (user-full-name custom-variable))
 
 (defgroup message '((user-mail-address custom-variable)
                    (user-full-name custom-variable))
   :group 'message
   :group 'faces)
 
   :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
 (defcustom message-directory "~/Mail/"
   "*Directory from which all other mail file variables are derived."
   :group 'message-various
@@ -125,6 +143,16 @@ mailbox format."
                (function :tag "Other"))
   :group 'message-sending)
 
                (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-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.
 (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.
@@ -139,6 +167,11 @@ If this variable is nil, no such courtesy message will be added."
   :group 'message-interface
   :type 'regexp)
 
   :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)
+
 ;;;###autoload
 (defcustom message-from-style 'default
   "*Specifies how \"From\" headers look.
 ;;;###autoload
 (defcustom message-from-style 'default
   "*Specifies how \"From\" headers look.
@@ -214,18 +247,65 @@ included.  Organization, Lines and User-Agent are optional."
   :group 'message-headers
   :type 'regexp)
 
   :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:"
+(defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:"
   "*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)
 
   "*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]:[ \t]*\\)*[ \t]*"
   "*Regexp matching \"Re: \" in the subject line."
   :group 'message-various
   :type 'regexp)
 
 (defcustom message-subject-re-regexp "^[ \t]*\\([Rr][Ee]:[ \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."
 ;;;###autoload
 (defcustom message-signature-separator "^-- *$"
   "Regexp matching the signature separator."
@@ -260,6 +340,15 @@ should return the new buffer name."
   :group 'message-buffers
   :type 'boolean)
 
   :group 'message-buffers
   :type 'boolean)
 
+(defcustom message-kill-buffer-query-function 'yes-or-no-p
+  "*A function called to query the user whether to kill buffer anyway or not.
+If it is t, the buffer will be killed peremptorily."
+  :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)
+
 (defvar gnus-local-organization)
 (defcustom message-user-organization
   (or (and (boundp 'gnus-local-organization)
 (defvar gnus-local-organization)
 (defcustom message-user-organization
   (or (and (boundp 'gnus-local-organization)
@@ -279,6 +368,29 @@ If t, use `message-user-organization-file'."
   :type 'file
   :group 'message-headers)
 
   :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-signature-before-forwarded-message t
+  "*If non-nil, put the signature before any included forwarded message."
+  :group 'message-forwarding
+  :type 'boolean)
+
+(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-author-subject
  "*A list of functions that are called to generate a subject header for forwarded messages.
 (defcustom message-make-forward-subject-function
   'message-forward-subject-author-subject
  "*A list of functions that are called to generate a subject header for forwarded messages.
@@ -324,16 +436,17 @@ variable `mail-header-separator'.
 
 Valid values include `message-send-mail-with-sendmail' (the default),
 `message-send-mail-with-mh', `message-send-mail-with-qmail' and
 
 Valid values include `message-send-mail-with-sendmail' (the default),
 `message-send-mail-with-mh', `message-send-mail-with-qmail' and
-`smtpmail-send-it'."
+`message-send-mail-with-smtp'."
   :type '(radio (function-item message-send-mail-with-sendmail)
                (function-item message-send-mail-with-mh)
                (function-item message-send-mail-with-qmail)
   :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 smtpmail-send-it)
+               (function-item message-send-mail-with-smtp)
                (function :tag "Other"))
   :group 'message-sending
   :group 'message-mail)
 
                (function :tag "Other"))
   :group 'message-sending
   :group 'message-mail)
 
-(defcustom message-send-news-function 'message-send-news
+;; 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'."
   "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'."
@@ -370,8 +483,45 @@ 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)
 `use', always use the value."
   :group 'message-interface
   :type '(choice (const :tag "ignore" nil)
-                (const use)
-                (const ask)))
+                (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)))
+
+(defcustom message-use-mail-followup-to 'ask
+  "*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)))
+
+;;; 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)))
 
 ;; stuff relating to broken sendmail in MMDF
 (defcustom message-sendmail-f-is-evil nil
 
 ;; stuff relating to broken sendmail in MMDF
 (defcustom message-sendmail-f-is-evil nil
@@ -420,7 +570,7 @@ variable isn't used."
   :group 'message-headers
   :type 'boolean)
 
   :group 'message-headers
   :type 'boolean)
 
-(defcustom message-setup-hook nil
+(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
   "Normal hook, run each time a new outgoing message is initialized.
 The function `message-setup' runs this hook."
   :group 'message-various
@@ -438,12 +588,24 @@ the signature is inserted."
   :group 'message-various
   :type 'hook)
 
   :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-mode-hook nil
   "Hook run in message mode buffers."
   :group 'message-various
   :type 'hook)
 
-(defcustom message-header-hook nil
+(defcustom message-header-hook '((lambda () (eword-encode-header t)))
   "Hook run in a message mode buffer narrowed to the headers."
   :group 'message-various
   :type 'hook)
   "Hook run in a message mode buffer narrowed to the headers."
   :group 'message-various
   :type 'hook)
@@ -465,6 +627,12 @@ the signature is inserted."
   :type 'string
   :group 'message-insertion)
 
   :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."
+  :type 'boolean
+  :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'."
 (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'."
@@ -534,8 +702,6 @@ If stringp, use this; if non-nil, use no host name (user name only)."
 
 (defvar message-reply-buffer nil)
 (defvar message-reply-headers nil)
 
 (defvar message-reply-buffer nil)
 (defvar message-reply-headers nil)
-(defvar message-newsreader nil)
-(defvar message-mailer nil)
 (defvar message-sent-message-via nil)
 (defvar message-checksum nil)
 (defvar message-send-actions nil
 (defvar message-sent-message-via nil)
 (defvar message-checksum nil)
 (defvar message-send-actions nil
@@ -546,6 +712,9 @@ If stringp, use this; if non-nil, use no host name (user name only)."
   "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.")
   "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."
 
 (define-widget 'message-header-lines 'text
   "All header lines must be LFD terminated."
@@ -600,6 +769,10 @@ actually occur."
   :group 'message-sending
   :type 'sexp)
 
   :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.")
+
 ;; Ignore errors in case this is used in Emacs 19.
 ;; Don't use ignore-errors because this is copied into loaddefs.el.
 ;;;###autoload
 ;; Ignore errors in case this is used in Emacs 19.
 ;; Don't use ignore-errors because this is copied into loaddefs.el.
 ;;;###autoload
@@ -795,7 +968,10 @@ Defaults to `text-mode-abbrev-table'.")
     `((,(concat "^\\([Tt]o:\\)" content)
        (1 'message-header-name-face)
        (2 'message-header-to-face nil t))
     `((,(concat "^\\([Tt]o:\\)" content)
        (1 'message-header-name-face)
        (2 'message-header-to-face nil t))
-      (,(concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content)
+      (,(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))
       (,(concat "^\\([Ss]ubject:\\)" content)
        (1 'message-header-name-face)
        (2 'message-header-cc-face nil t))
       (,(concat "^\\([Ss]ubject:\\)" content)
@@ -857,17 +1033,26 @@ The cdr of ech entry is a function for applying the face to a region.")
   :group 'message-various
   :type 'hook)
 
   :group 'message-various
   :type 'hook)
 
-(defvar message-send-coding-system 'binary
-  "Coding system to encode outgoing mail.")
+(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
   (cond
 
 (defvar message-draft-coding-system
   (cond
-   ((not (fboundp 'coding-system-p)) nil)
-   ((coding-system-p 'emacs-mule) 
+   ((not (fboundp 'find-coding-system)) nil)
+   ((find-coding-system 'emacs-mule)
     (if (string-match "nt\\|windows" system-configuration)
        'emacs-mule-dos 'emacs-mule))
     (if (string-match "nt\\|windows" system-configuration)
        'emacs-mule-dos 'emacs-mule))
-   ((memq 'escape-quoted (mm-get-coding-system-list)) 'escape-quoted)
-   ((coding-system-p 'no-conversion) 'no-conversion)
+   ((find-coding-system 'escape-quoted) 'escape-quoted)
+   ((find-coding-system 'no-conversion) 'no-conversion)
    (t nil))
   "Coding system to compose mail.")
 
    (t nil))
   "Coding system to compose mail.")
 
@@ -979,6 +1164,7 @@ The cdr of ech entry is a function for applying the face to a region.")
   (autoload 'nndraft-request-expire-articles "nndraft")
   (autoload 'gnus-open-server "gnus-int")
   (autoload 'gnus-request-post "gnus-int")
   (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 'rmail-output "rmail"))
 
   (autoload 'gnus-alive-p "gnus-util")
   (autoload 'rmail-output "rmail"))
 
@@ -987,6 +1173,22 @@ The cdr of ech entry is a function for applying the face to a region.")
 ;;;
 ;;; Utility functions.
 ;;;
 ;;;
 ;;; 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 the rest of the arguments in a temp. buffer if SHOW"
 
 (defmacro message-y-or-n-p (question show &rest text)
   "Ask QUESTION, displaying the rest of the arguments in a temp. buffer if SHOW"
@@ -1037,7 +1239,7 @@ The cdr of ech entry is a function for applying the face to a region.")
             (file-readable-p file)
             (file-regular-p file))
     (with-temp-buffer
             (file-readable-p file)
             (file-regular-p file))
     (with-temp-buffer
-      (mm-insert-file-contents file)
+      (nnheader-insert-file-contents file)
       (goto-char (point-min))
       (looking-at message-unix-mail-delimiter))))
 
       (goto-char (point-min))
       (looking-at message-unix-mail-delimiter))))
 
@@ -1080,11 +1282,12 @@ The cdr of ech entry is a function for applying the face to a region.")
 
 (defun message-fetch-reply-field (header)
   "Fetch FIELD from the message we're replying to."
 
 (defun message-fetch-reply-field (header)
   "Fetch FIELD from the message we're replying to."
-  (when (and message-reply-buffer
-            (buffer-name message-reply-buffer))
-    (save-excursion
-      (set-buffer message-reply-buffer)
-      (message-fetch-field header))))
+  (let ((buffer (message-eval-parameter message-reply-buffer)))
+    (when (and buffer
+              (buffer-name buffer))
+      (save-excursion
+       (set-buffer buffer)
+       (message-fetch-field header)))))
 
 (defun message-set-work-buffer ()
   (if (get-buffer " *message work*")
 
 (defun message-set-work-buffer ()
   (if (get-buffer " *message work*")
@@ -1092,8 +1295,7 @@ The cdr of ech entry is a function for applying the face to a region.")
        (set-buffer " *message work*")
        (erase-buffer))
     (set-buffer (get-buffer-create " *message work*"))
        (set-buffer " *message work*")
        (erase-buffer))
     (set-buffer (get-buffer-create " *message work*"))
-    (kill-all-local-variables)
-    (mm-enable-multibyte)))
+    (kill-all-local-variables)))
 
 (defun message-functionp (form)
   "Return non-nil if FORM is funcallable."
 
 (defun message-functionp (form)
   "Return non-nil if FORM is funcallable."
@@ -1274,7 +1476,9 @@ Point is left at the beginning of the narrowed-to region."
   (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-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-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-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)
@@ -1304,9 +1508,10 @@ Point is left at the beginning of the narrowed-to 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 "\C-c\C-z" 'message-kill-to-signature)
   (define-key message-mode-map "\M-\r" 'message-newline-and-reformat)
 
-  (define-key message-mode-map "\C-c\C-a" 'mml-attach-file)
+  (define-key message-mode-map "\t" 'message-tab)
 
 
-  (define-key message-mode-map "\t" 'message-tab))
+  (define-key message-mode-map "\C-x\C-s" 'message-save-drafts)
+  (define-key message-mode-map "\C-xk" 'message-mimic-kill-buffer))
 
 (easy-menu-define
  message-mode-menu message-mode-map "Message Menu."
 
 (easy-menu-define
  message-mode-menu message-mode-map "Message Menu."
@@ -1323,7 +1528,7 @@ Point is left at the beginning of the narrowed-to region."
    ["Newline and Reformat" message-newline-and-reformat t]
    ["Rename buffer" message-rename-buffer t]
    ["Spellcheck" ispell-message t]
    ["Newline and Reformat" message-newline-and-reformat t]
    ["Rename buffer" message-rename-buffer t]
    ["Spellcheck" ispell-message t]
-   ["Attach file as MIME" mml-attach-file t]
+   ["Attach file as MIME" mime-edit-insert-file t]
    "----"
    ["Send Message" message-send-and-exit t]
    ["Abort Message" message-dont-send t]
    "----"
    ["Send Message" message-send-and-exit t]
    ["Abort Message" message-dont-send t]
@@ -1339,6 +1544,9 @@ Point is left at the beginning of the narrowed-to region."
    ["Subject" message-goto-subject t]
    ["Cc" message-goto-cc t]
    ["Reply-To" message-goto-reply-to t]
    ["Subject" message-goto-subject t]
    ["Cc" message-goto-cc t]
    ["Reply-To" message-goto-reply-to t]
+   ["Mail-Reply-To" message-goto-mail-reply-to t]
+   ["Mail-Followup-To" message-goto-mail-followup-to t]
+   ["Mail-Copies-To" message-goto-mail-copies-to t]
    ["Summary" message-goto-summary t]
    ["Keywords" message-goto-keywords t]
    ["Newsgroups" message-goto-newsgroups t]
    ["Summary" message-goto-summary t]
    ["Keywords" message-goto-keywords t]
    ["Newsgroups" message-goto-newsgroups t]
@@ -1362,6 +1570,7 @@ C-c C-f  move to a header field (and create it if there isn't):
         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-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-m  move to Mail-Followup-To
         C-c C-f C-f  move to Followup-To
 C-c C-t  message-insert-to (add a To header to a news followup)
 C-c C-n  message-insert-newsgroups (add a Newsgroup header to a news reply)
         C-c C-f C-f  move to Followup-To
 C-c C-t  message-insert-to (add a To header to a news followup)
 C-c C-n  message-insert-newsgroups (add a Newsgroup header to a news reply)
@@ -1373,8 +1582,7 @@ 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-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-a  mml-attach-file (attach a file as MIME)."
+C-c C-r  message-caesar-buffer-body (rot13 the message body)."
   (interactive)
   (kill-all-local-variables)
   (set (make-local-variable 'message-reply-buffer) nil)
   (interactive)
   (kill-all-local-variables)
   (set (make-local-variable 'message-reply-buffer) nil)
@@ -1416,12 +1624,13 @@ C-c C-a  mml-attach-file (attach a file as MIME)."
   (setq paragraph-separate paragraph-start)
   (make-local-variable 'message-reply-headers)
   (setq message-reply-headers nil)
   (setq paragraph-separate paragraph-start)
   (make-local-variable 'message-reply-headers)
   (setq message-reply-headers nil)
-  (make-local-variable 'message-newsreader)
-  (make-local-variable 'message-mailer)
+  (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-post-method)
   (set (make-local-variable 'message-sent-message-via) nil)
   (set (make-local-variable 'message-checksum) nil)
-  (set (make-local-variable 'message-mime-part) 0)
+  (make-local-variable 'message-parameter-alist)
+  (setq message-parameter-alist
+       (copy-sequence message-startup-parameter-alist))
   ;;(when (fboundp 'mail-hist-define-keys)
   ;;  (mail-hist-define-keys))
   (when (string-match "XEmacs\\|Lucid" emacs-version)
   ;;(when (fboundp 'mail-hist-define-keys)
   ;;  (mail-hist-define-keys))
   (when (string-match "XEmacs\\|Lucid" emacs-version)
@@ -1446,10 +1655,8 @@ C-c C-a  mml-attach-file (attach a file as MIME)."
   (setq adaptive-fill-first-line-regexp
        (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|"
                adaptive-fill-first-line-regexp))
   (setq adaptive-fill-first-line-regexp
        (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|"
                adaptive-fill-first-line-regexp))
-  (mm-enable-multibyte)
   (make-local-variable 'indent-tabs-mode) ;Turn off tabs for indentation.
   (setq indent-tabs-mode nil)
   (make-local-variable 'indent-tabs-mode) ;Turn off tabs for indentation.
   (setq indent-tabs-mode nil)
-  (mml-mode)
   (run-hooks 'text-mode-hook 'message-mode-hook))
 
 \f
   (run-hooks 'text-mode-hook 'message-mode-hook))
 
 \f
@@ -1490,6 +1697,21 @@ C-c C-a  mml-attach-file (attach a file as MIME)."
   (interactive)
   (message-position-on-field "Reply-To" "Subject"))
 
   (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-followup-to ()
+  "Move point to the Mail-Followup-To header."
+  (interactive)
+  (message-position-on-field "Mail-Followup-To" "Subject"))
+
+(defun message-goto-mail-copies-to ()
+  "Move point to the Mail-Copies-To header."
+  (interactive)
+  (message-position-on-field "Mail-Copies-To" "Subject"))
+
 (defun message-goto-newsgroups ()
   "Move point to the Newsgroups header."
   (interactive)
 (defun message-goto-newsgroups ()
   "Move point to the Newsgroups header."
   (interactive)
@@ -1813,6 +2035,29 @@ However, if `message-yank-prefix' is non-nil, insert that prefix on each line."
          (forward-line 1))))
     (goto-char start)))
 
          (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)
+    (while refs-strs
+      (setq refs (car refs-strs)
+           refs-strs (cdr refs-strs))
+      (when refs
+       (setq refs (std11-parse-msg-ids (std11-lexical-analyze refs)))
+       (while refs
+         (setq ref (car refs)
+               refs (cdr refs))
+         (when (eq (car ref) 'msg-id)
+           (setq id (concat "<"
+                            (mapconcat
+                             (function (lambda (p) (cdr p)))
+                             (cdr ref) "")
+                            ">"))
+           (or (member id refs-list)
+               (push id refs-list))))))
+    refs-list))
+
+(defvar gnus-article-copy)
 (defun message-yank-original (&optional arg)
   "Insert the message being replied to, if any.
 Puts point before the text and mark after.
 (defun message-yank-original (&optional arg)
   "Insert the message being replied to, if any.
 Puts point before the text and mark after.
@@ -1822,13 +2067,52 @@ 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
 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."
+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 \"References\" field."
   (interactive "P")
   (interactive "P")
-  (let ((modified (buffer-modified-p)))
-    (when (and message-reply-buffer
+  (let ((modified (buffer-modified-p))
+       (buffer (message-eval-parameter message-reply-buffer))
+       start end refs)
+    (when (and buffer
               message-cite-function)
               message-cite-function)
-      (delete-windows-on message-reply-buffer t)
-      (insert-buffer message-reply-buffer)
+      (delete-windows-on buffer t)
+      (insert-buffer buffer) ; mark will be set at the end of article.
+      (setq start (point)
+           end (mark t))
+
+      ;; Add new IDs to References field.
+      (when (and message-yank-add-new-references (interactive-p))
+       (save-excursion
+         (save-restriction
+           (message-narrow-to-headers)
+           (setq refs (message-list-references
+                       nil
+                       (message-fetch-field "References")))
+           (widen)
+           (narrow-to-region start end)
+           (std11-narrow-to-header)
+           (when (setq refs (message-list-references
+                             refs
+                             (or (message-fetch-field "References")
+                                 (message-fetch-field "In-Reply-To"))
+                             (message-fetch-field "Message-ID")))
+             (widen)
+             (message-narrow-to-headers)
+             (goto-char (point-min))
+             (let ((case-fold-search t))
+               (if (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 refs) " "))))
+             (backward-delete-char 1)))))
+
       (funcall message-cite-function)
       (message-exchange-point-and-mark)
       (unless (bolp)
       (funcall message-cite-function)
       (message-exchange-point-and-mark)
       (unless (bolp)
@@ -1845,7 +2129,6 @@ prefix, and don't delete any headers."
           (if (listp message-indent-citation-function)
               message-indent-citation-function
             (list message-indent-citation-function)))))
           (if (listp message-indent-citation-function)
               message-indent-citation-function
             (list message-indent-citation-function)))))
-    (mml-quote-region start end)
     (goto-char end)
     (when (re-search-backward message-signature-separator start t)
       ;; Also peel off any blank lines before the signature.
     (goto-char end)
     (when (re-search-backward message-signature-separator start t)
       ;; Also peel off any blank lines before the signature.
@@ -1875,7 +2158,6 @@ prefix, and don't delete any headers."
             (if (listp message-indent-citation-function)
                 message-indent-citation-function
               (list message-indent-citation-function)))))
             (if (listp message-indent-citation-function)
                 message-indent-citation-function
               (list message-indent-citation-function)))))
-      (mml-quote-region start end)
       (goto-char start)
       (while functions
        (funcall (pop functions)))
       (goto-char start)
       (while functions
        (funcall (pop functions)))
@@ -1945,11 +2227,18 @@ The text will also be indented the normal way."
 ;;; Sending messages
 ;;;
 
 ;;; 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))
 (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))
+       (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
     (when (and (message-send arg)
               (buffer-name buf))
       (if message-kill-buffer-on-exit
@@ -1958,26 +2247,68 @@ The text will also be indented the normal way."
        (when (eq buf (current-buffer))
          (message-bury buf)))
       (message-do-actions actions)
        (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."
   (interactive)
       t)))
 
 (defun message-dont-send ()
   "Don't send the message you have been editing."
   (interactive)
-  (set-buffer-modified-p t)
-  (save-buffer)
-  (let ((actions message-postpone-actions))
+  (message-save-drafts)
+  (let ((actions message-postpone-actions)
+       (frame (selected-frame))
+       (org-frame message-original-frame))
     (message-bury (current-buffer))
     (message-bury (current-buffer))
-    (message-do-actions actions)))
+    (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))
 
 (defun message-kill-buffer ()
   "Kill the current buffer."
   (interactive)
   (when (or (not (buffer-modified-p))
-           (yes-or-no-p "Message modified; kill anyway? "))
-    (let ((actions message-kill-actions))
+           (eq t message-kill-buffer-query-function)
+           (funcall message-kill-buffer-query-function
+                    "The buffer modified; kill anyway? "))
+    (let ((actions message-kill-actions)
+         (frame (selected-frame))
+         (org-frame message-original-frame))
       (setq buffer-file-name nil)
       (kill-buffer (current-buffer))
       (setq buffer-file-name nil)
       (kill-buffer (current-buffer))
-      (message-do-actions actions))))
+      (message-do-actions actions)
+      (message-delete-frame frame org-frame)))
+  (message ""))
+
+(defun message-mimic-kill-buffer ()
+  "Kill the current buffer with query."
+  (interactive)
+  (unless (eq 'message-mode major-mode)
+    (error "%s must be invoked from a message buffer." this-command))
+  (let ((command this-command)
+       (bufname (read-buffer (format "Kill buffer: (default %s) "
+                                     (buffer-name)))))
+    (if (or (not bufname)
+           (string-equal bufname "")
+           (string-equal bufname (buffer-name)))
+       (message-kill-buffer)
+      (message "%s must be invoked only for the current buffer." command))))
+
+(defun message-delete-frame (frame org-frame)
+  "Delete frame for editing message."
+  (when (and (or (and (featurep 'xemacs)
+                     (not (eq 'tty (device-type))))
+                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."
 
 (defun message-bury (buffer)
   "Bury this mail buffer."
@@ -1996,45 +2327,60 @@ or error messages, and inform user.
 Otherwise any failure is reported in a message back to
 the user from the mailer."
   (interactive "P")
 Otherwise any failure is reported in a message back to
 the user from the mailer."
   (interactive "P")
-  ;; 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))
-  (message-fix-before-sending)
-  (run-hooks 'message-send-hook)
-  (message "Sending...")
-  (let ((alist message-send-method-alist)
-       (success t)
-       elem sent)
-    (while (and success
-               (setq elem (pop alist)))
-      (when (and (or (not (funcall (cadr elem)))
-                    (and (or (not (memq (car elem)
-                                        message-sent-message-via))
-                             (y-or-n-p
-                              (format
-                               "Already sent message via %s; resend? "
-                               (car elem))))
-                         (setq success (funcall (caddr elem) arg)))))
-       (setq sent t)))
-    (unless sent
-      (error "No methods specified to send by"))
-    (when (and success sent)
-      (message-do-fcc)
-      ;;(when (fboundp 'mail-hist-put-headers-into-history)
-      ;; (mail-hist-put-headers-into-history))
+  ;; 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 "Sending...")
+    (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)
       (save-excursion
       (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)))
+       (set-buffer message-encoding-buffer)
+       (erase-buffer)
+       (insert-buffer message-edit-buffer)
+       (funcall message-encode-function)
+       (message-fix-before-sending)
+       (while (and success
+                   (setq elem (pop alist)))
+         (when (and (or (not (funcall (cadr elem)))
+                        (and (or (not (memq (car elem)
+                                            message-sent-message-via))
+                                 (y-or-n-p
+                                  (format
+                                   "Already sent message via %s; resend? "
+                                   (car elem))))
+                             (setq success (funcall (caddr elem) arg)))))
+           (setq sent t))))
+      (unless sent
+       (error "No methods specified to send by"))
+      (prog1
+         (when (and success sent)
+           (message-do-fcc)
+           ;;(when (fboundp 'mail-hist-put-headers-into-history)
+           ;; (mail-hist-put-headers-into-history))
+           (save-excursion
+             (run-hooks 'message-sent-hook))
+           (message "Sending...done")
+           ;; Mark the buffer as unmodified and delete autosave.
+           (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."
 
 (defun message-send-via-mail (arg)
   "Send the current message via mail."
@@ -2042,7 +2388,7 @@ the user from the mailer."
 
 (defun message-send-via-news (arg)
   "Send the current message via news."
 
 (defun message-send-via-news (arg)
   "Send the current message via news."
-  (funcall message-send-news-function arg))
+  (message-send-news arg))
 
 (defmacro message-check (type &rest forms)
   "Eval FORMS if TYPE is to be checked."
 
 (defmacro message-check (type &rest forms)
   "Eval FORMS if TYPE is to be checked."
@@ -2088,12 +2434,56 @@ the user from the mailer."
        (eval (car actions)))))
     (pop actions)))
 
        (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 message-send-mail-function)
+                  (error
+                   (throw 'message-sending-mail-failure err))))))
+            nil)
+          (condition-case err
+              (progn
+                (funcall message-send-mail-function)
+                nil)
+            (error err))))
+    (when failure
+      (if (eq 'error (car failure))
+         (cadr failure)
+       (prin1-to-string failure)))))
+
 (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))
 (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))
-       (mailbuf (current-buffer)))
+       failure)
     (save-restriction
       (message-narrow-to-headers)
       ;; Insert some headers.
     (save-restriction
       (message-narrow-to-headers)
       ;; Insert some headers.
@@ -2102,37 +2492,40 @@ the user from the mailer."
        (message-generate-headers message-required-mail-headers))
       ;; Let the user do all of the above.
       (run-hooks 'message-header-hook))
        (message-generate-headers message-required-mail-headers))
       ;; Let the user do all of the above.
       (run-hooks 'message-header-hook))
-    (unwind-protect
-       (save-excursion
-         (set-buffer tembuf)
-         (erase-buffer)
-         ;; Avoid copying text props.
-         (insert (format
-                  "%s" (save-excursion
-                         (set-buffer mailbuf)
-                         (buffer-string))))
-         ;; Remove some headers.
-         (message-encode-message-body)
-         (save-restriction
-           (message-narrow-to-headers)
-           ;; We (re)generate the Lines header.
-           (when (memq 'Lines message-required-mail-headers)
-             (message-generate-headers '(Lines)))
+    (if (not (message-check-mail-syntax))
+       (progn
+         (message "")
+         nil)
+      (unwind-protect
+         (save-excursion
+           (set-buffer tembuf)
+           (erase-buffer)
+           (insert-buffer message-encoding-buffer)
            ;; Remove some headers.
            ;; Remove some headers.
-           (message-remove-header message-ignored-mail-headers t)
-           (mail-encode-encoded-word-buffer))
-         (goto-char (point-max))
-         ;; require one newline at the end.
-         (or (= (preceding-char) ?\n)
-             (insert ?\n))
-         (when (and news
-                    (or (message-fetch-field "cc")
-                        (message-fetch-field "to")))
-           (message-insert-courtesy-copy))
-         (funcall message-send-mail-function))
-      (kill-buffer tembuf))
-    (set-buffer mailbuf)
-    (push 'mail message-sent-message-via)))
+           (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-mail-headers t))
+           (goto-char (point-max))
+           ;; require one newline at the end.
+           (or (= (preceding-char) ?\n)
+               (insert ?\n))
+           (when (and news
+                      (or (message-fetch-field "cc")
+                          (message-fetch-field "to")))
+             (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."
 
 (defun message-send-mail-with-sendmail ()
   "Send off the prepared buffer with sendmail."
@@ -2161,31 +2554,31 @@ the user from the mailer."
        (save-excursion
          (set-buffer errbuf)
          (erase-buffer))))
        (save-excursion
          (set-buffer errbuf)
          (erase-buffer))))
-    (let ((default-directory "/")
-         (coding-system-for-write message-send-coding-system))
-      (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" (user-login-name)))
-                    ;; 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")))))
+    (let ((default-directory "/"))
+      (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" (user-login-name)))
+                     ;; 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"))))))
     (when message-interactive
       (save-excursion
        (set-buffer errbuf)
     (when message-interactive
       (save-excursion
        (set-buffer errbuf)
@@ -2207,31 +2600,32 @@ to find out how to use this."
   (re-search-forward
    (concat "^" (regexp-quote mail-header-separator) "\n"))
   (replace-match "\n")
   (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
   (run-hooks 'message-send-mail-hook)
   ;; send the message
   (case
-      (let ((coding-system-for-write message-send-coding-system))
-       (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
-        message-qmail-inject-args))
+      (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
+       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)
     ;; qmail-inject doesn't say anything on it's stdout/stderr,
     ;; we have to look at the retval instead
     (0 nil)
@@ -2258,73 +2652,129 @@ to find out how to use this."
     ;; Pass it on to mh.
     (mh-send-letter)))
 
     ;; 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
+       (let ((result (smtp-via-smtp user-mail-address
+                                    recipients
+                                    (current-buffer))))
+         (unless (eq result t)
+           (error "Sending failed; " result)))
+      (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-send-news (&optional arg)
   (let ((tembuf (message-generate-new-buffer-clone-locals " *message temp*"))
        (case-fold-search nil)
        (method (if (message-functionp message-post-method)
                    (funcall message-post-method arg)
                  message-post-method))
 (defun message-send-news (&optional arg)
   (let ((tembuf (message-generate-new-buffer-clone-locals " *message temp*"))
        (case-fold-search nil)
        (method (if (message-functionp message-post-method)
                    (funcall message-post-method arg)
                  message-post-method))
-       (messbuf (current-buffer))
        (message-syntax-checks
         (if arg
             (cons '(existing-newsgroups . disabled)
                   message-syntax-checks)
           message-syntax-checks))
        result)
        (message-syntax-checks
         (if arg
             (cons '(existing-newsgroups . disabled)
                   message-syntax-checks)
           message-syntax-checks))
        result)
-    (if (not (message-check-news-body-syntax))
+    (save-restriction
+      (message-narrow-to-headers)
+      ;; Insert some headers.
+      (message-generate-headers message-required-news-headers)
+      ;; Let the user do all of the above.
+      (run-hooks 'message-header-hook))
+    (message-cleanup-headers)
+    (if (not (message-check-news-syntax))
        nil
        nil
-      (save-restriction
-       (message-narrow-to-headers)
-       ;; Insert some headers.
-       (message-generate-headers message-required-news-headers)
-       ;; Let the user do all of the above.
-       (run-hooks 'message-header-hook))
-      (message-cleanup-headers)
-      (if (not (message-check-news-syntax))
-         nil
-       (unwind-protect
-           (save-excursion
-             (set-buffer tembuf)
-             (buffer-disable-undo)
-             (erase-buffer)
-             ;; Avoid copying text props.
-             (insert (format
-                      "%s" (save-excursion
-                             (set-buffer messbuf)
-                             (buffer-string))))
-             (message-encode-message-body)
+      (unwind-protect
+         (save-excursion
+           (set-buffer tembuf)
+           (buffer-disable-undo)
+           (erase-buffer)
+           (insert-buffer 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.
              ;; Remove some headers.
-             (save-restriction
-               (message-narrow-to-headers)
-               ;; 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)
-               (let ((mail-parse-charset message-posting-charset))
-                 (mail-encode-encoded-word-buffer)))
-             (goto-char (point-max))
-             ;; require one newline at the end.
-             (or (= (preceding-char) ?\n)
-                 (insert ?\n))
-             (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)
-           (setq result (let ((mail-header-separator ""))
-                          (gnus-request-post method))))
-         (kill-buffer tembuf))
-       (set-buffer messbuf)
-       (if result
-           (push 'news message-sent-message-via)
-         (message "Couldn't send message via news: %s"
-                  (nnheader-get-report (car method)))
-         nil)))))
+             (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)
+    (gnus-request-post method)
+    ))
 
 ;;;
 ;;; Header generation & syntax checking.
 
 ;;;
 ;;; Header generation & syntax checking.
@@ -2343,11 +2793,16 @@ to find out how to use this."
   (save-excursion
     (save-restriction
       (widen)
   (save-excursion
     (save-restriction
       (widen)
-      ;; We narrow to the headers and check them first.
-      (save-excursion
-       (save-restriction
-         (message-narrow-to-headers)
-         (message-check-news-header-syntax))))))
+      (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
 
 (defun message-check-news-header-syntax ()
   (and
@@ -2575,6 +3030,9 @@ to find out how to use this."
         (y-or-n-p
          "The article contains control characters.  Really post? ")
        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)
    ;; Check excessive size.
    (message-check 'size
      (if (> (buffer-size) 60000)
@@ -2593,12 +3051,60 @@ to find out how to use this."
    (message-check 'signature
      (goto-char (point-max))
      (if (> (count-lines (point) (point-max)) 5)
    (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)))))
+        (y-or-n-p
+         (format
+          "Your .sig is %d lines; it should be max 4.  Really post? "
+          (1- (count-lines (point) (point-max)))))
        t))))
 
        t))))
 
+(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 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))
 (defun message-checksum ()
   "Return a \"checksum\" for the current buffer."
   (let ((sum 0))
@@ -2616,12 +3122,12 @@ to find out how to use this."
 (defun message-do-fcc ()
   "Process Fcc headers in the current buffer."
   (let ((case-fold-search t)
 (defun message-do-fcc ()
   "Process Fcc headers in the current buffer."
   (let ((case-fold-search t)
-       (buf (current-buffer))
+       (coding-system-for-write 'raw-text)
        list file)
     (save-excursion
       (set-buffer (get-buffer-create " *message temp*"))
       (erase-buffer)
        list file)
     (save-excursion
       (set-buffer (get-buffer-create " *message temp*"))
       (erase-buffer)
-      (insert-buffer-substring buf)
+      (insert-buffer-substring message-encoding-buffer)
       (save-restriction
        (message-narrow-to-headers)
        (while (setq file (message-fetch-field "fcc"))
       (save-restriction
        (message-narrow-to-headers)
        (while (setq file (message-fetch-field "fcc"))
@@ -2649,7 +3155,6 @@ to find out how to use this."
                (rmail-output file 1 nil t)
              (let ((mail-use-rfc822 t))
                (rmail-output file 1 t t))))))
                (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)
       (kill-buffer (current-buffer)))))
 
 (defun message-output (filename)
@@ -2710,6 +3215,16 @@ If NOW, use that time instead."
      ;; We do all of this because XEmacs doesn't have the %z spec.
      (format "%s%02d%02d" sign (/ zone 3600) (% zone 3600)))))
 
      ;; We do all of this because XEmacs doesn't have the %z spec.
      (format "%s%02d%02d" sign (/ zone 3600) (% zone 3600)))))
 
+(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)
 (defun message-make-message-id ()
   "Make a unique Message-ID."
   (concat "<" (message-unique-id)
@@ -2806,18 +3321,19 @@ If NOW, use that time instead."
 (defun message-make-in-reply-to ()
   "Return the In-Reply-To header for this message."
   (when message-reply-headers
 (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))
+    (let ((mid (mail-header-message-id message-reply-headers))
+         (from (mail-header-from message-reply-headers))
          (date (mail-header-date message-reply-headers)))
          (date (mail-header-date message-reply-headers)))
-      (when from
-       (let ((stop-pos
-              (string-match "  *at \\|  *@ \\| *(\\| *<" from)))
-         (concat (if (and stop-pos
-                          (not (zerop stop-pos)))
-                     (substring from 0 stop-pos) from)
-                 "'s message of \""
-                 (if (or (not date) (string= date ""))
-                     "(unknown date)" date)
-                 "\""))))))
+      (when mid
+       (concat mid
+               (when from
+                 (let ((pair (std11-extract-address-components from)))
+                   (concat "\n ("
+                           (or (car pair) (cadr pair))
+                           "'s message of \""
+                           (if (or (not date) (string= date ""))
+                               "(unknown date)" date)
+                           "\")"))))))))
 
 (defun message-make-distribution ()
   "Make a Distribution header."
 
 (defun message-make-distribution ()
   "Make a Distribution header."
@@ -2919,7 +3435,7 @@ give as trustworthy answer as possible."
   "Return the pertinent part of `user-mail-address'."
   (when user-mail-address
     (if (string-match " " user-mail-address)
   "Return the pertinent part of `user-mail-address'."
   (when user-mail-address
     (if (string-match " " user-mail-address)
-       (nth 1 (mail-extract-address-components user-mail-address))
+       (nth 1 (std11-extract-address-components user-mail-address))
       user-mail-address)))
 
 (defun message-make-fqdn ()
       user-mail-address)))
 
 (defun message-make-fqdn ()
@@ -2955,6 +3471,31 @@ give as trustworthy answer as possible."
   (or mail-host-address
       (message-make-fqdn)))
 
   (or mail-host-address
       (message-make-fqdn)))
 
+;; 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, it's value will be added in the return
+string."
+  (when message-user-agent
+    (save-excursion
+      (goto-char (point-min))
+      (let ((case-fold-search t)
+           user-agent start p end)
+       (if (re-search-forward "^User-Agent:[\t ]*" nil t)
+           (progn
+             (setq start (match-beginning 0)
+                   p (match-end 0)
+                   end (std11-field-end)
+                   user-agent (buffer-substring-no-properties p end))
+             (delete-region start (1+ end))
+             (concat message-user-agent " " user-agent))
+         message-user-agent)))))
+
 (defun message-generate-headers (headers)
   "Prepare article HEADERS.
 Headers already prepared in the buffer are not modified."
 (defun message-generate-headers (headers)
   "Prepare article HEADERS.
 Headers already prepared in the buffer are not modified."
@@ -2971,7 +3512,7 @@ Headers already prepared in the buffer are not modified."
           (To nil)
           (Distribution (message-make-distribution))
           (Lines (message-make-lines))
           (To nil)
           (Distribution (message-make-distribution))
           (Lines (message-make-lines))
-          (User-Agent message-newsreader)
+          (User-Agent (message-make-user-agent))
           (Expires (message-make-expires))
           (case-fold-search t)
           header value elem)
           (Expires (message-make-expires))
           (case-fold-search t)
           header value elem)
@@ -3068,13 +3609,13 @@ Headers already prepared in the buffer are not modified."
                   (not (message-check-element 'sender))
                   (not (string=
                         (downcase
                   (not (message-check-element 'sender))
                   (not (string=
                         (downcase
-                         (cadr (mail-extract-address-components from)))
+                         (cadr (std11-extract-address-components from)))
                         (downcase secure-sender)))
                   (or (null sender)
                       (not
                        (string=
                         (downcase
                         (downcase secure-sender)))
                   (or (null sender)
                       (not
                        (string=
                         (downcase
-                         (cadr (mail-extract-address-components sender)))
+                         (cadr (std11-extract-address-components sender)))
                         (downcase secure-sender)))))
          (goto-char (point-min))
          ;; Rename any old Sender headers to Original-Sender.
                         (downcase secure-sender)))))
          (goto-char (point-min))
          ;; Rename any old Sender headers to Original-Sender.
@@ -3124,12 +3665,11 @@ Headers already prepared in the buffer are not modified."
            (when (not quoted)
              (if (and (> (current-column) 78)
                       last)
            (when (not quoted)
              (if (and (> (current-column) 78)
                       last)
-                 (progn
-                   (save-excursion
-                     (goto-char last)
-                     (insert "\n\t"))
-                   (setq last (1+ (point))))
-               (setq last (1+ (point)))))
+                  (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))))
          (setq quoted (not quoted)))
        (unless (eobp)
          (forward-char 1))))
@@ -3137,10 +3677,17 @@ Headers already prepared in the buffer are not modified."
     (widen)
     (forward-line 1)))
 
     (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-fill-header (header value)
   (let ((begin (point))
 (defun message-fill-header (header value)
   (let ((begin (point))
-       (fill-column 990)
-       (fill-prefix "\t"))
+       (fill-column 78)
+       (fill-prefix " "))
     (insert (capitalize (symbol-name header))
            ": "
            (if (consp value) (car value) value)
     (insert (capitalize (symbol-name header))
            ": "
            (if (consp value) (car value) value)
@@ -3204,7 +3751,7 @@ Headers already prepared in the buffer are not modified."
      (concat "*" type
             (if to
                 (concat " to "
      (concat "*" type
             (if to
                 (concat " to "
-                        (or (car (mail-extract-address-components to))
+                        (or (car (std11-extract-address-components to))
                             to) "")
               "")
             (if (and group (not (string= group ""))) (concat " on " group) "")
                             to) "")
               "")
             (if (and group (not (string= group ""))) (concat " on " group) "")
@@ -3229,7 +3776,24 @@ Headers already prepared in the buffer are not modified."
 
 (defun message-pop-to-buffer (name)
   "Pop to buffer NAME, and warn if it already exists and is modified."
 
 (defun message-pop-to-buffer (name)
   "Pop to buffer NAME, and warn if it already exists and is modified."
-  (let ((buffer (get-buffer name)))
+  (let ((pop-up-frames pop-up-frames)
+       (special-display-buffer-names special-display-buffer-names)
+       (special-display-regexps special-display-regexps)
+       (same-window-buffer-names same-window-buffer-names)
+       (same-window-regexps same-window-regexps)
+       (buffer (get-buffer name))
+       (cur (current-buffer)))
+    (if (or (and (featurep 'xemacs)
+                (not (eq 'tty (device-type))))
+           window-system
+           (>= emacs-major-version 20))
+       (when message-use-multi-frames
+         (setq pop-up-frames t
+               special-display-buffer-names nil
+               special-display-regexps nil
+               same-window-buffer-names nil
+               same-window-regexps nil))
+      (setq pop-up-frames nil))
     (if (and buffer
             (buffer-name buffer))
        (progn
     (if (and buffer
             (buffer-name buffer))
        (progn
@@ -3240,7 +3804,10 @@ Headers already prepared in the buffer are not modified."
            (error "Message being composed")))
       (set-buffer (pop-to-buffer name)))
     (erase-buffer)
            (error "Message being composed")))
       (set-buffer (pop-to-buffer name)))
     (erase-buffer)
-    (message-mode)))
+    (message-mode)
+    (when pop-up-frames
+      (make-local-variable 'message-original-frame)
+      (setq message-original-frame (selected-frame)))))
 
 (defun message-do-send-housekeeping ()
   "Kill old message buffers."
 
 (defun message-do-send-housekeeping ()
   "Kill old message buffers."
@@ -3275,7 +3842,9 @@ Headers already prepared in the buffer are not modified."
          mc-modes-alist))
   (when actions
     (setq message-send-actions actions))
          mc-modes-alist))
   (when actions
     (setq message-send-actions actions))
-  (setq message-reply-buffer replybuffer)
+  (setq message-reply-buffer
+       (or (message-get-parameter 'reply-buffer)
+           replybuffer))
   (goto-char (point-min))
   ;; Insert all the headers.
   (mail-header-format
   (goto-char (point-min))
   ;; Insert all the headers.
   (mail-header-format
@@ -3396,11 +3965,11 @@ OTHER-HEADERS is an alist of header/value pairs."
   "Start editing a reply to the article in the current buffer."
   (interactive)
   (let ((cur (current-buffer))
   "Start editing a reply to the article in the current buffer."
   (interactive)
   (let ((cur (current-buffer))
-       from subject date reply-to to cc
+       from subject date to cc
        references message-id follow-to
        (inhibit-point-motion-hooks t)
        (message-this-is-mail t)
        references message-id follow-to
        (inhibit-point-motion-hooks t)
        (message-this-is-mail t)
-       mct never-mct gnus-warning)
+       mct never-mct mft mrt gnus-warning in-reply-to)
     (save-restriction
       (message-narrow-to-head)
       ;; Allow customizations to have their say.
     (save-restriction
       (message-narrow-to-head)
       ;; Allow customizations to have their say.
@@ -3415,90 +3984,143 @@ OTHER-HEADERS is an alist of header/value pairs."
                    (funcall message-wide-reply-to-function)))))
       ;; Find all relevant headers we need.
       (setq from (message-fetch-field "from")
                    (funcall message-wide-reply-to-function)))))
       ;; Find all relevant headers we need.
       (setq from (message-fetch-field "from")
-           date (message-fetch-field "date")
+           date (message-fetch-field "date" t)
            subject (or (message-fetch-field "subject") "none")
            subject (or (message-fetch-field "subject") "none")
+           references (message-fetch-field "references")
+           message-id (message-fetch-field "message-id" t)
            to (message-fetch-field "to")
            cc (message-fetch-field "cc")
            to (message-fetch-field "to")
            cc (message-fetch-field "cc")
-           mct (message-fetch-field "mail-copies-to")
-           reply-to (message-fetch-field "reply-to")
-           references (message-fetch-field "references")
-           message-id (message-fetch-field "message-id" t))
+           mct (when (and wide message-use-mail-copies-to)
+                 (message-fetch-field "mail-copies-to"))
+           mft (when (and wide message-use-mail-followup-to)
+                 (message-fetch-field "mail-followup-to"))
+           mrt (when message-use-mail-reply-to
+                 (or (message-fetch-field "mail-reply-to")
+                     (message-fetch-field "reply-to")))
+           gnus-warning (message-fetch-field "gnus-warning"))
+      (when (and gnus-warning (string-match "<[^>]+>" gnus-warning))
+       (setq message-id (match-string 0 gnus-warning)))
+      ;; 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))))
       ;; Remove any (buggy) Re:'s that are present and make a
       ;; proper one.
       ;; Remove any (buggy) Re:'s that are present and make a
       ;; proper one.
-      (when (string-match message-subject-re-regexp subject)
-       (setq subject (substring subject (match-end 0))))
-      (setq subject (concat "Re: " subject))
-
-      (when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
-                (string-match "<[^>]+>" gnus-warning))
-       (setq message-id (match-string 0 gnus-warning)))
-
-      ;; Handle special values of Mail-Copies-To.
-      (when mct
-       (cond ((or (equal (downcase mct) "never")
-                  (equal (downcase mct) "nobody"))
-              (setq never-mct t)
-              (setq mct nil))
-             ((or (equal (downcase mct) "always")
-                  (equal (downcase mct) "poster"))
-              (setq mct (or reply-to from)))))
-
-      (unless follow-to
-       (if (or (not wide)
-               to-address)
-           (progn
-             (setq follow-to (list (cons 'To (or to-address reply-to from))))
-             (when (and wide mct)
-               (push (cons 'Cc mct) follow-to)))
-         (let (ccalist)
-           (save-excursion
-             (message-set-work-buffer)
-             (unless never-mct
-               (insert (or reply-to from "")))
-             (insert (if to (concat (if (bolp) "" ", ") to "") ""))
-             (insert (if mct (concat (if (bolp) "" ", ") mct) ""))
-             (insert (if cc (concat (if (bolp) "" ", ") cc) ""))
-             (goto-char (point-min))
-             (while (re-search-forward "[ \t]+" nil t)
-               (replace-match " " t t))
-             ;; Remove addresses that match `rmail-dont-reply-to-names'.
-             (insert (prog1 (rmail-dont-reply-to (buffer-string))
-                       (erase-buffer)))
-             (goto-char (point-min))
-             ;; Perhaps Mail-Copies-To: never removed the only address?
-             (when (eobp)
-               (insert (or reply-to from "")))
-             (setq ccalist
-                   (mapcar
-                    (lambda (addr)
-                      (cons (mail-strip-quoted-names addr) addr))
-                    (message-tokenize-header (buffer-string))))
-             (let ((s ccalist))
-               (while s
-                 (setq ccalist (delq (assoc (car (pop s)) s) ccalist)))))
-           (setq follow-to (list (cons 'To (cdr (pop ccalist)))))
-           (when ccalist
-             (let ((ccs (cons 'Cc (mapconcat
-                                   (lambda (addr) (cdr addr)) ccalist ", "))))
-               (when (string-match "^ +" (cdr ccs))
-                 (setcdr ccs (substring (cdr ccs) (match-end 0))))
-               (push ccs follow-to))))))
+      (setq subject (message-make-followup-subject subject))
       (widen))
 
       (widen))
 
+    ;; Handle special values of Mail-Copies-To.
+    (when mct
+      (cond
+       ((and (or (equal (downcase mct) "never")
+                (equal (downcase mct) "nobody"))
+            (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: never'
+directs you not to send your response to the author.")))
+       (setq never-mct t)
+       (setq mct nil))
+       ((and (or (equal (downcase mct) "always")
+                (equal (downcase mct) "poster"))
+            (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: always'
+sends a copy of your response to the author.")))
+       (setq mct (or mrt from)))
+       ((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-address (setq follow-to (list (cons 'To to-address))))
+       ((not wide) (setq follow-to (list (cons 'To (or mrt from)))))
+       ;; Handle Mail-Followup-To.
+       ((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") ".
+
+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 follow-to (list (cons 'To mft)))
+       (when mct
+         (push (cons 'Cc mct) follow-to)))
+       (t
+       (let (ccalist)
+         (save-excursion
+           (message-set-work-buffer)
+           (unless never-mct
+             (insert (or mrt from "")))
+           (insert (if to (concat (if (bolp) "" ", ") to "") ""))
+           (insert (if mct (concat (if (bolp) "" ", ") mct) ""))
+           (insert (if cc (concat (if (bolp) "" ", ") cc) ""))
+           (goto-char (point-min))
+           (while (re-search-forward "[ \t]+" nil t)
+             (replace-match " " t t))
+           ;; Remove addresses that match `rmail-dont-reply-to-names'.
+           (insert (prog1 (rmail-dont-reply-to (buffer-string))
+                     (erase-buffer)))
+           (goto-char (point-min))
+           ;; Perhaps Mail-Copies-To: never removed the only address?
+           (when (eobp)
+             (insert (or mrt from "")))
+           (setq ccalist
+                 (mapcar
+                  (lambda (addr)
+                    (cons (mail-strip-quoted-names addr) addr))
+                  (message-tokenize-header (buffer-string))))
+           (let ((s ccalist))
+             (while s
+               (setq ccalist (delq (assoc (car (pop s)) s) ccalist)))))
+         (setq follow-to (list (cons 'To (cdr (pop ccalist)))))
+         (when ccalist
+           (let ((ccs (cons 'Cc (mapconcat
+                                 (lambda (addr) (cdr addr)) ccalist ", "))))
+             (when (string-match "^ +" (cdr ccs))
+               (setcdr ccs (substring (cdr ccs) (match-end 0))))
+             (push ccs follow-to)))))))
+
     (message-pop-to-buffer (message-buffer-name
                            (if wide "wide reply" "reply") from
                            (if wide to-address nil)))
 
     (setq message-reply-headers
     (message-pop-to-buffer (message-buffer-name
                            (if wide "wide reply" "reply") from
                            (if wide to-address nil)))
 
     (setq message-reply-headers
-         (vector 0 subject from date message-id references 0 0 ""))
+         (make-full-mail-header-from-decoded-header
+          0 subject from date message-id references 0 0 ""))
 
     (message-setup
      `((Subject . ,subject)
        ,@follow-to
        ,@(if (or references message-id)
             `((References . ,(concat (or references "") (and references " ")
 
     (message-setup
      `((Subject . ,subject)
        ,@follow-to
        ,@(if (or references message-id)
             `((References . ,(concat (or references "") (and references " ")
-                                     (or message-id ""))))
-          nil))
+                                     (or message-id ""))))))
      cur)))
 
 ;;;###autoload
      cur)))
 
 ;;;###autoload
@@ -3513,33 +4135,35 @@ OTHER-HEADERS is an alist of header/value pairs."
 If TO-NEWSGROUPS, use that as the new Newsgroups line."
   (interactive)
   (let ((cur (current-buffer))
 If TO-NEWSGROUPS, use that as the new Newsgroups line."
   (interactive)
   (let ((cur (current-buffer))
-       from subject date reply-to mct
+       from subject date mct
        references message-id follow-to
        (inhibit-point-motion-hooks t)
        (message-this-is-news t)
        references message-id follow-to
        (inhibit-point-motion-hooks t)
        (message-this-is-news t)
-       followup-to distribution newsgroups gnus-warning posted-to)
+       followup-to distribution newsgroups gnus-warning posted-to mft mrt)
     (save-restriction
     (save-restriction
-      (narrow-to-region
-       (goto-char (point-min))
-       (if (search-forward "\n\n" nil t)
-          (1- (point))
-        (point-max)))
+      (message-narrow-to-head)
       (when (message-functionp message-followup-to-function)
        (setq follow-to
              (funcall message-followup-to-function)))
       (setq from (message-fetch-field "from")
       (when (message-functionp message-followup-to-function)
        (setq follow-to
              (funcall message-followup-to-function)))
       (setq from (message-fetch-field "from")
-           date (message-fetch-field "date")
+           date (message-fetch-field "date" t)
            subject (or (message-fetch-field "subject") "none")
            references (message-fetch-field "references")
            message-id (message-fetch-field "message-id" t)
            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")
+           followup-to (when message-use-followup-to
+                         (message-fetch-field "followup-to"))
+           distribution (message-fetch-field "distribution")
            newsgroups (message-fetch-field "newsgroups")
            posted-to (message-fetch-field "posted-to")
            newsgroups (message-fetch-field "newsgroups")
            posted-to (message-fetch-field "posted-to")
-           reply-to (message-fetch-field "reply-to")
-           distribution (message-fetch-field "distribution")
-           mct (message-fetch-field "mail-copies-to"))
-      (when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
-                (string-match "<[^>]+>" gnus-warning))
+           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"))
+           mrt (when message-use-mail-reply-to
+                 (or (message-fetch-field "mail-reply-to")
+                     (message-fetch-field "reply-to")))
+           gnus-warning (message-fetch-field "gnus-warning"))
+      (when (and gnus-warning (string-match "<[^>]+>" gnus-warning))
        (setq message-id (match-string 0 gnus-warning)))
       ;; Remove bogus distribution.
       (when (and (stringp distribution)
        (setq message-id (match-string 0 gnus-warning)))
       ;; Remove bogus distribution.
       (when (and (stringp distribution)
@@ -3548,40 +4172,70 @@ If TO-NEWSGROUPS, use that as the new Newsgroups line."
        (setq distribution nil))
       ;; Remove any (buggy) Re:'s that are present and make a
       ;; proper one.
        (setq distribution nil))
       ;; Remove any (buggy) Re:'s that are present and make a
       ;; proper one.
-      (when (string-match message-subject-re-regexp subject)
-       (setq subject (substring subject (match-end 0))))
-      (setq subject (concat "Re: " subject))
+      (setq subject (message-make-followup-subject subject))
       (widen))
 
       (widen))
 
-    (message-pop-to-buffer (message-buffer-name "followup" from newsgroups))
-
-    (message-setup
-     `((Subject . ,subject)
-       ,@(cond
-         (to-newsgroups
-          (list (cons 'Newsgroups to-newsgroups)))
-         (follow-to follow-to)
-         ((and followup-to message-use-followup-to)
-          (list
-           (cond
-            ((equal (downcase followup-to) "poster")
-             (if (or (eq message-use-followup-to 'use)
-                     (message-y-or-n-p "Obey Followup-To: poster? " t "\
+    ;; Handle special values of Mail-Copies-To.
+    (when mct
+      (cond
+       ((and (or (equal (downcase mct) "never")
+                (equal (downcase mct) "nobody"))
+            (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: never'
+directs you not to send your response to the author.")))
+       (setq mct nil))
+       ((and (or (equal (downcase mct) "always")
+                (equal (downcase mct) "poster"))
+            (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: always'
+sends a copy of your response to the author.")))
+       (setq mct (or mrt from)))
+       ((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 (eq message-use-followup-to 'use)
+                 (message-y-or-n-p "Obey Followup-To: poster? " t "\
 You should normally obey the Followup-To: header.
 
 You should normally obey the Followup-To: header.
 
-`Followup-To: poster' sends your response via e-mail instead of news.
+       `Followup-To: poster'
+sends your response via e-mail instead of news.
 
 
-A typical situation where `Followup-To: poster' is used is when the poster
+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."))
 does not read the newsgroup, so he wouldn't see any replies sent to it."))
-                 (progn
-                   (setq message-this-is-news nil)
-                   (cons 'To (or reply-to from "")))
-               (cons 'Newsgroups newsgroups)))
-            (t
-             (if (or (equal followup-to newsgroups)
-                     (not (eq message-use-followup-to 'ask))
-                     (message-y-or-n-p
-                      (concat "Obey Followup-To: " followup-to "? ") t "\
+             (setq message-this-is-news nil
+                   distribution nil
+                   follow-to (list (cons 'To (or mrt from ""))))
+           (setq follow-to (list (cons 'Newsgroups newsgroups)))))
+        (t
+         (if (or (equal followup-to newsgroups)
+                 (not (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 "'
 You should normally obey the Followup-To: header.
 
        `Followup-To: " followup-to "'
@@ -3596,29 +4250,47 @@ be fragmented and very difficult to follow.
 
 Also, some source/announcement newsgroups are not indented for discussion;
 responses here are directed to other newsgroups."))
 
 Also, some source/announcement newsgroups are not indented for discussion;
 responses here are directed to other newsgroups."))
-                 (cons 'Newsgroups followup-to)
-               (cons 'Newsgroups newsgroups))))))
-         (posted-to
-          `((Newsgroups . ,posted-to)))
-         (t
-          `((Newsgroups . ,newsgroups))))
-       ,@(and distribution (list (cons 'Distribution distribution)))
-       ,@(if (or references message-id)
-            `((References . ,(concat (or references "") (and references " ")
-                                     (or message-id "")))))
-       ,@(when (and mct
-                   (not (or (equal (downcase mct) "never")
-                            (equal (downcase mct) "nobody"))))
-          (list (cons 'Cc (if (or (equal (downcase mct) "always")
-                                  (equal (downcase mct) "poster"))
-                              (or reply-to from "")
-                            mct)))))
+             (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))))))
 
 
-     cur)
+    (message-pop-to-buffer (message-buffer-name "followup" from newsgroups))
 
     (setq message-reply-headers
 
     (setq message-reply-headers
-         (vector 0 subject from date message-id references 0 0 ""))))
+         (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)))
+       ,@(if (or references message-id)
+            `((References . ,(concat (or references "") (and references " ")
+                                     (or message-id ""))))))
+     cur)))
 
 ;;;###autoload
 (defun message-cancel-news ()
 
 ;;;###autoload
 (defun message-cancel-news ()
@@ -3638,13 +4310,14 @@ responses here are directed to other newsgroups."))
                message-id (message-fetch-field "message-id" t)
                distribution (message-fetch-field "distribution")))
        ;; Make sure that this article was written by the user.
                message-id (message-fetch-field "message-id" t)
                distribution (message-fetch-field "distribution")))
        ;; Make sure that this article was written by the user.
-       (unless (or (and sender
-                        (string-equal
-                         (downcase sender)
-                         (downcase (message-make-sender))))
-                   (string-equal
-                    (downcase (cadr (mail-extract-address-components from)))
-                    (downcase (cadr (mail-extract-address-components
+       (unless (or (and sender
+                        (string-equal
+                         (downcase sender)
+                         (downcase (message-make-sender))))
+                   (string-equal
+                    (downcase (cadr (std11-extract-address-components
+                                     from)))
+                    (downcase (cadr (std11-extract-address-components
                                      (message-make-from))))))
          (error "This article is not yours"))
        ;; Make control message.
                                      (message-make-from))))))
          (error "This article is not yours"))
        ;; Make control message.
@@ -3662,11 +4335,17 @@ responses here are directed to other newsgroups."))
        (run-hooks 'message-cancel-hook)
        (message "Canceling your article...")
        (if (let ((message-syntax-checks
        (run-hooks 'message-cancel-hook)
        (message "Canceling your article...")
        (if (let ((message-syntax-checks
-                  'dont-check-for-anything-just-trust-me))
-             (funcall message-send-news-function))
+                  '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)))))
 
            (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.
 ;;;###autoload
 (defun message-supersede ()
   "Start composing a message to supersede the current message.
@@ -3682,8 +4361,8 @@ header line with the old Message-ID."
                      (downcase sender)
                      (downcase (message-make-sender))))
                (string-equal
                      (downcase sender)
                      (downcase (message-make-sender))))
                (string-equal
-                (downcase (cadr (mail-extract-address-components from)))
-                (downcase (cadr (mail-extract-address-components
+                (downcase (cadr (std11-extract-address-components from)))
+                (downcase (cadr (std11-extract-address-components
                                  (message-make-from))))))
       (error "This article is not yours"))
     ;; Get a normal message buffer.
                                  (message-make-from))))))
       (error "This article is not yours"))
     ;; Get a normal message buffer.
@@ -3700,7 +4379,11 @@ header line with the old Message-ID."
     (goto-char (point-max))
     (insert mail-header-separator)
     (widen)
     (goto-char (point-max))
     (insert mail-header-separator)
     (widen)
-    (forward-line 1)))
+    (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 ()
 
 ;;;###autoload
 (defun message-recover ()
@@ -3778,10 +4461,14 @@ the message."
       (current-buffer)
       (message-narrow-to-head)
       (let ((funcs message-make-forward-subject-function)
       (current-buffer)
       (message-narrow-to-head)
       (let ((funcs message-make-forward-subject-function)
-           (subject (if message-wash-forwarded-subjects
-                        (message-wash-subject
-                         (or (message-fetch-field "Subject") ""))
-                      (or (message-fetch-field "Subject") ""))))
+           (subject (message-fetch-field "Subject")))
+       (setq subject
+             (if subject
+                 (if message-wash-forwarded-subjects
+                     (message-wash-subject
+                      (nnheader-decode-subject subject))
+                   (nnheader-decode-subject subject))
+               "(none)"))
        ;; Make sure funcs is a list.
        (and funcs
             (not (listp funcs))
        ;; Make sure funcs is a list.
        (and funcs
             (not (listp funcs))
@@ -3807,10 +4494,29 @@ Optional NEWS will use news to forward instead of mail."
       (message-mail nil subject))
     ;; Put point where we want it before inserting the forwarded
     ;; message.
       (message-mail nil subject))
     ;; Put point where we want it before inserting the forwarded
     ;; message.
-    (message-goto-body)
-    (insert "\n\n<#part type=message/rfc822 disposition=inline>\n")
-    (mml-insert-buffer cur)
-    (insert "<#/part>\n")
+    (if message-signature-before-forwarded-message
+       (goto-char (point-max))
+      (message-goto-body))
+    ;; Make sure we're at the start of the line.
+    (unless (eolp)
+      (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)
+    (setq art-beg (point))
+    (insert-buffer-substring cur)
+    (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
     (message-position-point)))
 
 ;;;###autoload
@@ -3824,7 +4530,10 @@ Optional NEWS will use news to forward instead of mail."
       ;; We first set up a normal mail buffer.
       (set-buffer (get-buffer-create " *message resend*"))
       (erase-buffer)
       ;; We first set up a normal mail buffer.
       (set-buffer (get-buffer-create " *message resend*"))
       (erase-buffer)
-      (message-setup `((To . ,address)))
+      ;; avoid to turn-on-mime-edit
+      (let (message-setup-hook)
+       (message-setup `((To . ,address)))
+       )
       ;; Insert our usual headers.
       (message-generate-headers '(From Date To))
       (message-narrow-to-headers)
       ;; Insert our usual headers.
       (message-generate-headers '(From Date To))
       (message-narrow-to-headers)
@@ -3855,12 +4564,17 @@ Optional NEWS will use news to forward instead of mail."
       (when (looking-at "From ")
        (replace-match "X-From-Line: "))
       ;; Send it.
       (when (looking-at "From ")
        (replace-match "X-From-Line: "))
       ;; Send it.
-      (let ((message-inhibit-body-encoding t)
-           message-required-mail-headers)
-       (message-send-mail))
+      (let ((message-encoding-buffer (current-buffer))
+           (message-edit-buffer (current-buffer)))
+       (let (message-required-mail-headers)
+         (message-send-mail)))
       (kill-buffer (current-buffer)))
     (message "Resending message to %s...done" address)))
 
       (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.
 ;;;###autoload
 (defun message-bounce ()
   "Re-mail the current message.
@@ -3874,7 +4588,7 @@ you."
     (insert-buffer-substring cur)
     (undo-boundary)
     (message-narrow-to-head)
     (insert-buffer-substring cur)
     (undo-boundary)
     (message-narrow-to-head)
-    (if (and (message-fetch-field "Mime-Version")
+    (if (and (message-fetch-field "MIME-Version")
             (setq boundary (message-fetch-field "Content-Type")))
        (if (string-match "boundary=\"\\([^\"]+\\)\"" boundary)
            (setq boundary (concat (match-string 1 boundary) " *\n"
             (setq boundary (message-fetch-field "Content-Type")))
        (if (string-match "boundary=\"\\([^\"]+\\)\"" boundary)
            (setq boundary (concat (match-string 1 boundary) " *\n"
@@ -3900,6 +4614,9 @@ you."
       (message-remove-header message-ignored-bounced-headers t)
       (goto-char (point-max))
       (insert mail-header-separator))
       (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)))
 
 ;;;
     (message-position-point)))
 
 ;;;
@@ -4101,7 +4818,8 @@ regexp varstr."
   (let ((locals (save-excursion
                  (set-buffer buffer)
                  (buffer-local-variables)))
   (let ((locals (save-excursion
                  (set-buffer buffer)
                  (buffer-local-variables)))
-       (regexp "^gnus\\|^nn\\|^message"))
+       (regexp
+        "^\\(gnus\\|nn\\|message\\|user-\\(mail-address\\|full-name\\)\\)"))
     (mapcar
      (lambda (local)
        (when (and (consp local)
     (mapcar
      (lambda (local)
        (when (and (consp local)
@@ -4112,6 +4830,49 @@ regexp varstr."
                (cdr local)))))
      locals)))
 
                (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!")
+      )
+    (end-of-invisible)
+    (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))
+
 ;;; Miscellaneous functions
 
 ;; stolen (and renamed) from nnheader.el
 ;;; Miscellaneous functions
 
 ;; stolen (and renamed) from nnheader.el
@@ -4131,10 +4892,10 @@ regexp varstr."
 ;;; MIME functions
 ;;;
 
 ;;; MIME functions
 ;;;
 
-(defvar message-inhibit-body-encoding nil)
+(defvar message-inhibit-body-encoding t)
 
 (defun message-encode-message-body ()
 
 (defun message-encode-message-body ()
-  (unless message-inhibit-body-encoding 
+  (unless message-inhibit-body-encoding
     (let ((mail-parse-charset (or mail-parse-charset
                                  message-default-charset
                                  message-posting-charset))
     (let ((mail-parse-charset (or mail-parse-charset
                                  message-default-charset
                                  message-posting-charset))
@@ -4177,6 +4938,21 @@ regexp varstr."
        (forward-line 1)
        (insert "Content-Type: text/plain; charset=us-ascii\n")))))
 
        (forward-line 1)
        (insert "Content-Type: text/plain; charset=us-ascii\n")))))
 
+(defvar message-save-buffer " *encoding")
+(defun message-save-drafts ()
+  (interactive)
+  (if (not (get-buffer message-save-buffer))
+      (get-buffer-create message-save-buffer))
+  (let ((filename buffer-file-name)
+       (buffer (current-buffer)))
+    (set-buffer message-save-buffer)
+    (erase-buffer)
+    (insert-buffer buffer)
+    (mime-edit-translate-buffer)
+    (write-region (point-min) (point-max) filename)
+    (set-buffer buffer)
+    (set-buffer-modified-p nil)))
+
 (provide 'message)
 
 (run-hooks 'message-load-hook)
 (provide 'message)
 
 (run-hooks 'message-load-hook)