`rcnum' -> `entity-node-id'.
[elisp/semi.git] / mime-view.el
index 1e4c157..98773aa 100644 (file)
@@ -1,15 +1,14 @@
 ;;; mime-view.el --- interactive MIME viewer for GNU Emacs
 
 ;;; mime-view.el --- interactive MIME viewer for GNU Emacs
 
-;; Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
+;; Copyright (C) 1995,1996,1997,1998 Free Software Foundation, Inc.
 
 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Created: 1994/7/13
 ;;     Renamed: 1994/8/31 from tm-body.el
 ;;     Renamed: 1997/02/19 from tm-view.el
 
 ;; Author: MORIOKA Tomohiko <morioka@jaist.ac.jp>
 ;; Created: 1994/7/13
 ;;     Renamed: 1994/8/31 from tm-body.el
 ;;     Renamed: 1997/02/19 from tm-view.el
-;; Version: $Revision: 0.80 $
 ;; Keywords: MIME, multimedia, mail, news
 
 ;; Keywords: MIME, multimedia, mail, news
 
-;; This file is part of SEMI (SEMI is Emacs MIME Interfaces).
+;; This file is part of SEMI (Sophisticated Emacs MIME Interfaces).
 
 ;; This program is free software; you can redistribute it and/or
 ;; modify it under the terms of the GNU General Public License as
 
 ;; This program is free software; you can redistribute it and/or
 ;; modify it under the terms of the GNU General Public License as
@@ -28,7 +27,6 @@
 
 ;;; Code:
 
 
 ;;; Code:
 
