Copy from Nana-gnus 6.13.
authorkeiichi <keiichi>
Thu, 23 Dec 1999 10:18:05 +0000 (10:18 +0000)
committerkeiichi <keiichi>
Thu, 23 Dec 1999 10:18:05 +0000 (10:18 +0000)
lisp/mess-bbdb.el [new file with mode: 0644]
lisp/mess-lcl.el [new file with mode: 0644]
lisp/message.el

diff --git a/lisp/mess-bbdb.el b/lisp/mess-bbdb.el
new file mode 100644 (file)
index 0000000..b85a841
--- /dev/null
@@ -0,0 +1,39 @@
+;; mess-bbdb.el --- Interface to message (For after Nana-gnus 6.12.1).
+
+;; Copyright (C) 1998 Keiichi Suzuki <keiichi@nanap.org>
+
+;; Author: Keiichi Suzuki <keiichi@nanap.org>
+;; Keywords: BBDB, mail, news
+
+;; This file is part of Nana-gnus.
+
+;; This program is free software; you can redistribute it and/or
+;; modify it under the terms of the GNU General Public License as
+;; published by the Free Software Foundation; either version 2, or (at
+;; your option) any later version.
+
+;; This program is distributed in the hope that it will be useful, but
+;; WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+;; General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Code:
+
+(require 'bbdb)
+
+(defvar message-bbdb/mailing-list-field 'ml-name)
+
+(defun message-bbdb/mailing-list-p (address)
+  (let ((record (bbdb-search-simple nil address)))
+    (and record
+        (bbdb-record-getprop record message-bbdb/mailing-list-field)
+        )))
+
+(provide 'mess-bbdb)
+                         
+;; mess-bbdb.el ends here.
diff --git a/lisp/mess-lcl.el b/lisp/mess-lcl.el
new file mode 100644 (file)
index 0000000..b0d1ffb
--- /dev/null
@@ -0,0 +1,374 @@
+;;; mess-lcl.el --- Control message format with recipient's locale
+;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
+
+;; Author: Keiichi Suzuki   <keiichi@nanap.org>
+;; Keywords: mail, news, MIME
+
+;; This file is part of GNU Emacs.
+
+;; GNU Emacs is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 2, or (at your option)
+;; any later version.
+
+;; GNU Emacs is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.         See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING.  If not, write to the
+;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+;; Boston, MA 02111-1307, USA.
+
+;;; Commentary:
+
+;; This module controls message format with recipient's locale.
+
+;;; Code:
+
+(eval-when-compile
+  (require 'cl)
+  )
+
+(require 'message)
+
+(defgroup message-locale '((message-encode-function custom-variable))
+  "Control message format with recipient."
+  :link '(custom-manual "(message)Top")
+  :group 'message)
+
+(defcustom message-locale-default nil
+  "Default locale for sending message."
+  :group 'message-locale
+  :type 'symbol)
+
+(defcustom message-locale-detect-for-mail nil
+  "*A function called to detect locale from recipient mail address."
+  :group 'message-locale
+  :type 'function)
+
+(defcustom message-locale-detect-for-news
+  'message-locale-detect-with-newsgroup-alist
+  "*A function called to detect locale from newsgroup."
+  :group 'message-locale
+  :type 'function)
+
+(defcustom message-mime-charset-recover-function
+  'message-mime-charset-recover-by-ask
+  "A function called to recover \
+when could not found legal MIME charset for sending message."
+  :type '(radio (function-item message-mime-charset-recover-by-ask)
+               (function :tag "Other"))
+  :group 'message-locale)
+
+(defvar message-locale-newsgroup-alist
+  '(("^fj\\." . fj)
+    ))
+
+(defvar message-locale-mail-address-alist nil)
+
+(defcustom message-mime-charset-recover-ask-function
+  'message-mime-charset-recover-ask-y-or-n
+  "A function called to ask MIME charset.
+This funtion will by called from \`message-mime-charset-recover-by-ask\'."
+  :type '(radio (function-item message-mime-charset-recover-ask-y-or-n)
+               (function-item message-mime-charset-recover-ask-charset)
+               (function :tag "Other"))
+  :group 'message-locale)
+
+(defvar message-locale-mime-charsets-alist
+  '((fj . (us-ascii iso-2022-jp iso-2022-jp-2))
+    (none . nil)
+    ))
+
+(defface message-illegal-charsets-face
+  '((((class color))
+     (:foreground "black" :background "red"))
+    (t
+     (:bold t :underline t)))
+  "Face used for displaying illegal charset."
+  :group 'message-faces)
+
+(defface message-warning-charsets-face
+  '((((class color))
+     (:foreground "black" :background "yellow"))
+    (t
+     (:bold t :underline t)))
+  "Face used for displaying illegal charset."
+  :group 'message-faces)
+
+
+;;; Internal variable.
+(defvar message-locale-args nil)
+
+\f
+;;;
+;;; Utility functions.
+;;;
+(defun message-set-charsets-face (charsets face &optional start end)
+  (or start (setq start (point-min)))
+  (or end (setq end (point-max)))
+  (goto-char start)
+  (when charsets
+    (let (top)
+      (while (< (point) end)
+       (if (memq (charset-after) charsets)
+           (let ((start (point)))
+             (unless top
+               (setq top (point)))
+             (forward-char 1)
+             (while (and (< (point) end)
+                         (memq (charset-after) charsets))
+               (forward-char 1))
+             (put-text-property start (point) 'face face))
+         (forward-char 1)))
+      top)))
+
+(defmacro message-locale-args (symbol)
+  `(cdr (assq (quote ,symbol) message-locale-args))
+  )
+
+(defmacro message-locale-args-set (symbol val)
+  `(setq message-locale-args
+        (put-alist (quote ,symbol) ,val message-locale-args))
+  )
+
+(defmacro message-locale-args-original (symbol)
+  `(or (message-locale-args ,symbol) ,symbol)
+  )
+
+(defmacro message-locale-args-original-set (symbol)
+  `(message-locale-args-set ,symbol ,symbol)
+  )
+
+;;;
+;;; Call from message.el
+;;;
+(defun message-locale-maybe-encode ()
+  "Control MIME encoding for message sending.
+
+If would you like to control MIME encoding with recipient's locale,
+then set this function to `message-encode-function'."
+  (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))
+  (let ((locale-list (message-locale-detect)))
+    (when message-mime-mode
+      (let ((message-save-encoder message-save-encoder)
+           (default-mime-charset-detect-method-for-write
+             default-mime-charset-detect-method-for-write)
+           (charsets-mime-charset-alist charsets-mime-charset-alist)
+           message-locale-args)
+       (message-locale-setup-mime-charset locale-list)
+       (when (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))))
+
+;;;
+;;; Detect locale.
+;;;
+(defun message-locale-detect ()
+  (when (or message-locale-detect-for-news
+           message-locale-detect-for-mail)
+    (save-excursion
+      (save-restriction
+       (message-narrow-to-head)
+       (let (lc dest)
+         (when message-locale-detect-for-news
+           (setq lc (mapcar
+                     (lambda (newsgroup)
+                       (funcall message-locale-detect-for-news
+                                (and (string-match "[^ \t]+" newsgroup)
+                                     (match-string 0 newsgroup))))
+                     (message-tokenize-header
+                      (message-fetch-field "newsgroups")))))
+         (when message-locale-detect-for-mail
+           (let ((field-list '("to" "cc" "bcc")))
+             (while (car field-list)
+               (setq lc (append
+                         lc
+                         (mapcar
+                          (lambda (address)
+                            (funcall message-locale-detect-for-mail
+                                     (car
+                                      (cdr (std11-extract-address-components
+                                            address)))))
+                          (message-tokenize-header
+                           (message-fetch-field (pop field-list)))))))))
+         (setq lc (delq nil lc))
+         (while lc
+           (setq dest (cons (car lc) dest)
+                 lc (delq (car lc) lc)))
+         (or dest
+             (and message-locale-default (list message-locale-default)))
+         )))))
+
+(defun message-locale-detect-with-newsgroup-alist (newsgroup)
+  (let ((rest message-locale-newsgroup-alist)
+       done)
+    (while (and (not done)
+               rest)
+      (when (string-match (car (car rest)) newsgroup)
+       (setq done (car rest)))
+      (setq rest (cdr rest)))
+    (cdr done)
+    ))
+
+(defun message-locale-detect-with-mail-address-alist (address)
+  (let ((rest message-locale-mail-address-alist)
+       done)
+    (while (and (not done)
+               rest)
+      (when (string-match (car (car rest)) address)
+       (setq done (car rest)))
+      (setq rest (cdr rest)))
+    (cdr done)
+    ))
+
+;;;
+;;; Control MIME charset with recipient's locale.
+;;;
+(defun message-locale-setup-mime-charset (locale-list)
+  (message-locale-args-original-set charsets-mime-charset-alist)
+  (message-locale-args-original-set
+   default-mime-charset-detect-method-for-write)
+  (setq default-mime-charset-detect-method-for-write
+       (or message-mime-charset-recover-function
+           default-mime-charset-detect-method-for-write)
+       message-save-encoder 'message-locale-mime-save-encoder)
+  (let (locale-cs)
+    (while (and charsets-mime-charset-alist
+               locale-list)
+      (unless (setq locale-cs
+                   (assq (car locale-list)
+                         message-locale-mime-charsets-alist))
+       (error "Unknown locale \`%s\'. Add locale to \`%s\'."
+              (car locale-list)
+              'message-locale-mime-charsets-alist))
+      (setq locale-cs (cdr locale-cs)
+           charsets-mime-charset-alist (delq nil
+                                          (mapcar
+                                           (lambda (cs)
+                                             (and (memq (cdr cs) locale-cs)
+                                                  cs))
+                                           charsets-mime-charset-alist))
+           locale-list (cdr locale-list))
+      )))
+
+;;;
+;;; Recover MIME charset.
+;;;
+(defun message-mime-charset-recover-by-ask (type charsets &rest args)
+  (let ((default-charset
+         (let ((charsets-mime-charset-alist
+                (message-locale-args-original charsets-mime-charset-alist)))
+           (charsets-to-mime-charset charsets)))
+       charset)
+    (save-excursion
+      (save-restriction
+       (save-window-excursion
+         (when (eq type 'region)
+           (narrow-to-region (car args) (car (cdr args)))
+           (message-mime-highlight-illegal-chars charsets)
+           (pop-to-buffer (current-buffer) nil t)
+           (recenter 1))
+         (if (setq charset
+                   (funcall message-mime-charset-recover-ask-function
+                            (upcase (symbol-name
+                                     (or default-charset
+                                         default-mime-charset-for-write)))
+                            charsets))
+                  (intern (downcase charset))
+           (throw 'message-sending-cancel t)))))))
+
+(defun message-mime-charset-recover-ask-y-or-n (default-charset charsets)
+  (and (y-or-n-p (format "MIME charset %s is selected. OK? "
+                       default-charset))
+       default-charset))
+
+(defun message-mime-charset-recover-ask-charset (default-charset charsets)
+  (let ((alist (mapcar
+               (lambda (cs)
+                 (list (upcase (symbol-name cs))))
+               (mime-charset-list)))
+       charset)
+    (while (not charset)
+      (setq charset
+           (completing-read "What MIME charset: "
+                            alist nil t default-charset))
+      (when (string= charset "")
+       (setq charset nil)))
+    charset))
+
+(defun message-mime-highlight-illegal-chars (charsets)
+  (when charsets-mime-charset-alist
+    (let* ((min 65535)
+          (delta-lists
+           (delq nil
+                 (mapcar
+                  (lambda (x)
+                    (when (<= (length x) min)
+                      x))
+                  (delq nil (mapcar
+                             (lambda (x)
+                               (setq x (delq nil
+                                             (mapcar
+                                              (lambda (y)
+                                                (unless (memq y (car x))
+                                                  y))
+                                              charsets)
+                                             ))
+                               (when (<= (length x) min)
+                                 (setq min (length x))
+                                 x))
+                             charsets-mime-charset-alist)))))
+          top cs done rest errors warns list)
+      (while (setq top (pop delta-lists))
+       (while (setq cs (pop top))
+         (setq done nil
+               list delta-lists)
+         (when cs
+           (while (setq rest (pop list))
+             (if (setq rest (memq cs rest))
+                 (setcar rest nil)
+               (push cs warns)
+               (setq done t)))
+           (unless done
+             (push cs errors)))))
+      (put-text-property (point-min) (point-max) 'face nil)
+      (if (setq top (message-set-charsets-face
+                    errors
+                    'message-illegal-charsets-face))
+         (message-set-charsets-face warns 'message-warning-charsets-face)
+       (setq top (message-set-charsets-face
+                  warns 'message-warning-charsets-face)))
+      (if top
+         (goto-char top)
+       (goto-char (point-min))))))
+
+;;; @ for MIME Edit mode
+;;;
+(defun message-locale-mime-save-encoder (orig-buf)
+  (when (with-current-buffer orig-buf mime-edit-mode-flag)
+    (let ((charsets-mime-charset-alist
+          (message-locale-args-original charsets-mime-charset-alist))
+         (default-mime-charset-detect-method-for-write
+           (message-locale-args-original
+            default-mime-charset-detect-method-for-write)))
+      (mime-edit-translate-body)
+      (mime-edit-translate-header)
+      )))
+
+(run-hooks 'mess-lcl-load-hook)
+
+(provide 'mess-lcl)
+
+;;; mess-lcl.el ends here
index a0642c1..3fe18df 100644 (file)
@@ -1,8 +1,14 @@
 ;;; message.el --- composing mail and news messages
-;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
+;; Copyright (C) 1996,97,98 Free Software Foundation, Inc.
 
 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
-;; Keywords: mail, news
+;;         MORIOKA Tomohiko <tomo@m17n.org>
+;;         Shuhei KOBAYASHI <shuhei-k@jaist.ac.jp>
+;;         Keiichi Suzuki   <keiichi@nanap.org>
+;;         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.
 
 
 ;;; Code:
 
-(eval-when-compile (require 'cl))
+(eval-when-compile
+  (require 'cl)
+  (require 'smtp)
+  )
 
 (require 'mailheader)
 (require 'nnheader)
+(require 'timezone)
 (require 'easymenu)
 (require 'custom)
 (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)
 
 (defgroup message '((user-mail-address custom-variable)
                    (user-full-name custom-variable))
   :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
@@ -125,6 +136,19 @@ mailbox format."
                (function :tag "Other"))
   :group 'message-sending)
 
+(autoload 'message-locale-maybe-encode "mess-lcl")
+(defcustom message-encode-function 'message-locale-maybe-encode
+  "*A function called to encode messages."
+  :type '(radio (function-item message-locale-maybe-encode)
+               (function-item message-maybe-encode)
+               (function :tag "Other"))
+  :group 'message-sending)
+
+(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.
@@ -139,6 +163,11 @@ If this variable is nil, no such courtesy message will be added."
   :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.
@@ -169,8 +198,7 @@ Don't touch this variable unless you really know what you're doing.
 Checks include subject-cmsg multiple-headers sendsys message-id from
 long-lines control-chars size new-text redirected-followup signature
 approved sender empty empty-headers message-id from subject
-shorten-followup-to existing-newsgroups buffer-file-name unchanged
-newsgroups."
+shorten-followup-to existing-newsgroups buffer-file-name unchanged."
   :group 'message-news)
 
 (defcustom message-required-news-headers
@@ -214,13 +242,19 @@ included.  Organization, Lines and User-Agent are optional."
   :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:\\|^X-Trace:\\|^X-Complaints-To:"
   "*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
@@ -232,7 +266,7 @@ any confusion."
   :type 'regexp
   :group 'message-various)
 
-(defcustom message-elide-ellipsis "\n[...]\n\n"
+(defcustom message-elide-elipsis "\n[...]\n\n"
   "*The string which is inserted for elided text."
   :type 'string
   :group 'message-various)
@@ -244,15 +278,14 @@ nil means let mailer mail back a message to report errors."
   :group 'message-mail
   :type 'boolean)
 
-(defcustom message-generate-new-buffers 'unique
+(defcustom message-generate-new-buffers t
   "*Non-nil means that a new message buffer will be created whenever `message-setup' is called.
 If this is a function, call that function with three parameters:  The type,
 the to address and the group name.  (Any of these may be nil.)  The function
 should return the new buffer name."
   :group 'message-buffers
   :type '(choice (const :tag "off" nil)
-                (const :tag "unique" unique)
-                (const :tag "unsent" unsent)
+                (const :tag "on" t)
                 (function fun)))
 
 (defcustom message-kill-buffer-on-exit nil
@@ -260,6 +293,15 @@ should return the new buffer name."
   :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)
@@ -279,7 +321,30 @@ If t, use `message-user-organization-file'."
   :type 'file
   :group 'message-headers)
 
-(defcustom message-make-forward-subject-function
+(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:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:\\|^Content-Transfer-Encoding:\\|^Content-Type:\\|^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.
 The subject generated by the previous function is passed into each
@@ -295,27 +360,16 @@ The provided functions are:
  :type '(radio (function-item message-forward-subject-author-subject)
               (function-item message-forward-subject-fwd)))
 
-(defcustom message-forward-as-mime t
-  "*If non-nil, forward messages as an inline/rfc822 MIME section.  Otherwise, directly inline the old message in the forwarded message."
-  :group 'message-forwarding
-  :type 'boolean)
-
 (defcustom message-wash-forwarded-subjects nil
   "*If non-nil, try to remove as much old cruft as possible from the subject of messages before generating the new subject of a forward."
   :group 'message-forwarding
   :type 'boolean)
 
-(defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:"
+(defcustom message-ignored-resent-headers "^Return-Receipt"
   "*All headers that match this regexp will be deleted when resending a message."
   :group 'message-interface
   :type 'regexp)
 
-(defcustom message-forward-ignored-headers nil
-  "*All headers that match this regexp will be deleted when forwarding a message."
-  :group 'message-forwarding
-  :type '(choice (const :tag "None" nil)
-                regexp))
-
 (defcustom message-ignored-cited-headers "."
   "*Delete these headers from the messages you yank."
   :group 'message-insertion
@@ -333,18 +387,19 @@ The provided functions are:
 The headers should be delimited by a line whose contents match the
 variable `mail-header-separator'.
 
-Valid values include `message-send-mail-with-sendmail' (the default),
+Legal 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)
-               (function-item smtpmail-send-it)
+               (function-item message-send-mail-with-smtp)
                (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'."
@@ -384,9 +439,10 @@ always query the user whether to use the value.  If it is the symbol
                 (const use)
                 (const ask)))
 
+;; stuff relating to broken sendmail in MMDF
 (defcustom message-sendmail-f-is-evil nil
-  "*Non-nil means that \"-f username\" should not be added to the sendmail command line.
-Doing so would be even more evil than leaving it out."
+  "*Non-nil means that \"-f username\" should not be added to the sendmail
+command line, because it is even more evil than leaving it out."
   :group 'message-sending
   :type 'boolean)
 
@@ -406,11 +462,6 @@ might set this variable to '(\"-f\" \"you@some.where\")."
   :group 'message-sending
   :type '(repeat string))
 
-(defvar message-cater-to-broken-inn t
-  "Non-nil means Gnus should not fold the `References' header.
-Folding `References' makes ancient versions of INN create incorrect
-NOV lines.")
-
 (defvar gnus-post-method)
 (defvar gnus-select-method)
 (defcustom message-post-method
@@ -435,17 +486,12 @@ variable isn't used."
   :group 'message-headers
   :type 'boolean)
 
-(defcustom message-setup-hook nil
+(defcustom message-setup-hook '(message-mime-setup)
   "Normal hook, run each time a new outgoing message is initialized.
 The function `message-setup' runs this hook."
   :group 'message-various
   :type 'hook)
 
-(defcustom message-cancel-hook nil
-  "Hook run when cancelling articles."
-  :group 'message-various
-  :type 'hook)
-
 (defcustom message-signature-setup-hook nil
   "Normal hook, run each time a new outgoing message is initialized.
 It is run after the headers have been inserted and before
@@ -453,13 +499,38 @@ the signature is inserted."
   :group 'message-various
   :type 'hook)
 
+(defcustom message-bounce-setup-hook nil
+  "Normal hook, run each time a a re-sending bounced message is initialized.
+The function `message-bounce' runs this hook."
+  :group 'message-various
+  :type 'hook)
+
+(defcustom message-supersede-setup-hook nil
+  "Normal hook, run each time a supersede message is initialized.
+The function `message-supersede' runs this hook."
+  :group 'message-various
+  :type 'hook)
+
 (defcustom message-mode-hook nil
   "Hook run in message mode buffers."
   :group 'message-various
   :type 'hook)
 
 (defcustom message-header-hook nil
-  "Hook run in a message mode buffer narrowed to the headers."
+  "Hook run in a message mode before header encode. Buffer narrowed 
+to the headers."
+   :group 'message-various
+   :type 'hook)
+
+(defcustom message-header-encode-function
+  '(lambda () (eword-encode-header t))
+  "A function called to encode header."
+  :group 'message-various
+  :type 'function)
+
+(defcustom message-header-encoded-hook nil
+  "Hook run in a message mode after header encoded. Buffer narrowed 
+to the headers."
   :group 'message-various
   :type 'hook)
 
@@ -476,10 +547,26 @@ the signature is inserted."
 
 ;;;###autoload
 (defcustom message-yank-prefix "> "
-  "*Prefix inserted on the lines of yanked messages."
+  "*Prefix inserted on the lines of yanked messages.
+nil means use indentation."
   :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 '(radio (const :tag "Do not add anything" nil)
+               (const :tag "From Message-Id, References and In-Reply-To fields" t)
+               (const :tag "From only Message-Id field." message-id-only))
+  :group 'message-insertion)
+
+(defcustom message-list-references-add-position nil
+  "*Integer value means position for adding to \"References\" field when
+an article is yanked by the command `message-yank-original' interactively."
+  :type '(radio (const :tag "Add to last" nil)
+               (integer :tag "Position from last ID"))
+  :group 'message-insertion)
+
 (defcustom message-indentation-spaces 3
   "*Number of spaces to insert at the beginning of each cited line.
 Used by `message-yank-original' via `message-yank-cite'."
@@ -493,7 +580,6 @@ Predefined functions include `message-cite-original' and
 `message-cite-original-without-signature'.
 Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil."
   :type '(radio (function-item message-cite-original)
-               (function-item message-cite-original-without-signature)
                (function-item sc-cite-original)
                (function :tag "Other"))
   :group 'message-insertion)
@@ -549,8 +635,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-newsreader nil)
-(defvar message-mailer nil)
 (defvar message-sent-message-via nil)
 (defvar message-checksum nil)
 (defvar message-send-actions nil
@@ -561,6 +645,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.")
+(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."
@@ -588,6 +675,11 @@ articles."
   :group 'message-news
   :type 'message-header-lines)
 
+(defcustom message-mail-follow-up-address-checker nil
+  "A function of check follow up mail address."
+  :group 'message-mail
+  :type 'function)
+
 ;; Note: could use /usr/ucb/mail instead of sendmail;
 ;; options -t, and -v if not interactive.
 (defcustom message-mailer-swallows-blank-line
@@ -615,13 +707,18 @@ actually occur."
   :group 'message-sending
   :type 'sexp)
 
+;;; XXX: This symbol is overloaded!  See below.
+(defvar message-user-agent nil
+  "String of the form of PRODUCT/VERSION.  Used for User-Agent header field.")
+
 ;; 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
-  (define-mail-user-agent 'message-user-agent
-    'message-mail 'message-send-and-exit
-    'message-kill-buffer 'message-send-hook))
+(condition-case nil
+    (define-mail-user-agent 'message-user-agent
+      'message-mail 'message-send-and-exit
+      'message-kill-buffer 'message-send-hook)
+  (error nil))
 
 (defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)
   "If non-nil, delete the deletable headers before feeding to mh.")
@@ -652,33 +749,12 @@ If nil, Message won't auto-save."
   :group 'message-buffers
   :type 'directory)
 
-(defcustom message-buffer-naming-style 'unique
-  "*The way new message buffers are named.
-Valid valued are `unique' and `unsent'."
-  :group 'message-buffers
-  :type '(choice (const :tag "unique" unique)
-                (const :tag "unsent" unsent)))
-
-(defcustom message-default-charset nil
-  "Default charset used in non-MULE XEmacsen."
-  :group 'message
-  :type 'symbol)
-
-(defcustom message-dont-reply-to-names rmail-dont-reply-to-names
-  "*A regexp specifying names to prune when doing wide replies.
-A value of nil means exclude your own name only."
-  :group 'message
-  :type '(choice (const :tag "Yourself" nil)
-                regexp))
-
 ;;; Internal variables.
 ;;; Well, not really internal.
 
 (defvar message-mode-syntax-table
   (let ((table (copy-syntax-table text-mode-syntax-table)))
     (modify-syntax-entry ?% ". " table)
-    (modify-syntax-entry ?> ". " table)
-    (modify-syntax-entry ?< ". " table)
     table)
   "Syntax table used while in Message mode.")
 
@@ -798,18 +874,6 @@ Defaults to `text-mode-abbrev-table'.")
   "Face used for displaying cited text names."
   :group 'message-faces)
 
-(defface message-mml-face
-  '((((class color)
-      (background dark))
-     (:foreground "ForestGreen"))
-    (((class color)
-      (background light))
-     (:foreground "ForestGreen"))
-    (t
-     (:bold t)))
-  "Face used for displaying MML."
-  :group 'message-faces)
-
 (defvar message-font-lock-keywords
   (let* ((cite-prefix "A-Za-z")
         (cite-suffix (concat cite-prefix "0-9_.@-"))
@@ -840,9 +904,7 @@ Defaults to `text-mode-abbrev-table'.")
       (,(concat "^[ \t]*"
                "\\([" cite-prefix "]+[" cite-suffix "]*\\)?"
                "[:>|}].*")
-       (0 'message-cited-text-face))
-      ("<#/?\\(multipart\\|part\\|external\\).*>"
-       (0 'message-mml-face))))
+       (0 'message-cited-text-face))))
   "Additional expressions to highlight in Message mode.")
 
 ;; XEmacs does it like this.  For Emacs, we have to set the
@@ -879,12 +941,17 @@ The cdr of ech entry is a function for applying the face to a region.")
   :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)
 
-(defvar message-draft-coding-system
-  mm-auto-save-coding-system
-  "Coding system to compose mail.")
+(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)))
 
 ;;; Internal variables.
 
@@ -892,8 +959,6 @@ The cdr of ech entry is a function for applying the face to a region.")
 (defvar message-this-is-news nil)
 (defvar message-this-is-mail nil)
 (defvar message-draft-article nil)
-(defvar message-mime-part nil)
-(defvar message-posting-charset nil)
 
 ;; Byte-compiler warning
 (defvar gnus-active-hashtb)
@@ -961,7 +1026,6 @@ The cdr of ech entry is a function for applying the face to a region.")
          "^ *---+ +Original message +---+ *$\\|"
          "^ *--+ +begin message +--+ *$\\|"
          "^ *---+ +Original message follows +---+ *$\\|"
-         "^ *---+ +Undelivered message follows +---+ *$\\|"
          "^|? *---+ +Message text follows: +---+ *|?$")
   "A regexp that matches the separator before the text of a failed message.")
 
@@ -979,7 +1043,7 @@ The cdr of ech entry is a function for applying the face to a region.")
     (Lines)
     (Expires)
     (Message-ID)
-    (References . message-shorten-references)
+    (References . message-fill-references)
     (User-Agent))
   "Alist used for formatting headers.")
 
@@ -990,11 +1054,13 @@ The cdr of ech entry is a function for applying the face to a region.")
   (autoload 'gnus-point-at-eol "gnus-util")
   (autoload 'gnus-point-at-bol "gnus-util")
   (autoload 'gnus-output-to-mail "gnus-util")
+  (autoload 'gnus-output-to-rmail "gnus-util")
   (autoload 'mail-abbrev-in-expansion-header-p "mailabbrev")
   (autoload 'nndraft-request-associate-buffer "nndraft")
   (autoload 'nndraft-request-expire-articles "nndraft")
   (autoload 'gnus-open-server "gnus-int")
   (autoload 'gnus-request-post "gnus-int")
+  (autoload 'gnus-copy-article-buffer "gnus-msg")
   (autoload 'gnus-alive-p "gnus-util")
   (autoload 'rmail-output "rmail"))
 
@@ -1003,6 +1069,22 @@ The cdr of ech entry is a function for applying the face to a region.")
 ;;;
 ;;; 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"
@@ -1062,24 +1144,7 @@ The cdr of ech entry is a function for applying the face to a region.")
   (let* ((inhibit-point-motion-hooks t)
         (value (mail-fetch-field header nil (not not-all))))
     (when value
-      (while (string-match "\n[\t ]+" value)
-       (setq value (replace-match " " t t value)))
-      ;; We remove all text props.
-      (format "%s" value))))
-
-(defun message-narrow-to-field ()
-  "Narrow the buffer to the header on the current line."
-  (beginning-of-line)
-  (narrow-to-region
-   (point)
-   (progn
-     (forward-line 1)
-     (if (re-search-forward "^[^ \n\t]" nil t)
-        (progn
-          (beginning-of-line)
-          (point))
-       (point-max))))
-  (goto-char (point-min)))
+      (nnheader-replace-chars-in-string value ?\n ? ))))
 
 (defun message-add-header (&rest headers)
   "Add the HEADERS to the message header, skipping those already present."
@@ -1094,14 +1159,14 @@ The cdr of ech entry is a function for applying the face to a region.")
        (insert (car headers) ?\n))))
     (setq headers (cdr headers))))
 
-
 (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*")
@@ -1110,7 +1175,7 @@ The cdr of ech entry is a function for applying the face to a region.")
        (erase-buffer))
     (set-buffer (get-buffer-create " *message work*"))
     (kill-all-local-variables)
-    (mm-enable-multibyte)))
+    (buffer-disable-undo (current-buffer))))
 
 (defun message-functionp (form)
   "Return non-nil if FORM is funcallable."
@@ -1155,21 +1220,9 @@ Return the number of headers removed."
        (forward-line 1)
        (if (re-search-forward "^[^ \t]" nil t)
            (goto-char (match-beginning 0))
-         (goto-char (point-max)))))
+         (point-max))))
     number))
 
-(defun message-remove-first-header (header)
-  "Remove the first instance of HEADER if there is more than one."
-  (let ((count 0)
-       (regexp (concat "^" (regexp-quote header) ":")))
-    (save-excursion
-      (goto-char (point-min))
-      (while (re-search-forward regexp nil t)
-       (incf count)))
-    (while (> count 1)
-      (message-remove-header header nil t)
-      (decf count))))
-
 (defun message-narrow-to-headers ()
   "Narrow the buffer to the head of the message."
   (widen)
@@ -1182,8 +1235,7 @@ Return the number of headers removed."
   (goto-char (point-min)))
 
 (defun message-narrow-to-head ()
-  "Narrow the buffer to the head of the message.
-Point is left at the beginning of the narrowed-to region."
+  "Narrow the buffer to the head of the message."
   (widen)
   (narrow-to-region
    (goto-char (point-min))
@@ -1192,21 +1244,6 @@ Point is left at the beginning of the narrowed-to region."
      (point-max)))
   (goto-char (point-min)))
 
-(defun message-narrow-to-headers-or-head ()
-  "Narrow the buffer to the head of the message."
-  (widen)
-  (narrow-to-region
-   (goto-char (point-min))
-   (cond
-    ((re-search-forward
-      (concat "^" (regexp-quote mail-header-separator) "\n") nil t)
-     (match-beginning 0))
-    ((search-forward "\n\n" nil t)
-     (1- (point)))
-    (t
-     (point-max))))
-  (goto-char (point-min)))
-
 (defun message-news-p ()
   "Say whether the current buffer contains a news message."
   (and (not message-this-is-mail)
@@ -1239,7 +1276,6 @@ Point is left at the beginning of the narrowed-to region."
 (defun message-sort-headers-1 ()
   "Sort the buffer as headers using `message-rank' text props."
   (goto-char (point-min))
-  (require 'sort)
   (sort-subr
    nil 'message-next-header
    (lambda ()
@@ -1270,7 +1306,6 @@ Point is left at the beginning of the narrowed-to region."
               (- max rank)
             (1+ max)))))
       (message-sort-headers-1))))
-
 \f
 
 ;;;
@@ -1282,8 +1317,7 @@ Point is left at the beginning of the narrowed-to region."
 (defvar message-mode-map nil)
 
 (unless message-mode-map
-  (setq message-mode-map (make-keymap))
-  (set-keymap-parent message-mode-map text-mode-map)
+  (setq message-mode-map (copy-keymap text-mode-map))
   (define-key message-mode-map "\C-c?" 'describe-mode)
 
   (define-key message-mode-map "\C-c\C-f\C-t" 'message-goto-to)
@@ -1307,7 +1341,6 @@ Point is left at the beginning of the narrowed-to region."
   (define-key message-mode-map "\C-c\M-\C-y" 'message-yank-buffer)
   (define-key message-mode-map "\C-c\C-q" 'message-fill-yanked-message)
   (define-key message-mode-map "\C-c\C-w" 'message-insert-signature)
-  (define-key message-mode-map "\C-c\M-h" 'message-insert-headers)
   (define-key message-mode-map "\C-c\C-r" 'message-caesar-buffer-body)
   (define-key message-mode-map "\C-c\C-o" 'message-sort-headers)
   (define-key message-mode-map "\C-c\M-r" 'message-rename-buffer)
@@ -1322,9 +1355,9 @@ 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-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-xk" 'message-mimic-kill-buffer))
 
 (easy-menu-define
  message-mode-menu message-mode-map "Message Menu."
@@ -1341,7 +1374,6 @@ 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]
-   ["Attach file as MIME" mml-attach-file t]
    "----"
    ["Send Message" message-send-and-exit t]
    ["Abort Message" message-dont-send t]
@@ -1373,7 +1405,6 @@ Point is left at the beginning of the narrowed-to region."
   "Major mode for editing mail and news to be sent.
 Like Text Mode but with these additional commands:
 C-c C-s  message-send (send the message)    C-c C-c  message-send-and-exit
-C-c C-d  Pospone sending the message        C-c C-k  Kill the message
 C-c C-f  move to a header field (and create it if there isn't):
         C-c C-f C-t  move to To        C-c C-f C-s  move to Subject
         C-c C-f C-c  move to Cc        C-c C-f C-b  move to Bcc
@@ -1389,16 +1420,14 @@ C-c C-w  message-insert-signature (insert `message-signature-file' file).
 C-c C-y  message-yank-original (insert current message, if any).
 C-c C-q  message-fill-yanked-message (fill what was yanked).
 C-c C-e  message-elide-region (elide the text between point and mark).
-C-c C-v  message-delete-not-region (remove the text outside the region).
 C-c C-z  message-kill-to-signature (kill the text up to the signature).
-C-c C-r  message-caesar-buffer-body (rot13 the message body).
-C-c C-a  mml-attach-file (attach a file as MIME).
-M-RET    message-newline-and-reformat (break the line and reformat)."
+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)
-  (make-local-variable 'message-send-actions)
-  (make-local-variable 'message-exit-actions)
+  (make-local-variable 'message-reply-buffer)
+  (setq message-reply-buffer nil)
+  (make-local-variable 'message-send-actions) 
+  (make-local-variable 'message-exit-actions) 
   (make-local-variable 'message-kill-actions)
   (make-local-variable 'message-postpone-actions)
   (make-local-variable 'message-draft-article)
@@ -1435,12 +1464,15 @@ M-RET    message-newline-and-reformat (break the line and reformat)."
   (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)
-  (set (make-local-variable 'message-mime-part) 0)
+  (make-local-variable 'message-sent-message-via)
+  (setq message-sent-message-via nil)
+  (make-local-variable 'message-checksum)
+  (setq message-checksum nil)
+  (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)
@@ -1458,17 +1490,13 @@ M-RET    message-newline-and-reformat (break the line and reformat)."
         '(message-font-lock-keywords t)))
   (make-local-variable 'adaptive-fill-regexp)
   (setq adaptive-fill-regexp
-       (concat "[ \t]*[-a-z0-9A-Z]*\\(>[ \t]*\\)+[ \t]*\\|" adaptive-fill-regexp))
+       (concat "[ \t]*[-a-z0-9A-Z]*>+[ \t]*\\|" adaptive-fill-regexp))
   (unless (boundp 'adaptive-fill-first-line-regexp)
     (setq adaptive-fill-first-line-regexp nil))
   (make-local-variable 'adaptive-fill-first-line-regexp)
   (setq adaptive-fill-first-line-regexp
-       (concat "[ \t]*[-a-z0-9A-Z]*\\(>[ \t]*\\)+[ \t]*\\|"
+       (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)
-  (mml-mode)
   (run-hooks 'text-mode-hook 'message-mode-hook))
 
 \f
@@ -1539,8 +1567,7 @@ M-RET    message-newline-and-reformat (break the line and reformat)."
   (interactive)
   (if (looking-at "[ \t]*\n") (expand-abbrev))
   (goto-char (point-min))
-  (or (search-forward (concat "\n" mail-header-separator "\n") nil t)
-      (search-forward "\n\n" nil t)))
+  (search-forward (concat "\n" mail-header-separator "\n") nil t))
 
 (defun message-goto-eoh ()
   "Move point to the end of the headers."
@@ -1570,8 +1597,7 @@ With the prefix argument FORCE, insert the header anyway."
   (let ((co (message-fetch-reply-field "mail-copies-to")))
     (when (and (null force)
               co
-              (or (equal (downcase co) "never")
-                  (equal (downcase co) "nobody")))
+              (equal (downcase co) "never"))
       (error "The user has requested not to have copies sent via mail")))
   (when (and (message-position-on-field "To")
             (mail-fetch-field "to")
@@ -1624,24 +1650,17 @@ With the prefix argument FORCE, insert the header anyway."
 (defun message-newline-and-reformat ()
   "Insert four newlines, and then reformat if inside quoted text."
   (interactive)
-  (let ((prefix "[]>»|:}+ \t]*")
-       (supercite-thing "[-._a-zA-Z0-9]*[>]+[ \t]*")
-       quoted point)
-    (unless (bolp)
-      (save-excursion
-       (beginning-of-line)
-       (when (looking-at (concat prefix
-                                 supercite-thing))
-         (setq quoted (match-string 0))))
-      (insert "\n"))
-    (setq point (point))
-    (insert "\n\n\n")
-    (delete-region (point) (re-search-forward "[ \t]*"))
+  (let ((point (point))
+       quoted)
+    (save-excursion
+      (beginning-of-line)
+      (setq quoted (looking-at (regexp-quote message-yank-prefix))))
+    (insert "\n\n\n\n")
     (when quoted
-      (insert quoted))
+      (insert message-yank-prefix))
     (fill-paragraph nil)
     (goto-char point)
-    (forward-line 1)))
+    (forward-line 2)))
 
 (defun message-insert-signature (&optional force)
   "Insert a signature.  See documentation for the `message-signature' variable."
@@ -1652,7 +1671,8 @@ With the prefix argument FORCE, insert the header anyway."
                 (eq force 0))
            (save-excursion
              (goto-char (point-max))
-             (not (re-search-backward message-signature-separator nil t))))
+             (not (re-search-backward
+                   message-signature-separator nil t))))
           ((and (null message-signature)
                 force)
            t)
@@ -1682,11 +1702,13 @@ With the prefix argument FORCE, insert the header anyway."
 
 (defun message-elide-region (b e)
   "Elide the text between point and mark.
-An ellipsis (from `message-elide-ellipsis') will be inserted where the
+An ellipsis (from `message-elide-elipsis') will be inserted where the
 text was killed."
   (interactive "r")
   (kill-region b e)
-  (insert message-elide-ellipsis))
+  (unless (bolp)
+    (insert "\n"))
+  (insert message-elide-elipsis))
 
 (defvar message-caesar-translation-table nil)
 
@@ -1710,10 +1732,9 @@ text was killed."
     ;; Then we translate the region.  Do it this way to retain
     ;; text properties.
     (while (< b e)
-      (when (< (char-after b) 255)
-       (subst-char-in-region
-        b (1+ b) (char-after b)
-        (aref message-caesar-translation-table (char-after b))))
+      (subst-char-in-region
+       b (1+ b) (char-after b)
+       (aref message-caesar-translation-table (char-after b)))
       (incf b))))
 
 (defun message-make-caesar-translation-table (n)
@@ -1755,7 +1776,7 @@ Mail and USENET news headers are not rotated."
         (unless (equal 0 (call-process-region
                            (point-min) (point-max) program t t))
             (insert body)
-            (message "%s failed" program))))))
+            (message "%s failed." program))))))
 
 (defun message-rename-buffer (&optional enter-string)
   "Rename the *message* buffer to \"*message* RECIPIENT\".
@@ -1789,7 +1810,7 @@ Numeric argument means justify as well."
     (goto-char (point-min))
     (search-forward (concat "\n" mail-header-separator "\n") nil t)
     (let ((fill-prefix message-yank-prefix))
-      (fill-individual-paragraphs (point) (point-max) justifyp))))
+      (fill-individual-paragraphs (point) (point-max) justifyp t))))
 
 (defun message-indent-citation ()
   "Modify text just inserted from a message to be cited.
@@ -1837,6 +1858,40 @@ However, if `message-yank-prefix' is non-nil, insert that prefix on each line."
          (forward-line 1))))
     (goto-char start)))
 
+(defun message-list-references (refs-list &rest refs-strs)
+  "Add `Message-ID's which appear in REFS-STRS but not in REFS-LIST,
+to REFS-LIST."
+  (let (refs ref id saved-id)
+    (when (and refs-list
+              (integerp message-list-references-add-position))
+      (let ((pos message-list-references-add-position))
+       (while (and refs-list
+                   (> pos 0))
+         (setq saved-id (cons (car refs-list) saved-id)
+               refs-list (cdr refs-list)
+               pos (1- pos)))))
+    (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))))))
+    (while saved-id
+      (setq refs-list (cons (car saved-id) refs-list)
+           saved-id (cdr saved-id)))
+    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.
@@ -1846,13 +1901,55 @@ if `message-yank-prefix' is non-nil, insert that prefix on each line.
 This function uses `message-cite-function' to do the actual citing.
 
 Just \\[universal-argument] as argument means don't indent, insert no
-prefix, and don't delete any headers."
+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.
+\(See also `message-yank-add-new-references'.)"
   (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)
-      (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
+                             (unless (eq message-yank-add-new-references
+                                         'message-id-only)
+                               (or (message-fetch-field "References")
+                                   (message-fetch-field "In-Reply-To")))
+                             (message-fetch-field "Message-ID")))
+             (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)
@@ -1867,17 +1964,6 @@ prefix, and don't delete any headers."
     (save-window-excursion
       (message-yank-original))))
 
-(defun message-buffers ()
-  "Return a list of active message buffers."
-  (let (buffers)
-    (save-excursion
-      (dolist (buffer (buffer-list t))
-       (set-buffer buffer)
-       (when (and (eq major-mode 'message-mode)
-                  (null message-sent-message-via))
-         (push (buffer-name buffer) buffers))))
-    (nreverse buffers)))
-
 (defun message-cite-original-without-signature ()
   "Cite function in the standard Message manner."
   (let ((start (point))
@@ -1887,9 +1973,8 @@ prefix, and don't delete any headers."
           (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)
+    (when (re-search-backward "^-- $" start t)
       ;; Also peel off any blank lines before the signature.
       (forward-line -1)
       (while (looking-at "^[ \t]*$")
@@ -1904,20 +1989,18 @@ prefix, and don't delete any headers."
        (insert "\n"))
       (funcall message-citation-line-function))))
 
-(defvar mail-citation-hook)            ;Compiler directive
+(defvar mail-citation-hook) ;Compiler directive
 (defun message-cite-original ()
   "Cite function in the standard Message manner."
   (if (and (boundp 'mail-citation-hook)
           mail-citation-hook)
       (run-hooks 'mail-citation-hook)
     (let ((start (point))
-         (end (mark t))
          (functions
           (when message-indent-citation-function
             (if (listp message-indent-citation-function)
                 message-indent-citation-function
               (list message-indent-citation-function)))))
-      (mml-quote-region start end)
       (goto-char start)
       (while functions
        (funcall (pop functions)))
@@ -1987,11 +2070,18 @@ The text will also be indented the normal way."
 ;;; Sending messages
 ;;;
 
+;; Avoid byte-compile warning.
+(defvar message-encoding-buffer nil)
+(defvar message-edit-buffer nil)
+(defvar message-mime-mode nil)
+
 (defun message-send-and-exit (&optional arg)
   "Send message like `message-send', then, if no errors, exit from mail buffer."
   (interactive "P")
   (let ((buf (current-buffer))
-       (actions message-exit-actions))
+       (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
@@ -2000,6 +2090,7 @@ The text will also be indented the normal way."
        (when (eq buf (current-buffer))
          (message-bury buf)))
       (message-do-actions actions)
+      (message-delete-frame frame org-frame)
       t)))
 
 (defun message-dont-send ()
@@ -2007,19 +2098,62 @@ The text will also be indented the normal way."
   (interactive)
   (set-buffer-modified-p t)
   (save-buffer)
-  (let ((actions message-postpone-actions))
+  (let ((actions message-postpone-actions)
+       (frame (selected-frame))
+       (org-frame message-original-frame))
     (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))
-           (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))
-      (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)))
+       (let ((message-delete-frame-on-exit nil))
+         (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."
@@ -2038,43 +2172,62 @@ or error messages, and inform user.
 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 (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 (or sent (not success))
-      (error "No methods specified to send by"))
-    (when (and success sent)
-      (message-do-fcc)
-      (save-excursion
-       (run-hooks 'message-sent-hook))
-      (message "Sending...done")
-      ;; Mark the buffer as unmodified and delete auto-save.
-      (set-buffer-modified-p nil)
-      (delete-auto-save-file-if-necessary t)
-      (message-disassociate-draft)
-      ;; Delete other mail buffers and stuff.
-      (message-do-send-housekeeping)
-      (message-do-actions message-send-actions)
-      ;; Return success.
-      t)))
+  (if (catch 'message-sending-cancel
+       ;; Disabled test.
+       (unless (or (buffer-modified-p)
+                   (message-check-element 'unchanged)
+                   (y-or-n-p "No changes in the buffer; really send? "))
+         (throw 'message-sending-cancel t))
+       ;; 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)
+         (unwind-protect
+             (if (save-excursion
+                   (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)))
+                     (and (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)))
+                   (not (and success sent)))
+                 (throw 'message-sending-cancel t)
+               (message-do-fcc)
+               (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)
+               nil)
+           (kill-buffer message-encoding-buffer))))
+      (progn
+       (message "Canceled")
+       nil)
+    ;; Return success.
+    t))
 
 (defun message-send-via-mail (arg)
   "Send the current message via mail."
@@ -2082,16 +2235,7 @@ the user from the mailer."
 
 (defun message-send-via-news (arg)
   "Send the current message via news."
-  (funcall message-send-news-function arg))
-
-(defmacro message-check (type &rest forms)
-  "Eval FORMS if TYPE is to be checked."
-  `(or (message-check-element ,type)
-       (save-excursion
-        ,@forms)))
-
-(put 'message-check 'lisp-indent-function 1)
-(put 'message-check 'edebug-form-spec '(form body))
+  (message-send-news arg))
 
 (defun message-fix-before-sending ()
   "Do various things to make the message nice before sending it."
@@ -2099,13 +2243,12 @@ the user from the mailer."
   (goto-char (point-max))
   (unless (bolp)
     (insert "\n"))
-  ;; Delete all invisible text.
-  (message-check 'invisible-text
-    (when (text-property-any (point-min) (point-max) 'invisible t)
-      (put-text-property (point-min) (point-max) 'invisible nil)
-      (unless (yes-or-no-p
-              "Invisible text found and made visible; continue posting? ")
-       (error "Invisible text found and made visible")))))
+  ;; Make all invisible text visible.
+  ;;(when (text-property-any (point-min) (point-max) 'invisible t)
+  ;;  (put-text-property (point-min) (point-max) 'invisible nil)
+  ;;  (unless (yes-or-no-p "Invisible text found and made visible; continue posting?")
+  ;;    (error "Invisible text found and made visible")))
+  )
 
 (defun message-add-action (action &rest types)
   "Add ACTION to be performed when doing an exit of type TYPES."
@@ -2128,12 +2271,56 @@ the user from the mailer."
        (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))
-       (mailbuf (current-buffer)))
+       failure)
     (save-restriction
       (message-narrow-to-headers)
       ;; Insert some headers.
@@ -2141,43 +2328,45 @@ the user from the mailer."
             (if news nil message-deletable-headers)))
        (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)))
+      (run-hooks 'message-header-hook)
+      (when (functionp message-header-encode-function)
+       (funcall message-header-encode-function))
+      (run-hooks 'message-header-encoded-hook))
+    (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.
-           (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)
+             ;; Remove some headers.
+             (message-remove-header message-ignored-mail-headers t))
+           (goto-char (point-max))
+           ;; require one newline at the end.
+           (or (eq (char-before) ?\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."
   (let ((errbuf (if message-interactive
-                   (message-generate-new-buffer-clone-locals " sendmail errors")
+                   (generate-new-buffer " sendmail errors")
                  0))
        resend-to-addresses delimline)
     (let ((case-fold-search t))
@@ -2201,34 +2390,31 @@ the user from the mailer."
        (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"
-                              (if (null user-mail-address)
-                                  (user-login-name)
-                                user-mail-address)))
-                    ;; 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)
@@ -2253,28 +2439,28 @@ to find out how to use this."
   (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)
@@ -2301,78 +2487,148 @@ to find out how to use this."
     ;; 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))
-       (messbuf (current-buffer))
        (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)
+      (when (functionp message-header-encode-function)
+       (funcall message-header-encode-function))
+      (run-hooks 'message-header-encoded-hook))
+    (message-cleanup-headers)
+    (if (not (message-check-news-syntax))
        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 (current-buffer))
+           (erase-buffer)
+           (insert-buffer message-encoding-buffer)
+           ;; Remove some headers.
+           (save-restriction
+             (message-narrow-to-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 (eq (char-before) ?\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)
+    ;;(require (car method))
+    ;;(funcall (intern (format "%s-open-server" (car method)))
+    ;;(cadr method) (cddr method))
+    ;;(setq result
+    ;;   (funcall (intern (format "%s-request-post" (car method)))
+    ;;            (cadr method)))
+    (gnus-open-server method)
+    (gnus-request-post method)
+    ))
 
 ;;;
 ;;; Header generation & syntax checking.
 ;;;
 
+(defmacro message-check (type &rest forms)
+  "Eval FORMS if TYPE is to be checked."
+  `(or (message-check-element ,type)
+       (save-excursion
+        ,@forms)))
+
+(put 'message-check 'lisp-indent-function 1)
+(put 'message-check 'edebug-form-spec '(form body))
+
 (defun message-check-element (type)
   "Returns non-nil if this type is not to be checked."
   (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me)
@@ -2386,23 +2642,19 @@ to find out how to use this."
   (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
-   ;; Check Newsgroups header.
-   (message-check 'newsgroyps
-     (let ((group (message-fetch-field "newsgroups")))
-       (or
-       (and group
-            (not (string-match "\\`[ \t]*\\'" group)))
-       (ignore
-        (message
-         "The newsgroups field is empty or missing.  Posting is denied.")))))
    ;; Check the Subject header.
    (message-check 'subject
      (let* ((case-fold-search t)
@@ -2565,15 +2817,12 @@ to find out how to use this."
    (message-check 'from
      (let* ((case-fold-search t)
            (from (message-fetch-field "from"))
-           ad)
+           (ad (nth 1 (mail-extract-address-components from))))
        (cond
        ((not from)
         (message "There is no From line.  Posting is denied.")
         nil)
-       ((or (not (string-match
-                  "@[^\\.]*\\."
-                  (setq ad (nth 1 (mail-extract-address-components
-                                   from))))) ;larsi@ifi
+       ((or (not (string-match "@[^\\.]*\\." ad)) ;larsi@ifi
             (string-match "\\.\\." ad) ;larsi@ifi..uio
             (string-match "@\\." ad)   ;larsi@.ifi.uio
             (string-match "\\.$" ad)   ;larsi@ifi.uio.
@@ -2614,10 +2863,13 @@ to find out how to use this."
           (y-or-n-p "Empty article.  Really post? "))))
    ;; Check for control characters.
    (message-check 'control-chars
-     (if (re-search-forward "[\000-\007\013\015-\032\034-\037\200-\237]" nil t)
+     (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t)
         (y-or-n-p
          "The article contains control characters.  Really post? ")
        t))
+   ;; Check 8bit characters.
+   (message-check '8bit
+     (message-check-8bit))
    ;; Check excessive size.
    (message-check 'size
      (if (> (buffer-size) 60000)
@@ -2635,12 +2887,63 @@ to find out how to use this."
    ;; Check the length of the signature.
    (message-check 'signature
      (goto-char (point-max))
-     (if (> (count-lines (point) (point-max)) 5)
-        (y-or-n-p
-         (format
-          "Your .sig is %d lines; it should be max 4.  Really post? "
-          (1- (count-lines (point) (point-max)))))
-       t))))
+     (if (or (not (re-search-backward message-signature-separator nil t))
+            (search-forward message-forward-end-separator nil t))
+        t
+       (if (> (count-lines (point) (point-max)) 5)
+          (y-or-n-p
+           (format
+            "Your .sig is %d lines; it should be max 4.  Really post? "
+            (1- (count-lines (point) (point-max)))))
+        t)))))
+
+(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."
@@ -2651,20 +2954,21 @@ to find out how to use this."
        (concat "^" (regexp-quote mail-header-separator) "$"))
       (while (not (eobp))
        (when (not (looking-at "[ \t\n]"))
-         (setq sum (logxor (ash sum 1) (if (natnump sum) 0 1)
-                           (char-after))))
+         (setq sum (logxor (ash sum 1) (if (natnump sum) 0 1)
+                           (char-after))))
        (forward-char 1)))
     sum))
 
 (defun message-do-fcc ()
   "Process Fcc headers in the current buffer."
   (let ((case-fold-search t)
-       (buf (current-buffer))
+       (coding-system-for-write nnheader-file-coding-system)
        list file)
     (save-excursion
       (set-buffer (get-buffer-create " *message temp*"))
+      (buffer-disable-undo (current-buffer))
       (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"))
@@ -2699,7 +3003,7 @@ to find out how to use this."
   "Append this article to Unix/babyl mail file.."
   (if (and (file-readable-p filename)
           (mail-file-babyl-p filename))
-      (rmail-output-to-rmail-file filename t)
+      (gnus-output-to-rmail filename t)
     (gnus-output-to-mail filename t)))
 
 (defun message-cleanup-headers ()
@@ -2850,17 +3154,21 @@ If NOW, use that time instead."
   "Return the In-Reply-To header for this message."
   (when message-reply-headers
     (let ((from (mail-header-from message-reply-headers))
-         (date (mail-header-date message-reply-headers)))
-      (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)
-                 "\""))))))
+         (date (mail-header-date message-reply-headers))
+         (msg-id (mail-header-message-id message-reply-headers)))
+      (when msg-id
+       (concat msg-id
+               (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)
+                           "\")"))))))))
 
 (defun message-make-distribution ()
   "Make a Distribution header."
@@ -2876,7 +3184,9 @@ If NOW, use that time instead."
     ;; Add the future to current.
     (setcar current (+ (car current) (round (/ future (expt 2 16)))))
     (setcar (cdr current) (+ (nth 1 current) (% (round future) (expt 2 16))))
-    (message-make-date current)))
+    ;; Return the date in the future in UT.
+    (timezone-make-date-arpa-standard
+     (current-time-string current) (current-time-zone current) '(0 "UT"))))
 
 (defun message-make-path ()
   "Return uucp path."
@@ -2998,6 +3308,24 @@ give as trustworthy answer as possible."
   (or mail-host-address
       (message-make-fqdn)))
 
+(defun message-make-user-agent ()
+  "Return user-agent info."
+  (if message-user-agent
+      (save-excursion
+       (goto-char (point-min))
+       (let ((case-fold-search t)
+             user-agent beg p end)
+         (if (re-search-forward "^User-Agent:[ \t]*" nil t)
+             (progn
+               (setq beg (match-beginning 0)
+                     p (match-end 0)
+                     end (std11-field-end)
+                     user-agent (buffer-substring p end))
+               (delete-region beg (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."
@@ -3014,7 +3342,7 @@ Headers already prepared in the buffer are not modified."
           (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)
@@ -3053,9 +3381,11 @@ Headers already prepared in the buffer are not modified."
                  (progn
                    ;; The header was found.  We insert a space after the
                    ;; colon, if there is none.
-                   (if (/= (char-after) ? ) (insert " ") (forward-char 1))
+                   (if (eq (char-after) ? )
+                       (forward-char 1)
+                     (insert " "))
                    ;; Find out whether the header is empty...
-                   (looking-at "[ \t]*\n[^ \t]")))
+                   (looking-at "[ \t]*$")))
          ;; So we find out what value we should insert.
          (setq value
                (cond
@@ -3180,9 +3510,16 @@ Headers already prepared in the buffer are not modified."
     (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))
-       (fill-column 78)
+       (fill-column 990)
        (fill-prefix "\t"))
     (insert (capitalize (symbol-name header))
            ": "
@@ -3201,60 +3538,23 @@ Headers already prepared in the buffer are not modified."
        (replace-match " " t t))
       (goto-char (point-max)))))
 
-(defun message-shorten-1 (list cut surplus)
-  ;; Cut SURPLUS elements out of LIST, beginning with CUTth one.
-  (setcdr (nthcdr (- cut 2) list)
-         (nthcdr (+ (- cut 2) surplus 1) list)))
-
 (defun message-shorten-references (header references)
-  "Trim REFERENCES to be less than 31 Message-ID long, and fold them.
-If folding is disallowed, also check that the REFERENCES are less
-than 988 characters long, and if they are not, trim them until they are."
-  (let ((maxcount 31)
-       (count 0)
-       (cut 6)
+  "Limit REFERENCES to be shorter than 988 characters."
+  (let ((max 988)
+       (cut 4)
        refs)
     (with-temp-buffer
       (insert references)
       (goto-char (point-min))
-      ;; Cons a list of valid references.
       (while (re-search-forward "<[^>]+>" nil t)
        (push (match-string 0) refs))
-      (setq refs (nreverse refs)
-           count (length refs)))
-
-    ;; If the list has more than MAXCOUNT elements, trim it by
-    ;; removing the CUTth element and the required number of
-    ;; elements that follow.
-    (when (> count maxcount)
-      (let ((surplus (- count maxcount)))
-       (message-shorten-1 refs cut surplus)
-       (decf count surplus)))
-
-    ;; If folding is disallowed, make sure the total length (including
-    ;; the spaces between) will be less than MAXSIZE characters.
-    (when message-cater-to-broken-inn
-      (let ((maxsize 988)
-           (totalsize (+ (apply #'+ (mapcar #'length refs))
-                         (1- count)))
-           (surplus 0)
-           (ptr (nthcdr (1- cut) refs)))
-       ;; Decide how many elements to cut off...
-       (while (> totalsize maxsize)
-         (decf totalsize (1+ (length (car ptr))))
-         (incf surplus)
-         (setq ptr (cdr ptr)))
-       ;; ...and do it.
-       (when (> surplus 0)
-         (message-shorten-1 refs cut surplus))))
-
-    ;; Finally, collect the references back into a string and insert
-    ;; it into the buffer.
-    (let ((refstring (mapconcat #'identity refs " ")))
-      (if message-cater-to-broken-inn
-         (insert (capitalize (symbol-name header)) ": "
-                 refstring "\n")
-       (message-fill-header header refstring)))))
+      (setq refs (nreverse refs))
+      (while (> (length (mapconcat 'identity refs " ")) max)
+       (when (< (length refs) (1+ cut))
+         (decf cut))
+       (setcdr (nthcdr cut refs) (cddr (nthcdr cut refs)))))
+    (insert (capitalize (symbol-name header)) ": "
+           (mapconcat 'identity refs " ") "\n")))
 
 (defun message-position-point ()
   "Move point to where the user probably wants to find it."
@@ -3278,24 +3578,14 @@ than 988 characters long, and if they are not, trim them until they are."
 (defun message-buffer-name (type &optional to group)
   "Return a new (unique) buffer name based on TYPE and TO."
   (cond
-   ;; Generate a new buffer name The Message Way.
-   ((eq message-generate-new-buffers 'unique)
-    (generate-new-buffer-name
-     (concat "*" type
-            (if to
-                (concat " to "
-                        (or (car (mail-extract-address-components to))
-                            to) "")
-              "")
-            (if (and group (not (string= group ""))) (concat " on " group) "")
-            "*")))
    ;; Check whether `message-generate-new-buffers' is a function,
    ;; and if so, call it.
    ((message-functionp message-generate-new-buffers)
     (funcall message-generate-new-buffers type to group))
-   ((eq message-generate-new-buffers 'unsent)
+   ;; Generate a new buffer name The Message Way.
+   (message-generate-new-buffers
     (generate-new-buffer-name
-     (concat "*unsent " type
+     (concat "*" type
             (if to
                 (concat " to "
                         (or (car (mail-extract-address-components to))
@@ -3309,7 +3599,24 @@ than 988 characters long, and if they are not, trim them until they are."
 
 (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
@@ -3320,7 +3627,10 @@ than 988 characters long, and if they are not, trim them until they are."
            (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."
@@ -3338,7 +3648,7 @@ than 988 characters long, and if they are not, trim them until they are."
   ;; Rename the buffer.
   (if message-send-rename-function
       (funcall message-send-rename-function)
-    (when (string-match "\\`\\*\\(unsent \\)?" (buffer-name))
+    (when (string-match "\\`\\*" (buffer-name))
       (rename-buffer
        (concat "*sent " (substring (buffer-name) (match-end 0))) t)))
   ;; Push the current buffer onto the list.
@@ -3355,7 +3665,9 @@ than 988 characters long, and if they are not, trim them until they are."
          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
@@ -3403,6 +3715,8 @@ than 988 characters long, and if they are not, trim them until they are."
     (run-hooks 'message-header-setup-hook))
   (set-buffer-modified-p nil)
   (setq buffer-undo-list nil)
+  (add-to-list 'buffer-file-format 'message)
+  (set-buffer-file-coding-system nnheader-file-coding-system)
   (run-hooks 'message-setup-hook)
   (message-position-point)
   (undo-boundary))
@@ -3416,8 +3730,7 @@ than 988 characters long, and if they are not, trim them until they are."
       (setq buffer-file-name (expand-file-name "*message*"
                                               message-auto-save-directory))
       (setq buffer-auto-save-file-name (make-auto-save-file-name)))
-    (clear-visited-file-modtime)
-    (setq buffer-file-coding-system message-draft-coding-system)))
+    (clear-visited-file-modtime)))
 
 (defun message-disassociate-draft ()
   "Disassociate the message buffer from the drafts directory."
@@ -3425,23 +3738,6 @@ than 988 characters long, and if they are not, trim them until they are."
     (nndraft-request-expire-articles
      (list message-draft-article) "drafts" nil t)))
 
-(defun message-insert-headers ()
-  "Generate the headers for the article."
-  (interactive)
-  (save-excursion
-    (save-restriction
-      (message-narrow-to-headers)
-      (when (message-news-p)
-       (message-generate-headers
-        (delq 'Lines
-              (delq 'Subject
-                    (copy-sequence message-required-news-headers)))))
-      (when (message-mail-p)
-       (message-generate-headers
-        (delq 'Lines
-              (delq 'Subject
-                    (copy-sequence message-required-mail-headers))))))))
-
 \f
 
 ;;;
@@ -3479,8 +3775,7 @@ OTHER-HEADERS is an alist of header/value pairs."
        from subject date reply-to to cc
        references message-id follow-to
        (inhibit-point-motion-hooks t)
-       (message-this-is-mail t)
-       mct never-mct gnus-warning)
+       mct never-mct gnus-warning in-reply-to)
     (save-restriction
       (message-narrow-to-head)
       ;; Allow customizations to have their say.
@@ -3503,6 +3798,12 @@ OTHER-HEADERS is an alist of header/value pairs."
            reply-to (message-fetch-field "reply-to")
            references (message-fetch-field "references")
            message-id (message-fetch-field "message-id" t))
+      ;; 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.
       (when (string-match message-subject-re-regexp subject)
@@ -3515,12 +3816,10 @@ OTHER-HEADERS is an alist of header/value pairs."
 
       ;; Handle special values of Mail-Copies-To.
       (when mct
-       (cond ((or (equal (downcase mct) "never")
-                  (equal (downcase mct) "nobody"))
+       (cond ((equal (downcase mct) "never")
               (setq never-mct t)
               (setq mct nil))
-             ((or (equal (downcase mct) "always")
-                  (equal (downcase mct) "poster"))
+             ((equal (downcase mct) "always")
               (setq mct (or reply-to from)))))
 
       (unless follow-to
@@ -3542,9 +3841,8 @@ OTHER-HEADERS is an alist of header/value pairs."
              (while (re-search-forward "[ \t]+" nil t)
                (replace-match " " t t))
              ;; Remove addresses that match `rmail-dont-reply-to-names'.
-             (let ((rmail-dont-reply-to-names message-dont-reply-to-names))
-               (insert (prog1 (rmail-dont-reply-to (buffer-string))
-                         (erase-buffer))))
+             (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)
@@ -3556,7 +3854,10 @@ OTHER-HEADERS is an alist of header/value pairs."
                     (message-tokenize-header (buffer-string))))
              (let ((s ccalist))
                (while s
-                 (setq ccalist (delq (assoc (car (pop s)) s) ccalist)))))
+                 (setq ccalist (delq (assoc (car (pop s)) s) ccalist))))
+             (when (functionp message-mail-follow-up-address-checker)
+               (setq ccalist (funcall message-mail-follow-up-address-checker
+                                      ccalist))))
            (setq follow-to (list (cons 'To (cdr (pop ccalist)))))
            (when ccalist
              (let ((ccs (cons 'Cc (mapconcat
@@ -3571,7 +3872,8 @@ OTHER-HEADERS is an alist of header/value pairs."
                            (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)
@@ -3688,17 +3990,16 @@ responses here are directed to other newsgroups."))
             `((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"))
+                   (not (equal (downcase mct) "never")))
+          (list (cons 'Cc (if (equal (downcase mct) "always")
                               (or reply-to from "")
                             mct)))))
 
      cur)
 
     (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 ""))))
 
 
 ;;;###autoload
@@ -3719,17 +4020,18 @@ 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.
-       (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
-                                     (message-make-from))))))
+       (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
+                                     (message-make-from))))))
          (error "This article is not yours"))
        ;; Make control message.
        (setq buf (set-buffer (get-buffer-create " *message cancel*")))
+       (buffer-disable-undo (current-buffer))
        (erase-buffer)
        (insert "Newsgroups: " newsgroups "\n"
                "From: " (message-make-from) "\n"
@@ -3740,14 +4042,19 @@ responses here are directed to other newsgroups."))
                  "")
                mail-header-separator "\n"
                message-cancel-message)
-       (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)))))
 
+(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.
@@ -3781,7 +4088,11 @@ header line with the old Message-ID."
     (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 ()
@@ -3832,7 +4143,7 @@ header line with the old Message-ID."
       (replace-match ""))
 
     (buffer-string)))
-
+    
 ;;; Forwarding messages.
 
 (defun message-forward-subject-author-subject (subject)
@@ -3859,10 +4170,14 @@ the message."
       (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))
@@ -3883,43 +4198,50 @@ Optional NEWS will use news to forward instead of mail."
   (let ((cur (current-buffer))
        (subject (message-make-forward-subject))
        art-beg)
-    (if news
-       (message-news nil subject)
-      (message-mail nil subject))
+    (if news (message-news nil subject) (message-mail nil subject))
     ;; Put point where we want it before inserting the forwarded
     ;; message.
-    (message-goto-body)
-    (if message-forward-as-mime
-        (insert "\n\n<#part type=message/rfc822 disposition=inline>\n")
-      (insert "\n\n"))
-    (let ((b (point))
-         e)
-      (mml-insert-buffer cur)
-      (setq e (point))
-      (and message-forward-as-mime
-          (insert "<#/part>\n"))
-      (when (and (not current-prefix-arg)
-                message-forward-ignored-headers)
-       (save-restriction
-         (narrow-to-region b e)
-         (goto-char b)
-         (narrow-to-region (point) (or (search-forward "\n\n" nil t) (point)))
-         (message-remove-header message-forward-ignored-headers t))))
+    (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
 (defun message-resend (address)
   "Resend the current article to ADDRESS."
-  (interactive
-   (list (message-read-from-minibuffer "Resend message to: ")))
+  (interactive "sResend message to: ")
   (message "Resending message to %s..." address)
   (save-excursion
     (let ((cur (current-buffer))
          beg)
       ;; We first set up a normal mail buffer.
       (set-buffer (get-buffer-create " *message resend*"))
+      (buffer-disable-undo (current-buffer))
       (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)
@@ -3950,12 +4272,16 @@ Optional NEWS will use news to forward instead of mail."
       (when (looking-at "From ")
        (replace-match "X-From-Line: "))
       ;; Send it.
-      (let ((message-inhibit-body-encoding t)
-           message-required-mail-headers)
+      (let ((message-encoding-buffer (current-buffer))
+           (message-edit-buffer (current-buffer)))
        (message-send-mail))
       (kill-buffer (current-buffer)))
     (message "Resending message to %s...done" address)))
 
+(defun message-bounce-setup-for-mime-edit ()
+  (set (make-local-variable 'message-setup-hook) nil)
+  (mime-edit-again))
+
 ;;;###autoload
 (defun message-bounce ()
   "Re-mail the current message.
@@ -3963,32 +4289,41 @@ This only makes sense if the current message is a bounce message than
 contains some mail you have written which has been bounced back to
 you."
   (interactive)
-  (let ((handles (mm-dissect-buffer t))
+  (let ((cur (current-buffer))
        boundary)
     (message-pop-to-buffer (message-buffer-name "bounce"))
-    (if (stringp (car handles))
-       ;; This is a MIME bounce.
-       (mm-insert-part (car (last handles)))
-      ;; This is a non-MIME bounce, so we try to remove things
-      ;; manually.
-      (mm-insert-part handles)
-      (undo-boundary)
-      (goto-char (point-min))
-      (search-forward "\n\n" nil t)
-      (or (and (re-search-forward message-unsent-separator nil t)
-              (forward-line 1))
-         (re-search-forward "^Return-Path:.*\n" nil t))
-      ;; We remove everything before the bounced mail.
-      (delete-region
-       (point-min)
-       (if (re-search-forward "^[^ \n\t]+:" nil t)
-          (match-beginning 0)
-        (point))))
+    (insert-buffer-substring cur)
+    (undo-boundary)
+    (message-narrow-to-head)
+    (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"
+                                  "Content-Type: message/rfc822"))
+         (setq boundary nil)))
+    (widen)
+    (goto-char (point-min))
+    (search-forward "\n\n" nil t)
+    (or (and boundary
+            (re-search-forward boundary nil t)
+            (forward-line 2))
+       (and (re-search-forward message-unsent-separator nil t)
+            (forward-line 1))
+       (re-search-forward "^Return-Path:.*\n" nil t))
+    ;; We remove everything before the bounced mail.
+    (delete-region
+     (point-min)
+     (if (re-search-forward "^[^ \n\t]+:" nil t)
+        (match-beginning 0)
+       (point)))
     (save-restriction
       (message-narrow-to-head)
       (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)))
 
 ;;;
@@ -4139,7 +4474,7 @@ Do a `tab-to-tab-stop' if not in those headers."
          (message "No matching groups")
        (save-selected-window
          (pop-to-buffer "*Completions*")
-         (buffer-disable-undo)
+         (buffer-disable-undo (current-buffer))
          (let ((buffer-read-only nil))
            (erase-buffer)
            (let ((standard-output (current-buffer)))
@@ -4182,103 +4517,171 @@ regexp varstr."
   (let ((oldbuf (current-buffer)))
     (save-excursion
       (set-buffer (generate-new-buffer name))
-      (message-clone-locals oldbuf varstr)
+      (message-clone-locals oldbuf)
       (current-buffer))))
 
-(defun message-clone-locals (buffer &optional varstr)
+(defun message-clone-locals (buffer)
   "Clone the local variables from BUFFER to the current buffer."
   (let ((locals (save-excursion
                  (set-buffer buffer)
                  (buffer-local-variables)))
-       (regexp "^gnus\\|^nn\\|^message\\|^user-mail-address"))
+       (regexp "^\\(gnus\\|nn\\|message\\|user-\\(mail-address\\|full-name\\)\\)"))
     (mapcar
      (lambda (local)
        (when (and (consp local)
                  (car local)
-                 (string-match regexp (symbol-name (car local)))
-                 (or (null varstr)
-                     (string-match varstr (symbol-name (car local)))))
+                 (string-match regexp (symbol-name (car local))))
         (ignore-errors
           (set (make-local-variable (car local))
                (cdr local)))))
      locals)))
 
-;;; Miscellaneous functions
-
-;; stolen (and renamed) from nnheader.el
-(defun message-replace-chars-in-string (string from to)
-  "Replace characters in STRING from FROM to TO."
-  (let ((string (substring string 0))  ;Copy string.
-       (len (length string))
-       (idx 0))
-    ;; Replace all occurrences of FROM with TO.
-    (while (< idx len)
-      (when (= (aref string idx) from)
-       (aset string idx to))
-      (setq idx (1+ idx)))
-    string))
+;; @ For `message-mail-follow-up-address-checker'.
 
+(defcustom message-mailing-list-address-list nil
+  "*Regexp matching addresses that are mailing lists.
+It must be a simple regexp string or a list of regexp strings.
+This variable is used by \`message-check-mailing-list-with-address-list\'."
+  :group 'message-mail
+  :type '(repeat regexp))
+
+(defun message-check-mailing-list-with-address-list (alist)
+  (let ((s alist)
+       (regexp (if (stringp message-mailing-list-address-list)
+                   message-mailing-list-address-list
+                 (mapconcat
+                  (lambda (x)
+                    x)
+                  message-mailing-list-address-list
+                  "\\|")))
+       address non-mailing-list mailing-list)
+    (while (setq address (car (pop s)))
+      (if (string-match regexp address)
+         (setq mailing-list t)
+       (setq non-mailing-list
+             (append non-mailing-list (list address)))))
+    (if (or (not non-mailing-list)
+           (not mailing-list)
+           (not (y-or-n-p "Do you want to remove private address? ")))
+       alist
+      (setq s non-mailing-list)
+      (while s
+       (setq alist (delq (assoc (pop s) alist) alist)))
+      alist)
+    ))
+
+(defcustom message-mailing-list-address-p nil
+  "*The function return t if address is a mailing list.
+It must be function, and interface is (ADDRESS).
+ADDRESS is a string of mail address.
+This variable is used by \`message-check-mailing-list-with-function\'."
+  :group 'message-mail
+  :type 'function)
+
+(defun message-check-mailing-list-with-function (alist)
+  (let ((s alist)
+       address non-mailing-list mailing-list)
+    (while (setq address (car (pop s)))
+      (if (funcall message-mailing-list-address-p address)
+         (setq mailing-list t)
+       (setq non-mailing-list
+             (append non-mailing-list (list address)))))
+    (if (or (not non-mailing-list)
+           (not mailing-list)
+           (not (y-or-n-p "Do you want to remove private address? ")))
+       alist
+      (setq s non-mailing-list)
+      (while s
+       (setq alist (delq (assoc (pop s) alist) alist)))
+      alist)
+    ))
+
+;;; @ Encode buffer.
 ;;;
-;;; MIME functions
+
+(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)
+  )
+
+;;; @ for saving buffer
 ;;;
 
-(defvar message-inhibit-body-encoding nil)
+(defvar message-save-encoder 'message-mime-save-encoder)
 
-(defun message-encode-message-body ()
-  (unless message-inhibit-body-encoding 
-    (let ((mail-parse-charset (or mail-parse-charset
-                                 message-default-charset
-                                 message-posting-charset))
-         (case-fold-search t)
-         lines content-type-p)
-      (message-goto-body)
-      (save-restriction
-       (narrow-to-region (point) (point-max))
-       (let ((new (mml-generate-mime)))
-         (when new
-           (delete-region (point-min) (point-max))
-           (insert new)
-           (goto-char (point-min))
-           (if (eq (aref new 0) ?\n)
-               (delete-char 1)
-             (search-forward "\n\n")
-             (setq lines (buffer-substring (point-min) (1- (point))))
-             (delete-region (point-min) (point))))))
-      (save-restriction
-       (message-narrow-to-headers-or-head)
-       (message-remove-header "Mime-Version")
-       (goto-char (point-max))
-       (insert "MIME-Version: 1.0\n")
-       (when lines
-         (insert lines))
-       (setq content-type-p
-             (re-search-backward "^Content-Type:" nil t)))
-      (save-restriction
-       (message-narrow-to-headers-or-head)
-       (message-remove-first-header "Content-Type")
-       (message-remove-first-header "Content-Transfer-Encoding"))
-      ;; We always make sure that the message has a Content-Type header.
-      ;; This is because some broken MTAs and MUAs get awfully confused
-      ;; when confronted with a message with a MIME-Version header and
-      ;; without a Content-Type header.  For instance, Solaris'
-      ;; /usr/bin/mail.
-      (unless content-type-p
-       (goto-char (point-min))
-       (re-search-forward "^MIME-Version:")
-       (forward-line 1)
-       (insert "Content-Type: text/plain; charset=us-ascii\n")))))
+(defun message-save-formatter (start end &optional orig-buf)
+  "Format message, when save message buffer. [message.el]"
+  (save-restriction
+    (narrow-to-region start end)
+    (and message-save-encoder
+        (funcall message-save-encoder orig-buf))
+    (goto-char start)
+    (and (search-forward (concat "\n" mail-header-separator "\n") nil t)
+        (replace-match "\n\n"))
+    ))
+
+(set-alist 'format-alist
+          'message
+          '("Message."
+            "1\\(^\\)"
+            nil
+            message-save-formatter
+            t nil))
+
+;;; @ for MIME Edit mode
+;;;
+
+(defun message-mime-insert-article (&optional message)
+  (interactive)
+  (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))
+      (message-remove-header message-included-forward-headers t nil t)
+      (widen))))
 
-(defun message-read-from-minibuffer (prompt)
-  "Read from the minibuffer while providing abbrev expansion."
-  (if (fboundp 'mail-abbrevs-setup)
-      (let ((mail-abbrev-mode-regexp "")
-           (minibuffer-setup-hook 'mail-abbrevs-setup))
-       (read-from-minibuffer prompt)))
-  (let ((minibuffer-setup-hook 'mail-abbrev-minibuffer-setup-hook))
-    (read-string prompt)))
+(set-alist 'mime-edit-message-inserter-alist
+          'message-mode (function message-mime-insert-article))
 
-(provide 'message)
+(defun message-mime-save-encoder (orig-buf)
+  (when (with-current-buffer orig-buf mime-edit-mode-flag)
+    (mime-edit-translate-body)
+    (mime-edit-translate-header)
+    ))
+
+(defun message-mime-after-save-hook ()
+  (set-buffer-file-coding-system nnheader-file-coding-system)
+  (set-buffer-modified-p nil)
+  )
+
+(defun message-mime-setup ()
+  (turn-on-mime-edit)
+  (make-local-hook 'after-save-hook)
+  (add-hook 'after-save-hook 'message-mime-after-save-hook nil t)
+  )
 
 (run-hooks 'message-load-hook)
 
+(provide 'message)
+
 ;;; message.el ends here