-(require 'cl)
 (require 'std11)
 (require 'mel)
 (require 'eword-decode)
 (require 'std11)
 (require 'mel)
 (require 'eword-decode)
 ;;; @ version
 ;;;
 
 ;;; @ version
 ;;;
 
-(defconst mime-view-RCS-ID
-  "$Id: mime-view.el,v 0.80 1997-03-27 22:15:02 morioka Exp $")
+(defconst mime-view-version-string
+  `,(concat "SEMI MIME-View "
+           (mapconcat #'number-to-string (cdr semi-version) ".")
+           " (" (car semi-version) ")"))
 
 
-(defconst mime-view-version (get-version-string mime-view-RCS-ID))
 
 
-
-;;; @ variables
+;;; @ variables or settings
 ;;;
 
 ;;;
 
-(defvar mime/content-decoding-condition
-  '(((type . "text/plain")
-     (method "tm-plain" nil 'file 'type 'encoding 'mode 'name)
+(defvar mime-acting-condition
+  '(((type . text)(subtype . plain)
+     (method "tm-plain" nil 'file "" 'encoding 'mode 'name)
      (mode "play" "print")
      )
      (mode "play" "print")
      )
-    ((type . "text/html")
-     (method "tm-html" nil 'file 'type 'encoding 'mode 'name)
+    ((type . text)(subtype . html)
+     (method "tm-html" nil 'file "" 'encoding 'mode 'name)
      (mode . "play")
      )
      (mode . "play")
      )
-    ((type . "text/x-rot13-47")
-     (method . mime-article/decode-caesar)
+    ((type . text)(subtype . x-rot13-47)
+     (method . mime-method-to-display-caesar)
      (mode . "play")
      )
      (mode . "play")
      )
-    ((type . "audio/basic")
-     (method "tm-au"    nil 'file 'type 'encoding 'mode 'name)
+    ((type . text)(subtype . x-rot13-47-48)
+     (method . mime-method-to-display-caesar)
      (mode . "play")
      )
      (mode . "play")
      )
-    
-    ((type . "image/jpeg")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
-     )
-    ((type . "image/gif")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
-     )
-    ((type . "image/tiff")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
-     )
-    ((type . "image/x-tiff")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
-     )
-    ((type . "image/x-xbm")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
-     )
-    ((type . "image/x-pic")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
+
+    ((type . audio)(subtype . basic)
+     (method "tm-au"    nil 'file "" 'encoding 'mode 'name)
+     (mode . "play")
      )
      )
-    ((type . "image/x-mag")
-     (method "tm-image" nil 'file 'type 'encoding 'mode 'name)
+    
+    ((type . image)
+     (method "tm-image" nil 'file "" 'encoding 'mode 'name)
      (mode "play" "print")
      )
     
      (mode "play" "print")
      )
     
-    ((type . "video/mpeg")
-     (method "tm-mpeg"  nil 'file 'type 'encoding 'mode 'name)
+    ((type . video)(subtype . mpeg)
+     (method "tm-mpeg"  nil 'file "" 'encoding 'mode 'name)
      (mode . "play")
      )
     
      (mode . "play")
      )
     
-    ((type . "application/postscript")
-     (method "tm-ps" nil 'file 'type 'encoding 'mode 'name)
+    ((type . application)(subtype . postscript)
+     (method "tm-ps" nil 'file "" 'encoding 'mode 'name)
      (mode "play" "print")
      )
      (mode "play" "print")
      )
-    ((type . "application/octet-stream")
-     (method "tm-file"  nil 'file 'type 'encoding 'mode 'name)
-     (mode "play" "print")
+    ((type . application)(subtype . octet-stream)
+     (method . mime-method-to-save)(mode "play" "print")
      )
      )
-    
-    ;;((type . "message/external-body")
-    ;; (method "xterm" nil
-    ;;        "-e" "showexternal"
-    ;;         'file '"access-type" '"name" '"site" '"directory"))
-    ((type . "message/external-body")
+
+    ((type . message)(subtype . external-body)
      ("access-type" . "anon-ftp")
      ("access-type" . "anon-ftp")
-     (method . mime-article/decode-message/external-ftp)
+     (method . mime-method-to-display-message/external-ftp)
      )
      )
-    ((type . "message/rfc822")
-     (method . mime-article/view-message/rfc822)
+    ((type . message)(subtype . rfc822)
+     (method . mime-method-to-display-message/rfc822)
      (mode . "play")
      )
      (mode . "play")
      )
-    ((type . "message/partial")
-     (method . mime-article/decode-message/partial)
+    ((type . message)(subtype . partial)
+     (method . mime-method-to-store-message/partial)
      (mode . "play")
      )
     
     ((method "metamail" t "-m" "tm" "-x" "-d" "-z" "-e" 'file)
      (mode . "play")
      )
      (mode . "play")
      )
     
     ((method "metamail" t "-m" "tm" "-x" "-d" "-z" "-e" 'file)
      (mode . "play")
      )
-    ((method "tm-file"  nil 'file 'type 'encoding 'mode 'name)
-     (mode . "extract")
-     )
+    ((method . mime-method-to-save)(mode . "extract"))
     ))
 
     ))
 
-(defvar mime-view-childrens-header-showing-Content-Type-list
-  '("message/rfc822" "message/news"))
-
 (defvar mime-view-visible-media-type-list
   '("text/plain" nil "text/richtext" "text/enriched"
     "text/rfc822-headers"
 (defvar mime-view-visible-media-type-list
   '("text/plain" nil "text/richtext" "text/enriched"
     "text/rfc822-headers"
     "application/pgp" "text/x-pgp"
     "application/octet-stream"
     "application/x-selection" "application/x-comment")
     "application/pgp" "text/x-pgp"
     "application/octet-stream"
     "application/x-selection" "application/x-comment")
-  "*List of media-types to be able to display in MIME-View buffer.
+  "*List of media-types to be able to display in MIME-preview buffer.
 Each elements are string of TYPE/SUBTYPE, e.g. \"text/plain\".")
 
 (defvar mime-view-content-button-visible-ctype-list
 Each elements are string of TYPE/SUBTYPE, e.g. \"text/plain\".")
 
 (defvar mime-view-content-button-visible-ctype-list
@@ -153,24 +122,6 @@ Each elements are string of TYPE/SUBTYPE, e.g. \"text/plain\".")
 
 (defvar mime-view-uuencode-encoding-name-list '("x-uue" "x-uuencode"))
 
 
 (defvar mime-view-uuencode-encoding-name-list '("x-uue" "x-uuencode"))
 
-(defvar mime-view-ignored-field-list
-  '(".*Received" ".*Path" ".*Id" "References"
-    "Replied" "Errors-To"
-    "Lines" "Sender" ".*Host" "Xref"
-    "Content-Type" "Precedence"
-    "Status" "X-VM-.*")
-  "All fields that match this list will be hidden in MIME preview buffer.
-Each elements are regexp of field-name. [mime-view.el]")
-
-(defvar mime-view-ignored-field-regexp
-  (concat "^"
-         (apply (function regexp-or) mime-view-ignored-field-list)
-         ":"))
-
-(defvar mime-view-visible-field-list '("Dnas.*" "Message-Id")
-  "All fields that match this list will be displayed in MIME preview buffer.
-Each elements are regexp of field-name.")
-
 (defvar mime-view-redisplay nil)
 
 (defvar mime-view-announcement-for-message/partial
 (defvar mime-view-redisplay nil)
 
 (defvar mime-view-announcement-for-message/partial
@@ -185,121 +136,122 @@ Each elements are regexp of field-name.")
     ))
 
 
     ))
 
 
-;;; @@ predicate functions
-;;;
-
-(defun mime-view-header-visible-p (rcnum cinfo)
-  "Return non-nil if header of current entity is visible."
-  (or (null rcnum)
-      (member (mime::content-info/type
-              (mime-article/rcnum-to-cinfo (cdr rcnum) cinfo))
-             mime-view-childrens-header-showing-Content-Type-list)
-      ))
-
-(defun mime-view-body-visible-p (rcnum cinfo &optional ctype)
-  (let (ccinfo)
-    (or ctype
-       (setq ctype
-             (mime::content-info/type
-              (setq ccinfo (mime-article/rcnum-to-cinfo rcnum cinfo))
-              ))
-       )
-    (and (member ctype mime-view-visible-media-type-list)
-        (if (string-equal ctype "application/octet-stream")
-            (progn
-              (or ccinfo
-                  (setq ccinfo (mime-article/rcnum-to-cinfo rcnum cinfo))
-                  )
-              (member (mime::content-info/encoding ccinfo)
-                      '(nil "7bit" "8bit"))
-              )
-          t))
-    ))
-
-
 ;;; @@ entity button
 ;;;
 
 ;;; @@ entity button
 ;;;
 
-(defun mime-view-insert-entity-button (rcnum cinfo ctype params subj encoding)
+(defun mime-view-insert-entity-button (entity-node-id
+                                      cinfo
+                                      media-type media-subtype params
+                                      subj encoding)
   "Insert entity-button."
   "Insert entity-button."
-  (save-restriction
-    (narrow-to-region (point)(point))
-    (let ((access-type (assoc "access-type" params))
-         (num (or (cdr (assoc "x-part-number" params))
-                  (if (consp rcnum)
-                      (mapconcat (function
-                                  (lambda (num)
-                                    (format "%s" (1+ num))
-                                    ))
-                                 (reverse rcnum) ".")
-                    "0"))
-              ))
-      (cond (access-type
-            (let ((server (assoc "server" params)))
-              (setq access-type (cdr access-type))
-              (if server
-                  (insert (format "[%s %s ([%s] %s)]\n" num subj
-                                  access-type (cdr server)))
-                (let ((site (cdr (assoc "site" params)))
-                      (dir (cdr (assoc "directory" params)))
-                      )
-                  (insert (format "[%s %s ([%s] %s:%s)]\n" num subj
-                                  access-type site dir))
-                  )))
-            )
-           (t
-            (let ((charset (cdr (assoc "charset" params))))
-              (insert (concat "[" num " " subj))
+  (mime-insert-button
+   (let ((access-type (assoc "access-type" params))
+        (num (or (cdr (assoc "x-part-number" params))
+                 (if (consp entity-node-id)
+                     (mapconcat (function
+                                 (lambda (num)
+                                   (format "%s" (1+ num))
+                                   ))
+                                (reverse entity-node-id) ".")
+                   "0"))
+             ))
+     (cond (access-type
+           (let ((server (assoc "server" params)))
+             (setq access-type (cdr access-type))
+             (if server
+                 (format "%s %s ([%s] %s)"
+                         num subj access-type (cdr server))
+               (let ((site (cdr (assoc "site" params)))
+                     (dir (cdr (assoc "directory" params)))
+                     )
+                 (format "%s %s ([%s] %s:%s)"
+                         num subj access-type site dir)
+                 )))
+           )
+          (t
+           (let ((charset (cdr (assoc "charset" params))))
+             (concat
+              num " " subj
               (let ((rest
               (let ((rest
-                     (concat " <" ctype
+                     (format " <%s/%s%s%s>"
+                             media-type media-subtype
                              (if charset
                                  (concat "; " charset)
                              (if charset
                                  (concat "; " charset)
-                               (if encoding (concat " (" encoding ")"))
-                               )
-                             ">]\n")))
+                               "")
+                             (if encoding
+                                 (concat " (" encoding ")")
+                               ""))))
                 (if (>= (+ (current-column)(length rest))(window-width))
                 (if (>= (+ (current-column)(length rest))(window-width))
-                    (insert "\n\t")
-                  )
-                (insert rest)
-                ))))
-      )
-    (mime-add-button (point-min)(1- (point-max))
-                    (function mime-view-play-current-entity))
-    ))
+                    "\n\t")
+                rest)))
+           )))
+   (function mime-preview-play-current-entity))
+  )
 
 
-(defun mime-view-entity-button-function
-  (rcnum cinfo ctype params subj encoding)
+(defun mime-view-entity-button-function (entity-node-id
+                                        cinfo
+                                        media-type media-subtype
+                                        params subj encoding)
   "Insert entity button conditionally.
 Please redefine this function if you want to change default setting."
   "Insert entity button conditionally.
 Please redefine this function if you want to change default setting."
-  (or (null rcnum)
-      (string= ctype "application/x-selection")
-      (and (string= ctype "application/octet-stream")
-          (string= (mime::content-info/type
-                    (mime-article/rcnum-to-cinfo (cdr rcnum) cinfo))
-                   "multipart/encrypted"))
-      (mime-view-insert-entity-button rcnum cinfo ctype params subj encoding)
+  (or (null entity-node-id)
+      (and (eq media-type 'application)
+          (or (eq media-subtype 'x-selection)
+              (and (eq media-subtype 'octet-stream)
+                   (let ((entity-info
+                          (mime-raw-entity-node-id-to-entity-info
+                           (cdr entity-node-id) cinfo)))
+                     (and (eq (mime-entity-info-media-type entity-info)
+                              'multipart)
+                          (eq (mime-entity-info-media-subtype entity-info)
+                              'encrypted)
+                          )))))
+      (mime-view-insert-entity-button
+       entity-node-id cinfo media-type media-subtype params subj encoding)
       ))
 
 
 ;;; @@ content header filter
 ;;;
 
       ))
 
 
 ;;; @@ content header filter
 ;;;
 
-(defsubst mime-view-cut-header ()
+(defvar mime-view-ignored-field-list
+  '(".*Received" ".*Path" ".*Id" "References"
+    "Replied" "Errors-To"
+    "Lines" "Sender" ".*Host" "Xref"
+    "Content-Type" "Precedence"
+    "Status" "X-VM-.*")
+  "All fields that match this list will be hidden in MIME preview buffer.
+Each elements are regexp of field-name.")
+
+(defvar mime-view-ignored-field-regexp
+  (concat "^"
+         (apply (function regexp-or) mime-view-ignored-field-list)
+         ":"))
+
+(defvar mime-view-visible-field-list '("Dnas.*" "Message-Id")
+  "All fields that match this list will be displayed in MIME preview buffer.
+Each elements are regexp of field-name.")
+
+(defun mime-view-cut-header ()
   (goto-char (point-min))
   (while (re-search-forward mime-view-ignored-field-regexp nil t)
     (let* ((beg (match-beginning 0))
           (end (match-end 0))
           (name (buffer-substring beg end))
           )
   (goto-char (point-min))
   (while (re-search-forward mime-view-ignored-field-regexp nil t)
     (let* ((beg (match-beginning 0))
           (end (match-end 0))
           (name (buffer-substring beg end))
           )
-      (or (member-if (function
-                     (lambda (regexp)
-                       (string-match regexp name)
-                       )) mime-view-visible-field-list)
-         (delete-region beg
+      (catch 'visible
+       (let ((rest mime-view-visible-field-list))
+         (while rest
+           (if (string-match (car rest) name)
+               (throw 'visible nil)
+             )
+           (setq rest (cdr rest))))
+       (delete-region beg
+                      (save-excursion
                         (if (re-search-forward "^\\([^ \t]\\|$\\)" nil t)
                             (match-beginning 0)
                         (if (re-search-forward "^\\([^ \t]\\|$\\)" nil t)
                             (match-beginning 0)
-                          (point-max)))
-         ))))
+                          (point-max))))
+       ))))
 
 (defun mime-view-default-content-header-filter ()
   (mime-view-cut-header)
 
 (defun mime-view-default-content-header-filter ()
   (mime-view-cut-header)
@@ -313,20 +265,27 @@ Please redefine this function if you want to change default setting."
 ;;;
 
 (defvar mime-view-content-filter-alist
 ;;;
 
 (defvar mime-view-content-filter-alist
-  '(("text/enriched" . mime-preview/filter-for-text/enriched)
-    ("text/richtext" . mime-preview/filter-for-text/richtext)
-    (t . mime-preview/filter-for-text/plain)
-    ))
+  '(("text/enriched" . mime-view-filter-for-text/enriched)
+    ("text/richtext" . mime-view-filter-for-text/richtext)
+    (t . mime-view-filter-for-text/plain)
+    )
+  "Alist of media-types vs. corresponding MIME-preview filter functions.
+Each element looks like (TYPE/SUBTYPE . FUNCTION) or (t . FUNCTION).
+TYPE/SUBTYPE is a string of media-type and FUNCTION is a filter
+function.  t means default media-type.")
 
 
 ;;; @@ entity separator
 ;;;
 
 
 
 ;;; @@ entity separator
 ;;;
 
-(defun mime-view-entity-separator-function (rcnum cinfo ctype params subj)
+(defun mime-view-entity-separator-function (entity-node-id
+                                           cinfo
+                                           media-type media-subtype
+                                           params subj)
   "Insert entity separator conditionally.
 Please redefine this function if you want to change default setting."
   "Insert entity separator conditionally.
 Please redefine this function if you want to change default setting."
-  (or (mime-view-header-visible-p rcnum cinfo)
-      (mime-view-body-visible-p rcnum cinfo ctype)
+  (or (mime-view-header-visible-p entity-node-id cinfo)
+      (mime-view-body-visible-p entity-node-id cinfo media-type media-subtype)
       (progn
        (goto-char (point-max))
        (insert "\n")
       (progn
        (goto-char (point-max))
        (insert "\n")
@@ -336,60 +295,62 @@ Please redefine this function if you want to change default setting."
 ;;; @@ buffer local variables
 ;;;
 
 ;;; @@ buffer local variables
 ;;;
 
-;;; @@@ in raw buffer
+;;; @@@ in raw-buffer
 ;;;
 
 ;;;
 
-(defvar mime::article/content-info
+(defvar mime-raw-message-info
   "Information about structure of message.
   "Information about structure of message.
-Please use reference function `mime::content-info/SLOT-NAME' to
-reference slot of content-info.  Their argument is only content-info.
+Please use reference function `mime-entity-info-SLOT' to get value of
+SLOT.
 
 Following is a list of slots of the structure:
 
 
 Following is a list of slots of the structure:
 
-rcnum          reversed content-number (list)
+node-id                reversed entity-number (list of integers or t)
 point-min      beginning point of region in raw-buffer
 point-max      end point of region in raw-buffer
 point-min      beginning point of region in raw-buffer
 point-max      end point of region in raw-buffer
-type           media-type/subtype (string or nil)
+type           media-type (symbol)
+subtype                media-subtype (symbol)
+type/subtype   media-type/subtype (string or nil)
 parameters     parameter of Content-Type field (association list)
 encoding       Content-Transfer-Encoding (string or nil)
 children       entities included in this entity (list of content-infos)
 
 parameters     parameter of Content-Type field (association list)
 encoding       Content-Transfer-Encoding (string or nil)
 children       entities included in this entity (list of content-infos)
 
-If a entity includes other entities in its body, such as multipart or
-message/rfc822, content-infos of other entities are included in
-`children', so content-info become a tree.")
-(make-variable-buffer-local 'mime::article/content-info)
+If an entity includes other entities in its body, such as multipart or
+message/rfc822, entity-infos of other entities are included in
+`children', so entity-info become a tree.")
+(make-variable-buffer-local 'mime-raw-message-info)
 
 
-(defvar mime-view-buffer nil
-  "MIME View buffer corresponding with the (raw) buffer.")
-(make-variable-buffer-local 'mime-view-buffer)
+(defvar mime-preview-buffer nil
+  "MIME-preview buffer corresponding with the (raw) buffer.")
+(make-variable-buffer-local 'mime-preview-buffer)
 
 
 
 
-;;; @@@ in view buffer
+;;; @@@ in preview-buffer
 ;;;
 
 (defvar mime-mother-buffer nil
 ;;;
 
 (defvar mime-mother-buffer nil
-  "Mother buffer corresponding with the (MIME-View) buffer.
-If current MIME-View buffer is generated by other buffer, such as
+  "Mother buffer corresponding with the (MIME-preview) buffer.
+If current MIME-preview buffer is generated by other buffer, such as
 message/partial, it is called `mother-buffer'.")
 (make-variable-buffer-local 'mime-mother-buffer)
 
 (defvar mime-raw-buffer nil
 message/partial, it is called `mother-buffer'.")
 (make-variable-buffer-local 'mime-mother-buffer)
 
 (defvar mime-raw-buffer nil
-  "Raw buffer corresponding with the (MIME-View) buffer.")
+  "Raw buffer corresponding with the (MIME-preview) buffer.")
 (make-variable-buffer-local 'mime-raw-buffer)
 
 (make-variable-buffer-local 'mime-raw-buffer)
 
-(defvar mime-view-original-major-mode nil
-  "Major-mode in mime-raw-buffer.")
-(make-variable-buffer-local 'mime-view-original-major-mode)
+(defvar mime-preview-original-major-mode nil
+  "Major-mode of mime-raw-buffer.")
+(make-variable-buffer-local 'mime-preview-original-major-mode)
 
 
-(make-variable-buffer-local 'mime::preview/original-window-configuration)
+(make-variable-buffer-local 'mime-preview-original-window-configuration)
 
 
 ;;; @@ quitting method
 ;;;
 
 
 
 ;;; @@ quitting method
 ;;;
 
-(defvar mime-view-quitting-method-alist
+(defvar mime-preview-quitting-method-alist
   '((mime-show-message-mode
   '((mime-show-message-mode
-     . mime-view-quitting-method-for-mime-show-message-mode))
+     . mime-preview-quitting-method-for-mime-show-message-mode))
   "Alist of major-mode vs. quitting-method of mime-view.")
 
 (defvar mime-view-over-to-previous-method-alist nil)
   "Alist of major-mode vs. quitting-method of mime-view.")
 
 (defvar mime-view-over-to-previous-method-alist nil)
@@ -441,18 +402,6 @@ The compressed face will be piped to this command.")
          ))))
 
 
          ))))
 
 
-;;; @@ utility
-;;;
-
-(defun mime-preview/get-original-major-mode ()
-  (if mime-mother-buffer
-      (save-excursion
-       (set-buffer mime-mother-buffer)
-       (mime-preview/get-original-major-mode)
-       )
-    mime-view-original-major-mode))
-
-
 ;;; @ buffer setup
 ;;;
 
 ;;; @ buffer setup
 ;;;
 
@@ -463,42 +412,50 @@ The compressed face will be piped to this command.")
        (set-buffer ibuf)
        ))
   (or mime-view-redisplay
        (set-buffer ibuf)
        ))
   (or mime-view-redisplay
-      (setq mime::article/content-info (mime-parse-message ctl encoding))
+      (setq mime-raw-message-info (mime-parse-message ctl encoding))
       )
       )
-  (let* ((cinfo mime::article/content-info)
-        (pcl (mime/flatten-content-info cinfo))
+  (let* ((cinfo mime-raw-message-info)
+        (pcl (mime-raw-flatten-message-info cinfo))
         (the-buf (current-buffer))
         (mode major-mode)
         )
     (or obuf
        (setq obuf (concat "*Preview-" (buffer-name the-buf) "*")))
     (set-buffer (get-buffer-create obuf))
         (the-buf (current-buffer))
         (mode major-mode)
         )
     (or obuf
        (setq obuf (concat "*Preview-" (buffer-name the-buf) "*")))
     (set-buffer (get-buffer-create obuf))
-    (setq buffer-read-only nil)
-    (widen)
-    (erase-buffer)
-    (setq mime-raw-buffer the-buf)
-    (setq mime-view-original-major-mode mode)
-    (setq major-mode 'mime-view-mode)
-    (setq mode-name "MIME-View")
-    (while pcl
-      (mime-view-display-entity (car pcl) cinfo the-buf obuf)
-      (setq pcl (cdr pcl))
+    (let ((inhibit-read-only t))
+      ;;(setq buffer-read-only nil)
+      (widen)
+      (erase-buffer)
+      (setq mime-raw-buffer the-buf)
+      (setq mime-preview-original-major-mode mode)
+      (setq major-mode 'mime-view-mode)
+      (setq mode-name "MIME-View")
+      (while pcl
+       (mime-view-display-entity (car pcl) cinfo the-buf obuf)
+       (setq pcl (cdr pcl))
+       )
+      (set-buffer-modified-p nil)
       )
       )
-    (set-buffer-modified-p nil)
     (setq buffer-read-only t)
     (set-buffer the-buf)
     )
     (setq buffer-read-only t)
     (set-buffer the-buf)
     )
-  (setq mime-view-buffer obuf)
+  (setq mime-preview-buffer obuf)
   )
 
 (defun mime-view-display-entity (content cinfo ibuf obuf)
   "Display entity from content-info CONTENT."
   )
 
 (defun mime-view-display-entity (content cinfo ibuf obuf)
   "Display entity from content-info CONTENT."
-  (let* ((beg (mime::content-info/point-min content))
-        (end (mime::content-info/point-max content))
-        (ctype (mime::content-info/type content))
-        (params (mime::content-info/parameters content))
-        (encoding (mime::content-info/encoding content))
-        (rcnum (mime::content-info/rcnum content))
+  (let* ((beg (mime-entity-info-point-min content))
+        (end (mime-entity-info-point-max content))
+        (media-type (mime-entity-info-media-type content))
+        (media-subtype (mime-entity-info-media-subtype content))
+        (ctype (if media-type
+                   (if media-subtype
+                       (format "%s/%s" media-type media-subtype)
+                     (symbol-name media-type)
+                     )))
+        (params (mime-entity-info-parameters content))
+        (encoding (mime-entity-info-encoding content))
+        (entity-node-id (mime-entity-info-node-id content))
         he e nb ne subj)
     (set-buffer ibuf)
     (goto-char beg)
         he e nb ne subj)
     (set-buffer ibuf)
     (goto-char beg)
@@ -512,50 +469,55 @@ The compressed face will be piped to this command.")
       (narrow-to-region beg end)
       (setq subj
            (eword-decode-string
       (narrow-to-region beg end)
       (setq subj
            (eword-decode-string
-            (mime-article/get-subject params encoding)))
+            (mime-raw-get-subject params encoding)))
       )
     (set-buffer obuf)
     (setq nb (point))
     (narrow-to-region nb nb)
       )
     (set-buffer obuf)
     (setq nb (point))
     (narrow-to-region nb nb)
-    (mime-view-entity-button-function rcnum cinfo ctype params subj encoding)
-    (if (mime-view-header-visible-p rcnum cinfo)
-       (mime-preview/display-header beg he)
+    (mime-view-entity-button-function
+     entity-node-id cinfo media-type media-subtype params subj encoding)
+    (if (mime-view-header-visible-p entity-node-id cinfo)
+       (mime-view-display-header beg he)
       )
       )
-    (if (and (null rcnum)
+    (if (and (null entity-node-id)
             (member
              ctype mime-view-content-button-visible-ctype-list))
        (save-excursion
          (goto-char (point-max))
          (mime-view-insert-entity-button
             (member
              ctype mime-view-content-button-visible-ctype-list))
        (save-excursion
          (goto-char (point-max))
          (mime-view-insert-entity-button
-          rcnum cinfo ctype params subj encoding)
+          entity-node-id cinfo media-type media-subtype params subj encoding)
          ))
          ))
-    (cond ((mime-view-body-visible-p rcnum cinfo ctype)
-          (mime-preview/display-body he end
-                                     rcnum cinfo ctype params subj encoding)
+    (cond ((mime-view-body-visible-p entity-node-id cinfo
+                                    media-type media-subtype)
+          (mime-view-display-body he end
+                                  entity-node-id cinfo
+                                  ctype params subj encoding)
           )
           )
-         ((equal ctype "message/partial")
-          (mime-preview/display-message/partial)
+         ((and (eq media-type 'message)(eq media-subtype 'partial))
+          (mime-view-insert-message/partial-button)
           )
           )
-         ((and (null rcnum)
-               (null (mime::content-info/children cinfo))
+         ((and (null entity-node-id)
+               (null (mime-entity-info-children cinfo))
                )
           (goto-char (point-max))
                )
           (goto-char (point-max))
-          (mime-view-insert-entity-button
-           rcnum cinfo ctype params subj encoding)
+          (mime-view-insert-entity-button entity-node-id cinfo
+                                          media-type media-subtype params
+                                          subj encoding)
           ))
           ))
-    (mime-view-entity-separator-function rcnum cinfo ctype params subj)
+    (mime-view-entity-separator-function
+     entity-node-id cinfo media-type media-subtype params subj)
     (setq ne (point-max))
     (widen)
     (put-text-property nb ne 'mime-view-raw-buffer ibuf)
     (setq ne (point-max))
     (widen)
     (put-text-property nb ne 'mime-view-raw-buffer ibuf)
-    (put-text-property nb ne 'mime-view-cinfo content)
+    (put-text-property nb ne 'mime-view-entity-info content)
     (goto-char ne)
     ))
 
     (goto-char ne)
     ))
 
-(defun mime-preview/display-header (beg end)
+(defun mime-view-display-header (beg end)
   (save-restriction
     (narrow-to-region (point)(point))
     (insert-buffer-substring mime-raw-buffer beg end)
   (save-restriction
     (narrow-to-region (point)(point))
     (insert-buffer-substring mime-raw-buffer beg end)
-    (let ((f (cdr (assq mime-view-original-major-mode
+    (let ((f (cdr (assq mime-preview-original-major-mode
                        mime-view-content-header-filter-alist))))
       (if (functionp f)
          (funcall f)
                        mime-view-content-header-filter-alist))))
       (if (functionp f)
          (funcall f)
@@ -564,8 +526,8 @@ The compressed face will be piped to this command.")
     (run-hooks 'mime-view-content-header-filter-hook)
     ))
 
     (run-hooks 'mime-view-content-header-filter-hook)
     ))
 
-(defun mime-preview/display-body (beg end
-                                     rcnum cinfo ctype params subj encoding)
+(defun mime-view-display-body (beg end entity-node-id cinfo
+                                  ctype params subj encoding)
   (save-restriction
     (narrow-to-region (point-max)(point-max))
     (insert-buffer-substring mime-raw-buffer beg end)
   (save-restriction
     (narrow-to-region (point-max)(point-max))
     (insert-buffer-substring mime-raw-buffer beg end)
@@ -576,20 +538,20 @@ The compressed face will be piped to this command.")
           )
       )))
 
           )
       )))
 
-(defun mime-preview/display-message/partial ()
+(defun mime-view-insert-message/partial-button ()
   (save-restriction
     (goto-char (point-max))
     (if (not (search-backward "\n\n" nil t))
        (insert "\n")
       )
   (save-restriction
     (goto-char (point-max))
     (if (not (search-backward "\n\n" nil t))
        (insert "\n")
       )
-    (let ((be (point-max)))
-      (narrow-to-region be be)
-      (insert mime-view-announcement-for-message/partial)
-      (mime-add-button (point-min)(point-max)
-                      (function mime-view-play-current-entity))
-      )))
+    (goto-char (point-max))
+    (narrow-to-region (point-max)(point-max))
+    (insert mime-view-announcement-for-message/partial)
+    (mime-add-button (point-min)(point-max)
+                    (function mime-preview-play-current-entity))
+    ))
 
 
-(defun mime-article/get-uu-filename (param &optional encoding)
+(defun mime-raw-get-uu-filename (param &optional encoding)
   (if (member (or encoding
                  (cdr (assq 'encoding param))
                  )
   (if (member (or encoding
                  (cdr (assq 'encoding param))
                  )
@@ -602,7 +564,7 @@ The compressed face will be piped to this command.")
            ""))
     ))
 
            ""))
     ))
 
-(defun mime-article/get-subject (param &optional encoding)
+(defun mime-raw-get-subject (param &optional encoding)
   (or (std11-find-field-body '("Content-Description" "Subject"))
       (let (ret)
        (if (or (and (setq ret (mime/Content-Disposition))
   (or (std11-find-field-body '("Content-Description" "Subject"))
       (let (ret)
        (if (or (and (setq ret (mime/Content-Disposition))
@@ -613,27 +575,29 @@ The compressed face will be piped to this command.")
                )
            (std11-strip-quoted-string (cdr ret))
          ))
                )
            (std11-strip-quoted-string (cdr ret))
          ))
-      (mime-article/get-uu-filename param encoding)
+      (mime-raw-get-uu-filename param encoding)
       ""))
 
 
       ""))
 
 
-;;; @ content information
+;;; @ entity information
 ;;;
 
 ;;;
 
-(defun mime-article/point-content-number (p &optional cinfo)
-  (or cinfo
-      (setq cinfo mime::article/content-info)
-      )
-  (let ((b (mime::content-info/point-min cinfo))
-       (e (mime::content-info/point-max cinfo))
-       (c (mime::content-info/children cinfo))
+(defun mime-raw-point-to-entity-number (position &optional message-info)
+  "Return entity-number from POTION in mime-raw-buffer.
+If optional argument MESSAGE-INFO is not specified,
+`mime-raw-message-info' is used."
+  (or message-info
+      (setq message-info mime-raw-message-info))
+  (let ((b (mime-entity-info-point-min message-info))
+       (e (mime-entity-info-point-max message-info))
+       (c (mime-entity-info-children message-info))
        )
        )
-    (if (and (<= b p)(<= p e))
+    (if (and (<= b position)(<= position e))
        (or (let (co ret (sn 0))
              (catch 'tag
                (while c
                  (setq co (car c))
        (or (let (co ret (sn 0))
              (catch 'tag
                (while c
                  (setq co (car c))
-                 (setq ret (mime-article/point-content-number p co))
+                 (setq ret (mime-raw-point-to-entity-number position co))
                  (cond ((eq ret t) (throw 'tag (list sn)))
                        (ret (throw 'tag (cons sn ret)))
                        )
                  (cond ((eq ret t) (throw 'tag (list sn)))
                        (ret (throw 'tag (cons sn ret)))
                        )
@@ -642,60 +606,101 @@ The compressed face will be piped to this command.")
                  )))
            t))))
 
                  )))
            t))))
 
-(defun mime-article/rcnum-to-cinfo (rcnum &optional cinfo)
-  (or cinfo
-      (setq cinfo mime::article/content-info)
-      )
-  (find-if (function
-           (lambda (ci)
-             (equal (mime::content-info/rcnum ci) rcnum)
-             ))
-          (mime/flatten-content-info cinfo)
-          ))
-
-(defun mime-article/cnum-to-cinfo (cn &optional cinfo)
-  (or cinfo
-      (setq cinfo mime::article/content-info)
-      )
-  (if (eq cn t)
-      cinfo
-    (let ((sn (car cn)))
+(defun mime-raw-point-to-entity-node-id (position &optional message-info)
+  "Return entity-node-id from POTION in mime-raw-buffer.
+If optional argument MESSAGE-INFO is not specified,
+`mime-raw-message-info' is used."
+  (reverse (mime-raw-point-to-entity-number position message-info)))
+
+(defsubst mime-raw-entity-node-id-to-entity-info (entity-node-id
+                                                 &optional message-info)
+  "Return entity-info from ENTITY-NODE-ID in mime-raw-buffer.
+If optional argument MESSAGE-INFO is not specified,
+`mime-raw-message-info' is used."
+  (mime-raw-entity-number-to-entity-info (reverse entity-node-id)
+                                        message-info))
+
+(defun mime-raw-entity-number-to-entity-info (entity-number
+                                             &optional message-info)
+  "Return entity-info from ENTITY-NUMBER in mime-raw-buffer.
+If optional argument MESSAGE-INFO is not specified,
+`mime-raw-message-info' is used."
+  (or message-info
+      (setq message-info mime-raw-message-info))
+  (if (eq entity-number t)
+      message-info
+    (let ((sn (car entity-number)))
       (if (null sn)
       (if (null sn)
-         cinfo
-       (let ((rc (nth sn (mime::content-info/children cinfo))))
+         message-info
+       (let ((rc (nth sn (mime-entity-info-children message-info))))
          (if rc
          (if rc
-             (mime-article/cnum-to-cinfo (cdr cn) rc)
+             (mime-raw-entity-number-to-entity-info (cdr entity-number) rc)
            ))
        ))))
 
            ))
        ))))
 
-(defun mime/flatten-content-info (&optional cinfo)
-  (or cinfo
-      (setq cinfo mime::article/content-info)
-      )
-  (let ((dest (list cinfo))
-       (rcl (mime::content-info/children cinfo))
-       )
+(defun mime-raw-flatten-message-info (&optional message-info)
+  "Return list of entity-infos in mime-raw-buffer.
+If optional argument MESSAGE-INFO is not specified,
+`mime-raw-message-info' is used."
+  (or message-info
+      (setq message-info mime-raw-message-info))
+  (let ((dest (list message-info))
+       (rcl (mime-entity-info-children message-info)))
     (while rcl
     (while rcl
-      (setq dest (nconc dest (mime/flatten-content-info (car rcl))))
-      (setq rcl (cdr rcl))
-      )
+      (setq dest (nconc dest (mime-raw-flatten-message-info (car rcl))))
+      (setq rcl (cdr rcl)))
     dest))
 
 
     dest))
 
 
+;;; @@ predicate functions
+;;;
+
+(defvar mime-view-childrens-header-showing-Content-Type-list
+  '("message/rfc822" "message/news"))
+
+(defun mime-view-header-visible-p (entity-node-id cinfo)
+  "Return non-nil if header of current entity is visible."
+  (or (null entity-node-id)
+      (member (mime-entity-info-type/subtype
+              (mime-raw-entity-node-id-to-entity-info
+               (cdr entity-node-id) cinfo))
+             mime-view-childrens-header-showing-Content-Type-list)
+      ))
+
+(defun mime-view-body-visible-p (entity-node-id cinfo
+                                               media-type media-subtype)
+  (let ((ctype (if media-type
+                  (if media-subtype
+                      (format "%s/%s" media-type media-subtype)
+                    (symbol-name media-type)
+                    ))))
+    (and (member ctype mime-view-visible-media-type-list)
+        (if (and (eq media-type 'application)
+                 (eq media-subtype 'octet-stream))
+            (let ((ccinfo
+                   (mime-raw-entity-node-id-to-entity-info
+                    entity-node-id cinfo)))
+              (member (mime-entity-info-encoding ccinfo)
+                      '(nil "7bit" "8bit"))
+              )
+          t))
+    ))
+
+
 ;;; @ MIME viewer mode
 ;;;
 
 (defconst mime-view-menu-title "MIME-View")
 (defconst mime-view-menu-list
 ;;; @ MIME viewer mode
 ;;;
 
 (defconst mime-view-menu-title "MIME-View")
 (defconst mime-view-menu-list
-  '((up                 "Move to upper content"      mime-view-move-to-upper)
-    (previous   "Move to previous content"   mime-view-move-to-previous)
-    (next       "Move to next content"       mime-view-move-to-next)
-    (scroll-down "Scroll to previous content" mime-view-scroll-down-entity)
-    (scroll-up  "Scroll to next content"     mime-view-scroll-up-entity)
-    (play       "Play Content"               mime-view-play-current-entity)
-    (extract    "Extract Content"            mime-view-extract-current-entity)
-    (print      "Print"                      mime-view-print-current-entity)
-    (x-face     "Show X Face"                mime-view-display-x-face)
+  '((up                 "Move to upper entity"    mime-preview-move-to-upper)
+    (previous   "Move to previous entity" mime-preview-move-to-previous)
+    (next       "Move to next entity"     mime-preview-move-to-next)
+    (scroll-down "Scroll-down"             mime-preview-scroll-down-entity)
+    (scroll-up  "Scroll-up"               mime-preview-scroll-up-entity)
+    (play       "Play current entity"     mime-preview-play-current-entity)
+    (extract    "Extract current entity"  mime-preview-extract-current-entity)
+    (print      "Print current entity"    mime-preview-print-current-entity)
+    (x-face     "Show X Face"             mime-preview-display-x-face)
     )
   "Menu for MIME Viewer")
 
     )
   "Menu for MIME Viewer")
 
@@ -725,49 +730,59 @@ The compressed face will be piped to this command.")
                              (make-sparse-keymap)
                              )))
     (define-key mime-view-mode-map
                              (make-sparse-keymap)
                              )))
     (define-key mime-view-mode-map
-      "u"        (function mime-view-move-to-upper))
+      "u"        (function mime-preview-move-to-upper))
+    (define-key mime-view-mode-map
+      "p"        (function mime-preview-move-to-previous))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "p"        (function mime-view-move-to-previous))
+      "n"        (function mime-preview-move-to-next))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "n"        (function mime-view-move-to-next))
+      "\e\t"     (function mime-preview-move-to-previous))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\e\t"     (function mime-view-move-to-previous))
+      "\t"       (function mime-preview-move-to-next))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\t"       (function mime-view-move-to-next))
+      " "        (function mime-preview-scroll-up-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      " "        (function mime-view-scroll-up-entity))
+      "\M- "     (function mime-preview-scroll-down-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\M- "     (function mime-view-scroll-down-entity))
+      "\177"     (function mime-preview-scroll-down-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\177"     (function mime-view-scroll-down-entity))
+      "\C-m"     (function mime-preview-next-line-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\C-m"     (function mime-view-next-line-content))
+      "\C-\M-m"  (function mime-preview-previous-line-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\C-\M-m"  (function mime-view-previous-line-content))
+      "v"        (function mime-preview-play-current-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "v"        (function mime-view-play-current-entity))
+      "e"        (function mime-preview-extract-current-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "e"        (function mime-view-extract-current-entity))
+      "\C-c\C-p" (function mime-preview-print-current-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\C-c\C-p" (function mime-view-print-current-entity))
+      "a"        (function mime-preview-follow-current-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "a"        (function mime-view-follow-current-entity))
+      "q"        (function mime-preview-quit))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "q"        (function mime-view-quit))
+      "h"        (function mime-preview-show-summary))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "h"        (function mime-view-show-summary))
+      "\C-c\C-x" (function mime-preview-kill-buffer))
+    ;; (define-key mime-view-mode-map
+    ;;   "<"        (function beginning-of-buffer))
+    ;; (define-key mime-view-mode-map
+    ;;   ">"        (function end-of-buffer))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "\C-c\C-x" (function mime-view-kill-buffer))
+      "?"        (function describe-mode))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "<"        (function beginning-of-buffer))
+      [tab] (function mime-preview-move-to-next))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      ">"        (function end-of-buffer))
+      [delete] (function mime-preview-scroll-down-entity))
     (define-key mime-view-mode-map
     (define-key mime-view-mode-map
-      "?"        (function describe-mode))
+      [backspace] (function mime-preview-scroll-down-entity))
     (if (functionp default)
     (if (functionp default)
-       (setq mime-view-mode-map
-             (append mime-view-mode-map (list (cons t default)))
-             ))
+       (cond (running-xemacs
+              (set-keymap-default-binding mime-view-mode-map default)
+              )
+             (t
+              (setq mime-view-mode-map
+                    (append mime-view-mode-map (list (cons t default))))
+              )))
     (if mouse-button-2
        (define-key mime-view-mode-map
          mouse-button-2 (function mime-button-dispatcher))
     (if mouse-button-2
        (define-key mime-view-mode-map
          mouse-button-2 (function mime-button-dispatcher))
@@ -794,12 +809,19 @@ The compressed face will be piped to this command.")
     (run-hooks 'mime-view-define-keymap-hook)
     ))
 
     (run-hooks 'mime-view-define-keymap-hook)
     ))
 
-(defsubst mime-hide-echo-buffer ()
-  "Hide mime-echo buffer."
-  (let ((win (get-buffer-window mime-echo-buffer-name)))
-    (if win
-       (delete-window win)
-      )))
+(defsubst mime-maybe-hide-echo-buffer ()
+  "Clear mime-echo buffer and delete window for it."
+  (let ((buf (get-buffer mime-echo-buffer-name)))
+    (if buf
+       (save-excursion
+         (set-buffer buf)
+         (erase-buffer)
+         (let ((win (get-buffer-window buf)))
+           (if win
+               (delete-window win)
+             ))
+         (bury-buffer buf)
+         ))))
 
 (defun mime-view-mode (&optional mother ctl encoding ibuf obuf
                                 default-keymap-or-function)
 
 (defun mime-view-mode (&optional mother ctl encoding ibuf obuf
                                 default-keymap-or-function)
@@ -827,24 +849,19 @@ button-2  Move to point under the mouse cursor
                and decode current content as `play mode'
 "
   (interactive)
                and decode current content as `play mode'
 "
   (interactive)
-  (let ((buf (get-buffer mime-echo-buffer-name)))
-    (if buf
-       (save-excursion
-         (set-buffer buf)
-         (erase-buffer)
-         )))
+  (mime-maybe-hide-echo-buffer)
   (let ((ret (mime-view-setup-buffers ctl encoding ibuf obuf))
        (win-conf (current-window-configuration))
        )
     (prog1
        (switch-to-buffer ret)
   (let ((ret (mime-view-setup-buffers ctl encoding ibuf obuf))
        (win-conf (current-window-configuration))
        )
     (prog1
        (switch-to-buffer ret)
-      (setq mime::preview/original-window-configuration win-conf)
+      (setq mime-preview-original-window-configuration win-conf)
       (if mother
          (progn
            (setq mime-mother-buffer mother)
            ))
       (mime-view-define-keymap default-keymap-or-function)
       (if mother
          (progn
            (setq mime-mother-buffer mother)
            ))
       (mime-view-define-keymap default-keymap-or-function)
-      (let ((point (next-single-property-change (point-min) 'mime-view-cinfo)))
+      (let ((point (next-single-property-change (point-min) 'mime-view-entity-info)))
        (if point
            (goto-char point)
          (goto-char (point-min))
        (if point
            (goto-char point)
          (goto-char (point-min))
@@ -853,58 +870,80 @@ button-2  Move to point under the mouse cursor
       (run-hooks 'mime-view-mode-hook)
       )))
 
       (run-hooks 'mime-view-mode-hook)
       )))
 
-(autoload 'mime-view-play-current-entity "mime-play" "Play current entity." t)
 
 
-(defun mime-view-extract-current-entity ()
+;;; @@ playing
+;;;
+
+(autoload 'mime-preview-play-current-entity "mime-play"
+  "Play current entity." t)
+
+(defun mime-preview-extract-current-entity ()
   "Extract current entity into file (maybe).
 It decodes current entity to call internal or external method as
 \"extract\" mode.  The method is selected from variable
   "Extract current entity into file (maybe).
 It decodes current entity to call internal or external method as
 \"extract\" mode.  The method is selected from variable
-`mime/content-decoding-condition'."
+`mime-acting-condition'."
   (interactive)
   (interactive)
-  (mime-view-play-current-entity "extract")
+  (mime-preview-play-current-entity "extract")
   )
 
   )
 
-(defun mime-view-print-current-entity ()
+(defun mime-preview-print-current-entity ()
   "Print current entity (maybe).
 It decodes current entity to call internal or external method as
 \"print\" mode.  The method is selected from variable
   "Print current entity (maybe).
 It decodes current entity to call internal or external method as
 \"print\" mode.  The method is selected from variable
-`mime/content-decoding-condition'."
+`mime-acting-condition'."
   (interactive)
   (interactive)
-  (mime-view-play-current-entity "print")
+  (mime-preview-play-current-entity "print")
   )
 
   )
 
-(defun mime-view-follow-current-entity ()
+
+;;; @@ following
+;;;
+
+(defun mime-preview-original-major-mode ()
+  "Return major-mode of original buffer.
+If a current buffer has mime-mother-buffer, return original major-mode
+of the mother-buffer."
+  (if mime-mother-buffer
+      (save-excursion
+       (set-buffer mime-mother-buffer)
+       (mime-preview-original-major-mode)
+       )
+    mime-preview-original-major-mode))
+
+(defun mime-preview-follow-current-entity ()
   "Write follow message to current entity.
 It calls following-method selected from variable
 `mime-view-following-method-alist'."
   (interactive)
   "Write follow message to current entity.
 It calls following-method selected from variable
 `mime-view-following-method-alist'."
   (interactive)
-  (let ((root-cinfo (get-text-property (point-min) 'mime-view-cinfo))
+  (let ((root-cinfo (get-text-property (point-min) 'mime-view-entity-info))
        cinfo)
        cinfo)
-    (while (null (setq cinfo (get-text-property (point) 'mime-view-cinfo)))
+    (while (null (setq cinfo
+                      (get-text-property (point) 'mime-view-entity-info)))
       (backward-char)
       )
       (backward-char)
       )
-    (let* ((p-beg (previous-single-property-change (point) 'mime-view-cinfo))
+    (let* ((p-beg
+           (previous-single-property-change (point) 'mime-view-entity-info))
           p-end
           p-end
-          (rcnum (mime::content-info/rcnum cinfo))
-          (len (length rcnum))
+          (entity-node-id (mime-entity-info-node-id cinfo))
+          (len (length entity-node-id))
           )
       (cond ((null p-beg)
             (setq p-beg
                   (if (eq (next-single-property-change (point-min)
           )
       (cond ((null p-beg)
             (setq p-beg
                   (if (eq (next-single-property-change (point-min)
-                                                       'mime-view-cinfo)
+                                                       'mime-view-entity-info)
                           (point))
                       (point)
                     (point-min)))
             )
                           (point))
                       (point)
                     (point-min)))
             )
-           ((eq (next-single-property-change p-beg 'mime-view-cinfo)
+           ((eq (next-single-property-change p-beg 'mime-view-entity-info)
                 (point))
             (setq p-beg (point))
             ))
                 (point))
             (setq p-beg (point))
             ))
-      (setq p-end (next-single-property-change p-beg 'mime-view-cinfo))
+      (setq p-end (next-single-property-change p-beg 'mime-view-entity-info))
       (cond ((null p-end)
             (setq p-end (point-max))
             )
       (cond ((null p-end)
             (setq p-end (point-max))
             )
-           ((null rcnum)
+           ((null entity-node-id)
             (setq p-end (point-max))
             )
            (t
             (setq p-end (point-max))
             )
            (t
@@ -914,12 +953,13 @@ It calls following-method selected from variable
                 (let (e)
                   (while (setq e
                                (next-single-property-change
                 (let (e)
                   (while (setq e
                                (next-single-property-change
-                                (point) 'mime-view-cinfo))
+                                (point) 'mime-view-entity-info))
                     (goto-char e)
                     (goto-char e)
-                    (let ((rc (mime::content-info/rcnum
+                    (let ((rc (mime-entity-info-node-id
                                (get-text-property (point)
                                (get-text-property (point)
-                                                  'mime-view-cinfo))))
-                      (or (equal rcnum (nthcdr (- (length rc) len) rc))
+                                                  'mime-view-entity-info))))
+                      (or (equal entity-node-id
+                                 (nthcdr (- (length rc) len) rc))
                           (throw 'tag nil)
                           ))
                     (setq p-end e)
                           (throw 'tag nil)
                           ))
                     (setq p-end e)
@@ -927,8 +967,9 @@ It calls following-method selected from variable
                 (setq p-end (point-max))
                 ))
             ))
                 (setq p-end (point-max))
                 ))
             ))
-      (let* ((mode (mime-preview/get-original-major-mode))
-            (new-name (format "%s-%s" (buffer-name) (reverse rcnum)))
+      (let* ((mode (mime-preview-original-major-mode))
+            (new-name
+             (format "%s-%s" (buffer-name) (reverse entity-node-id)))
             new-buf
             (the-buf (current-buffer))
             (a-buf mime-raw-buffer)
             new-buf
             (the-buf (current-buffer))
             (a-buf mime-raw-buffer)
@@ -938,7 +979,7 @@ It calls following-method selected from variable
          (erase-buffer)
          (insert-buffer-substring the-buf p-beg p-end)
          (goto-char (point-min))
          (erase-buffer)
          (insert-buffer-substring the-buf p-beg p-end)
          (goto-char (point-min))
-         (if (mime-view-header-visible-p rcnum root-cinfo)
+         (if (mime-view-header-visible-p entity-node-id root-cinfo)
              (delete-region (goto-char (point-min))
                             (if (re-search-forward "^$" nil t)
                                 (match-end 0)
              (delete-region (goto-char (point-min))
                             (if (re-search-forward "^$" nil t)
                                 (match-end 0)
@@ -947,30 +988,35 @@ It calls following-method selected from variable
          (goto-char (point-min))
          (insert "\n")
          (goto-char (point-min))
          (goto-char (point-min))
          (insert "\n")
          (goto-char (point-min))
-         (let ((rcnum (mime::content-info/rcnum cinfo)) ci str)
+         (let ((entity-node-id (mime-entity-info-node-id cinfo)) ci str)
            (while (progn
            (while (progn
-                    (setq str
-                          (save-excursion
-                            (set-buffer a-buf)
-                            (setq ci (mime-article/rcnum-to-cinfo rcnum))
-                            (save-restriction
-                              (narrow-to-region
-                               (mime::content-info/point-min ci)
-                               (mime::content-info/point-max ci)
-                               )
-                              (std11-header-string-except
-                               (concat "^"
-                                       (apply (function regexp-or) fields)
-                                       ":") ""))))
-                    (if (string= (mime::content-info/type ci)
-                                 "message/rfc822")
+                    (setq
+                     str
+                     (save-excursion
+                       (set-buffer a-buf)
+                       (setq
+                        ci
+                        (mime-raw-entity-node-id-to-entity-info
+                         entity-node-id))
+                       (save-restriction
+                         (narrow-to-region
+                          (mime-entity-info-point-min ci)
+                          (mime-entity-info-point-max ci)
+                          )
+                         (std11-header-string-except
+                          (concat "^"
+                                  (apply (function regexp-or) fields)
+                                  ":") ""))))
+                    (if (and
+                         (eq (mime-entity-info-media-type ci) 'message)
+                         (eq (mime-entity-info-media-subtype ci) 'rfc822))
                         nil
                       (if str
                           (insert str)
                         )
                         nil
                       (if str
                           (insert str)
                         )
-                      rcnum))
+                      entity-node-id))
              (setq fields (std11-collect-field-names)
              (setq fields (std11-collect-field-names)
-                   rcnum (cdr rcnum))
+                   entity-node-id (cdr entity-node-id))
              )
            )
          (let ((rest mime-view-following-required-fields-list))
              )
            )
          (let ((rest mime-view-following-required-fields-list))
@@ -1003,70 +1049,80 @@ It calls following-method selected from variable
            ))
        ))))
 
            ))
        ))))
 
-(defun mime-view-display-x-face ()
+
+;;; @@ X-Face
+;;;
+
+(defun mime-preview-display-x-face ()
   (interactive)
   (save-window-excursion
     (set-buffer mime-raw-buffer)
     (mime-view-x-face-function)
     ))
 
   (interactive)
   (save-window-excursion
     (set-buffer mime-raw-buffer)
     (mime-view-x-face-function)
     ))
 
-(defun mime-view-move-to-upper ()
+
+;;; @@ moving
+;;;
+
+(defun mime-preview-move-to-upper ()
   "Move to upper entity.
   "Move to upper entity.
-If there is no upper entity, call function `mime-view-quit'."
+If there is no upper entity, call function `mime-preview-quit'."
   (interactive)
   (let (cinfo)
   (interactive)
   (let (cinfo)
-    (while (null (setq cinfo (get-text-property (point) 'mime-view-cinfo)))
+    (while (null (setq cinfo
+                      (get-text-property (point) 'mime-view-entity-info)))
       (backward-char)
       )
       (backward-char)
       )
-    (let ((r (mime-article/rcnum-to-cinfo
-             (cdr (mime::content-info/rcnum cinfo))
-             (get-text-property 1 'mime-view-cinfo)))
+    (let ((r (mime-raw-entity-node-id-to-entity-info
+             (cdr (mime-entity-info-node-id cinfo))
+             (get-text-property 1 'mime-view-entity-info)))
          point)
       (catch 'tag
        (while (setq point (previous-single-property-change
          point)
       (catch 'tag
        (while (setq point (previous-single-property-change
-                           (point) 'mime-view-cinfo))
+                           (point) 'mime-view-entity-info))
          (goto-char point)
          (goto-char point)
-         (if (eq r (get-text-property (point) 'mime-view-cinfo))
+         (if (eq r (get-text-property (point) 'mime-view-entity-info))
              (throw 'tag t)
            )
          )
              (throw 'tag t)
            )
          )
-       (mime-view-quit)
+       (mime-preview-quit)
        ))))
 
        ))))
 
-(defun mime-view-move-to-previous ()
+(defun mime-preview-move-to-previous ()
   "Move to previous entity.
 If there is no previous entity, it calls function registered in
 variable `mime-view-over-to-previous-method-alist'."
   (interactive)
   "Move to previous entity.
 If there is no previous entity, it calls function registered in
 variable `mime-view-over-to-previous-method-alist'."
   (interactive)
-  (while (null (get-text-property (point) 'mime-view-cinfo))
+  (while (null (get-text-property (point) 'mime-view-entity-info))
     (backward-char)
     )
     (backward-char)
     )
-  (let ((point (previous-single-property-change (point) 'mime-view-cinfo)))
+  (let ((point
+        (previous-single-property-change (point) 'mime-view-entity-info)))
     (if point
        (goto-char point)
     (if point
        (goto-char point)
-      (let ((f (assq mime-view-original-major-mode
+      (let ((f (assq mime-preview-original-major-mode
                     mime-view-over-to-previous-method-alist)))
        (if f
            (funcall (cdr f))
          ))
       )))
 
                     mime-view-over-to-previous-method-alist)))
        (if f
            (funcall (cdr f))
          ))
       )))
 
-(defun mime-view-move-to-next ()
+(defun mime-preview-move-to-next ()
   "Move to next entity.
 If there is no previous entity, it calls function registered in
 variable `mime-view-over-to-next-method-alist'."
   (interactive)
   "Move to next entity.
 If there is no previous entity, it calls function registered in
 variable `mime-view-over-to-next-method-alist'."
   (interactive)
-  (let ((point (next-single-property-change (point) 'mime-view-cinfo)))
+  (let ((point (next-single-property-change (point) 'mime-view-entity-info)))
     (if point
        (goto-char point)
     (if point
        (goto-char point)
-      (let ((f (assq mime-view-original-major-mode
+      (let ((f (assq mime-preview-original-major-mode
                     mime-view-over-to-next-method-alist)))
        (if f
            (funcall (cdr f))
          ))
       )))
 
                     mime-view-over-to-next-method-alist)))
        (if f
            (funcall (cdr f))
          ))
       )))
 
-(defun mime-view-scroll-up-entity (&optional h)
+(defun mime-preview-scroll-up-entity (&optional h)
   "Scroll up current entity.
 If reached to (point-max), it calls function registered in variable
 `mime-view-over-to-next-method-alist'."
   "Scroll up current entity.
 If reached to (point-max), it calls function registered in variable
 `mime-view-over-to-next-method-alist'."
@@ -1075,13 +1131,13 @@ If reached to (point-max), it calls function registered in variable
       (setq h (1- (window-height)))
       )
   (if (= (point) (point-max))
       (setq h (1- (window-height)))
       )
   (if (= (point) (point-max))
-      (let ((f (assq mime-view-original-major-mode
+      (let ((f (assq mime-preview-original-major-mode
                      mime-view-over-to-next-method-alist)))
         (if f
             (funcall (cdr f))
           ))
     (let ((point
                      mime-view-over-to-next-method-alist)))
         (if f
             (funcall (cdr f))
           ))
     (let ((point
-          (or (next-single-property-change (point) 'mime-view-cinfo)
+          (or (next-single-property-change (point) 'mime-view-entity-info)
               (point-max))))
       (forward-line h)
       (if (> (point) point)
               (point-max))))
       (forward-line h)
       (if (> (point) point)
@@ -1089,7 +1145,7 @@ If reached to (point-max), it calls function registered in variable
         )
       )))
 
         )
       )))
 
-(defun mime-view-scroll-down-entity (&optional h)
+(defun mime-preview-scroll-down-entity (&optional h)
   "Scroll down current entity.
 If reached to (point-min), it calls function registered in variable
 `mime-view-over-to-previous-method-alist'."
   "Scroll down current entity.
 If reached to (point-min), it calls function registered in variable
 `mime-view-over-to-previous-method-alist'."
@@ -1098,7 +1154,7 @@ If reached to (point-min), it calls function registered in variable
       (setq h (1- (window-height)))
       )
   (if (= (point) (point-min))
       (setq h (1- (window-height)))
       )
   (if (= (point) (point-min))
-      (let ((f (assq mime-view-original-major-mode
+      (let ((f (assq mime-preview-original-major-mode
                      mime-view-over-to-previous-method-alist)))
         (if f
             (funcall (cdr f))
                      mime-view-over-to-previous-method-alist)))
         (if f
             (funcall (cdr f))
@@ -1109,7 +1165,7 @@ If reached to (point-min), it calls function registered in variable
          (while (> (point) 1)
            (if (setq point
                      (previous-single-property-change (point)
          (while (> (point) 1)
            (if (setq point
                      (previous-single-property-change (point)
-                                                      'mime-view-cinfo))
+                                                      'mime-view-entity-info))
                (throw 'tag t)
              )
            (backward-char)
                (throw 'tag t)
              )
            (backward-char)
@@ -1121,39 +1177,43 @@ If reached to (point-min), it calls function registered in variable
           (goto-char point)
         ))))
 
           (goto-char point)
         ))))
 
-(defun mime-view-next-line-content ()
+(defun mime-preview-next-line-entity ()
   (interactive)
   (interactive)
-  (mime-view-scroll-up-entity 1)
+  (mime-preview-scroll-up-entity 1)
   )
 
   )
 
-(defun mime-view-previous-line-content ()
+(defun mime-preview-previous-line-entity ()
   (interactive)
   (interactive)
-  (mime-view-scroll-down-entity 1)
+  (mime-preview-scroll-down-entity 1)
   )
 
   )
 
-(defun mime-view-quit ()
-  "Quit from MIME-View buffer.
+
+;;; @@ quitting
+;;;
+
+(defun mime-preview-quit ()
+  "Quit from MIME-preview buffer.
 It calls function registered in variable
 It calls function registered in variable
-`mime-view-quitting-method-alist'."
+`mime-preview-quitting-method-alist'."
   (interactive)
   (interactive)
-  (let ((r (assq mime-view-original-major-mode
-                mime-view-quitting-method-alist)))
+  (let ((r (assq mime-preview-original-major-mode
+                mime-preview-quitting-method-alist)))
     (if r
        (funcall (cdr r))
       )))
 
     (if r
        (funcall (cdr r))
       )))
 
-(defun mime-view-show-summary ()
+(defun mime-preview-show-summary ()
   "Show summary.
 It calls function registered in variable
 `mime-view-show-summary-method'."
   (interactive)
   "Show summary.
 It calls function registered in variable
 `mime-view-show-summary-method'."
   (interactive)
-  (let ((r (assq mime-view-original-major-mode
+  (let ((r (assq mime-preview-original-major-mode
                 mime-view-show-summary-method)))
     (if r
        (funcall (cdr r))
       )))
 
                 mime-view-show-summary-method)))
     (if r
        (funcall (cdr r))
       )))
 
-(defun mime-view-kill-buffer ()
+(defun mime-preview-kill-buffer ()
   (interactive)
   (kill-buffer (current-buffer))
   )
   (interactive)
   (kill-buffer (current-buffer))
   )