* wl-vars.el (wl-message-use-header-narrowing): New user option.
[elisp/wanderlust.git] / wl / wl-summary.el
index 741d99f..476b6f7 100644 (file)
@@ -60,6 +60,7 @@
 (defvar dragdrop-drop-functions)
 (defvar scrollbar-height)
 (defvar mail-reply-buffer)
+(defvar elmo-global-flags)
 
 (defvar wl-summary-buffer-name "Summary")
 (defvar wl-summary-mode-map nil)
@@ -90,7 +91,7 @@
 (defvar wl-summary-buffer-temp-mark-column nil)
 (defvar wl-summary-buffer-persistent-mark-column nil)
 
-(defvar wl-summary-buffer-unsync-mark-number-list nil)
+(defvar wl-summary-buffer-persistent-mark-version 0)
 
 (defvar wl-summary-buffer-persistent nil)
 (defvar wl-summary-buffer-thread-nodes nil)
 (defvar wl-summary-buffer-line-format nil)
 (defvar wl-summary-buffer-mode-line-formatter nil)
 (defvar wl-summary-buffer-mode-line nil)
+(defvar wl-summary-buffer-display-mime-mode 'mime)
+(defvar wl-summary-buffer-display-header-mode 'partial)
 
 (defvar wl-thread-indent-level-internal nil)
 (defvar wl-thread-have-younger-brother-str-internal nil)
 (make-variable-buffer-local 'wl-summary-buffer-number-column)
 (make-variable-buffer-local 'wl-summary-buffer-temp-mark-column)
 (make-variable-buffer-local 'wl-summary-buffer-persistent-mark-column)
-(make-variable-buffer-local 'wl-summary-buffer-unsync-mark-number-list)
+(make-variable-buffer-local 'wl-summary-buffer-persistent-mark-version)
 (make-variable-buffer-local 'wl-summary-buffer-persistent)
 (make-variable-buffer-local 'wl-summary-buffer-thread-nodes)
 (make-variable-buffer-local 'wl-summary-buffer-prev-refile-destination)
 (make-variable-buffer-local 'wl-summary-buffer-line-format)
 (make-variable-buffer-local 'wl-summary-buffer-mode-line-formatter)
 (make-variable-buffer-local 'wl-summary-buffer-mode-line)
+(make-variable-buffer-local 'wl-summary-buffer-display-mime-mode)
+(make-variable-buffer-local 'wl-summary-buffer-display-header-mode)
 
 (defvar wl-datevec)
 (defvar wl-thr-indent-string)
@@ -250,7 +255,7 @@ See also variable `wl-use-petname'."
          string)
     string))
 
-(defvar wl-summary-sort-specs '(number date subject from list-info))
+(defvar wl-summary-sort-specs '(number date subject from list-info size))
 (defvar wl-summary-default-sort-spec 'date)
 
 (defvar wl-summary-mode-menu-spec
@@ -278,6 +283,7 @@ See also variable `wl-use-petname'."
     ["Stick" wl-summary-stick t]
     ("Sort"
      ["By Number" wl-summary-sort-by-number t]
+     ["By Size" wl-summary-sort-by-size t]
      ["By Date" wl-summary-sort-by-date t]
      ["By From" wl-summary-sort-by-from t]
      ["By Subject" wl-summary-sort-by-subject t]
@@ -285,16 +291,16 @@ See also variable `wl-use-petname'."
     "----"
     ("Message Operation"
      ["Mark as read"    wl-summary-mark-as-read t]
-     ["Mark as important" wl-summary-mark-as-important t]
+     ["Set flags"      wl-summary-set-flags t]
      ["Mark as unread"   wl-summary-mark-as-unread t]
      ["Mark as answered" wl-summary-mark-as-answered t]
      ["Set dispose mark" wl-summary-dispose t]
      ["Set refile mark" wl-summary-refile t]
      ["Set copy mark"   wl-summary-copy t]
      ["Set resend mark" wl-summary-resend t]
-     ["Prefetch"        wl-summary-prefetch t]
+     ["Prefetch"       wl-summary-prefetch t]
      ["Set target mark" wl-summary-target-mark t]
-     ["Unmark"          wl-summary-unmark t]
+     ["Unmark"         wl-summary-unmark t]
      ["Save"           wl-summary-save t]
      ["Cancel posted news" wl-summary-cancel-message t]
      ["Supersedes message" wl-summary-supersedes-message t]
@@ -307,7 +313,7 @@ See also variable `wl-use-petname'."
      ["Open all"     wl-thread-open-all (eq wl-summary-buffer-view 'thread)]
      ["Close all"    wl-thread-close-all (eq wl-summary-buffer-view 'thread)]
      ["Mark as read" wl-thread-mark-as-read (eq wl-summary-buffer-view 'thread)]
-     ["Mark as important"      wl-thread-mark-as-important (eq wl-summary-buffer-view 'thread)]
+     ["Set flags"      wl-thread-set-flags (eq wl-summary-buffer-view 'thread)]
      ["Mark as unread"         wl-thread-mark-as-unread (eq wl-summary-buffer-view 'thread)]
      ["Mark as answered"       wl-thread-mark-as-answered (eq wl-summary-buffer-view 'thread)]
      ["Set delete mark"  wl-thread-delete (eq wl-summary-buffer-view 'thread)]
@@ -320,7 +326,7 @@ See also variable `wl-use-petname'."
      ["Execute"      wl-thread-exec (eq wl-summary-buffer-view 'thread)])
     ("Region Operation"
      ["Mark as read" wl-summary-mark-as-read-region t]
-     ["Mark as important" wl-summary-mark-as-important-region t]
+     ["Set flags" wl-summary-set-flags-region t]
      ["Mark as unread" wl-summary-mark-as-unread-region t]
      ["Mark as answered" wl-summary-mark-as-answered-region t]
      ["Set dispose mark" wl-summary-dispose-region t]
@@ -333,7 +339,7 @@ See also variable `wl-use-petname'."
      ["Execute" wl-summary-exec-region t])
     ("Mark Operation"
      ["Mark as read" wl-summary-target-mark-mark-as-read t]
-     ["Mark as important" wl-summary-target-mark-mark-as-important t]
+     ["Set flags" wl-summary-target-mark-set-flags t]
      ["Mark as unread" wl-summary-target-mark-mark-as-unread t]
      ["Set delete mark" wl-summary-target-mark-delete t]
      ["Set refile mark" wl-summary-target-mark-refile t]
@@ -379,19 +385,30 @@ See also variable `wl-use-petname'."
     (define-key wl-summary-mode-map [mouse-5] 'wl-summary-next)
     (define-key wl-summary-mode-map [S-mouse-4] 'wl-summary-up)
     (define-key wl-summary-mode-map [S-mouse-5] 'wl-summary-down)
+    ;; For Meadow2
+    (define-key wl-summary-mode-map [mouse-wheel1]
+      'wl-summary-wheel-dispatcher)
+    (define-key wl-summary-mode-map [S-mouse-wheel1]
+      'wl-summary-wheel-dispatcher)
     (define-key wl-summary-mode-map [mouse-2] 'wl-summary-click)))
 
 (if wl-summary-mode-map
     ()
-  (setq wl-summary-mode-map (make-sparse-keymap))
+  (setq wl-summary-mode-map (make-keymap))
+  (suppress-keymap wl-summary-mode-map)
+  (substitute-key-definition 'kill-buffer
+                            'wl-summary-mimic-kill-buffer
+                            wl-summary-mode-map
+                            global-map)
+  ;; basic commands
   (define-key wl-summary-mode-map " "    'wl-summary-read)
   (define-key wl-summary-mode-map "."    'wl-summary-redisplay)
   (define-key wl-summary-mode-map "<"    'wl-summary-display-top)
   (define-key wl-summary-mode-map ">"    'wl-summary-display-bottom)
   (define-key wl-summary-mode-map "\177" 'wl-summary-prev-page)
   (define-key wl-summary-mode-map [backspace] 'wl-summary-prev-page)
-  (define-key wl-summary-mode-map "\r"   'wl-summary-next-line-content)
-  (define-key wl-summary-mode-map "\C-m" 'wl-summary-next-line-content)
+  (define-key wl-summary-mode-map "\r"   'wl-summary-enter-handler)
+  (define-key wl-summary-mode-map "\C-m" 'wl-summary-enter-handler)
   (define-key wl-summary-mode-map "/"    'wl-thread-open-close)
   (define-key wl-summary-mode-map "["    'wl-thread-open-all)
   (define-key wl-summary-mode-map "]"    'wl-thread-close-all)
@@ -408,6 +425,8 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "\eE"  'wl-summary-resend-bounced-mail)
   (define-key wl-summary-mode-map "f"    'wl-summary-forward)
   (define-key wl-summary-mode-map "$"    'wl-summary-mark-as-important)
+  (define-key wl-summary-mode-map "F"    'wl-summary-set-flags)
+  (define-key wl-summary-mode-map "\M-k"  'wl-summary-toggle-persistent-mark)
   (define-key wl-summary-mode-map "&"    'wl-summary-mark-as-answered)
   (define-key wl-summary-mode-map "@"    'wl-summary-edit-addresses)
 
@@ -423,8 +442,8 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "\C-c\C-a" 'wl-addrmgr)
   (define-key wl-summary-mode-map "\C-c\C-p" 'wl-summary-previous-buffer)
   (define-key wl-summary-mode-map "\C-c\C-n" 'wl-summary-next-buffer)
-  (define-key wl-summary-mode-map "H"    'wl-summary-redisplay-all-header)
-  (define-key wl-summary-mode-map "M"    'wl-summary-redisplay-no-mime)
+  (define-key wl-summary-mode-map "H"    'wl-summary-toggle-all-header)
+  (define-key wl-summary-mode-map "M"    'wl-summary-toggle-mime)
   (define-key wl-summary-mode-map "B"    'wl-summary-burst)
   (define-key wl-summary-mode-map "Z"    'wl-status-update)
   (define-key wl-summary-mode-map "#"    'wl-summary-print-message)
@@ -487,6 +506,7 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "tu" 'wl-thread-unmark)
   (define-key wl-summary-mode-map "t!" 'wl-thread-mark-as-unread)
   (define-key wl-summary-mode-map "t$" 'wl-thread-mark-as-important)
+  (define-key wl-summary-mode-map "tF" 'wl-thread-set-flags)
   (define-key wl-summary-mode-map "t&" 'wl-thread-mark-as-answered)
   (define-key wl-summary-mode-map "ty" 'wl-thread-save)
   (define-key wl-summary-mode-map "ts" 'wl-thread-set-parent)
@@ -506,7 +526,9 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "my"   'wl-summary-target-mark-save)
   (define-key wl-summary-mode-map "mR"   'wl-summary-target-mark-mark-as-read)
   (define-key wl-summary-mode-map "m!"   'wl-summary-target-mark-mark-as-unread)
+  (define-key wl-summary-mode-map "m&"   'wl-summary-target-mark-mark-as-answered)
   (define-key wl-summary-mode-map "m$"   'wl-summary-target-mark-mark-as-important)
+  (define-key wl-summary-mode-map "mF"   'wl-summary-target-mark-set-flags)
   (define-key wl-summary-mode-map "mU"   'wl-summary-target-mark-uudecode)
   (define-key wl-summary-mode-map "ma"   'wl-summary-target-mark-all)
   (define-key wl-summary-mode-map "mt"   'wl-summary-target-mark-thread)
@@ -532,6 +554,7 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "ru"   'wl-summary-unmark-region)
   (define-key wl-summary-mode-map "r!"   'wl-summary-mark-as-unread-region)
   (define-key wl-summary-mode-map "r$"   'wl-summary-mark-as-important-region)
+  (define-key wl-summary-mode-map "rF"   'wl-summary-set-flags-region)
   (define-key wl-summary-mode-map "r&"   'wl-summary-mark-as-answered-region)
   (define-key wl-summary-mode-map "ry"   'wl-summary-save-region)
 
@@ -560,6 +583,15 @@ See also variable `wl-use-petname'."
    "Menu used in Summary mode."
    wl-summary-mode-menu-spec))
 
+(defun wl-summary-mimic-kill-buffer (buffer)
+  "Kill the current (Summary) buffer with query."
+  (interactive "bKill buffer: ")
+  (if (or (not buffer)
+         (string-equal buffer "")
+         (string-equal buffer (buffer-name)))
+      (wl-summary-exit 'force-exit)
+    (kill-buffer buffer)))
+
 (defsubst wl-summary-message-visible-p (number)
   "Return non-nil if the message with NUMBER is visible."
   (or (eq wl-summary-buffer-view 'sequence)
@@ -574,31 +606,98 @@ See also variable `wl-use-petname'."
            (end (condition-case nil
                     (window-end win t) ; old emacsen doesn't support 2nd arg.
                   (error (window-end win))))
-           number flags
-           wl-summary-highlight)
+           number flags)
        (save-excursion
          (goto-char beg)
          (while (and (< (point) end) (not (eobp)))
-           (when (null (get-text-property (point) 'face))
-             (setq number (wl-summary-message-number)
-                   flags (elmo-message-flags wl-summary-buffer-elmo-folder
-                                             number))
-             (setq wl-summary-highlight nil)
-             (wl-summary-update-persistent-mark number flags)
-             (setq wl-summary-highlight t)
+           (when (or (null (get-text-property (point) 'face))
+                     (wl-summary-persistent-mark-invalid-p))
+             (setq number (wl-summary-message-number))
+             (when number
+               (setq flags (elmo-message-flags wl-summary-buffer-elmo-folder
+                                               number)))
+             (let (wl-summary-highlight)
+               (wl-summary-update-persistent-mark number flags))
              (wl-highlight-summary-current-line number flags))
            (forward-line 1)))))
     (set-buffer-modified-p nil)))
 
 (defun wl-summary-window-scroll-functions ()
-  (cond ((and wl-summary-lazy-highlight
+  (cond ((and wl-summary-highlight
+             wl-summary-lazy-highlight
              wl-summary-lazy-update-mark)
         (list 'wl-summary-update-mark-and-highlight-window))
-       (wl-summary-lazy-highlight
+       ((and wl-summary-highlight
+             wl-summary-lazy-highlight)
         (list 'wl-highlight-summary-window))
        (wl-summary-lazy-update-mark
         (list 'wl-summary-update-mark-window))))
 
+(defun wl-summary-after-resize-function (frame)
+  "Called from `window-size-change-functions'."
+  (save-excursion
+    (save-selected-window
+      (select-frame frame)
+      (walk-windows
+       (lambda (window)
+        (set-buffer (window-buffer window))
+        (when (eq major-mode 'wl-summary-mode)
+          (run-hook-with-args 'wl-summary-buffer-window-scroll-functions
+                              window)))
+       'nomini frame))))
+
+;; Handler of event from elmo-folder
+(defun wl-summary-update-persistent-mark-on-event (buffer numbers)
+  (save-excursion
+    (set-buffer buffer)
+    (if wl-summary-lazy-update-mark
+       (let ((window-list (get-buffer-window-list (current-buffer) 'nomini t))
+             invalidate)
+         (dolist (number numbers)
+           (when (wl-summary-message-visible-p number)
+             (if (catch 'visible
+                   (let ((window-list window-list)
+                         win)
+                     (while (setq win (car window-list))
+                       (when (wl-summary-jump-to-msg number
+                                                     (window-start win)
+                                                     (window-end win))
+                         (throw 'visible t))
+                       (setq window-list (cdr window-list)))))
+                 (wl-summary-update-persistent-mark number)
+               (setq invalidate t))))
+         (when invalidate
+           (wl-summary-invalidate-persistent-mark)
+           (dolist (win window-list)
+             (wl-summary-validate-persistent-mark
+              (window-start win)
+              (window-end win)))))
+      (dolist (number numbers)
+       (when (and (wl-summary-message-visible-p number)
+                  (wl-summary-jump-to-msg number))
+         (wl-summary-update-persistent-mark number))))))
+
+(defun wl-summary-buffer-attach ()
+  (when wl-summary-buffer-elmo-folder
+    (elmo-connect-signal
+     wl-summary-buffer-elmo-folder
+     'flag-changed
+     (current-buffer)
+     (elmo-define-signal-handler (buffer folder numbers)
+       (wl-summary-update-persistent-mark-on-event buffer numbers)))
+    (elmo-connect-signal
+     wl-summary-buffer-elmo-folder
+     'cache-changed
+     (current-buffer)
+     (elmo-define-signal-handler (buffer folder number)
+       (wl-summary-update-persistent-mark-on-event buffer (list number))))))
+
+(defun wl-summary-buffer-detach ()
+  (when (and (eq major-mode 'wl-summary-mode)
+            wl-summary-buffer-elmo-folder)
+    (elmo-disconnect-signal 'flag-changed (current-buffer))
+    (elmo-disconnect-signal 'cache-changed (current-buffer))))
+
 (defun wl-status-update ()
   (interactive)
   (wl-address-init))
@@ -619,12 +718,14 @@ See also variable `wl-use-petname'."
       (wl-summary-redisplay)))
 
 (defun wl-summary-count-unread ()
-  (let ((lst (elmo-folder-count-flags wl-summary-buffer-elmo-folder)))
-    (if (eq major-mode 'wl-summary-mode)
-       (setq wl-summary-buffer-new-count (car lst)
-             wl-summary-buffer-unread-count (nth 1 lst)
-             wl-summary-buffer-answered-count (nth 2 lst)))
-    lst))
+  (let ((flag-count (elmo-folder-count-flags wl-summary-buffer-elmo-folder)))
+    (setq wl-summary-buffer-new-count
+         (or (cdr (assq 'new flag-count)) 0)
+         wl-summary-buffer-unread-count
+         (or (cdr (assq 'unread flag-count)) 0)
+         wl-summary-buffer-answered-count
+         (or (cdr (assq 'answered flag-count)) 0))
+    flag-count))
 
 (defun wl-summary-message-string (&optional use-cache)
   "Return full body string of current message.
@@ -633,21 +734,18 @@ If optional USE-CACHE is non-nil, use cache if exists."
        (folder wl-summary-buffer-elmo-folder))
     (if (null number)
        (message "No message.")
-      (elmo-set-work-buf
-       (elmo-message-fetch folder
-                          number
-                          (elmo-make-fetch-strategy
-                           'entire
-                           use-cache ; use cache
-                           nil ; save cache (should `t'?)
-                           (and
-                            use-cache
-                            (elmo-file-cache-get-path
-                             (elmo-message-field folder number 'message-id))))
-                          nil
-                          (current-buffer)
-                          'unread)
-       (buffer-string)))))
+      (elmo-message-fetch-string folder
+                                number
+                                (elmo-make-fetch-strategy
+                                 'entire
+                                 use-cache ; use cache
+                                 nil ; save cache (should `t'?)
+                                 (and
+                                  use-cache
+                                  (elmo-file-cache-get-path
+                                   (elmo-message-field folder number
+                                                       'message-id))))
+                                'unread))))
 
 (defun wl-summary-reedit (&optional arg)
   "Re-edit current message.
@@ -655,7 +753,7 @@ If ARG is non-nil, Supersedes message"
   (interactive "P")
   (wl-summary-toggle-disp-msg 'off)
   (cond
-   ((not (wl-summary-message-number))
+   ((null (wl-summary-message-number))
     (message "No message."))
    (arg
     (wl-summary-supersedes-message))
@@ -665,7 +763,7 @@ If ARG is non-nil, Supersedes message"
        (mail-position-on-field "Newsgroups")
       (mail-position-on-field "To")))
    (t
-    (wl-draft-edit-string (wl-summary-message-string)))))
+    (wl-draft-edit-string (wl-summary-message-string 'maybe)))))
 
 (defun wl-summary-resend-bounced-mail ()
   "Re-mail the current message.
@@ -712,7 +810,7 @@ you."
        (dummy-temp (char-to-string 200))
        ;; bind only for the check.
        (wl-summary-new-uncached-mark (char-to-string 201))
-       (wl-summary-flag-priority-list '(new))     ; ditto.
+       (wl-summary-persistent-mark-priority-list '(new))     ; ditto.
        (lang wl-summary-buffer-weekday-name-lang)
        wl-summary-highlight
        temp persistent)
@@ -744,6 +842,7 @@ you."
          wl-summary-buffer-persistent-mark-column persistent)))
 
 (defun wl-summary-buffer-set-folder (folder)
+  (wl-summary-buffer-detach)
   (if (stringp folder)
       (setq folder (wl-folder-get-elmo-folder folder)))
   (setq wl-summary-buffer-elmo-folder folder)
@@ -780,6 +879,7 @@ you."
   (setq wl-summary-buffer-persistent
        (wl-folder-persistent-p (elmo-folder-name-internal folder)))
   (elmo-folder-set-persistent-internal folder wl-summary-buffer-persistent)
+  (wl-summary-buffer-attach)
   ;; process duplicates.
   (elmo-folder-set-process-duplicates-internal
    folder (cdr (elmo-string-matched-assoc
@@ -822,6 +922,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
 ;;;(setq default-directory (or wl-tmp-dir (expand-file-name "~/")))
   (setq buffer-read-only t)
   (setq truncate-lines t)
+  (when (boundp 'show-trailing-whitespace)
+    (setq show-trailing-whitespace nil))
 ;;;(make-local-variable 'tab-width)
 ;;;(setq tab-width 1)
   (buffer-disable-undo (current-buffer))
@@ -835,12 +937,23 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
     (let ((hook (if wl-on-xemacs 'pre-idle-hook 'window-scroll-functions)))
       (make-local-hook hook)
       (dolist (function wl-summary-buffer-window-scroll-functions)
-       (add-hook hook function nil t))))
+       (add-hook hook function nil t)))
+    (add-hook 'window-size-change-functions
+             #'wl-summary-after-resize-function))
+  (dolist (hook '(change-major-mode-hook kill-buffer-hook))
+    (make-local-hook hook)
+    (add-hook hook #'wl-summary-buffer-detach nil t))
   ;; This hook may contain the function `wl-setup-summary' for reasons
   ;; of system internal to accord facilities for the Emacs variants.
   (run-hooks 'wl-summary-mode-hook))
 
 ;;;
+(defun wl-summary-overview-entity-compare-by-size (x y)
+   "Compare entity X and Y by size."
+   (< (elmo-message-entity-field x 'size)
+      (elmo-message-entity-field y 'size)))
+
+
 (defun wl-summary-overview-entity-compare-by-date (x y)
   "Compare entity X and Y by date."
   (condition-case nil
@@ -860,12 +973,10 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
 (defun wl-summary-overview-entity-compare-by-from (x y)
   "Compare entity X and Y by from."
   (string<
-   (wl-address-header-extract-address
-    (or (elmo-message-entity-field x 'from t)
-       wl-summary-no-from-message))
-   (wl-address-header-extract-address
-    (or (elmo-message-entity-field y 'from t)
-       wl-summary-no-from-message))))
+   (or (elmo-message-entity-field x 'from t)
+       wl-summary-no-from-message)
+   (or (elmo-message-entity-field y 'from t)
+       wl-summary-no-from-message)))
 
 (defun wl-summary-overview-entity-compare-by-subject (x y)
   "Compare entity X and Y by subject."
@@ -919,29 +1030,36 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
       (string< (or (car list-info-x) "")
               (or (car list-info-y) "")))))
 
-(defun wl-summary-sort-by-date ()
-  (interactive)
-  (wl-summary-rescan "date"))
-(defun wl-summary-sort-by-number ()
-  (interactive)
-  (wl-summary-rescan "number"))
-(defun wl-summary-sort-by-subject ()
-  (interactive)
-  (wl-summary-rescan "subject"))
-(defun wl-summary-sort-by-from ()
-  (interactive)
-  (wl-summary-rescan "from"))
-(defun wl-summary-sort-by-list-info ()
-  (interactive)
-  (wl-summary-rescan "list-info"))
+(defun wl-summary-sort-by-date (reverse)
+  "Sort summary lines into the order by message date; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "date" reverse))
+(defun wl-summary-sort-by-number (reverse)
+  "Sort summary lines into the order by message number; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "number" reverse))
+(defun wl-summary-sort-by-subject (reverse)
+  "Sort summary lines into the order by subject; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "subject" reverse))
+(defun wl-summary-sort-by-from (reverse)
+  "Sort summary lines into the order by from; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "from" reverse))
+(defun wl-summary-sort-by-list-info (reverse)
+  "Sort summary lines into the order by mailing list info; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "list-info" reverse))
+(defun wl-summary-sort-by-size (reverse)
+  "Sort summary lines into the order by message size; argument means descending order."
+  (interactive "P")
+  (wl-summary-rescan "size" reverse))
 
-(defun wl-summary-rescan (&optional sort-by disable-killed disable-thread)
+(defun wl-summary-rescan (&optional sort-by reverse disable-killed disable-thread)
   "Rescan current folder without updating."
   (interactive)
   (let ((elmo-mime-charset wl-summary-buffer-mime-charset)
-       i percent num
-       gc-message entity
-       curp
+       gc-message                      ; for XEmacs
        (inhibit-read-only t)
        (buffer-read-only nil)
        (numbers (elmo-folder-list-messages wl-summary-buffer-elmo-folder
@@ -952,36 +1070,41 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
         (and disable-thread wl-summary-search-parent-by-subject-regexp))
        (wl-summary-divide-thread-when-subject-changed
         (and disable-thread wl-summary-divide-thread-when-subject-changed))
+       (predicate (and sort-by
+                       (intern (format "wl-summary-overview-entity-compare-by-%s"
+                                       sort-by))))
+       (sort-label (if reverse "Reverse sorting" "Sorting"))
+       (i 0)
+       num
        expunged)
     (erase-buffer)
     (message "Re-scanning...")
-    (setq i 0)
     (when sort-by
-      (message "Sorting by %s..." sort-by)
+      (message "%s by %s..." sort-label sort-by)
       (setq numbers
            (sort numbers
                  (lambda (x y)
                    (funcall
-                    (intern (format "wl-summary-overview-entity-compare-by-%s"
-                                    sort-by))
+                    predicate
                     (elmo-message-entity wl-summary-buffer-elmo-folder x)
                     (elmo-message-entity wl-summary-buffer-elmo-folder y)))))
-      (message "Sorting by %s...done" sort-by))
+      (if reverse (setq numbers (nreverse numbers)))
+      (message "%s by %s...done" sort-label sort-by))
     (setq num (length numbers))
     (setq wl-thread-entity-hashtb (elmo-make-hash (* num 2))
          wl-thread-entity-list nil
          wl-thread-entities nil
          wl-summary-scored nil
          wl-summary-buffer-number-list nil
-         wl-summary-buffer-unsync-mark-number-list nil
+         wl-summary-buffer-persistent-mark-version 0
          wl-summary-buffer-target-mark-list nil
          wl-summary-buffer-temp-mark-list nil
          wl-summary-delayed-update nil)
     (elmo-kill-buffer wl-summary-search-buf-name)
     (while numbers
-      (setq entity (elmo-message-entity wl-summary-buffer-elmo-folder
-                                       (car numbers)))
-      (wl-summary-insert-message entity
+      (wl-summary-insert-message (elmo-message-entity
+                                 wl-summary-buffer-elmo-folder
+                                 (car numbers))
                                 wl-summary-buffer-elmo-folder
                                 nil)
       (setq numbers (cdr numbers))
@@ -1071,18 +1194,25 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
 (defun wl-summary-thread-modified-p ()
   wl-summary-buffer-thread-modified)
 
-(defsubst wl-summary-cleanup-temp-marks (&optional sticky)
+(defun wl-summary-exec-with-confirmation (&optional message)
   (when wl-summary-buffer-temp-mark-list
-    (if (y-or-n-p (format "Execute remaining marks in %s? "
-                         (wl-summary-buffer-folder-name)))
+    (if (y-or-n-p (or message
+                     (format "Execute marks in %s? "
+                             (wl-summary-buffer-folder-name))))
        (progn
          (wl-summary-exec)
          (if wl-summary-buffer-temp-mark-list
              (error "Some execution was failed")))
       ;; temp-mark-list is remained.
-      (message "")))
-  (wl-summary-delete-all-temp-marks 'no-msg)
-  (setq wl-summary-scored nil))
+      (message ""))))
+
+(defun wl-summary-cleanup-temp-marks ()
+  (when wl-summary-buffer-temp-mark-list
+    (wl-summary-exec-with-confirmation
+     (format "Execute marks in %s? (answer \"n\" to discard them) "
+            (wl-summary-buffer-folder-name)))
+    (wl-summary-delete-all-temp-marks 'no-msg)
+    (setq wl-summary-scored nil)))
 
 ;; a subroutine for wl-summary-exit/wl-save-status
 ;; Note that folder is not commited here.
@@ -1122,7 +1252,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
     (if wl-summary-buffer-exit-function
        (funcall wl-summary-buffer-exit-function)
       (if (or force-exit (not sticky))
-         (wl-summary-cleanup-temp-marks sticky))
+         (wl-summary-cleanup-temp-marks))
       (unwind-protect
          ;; save summary status
          (progn
@@ -1216,6 +1346,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
                                     nil
                                   wl-use-scoring)))
             (wl-summary-rescan nil
+                               nil
                                (string-match "noscore" range)
                                (string-match "thread" range))
             (and msg (wl-summary-jump-to-msg msg))))
@@ -1255,7 +1386,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
       (setq fields (cdr fields)))
     (setq candidates (elmo-uniq-list candidates))
     (elmo-set-work-buf
-     (elmo-set-buffer-multibyte default-enable-multibyte-characters)
+     (set-buffer-multibyte default-enable-multibyte-characters)
      (mapcar (function
              (lambda (x)
                (setq components (std11-extract-address-components x))
@@ -1365,6 +1496,31 @@ If ARG is non-nil, checking is omitted."
   (wl-summary-prefetch-region-no-mark (point-min) (point-max)
                                      wl-summary-incorporate-marks))
 
+(defun wl-summary-force-prefetch ()
+  "All uncached messages are cached."
+  (interactive)
+  (unless (elmo-folder-local-p wl-summary-buffer-elmo-folder)
+    (let ((targets (elmo-folder-list-flagged wl-summary-buffer-elmo-folder
+                                            'uncached 'in-msgdb))
+         (count 0)
+         wl-prefetch-confirm
+         wl-prefetch-threshold
+         (elmo-inhibit-display-retrieval-progress t)
+         length msg)
+      (save-excursion
+       (goto-char (point-min))
+       (setq length (length targets))
+       (dolist (target targets)
+         (when (if (not (wl-thread-entity-parent-invisible-p
+                         (wl-thread-get-entity target)))
+                   (progn
+                     (wl-summary-jump-to-msg target)
+                     (wl-summary-prefetch-msg
+                      (wl-summary-message-number)))
+                 (wl-summary-prefetch-msg target))
+           (message "Retrieving... %d/%d" (incf count) length)))
+       (message "Retrieved %d/%d message(s)" count length)))))
+
 (defun wl-summary-prefetch-msg (number &optional arg)
   "Prefetch message and return non-nil value. If skipped, return nil."
   ;; prefetching procedure.
@@ -1413,21 +1569,11 @@ If ARG is non-nil, checking is omitted."
            (save-excursion
              (save-match-data
                ;; online
-               (if (or arg (not file-cached))
-                   (elmo-message-encache
-                    wl-summary-buffer-elmo-folder
-                    number))
+               (when (or arg (not file-cached))
+                 (elmo-message-encache wl-summary-buffer-elmo-folder
+                                       number))
                (elmo-message-set-cached wl-summary-buffer-elmo-folder
-                                        number t)
-               (when (and (wl-summary-jump-to-msg number)
-                          (wl-summary-update-persistent-mark))
-                 (sit-for 0)
-                 (wl-summary-count-unread)
-                 (wl-summary-update-modeline)
-                 (wl-folder-update-unread
-                  (wl-summary-buffer-folder-name)
-                  (+ wl-summary-buffer-unread-count
-                     wl-summary-buffer-new-count))))
+                                        number t))
              t)
          nil)))))
 
@@ -1504,113 +1650,83 @@ If ARG is non-nil, checking is omitted."
 (defun wl-summary-delete-all-target-marks ()
   (wl-summary-delete-marks-on-buffer wl-summary-buffer-target-mark-list))
 
-(defun wl-summary-mark-as-read-region (beg end)
-  (interactive "r")
+(defun wl-summary-number-list-from-region (beg end)
   (save-excursion
     (save-restriction
       (wl-summary-narrow-to-region beg end)
       (goto-char (point-min))
-      (if (eq wl-summary-buffer-view 'thread)
-         (let (number-list)
+      (let (number-list)
+       (if (eq wl-summary-buffer-view 'thread)
            (while (not (eobp))
              (let* ((number (wl-summary-message-number))
                     (entity (wl-thread-get-entity number)))
-               (if (wl-thread-entity-get-opened entity)
-                   (setq number-list (append number-list (list number)))
-                 (setq number-list
-                       (append number-list
-                               (wl-thread-get-children-msgs number))))
+               (setq number-list
+                     (nconc number-list
+                            (if (wl-thread-entity-get-opened entity)
+                                (list number)
+                              (wl-thread-get-children-msgs number))))
                (forward-line 1)))
-           (wl-summary-mark-as-read number-list))
-       (let (number-list)
          (while (not (eobp))
            (setq number-list
-                 (append number-list (list (wl-summary-message-number))))
-           (forward-line 1))
-         (wl-summary-mark-as-read number-list))))))
+                 (nconc number-list (list (wl-summary-message-number))))
+           (forward-line 1)))
+       number-list))))
 
-(defun wl-summary-mark-as-unread-region (beg end)
+(defun wl-summary-mark-as-read-region (beg end)
   (interactive "r")
-  (save-excursion
-    (save-restriction
-      (wl-summary-narrow-to-region beg end)
-      (goto-char (point-min))
-      (if (eq wl-summary-buffer-view 'thread)
-         (let (number-list)
-           (while (not (eobp))
-             (let* ((number (wl-summary-message-number))
-                    (entity (wl-thread-get-entity number)))
-               (if (wl-thread-entity-get-opened entity)
-                   (setq number-list (append number-list (list number)))
-                 (setq number-list
-                       (append number-list
-                               (wl-thread-get-children-msgs number))))
-               (forward-line 1)))
-           (wl-summary-mark-as-unread number-list))
-       (let (number-list)
-         (while (not (eobp))
-           (setq number-list
-                 (append number-list (list (wl-summary-message-number))))
-           (forward-line 1))
-         (wl-summary-mark-as-unread number-list))))))
+  (let ((number-list (wl-summary-number-list-from-region beg end)))
+    (if (null number-list)
+       (message "No message.")
+      (wl-summary-mark-as-read number-list))))
 
-(defun wl-summary-mark-as-important-region (beg end)
+(defun wl-summary-mark-as-unread-region (beg end)
   (interactive "r")
-  (save-excursion
-    (save-restriction
-      (wl-summary-narrow-to-region beg end)
-      (goto-char (point-min))
-      (let ((inverse (elmo-message-flagged-p wl-summary-buffer-elmo-folder
-                                            (wl-summary-message-number)
-                                            'important)))
-       (if (eq wl-summary-buffer-view 'thread)
-           (while (not (eobp))
-             (let* ((number (wl-summary-message-number))
-                    (entity (wl-thread-get-entity number))
-                    children)
-               (if (wl-thread-entity-get-opened entity)
-                   ;; opened...mark line.
-                   ;; Crossposts are not processed
-                   (wl-summary-mark-as-important-internal inverse)
-                 ;; closed
-                 (wl-summary-mark-as-important-internal
-                  inverse
-                  (wl-thread-get-children-msgs number)))
-               (forward-line 1)))
-         (while (not (eobp))
-           (wl-summary-mark-as-important-internal inverse)
-           (forward-line 1))))))
-  (wl-summary-count-unread)
-  (wl-summary-update-modeline))
+  (let ((number-list (wl-summary-number-list-from-region beg end)))
+    (if (null number-list)
+       (message "No message.")
+      (wl-summary-mark-as-unread number-list))))
 
-(defun wl-summary-mark-as-answered-region (beg end)
-  (interactive "r")
-  (save-excursion
-    (save-restriction
-      (wl-summary-narrow-to-region beg end)
-      (goto-char (point-min))
-      (let ((inverse (elmo-message-flagged-p wl-summary-buffer-elmo-folder
-                                            (wl-summary-message-number)
-                                            'answered)))
-       (if (eq wl-summary-buffer-view 'thread)
-           (while (not (eobp))
-             (let* ((number (wl-summary-message-number))
-                    (entity (wl-thread-get-entity number))
-                    children)
-               (if (wl-thread-entity-get-opened entity)
-                   ;; opened...mark line.
-                   ;; Crossposts are not processed
-                   (wl-summary-mark-as-answered-internal inverse)
-                 ;; closed
-                 (wl-summary-mark-as-answered-internal
-                  inverse
-                  (wl-thread-get-children-msgs number)))
-               (forward-line 1)))
-         (while (not (eobp))
-           (wl-summary-mark-as-answered-internal inverse)
-           (forward-line 1))))))
-  (wl-summary-count-unread)
-  (wl-summary-update-modeline))
+(defun wl-summary-set-flags-region (beg end &optional remove)
+  (interactive "r\nP")
+  (let ((number-list (wl-summary-number-list-from-region beg end)))
+    (if (null number-list)
+       (message "No message.")
+      (wl-summary-set-flags-internal number-list nil nil remove)
+      (wl-summary-count-unread)
+      (wl-summary-update-modeline))))
+
+(defun wl-summary-mark-as-answered-region (beg end &optional remove)
+  (interactive "r\nP")
+  (let ((number-list (wl-summary-number-list-from-region beg end))
+       (remove (or remove
+                   (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                                           (save-excursion
+                                             (goto-char beg)
+                                             (wl-summary-message-number))
+                                           'answered))))
+    (if (null number-list)
+       (message "No message.")
+      (wl-summary-set-persistent-mark-internal remove 'answered
+                                              number-list
+                                              nil nil (interactive-p))
+      (wl-summary-count-unread)
+      (wl-summary-update-modeline))))
+
+(defun wl-summary-mark-as-important-region (beg end &optional remove)
+  (interactive "r\nP")
+  (let ((number-list (wl-summary-number-list-from-region beg end))
+       (remove (or remove
+                   (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                                           (save-excursion
+                                             (goto-char beg)
+                                             (wl-summary-message-number))
+                                           'important))))
+    (if (null number-list)
+       (message "No message.")
+      (wl-summary-set-persistent-mark-internal remove 'important number-list
+                                              nil nil (interactive-p))
+      (wl-summary-count-unread)
+      (wl-summary-update-modeline))))
 
 (defun wl-summary-mark-as-read-all ()
   (interactive)
@@ -1619,15 +1735,10 @@ If ARG is non-nil, checking is omitted."
       (let ((folder wl-summary-buffer-elmo-folder)
            (cur-buf (current-buffer)))
        (message "Setting all msgs as read...")
-       (elmo-folder-set-flag
+       (elmo-folder-unset-flag
         folder
         (elmo-folder-list-flagged folder 'unread 'in-msgdb)
-        'read)
-       (save-excursion
-         (goto-char (point-min))
-         (while (not (eobp))
-           (wl-summary-update-persistent-mark)
-           (forward-line 1)))
+        'unread)
        (wl-folder-update-unread (wl-summary-buffer-folder-name) 0)
        (setq wl-summary-buffer-unread-count 0)
        (setq wl-summary-buffer-new-count    0)
@@ -1642,7 +1753,7 @@ If ARG is non-nil, checking is omitted."
           number)
       (setq number (wl-summary-message-number))
       (elmo-message-set-cached folder number nil)
-      (when (wl-summary-update-persistent-mark)
+      (ignore-errors
        (elmo-file-cache-delete
         (elmo-file-cache-get-path
          (elmo-message-field wl-summary-buffer-elmo-folder
@@ -1662,7 +1773,6 @@ If ARG is non-nil, checking is omitted."
        (setq msgid (elmo-message-field folder number 'message-id))
        (elmo-message-set-cached folder number
                                 (elmo-file-cache-exists-p msgid))
-       (wl-summary-update-persistent-mark)
        (forward-line 1))
       (wl-summary-count-unread)
       (wl-summary-update-modeline)
@@ -1716,12 +1826,7 @@ If ARG is non-nil, checking is omitted."
     (goto-char beg)
     (while (and (< (point) end) (not (eobp)))
       (when (or (not check)
-               (let ((number (wl-summary-message-number)))
-                 (when (memq number wl-summary-buffer-unsync-mark-number-list)
-                   (setq wl-summary-buffer-unsync-mark-number-list
-                         (delq number
-                               wl-summary-buffer-unsync-mark-number-list))
-                   t)))
+               (wl-summary-persistent-mark-invalid-p))
        (wl-summary-update-persistent-mark))
       (forward-line 1))))
 
@@ -1741,76 +1846,51 @@ This function is defined for `window-scroll-functions'"
       (apply 'wl-summary-insert-thread args)
     (apply 'wl-summary-insert-sequential args)))
 
-(defun wl-summary-sort ()
-  (interactive)
+(defun wl-summary-sort (reverse)
+  "Sort summary lines into the selected order; argument means descending order."
+  (interactive "P")
   (wl-summary-rescan
    (completing-read
-    (format "Sort by (%s): " (symbol-name wl-summary-default-sort-spec))
+    (format "%s by (%s): "
+           (if reverse "Reverse sort" "Sort")
+           (symbol-name wl-summary-default-sort-spec))
     (mapcar (lambda (spec)
              (list (symbol-name spec)))
            wl-summary-sort-specs)
-    nil t nil nil (symbol-name wl-summary-default-sort-spec))))
+    nil t nil nil (symbol-name wl-summary-default-sort-spec))
+   reverse))
+
+(defun wl-summary-get-available-flags (&optional include-specials)
+  (let ((flags (elmo-uniq-list
+               (append elmo-global-flags
+                       (copy-sequence elmo-preserved-flags))
+               #'delq)))
+    (if include-specials
+       flags
+      (delq 'new (delq 'cached flags)))))
 
 (defun wl-summary-sync-marks ()
   "Update persistent marks in summary."
   (interactive)
-  (let (diff diffs mes)
-    ;; synchronize marks.
-    (when (not (eq (elmo-folder-type-internal
-                   wl-summary-buffer-elmo-folder)
-                  'internal))
-      (message "Updating marks...")
-      (setq diff (elmo-list-diff (elmo-folder-list-flagged
-                                 wl-summary-buffer-elmo-folder
-                                 'important)
-                                (elmo-folder-list-flagged
-                                 wl-summary-buffer-elmo-folder
-                                 'important 'in-msgdb)))
-      (setq diffs (cadr diff)) ; important-deletes
-      (setq mes (format "Updated (-%d" (length diffs)))
-      (while diffs
-       (wl-summary-mark-as-unimportant (car diffs) 'no-server)
-       (setq diffs (cdr diffs)))
-      (setq diffs (car diff)) ; important-appends
-      (setq mes (concat mes (format "/+%d) important," (length diffs))))
-      (while diffs
-       (wl-summary-mark-as-important (car diffs) 'no-server)
-       (setq diffs (cdr diffs)))
-
-      (setq diff (elmo-list-diff (elmo-folder-list-flagged
-                                 wl-summary-buffer-elmo-folder
-                                 'answered)
-                                (elmo-folder-list-flagged
-                                 wl-summary-buffer-elmo-folder
-                                 'answered 'in-msgdb)))
-      (setq diffs (cadr diff))
-      (setq mes (concat mes (format "(-%d" (length diffs))))
-      (while diffs
-       (wl-summary-mark-as-unanswered (car diffs) 'no-modeline)
-       (setq diffs (cdr diffs)))
-      (setq diffs (car diff)) ; unread-appends
-      (setq mes (concat mes (format "/+%d) answered mark(s)," (length diffs))))
-      (while diffs
-       (wl-summary-mark-as-answered (car diffs) 'no-modeline)
-       (setq diffs (cdr diffs)))
-
+  (let ((mes "Updated ")
+       diff diffs)
+    (message "Updating marks...")
+    (dolist (flag (wl-summary-get-available-flags))
       (setq diff (elmo-list-diff (elmo-folder-list-flagged
                                  wl-summary-buffer-elmo-folder
-                                 'unread)
+                                 flag)
                                 (elmo-folder-list-flagged
                                  wl-summary-buffer-elmo-folder
-                                 'unread 'in-msgdb)))
+                                 flag 'in-msgdb)))
       (setq diffs (cadr diff))
-      (setq mes (concat mes (format "(-%d" (length diffs))))
-      (while diffs
-       (wl-summary-mark-as-read (car diffs) 'no-folder 'no-modeline)
-       (setq diffs (cdr diffs)))
-      (setq diffs (car diff)) ; unread-appends
-      (setq mes (concat mes (format "/+%d) unread mark(s)." (length diffs))))
-      (while diffs
-       (wl-summary-mark-as-unread (car diffs) 'no-folder 'no-modeline)
-       (setq diffs (cdr diffs)))
-      (if (interactive-p) (message "%s" mes)))))
+      (setq mes (concat mes (format "-%d" (length diffs))))
+      (when diffs
+       (wl-summary-unset-persistent-mark flag diffs 'no-modeline 'no-server))
+      (setq diffs (car diff)
+           mes (concat mes (format "/+%d %s " (length diffs) flag)))
+      (when diffs
+       (wl-summary-set-persistent-mark flag diffs 'no-modeline 'no-server)))
+    (if (interactive-p) (message "%s" mes))))
 
 (defun wl-summary-sync-update (&optional unset-cursor
                                         disable-killed
@@ -1822,12 +1902,8 @@ This function is defined for `window-scroll-functions'"
         (elmo-mime-charset wl-summary-buffer-mime-charset)
         (inhibit-read-only t)
         (buffer-read-only nil)
-        gc-message
-        overview
-        curp num i diff
-        append-list delete-list crossed
-        update-thread update-top-list
-        expunged mes entity)
+        gc-message                     ; for XEmacs
+        crossed expunged mes)
     (unwind-protect
        (progn
          (unless wl-summary-buffer-elmo-folder
@@ -1843,7 +1919,13 @@ This function is defined for `window-scroll-functions'"
                                                 sync-all
                                                 no-check))
          (if crossed
-             (progn
+             (let ((wl-summary-highlight
+                    (and wl-summary-highlight
+                         (not wl-summary-lazy-highlight)))
+                   append-list delete-list
+                   update-thread update-top-list
+                   num diff entity
+                   (i 0))
                ;; Setup sync-all
                (if sync-all (wl-summary-sync-all-init))
                (setq diff (elmo-list-diff (elmo-folder-list-messages
@@ -1861,10 +1943,8 @@ This function is defined for `window-scroll-functions'"
                (when (and wl-summary-lazy-highlight
                           wl-summary-lazy-update-mark)
                  (let (buffer-read-only)
-                   (put-text-property (point-min) (point-max) 'face nil))
-                 (run-hooks 'wl-summary-buffer-window-scroll-functions))
+                   (put-text-property (point-min) (point-max) 'face nil)))
                (setq num (length append-list))
-               (setq i 0)
                (setq wl-summary-delayed-update nil)
                (elmo-kill-buffer wl-summary-search-buf-name)
                (dolist (number append-list)
@@ -1926,7 +2006,7 @@ This function is defined for `window-scroll-functions'"
                                                    folder))
                        (format "Updated (-%d/+%d) message(s)"
                                (length delete-list) num))))
-           (setq mes "Quit updating.")))
+           (setq mes "Quit updating")))
       ;; synchronize marks.
       (if (and crossed wl-summary-auto-sync-marks)
          (wl-summary-sync-marks))
@@ -1953,8 +2033,7 @@ This function is defined for `window-scroll-functions'"
       (wl-folder-set-folder-updated
        (elmo-folder-name-internal folder)
        (list 0
-            (let ((lst (wl-summary-count-unread)))
-              (+ (car lst) (nth 1 lst)))
+            (or (cdr (assq 'unread (wl-summary-count-unread))) 0)
             (elmo-folder-length folder)))
       (wl-summary-update-modeline)
       ;;
@@ -1964,16 +2043,17 @@ This function is defined for `window-scroll-functions'"
            (progn
              (goto-char (point-max))
              (forward-line -1))
-         (if (and wl-summary-highlight
-                  (not wl-summary-lazy-highlight)
-                  (not (get-text-property (point) 'face)))
-             (save-excursion
-               (forward-line (- 0
-                                (or
-                                 wl-summary-partial-highlight-above-lines
-                                 wl-summary-highlight-partial-threshold)))
-               (wl-highlight-summary (point) (point-max))))))
+         (when (and wl-summary-highlight
+                    (not wl-summary-lazy-highlight)
+                    (not (get-text-property (point) 'face)))
+           (save-excursion
+             (forward-line (- 0
+                              (or
+                               wl-summary-partial-highlight-above-lines
+                               wl-summary-highlight-partial-threshold)))
+             (wl-highlight-summary (point) (point-max))))))
       (wl-delete-all-overlays)
+      (run-hooks 'wl-summary-buffer-window-scroll-functions)
       (set-buffer-modified-p nil)
       (if mes (message "%s" mes)))))
 
@@ -2001,18 +2081,27 @@ This function is defined for `window-scroll-functions'"
   (setq wl-summary-buffer-mode-line
        (funcall wl-summary-buffer-mode-line-formatter)))
 
-(defun wl-summary-jump-to-msg (&optional number)
-  (interactive)
+(defun wl-summary-jump-to-msg (&optional number beg end)
+  (interactive "NJump to Number:")
   (let ((num (or number
                 (string-to-int
-                 (read-from-minibuffer "Jump to Message(No.): ")))))
-    (setq num (int-to-string num))
-    (beginning-of-line)
-    (if (or (and (re-search-forward (concat "\r" num "[^0-9]") nil t)
-                (progn (backward-char 1) t))
-           (re-search-backward (concat "\r" num "[^0-9]") nil t))
-       (progn (beginning-of-line) t)
-      nil)))
+                 (read-from-minibuffer "Jump to Message(No.): "))))
+       (pos (point))
+       regexp)
+    (setq regexp (concat "\r" (int-to-string num) "[^0-9]"))
+    (if (and beg end (or (< pos beg) (< end pos)))
+       (progn
+         (goto-char beg)
+         (if (re-search-forward regexp end t)
+             (progn (backward-char 1) (beginning-of-line) t)
+           (goto-char pos)
+           nil))
+      (beginning-of-line)
+      (if (or (and (re-search-forward regexp end t)
+                  (progn (backward-char 1) t))
+             (re-search-backward regexp beg t))
+         (progn (beginning-of-line) t)
+       nil))))
 
 (defun wl-summary-highlight-msgs (msgs)
   (save-excursion
@@ -2084,25 +2173,20 @@ If ARG, without confirm."
       (setq wl-summary-buffer-view 'thread))
     (wl-summary-update-modeline)
     (force-mode-line-update)
-    (wl-summary-rescan)))
+    (wl-summary-rescan nil nil nil t)))
 
 (defun wl-summary-load-file-object (filename)
   "Load lisp object from dir."
-  (save-excursion
-    (let ((tmp-buffer (get-buffer-create " *wl-summary-load-file-object*"))
-         insert-file-contents-pre-hook   ; To avoid autoconv-xmas...
+  (with-temp-buffer
+    (let (insert-file-contents-pre-hook        ; To avoid autoconv-xmas...
          insert-file-contents-post-hook
          ret-val)
       (if (not (file-readable-p filename))
          ()
-       (set-buffer tmp-buffer)
        (as-binary-input-file (insert-file-contents filename))
-       (setq ret-val
-             (condition-case nil
-                 (read (current-buffer))
-               (error (error "Reading failed")))))
-      (kill-buffer tmp-buffer)
-      ret-val)))
+       (condition-case nil
+           (read (current-buffer))
+         (error (error "Reading failed")))))))
 
 (defun wl-summary-goto-folder (&optional arg)
   (interactive "P")
@@ -2165,7 +2249,7 @@ If ARG, without confirm."
                   wl-summary-buffer-message-modified
                   wl-summary-buffer-thread-modified
                   wl-summary-buffer-number-list
-                  wl-summary-buffer-unsync-mark-number-list
+                  wl-summary-buffer-persistent-mark-version
                   wl-summary-buffer-folder-name
                   wl-summary-buffer-line-formatter)
                 (and (eq wl-summary-buffer-view 'thread)
@@ -2231,9 +2315,8 @@ If ARG, without confirm."
 
 (defun wl-summary-auto-select-msg-p (unread-msg)
   (and unread-msg
-       (not (elmo-message-flagged-p wl-summary-buffer-elmo-folder
-                                   unread-msg
-                                   'important))))
+       (not (elmo-message-has-global-flag-p
+            wl-summary-buffer-elmo-folder unread-msg))))
 
 (defsubst wl-summary-open-folder (folder)
   ;; Select folder
@@ -2265,7 +2348,7 @@ If ARG, without confirm."
       (setq wl-summary-last-visited-folder (wl-summary-buffer-folder-name))
       (run-hooks 'wl-summary-exit-pre-hook)
       (if (or force-exit (not (wl-summary-sticky-p)))
-         (wl-summary-cleanup-temp-marks (wl-summary-sticky-p)))
+         (wl-summary-cleanup-temp-marks))
       (wl-summary-save-view)
       (elmo-folder-commit wl-summary-buffer-elmo-folder)
       (if (and (wl-summary-sticky-p) force-exit)
@@ -2288,9 +2371,14 @@ If ARG, without confirm."
          (unless (eq major-mode 'wl-summary-mode)
            (wl-summary-mode))
          (wl-summary-buffer-set-folder folder)
+         (setq wl-summary-buffer-display-mime-mode
+               (if (wl-summary-no-mime-p wl-summary-buffer-elmo-folder)
+                   'as-is
+                 'mime))
          (setq wl-summary-buffer-disp-msg nil)
          (setq wl-summary-buffer-last-displayed-msg nil)
          (setq wl-summary-buffer-current-msg nil)
+         (setq wl-summary-buffer-persistent-mark-version 0)
          (let ((inhibit-read-only t)
                (buffer-read-only nil))
            (erase-buffer)
@@ -2301,7 +2389,7 @@ If ARG, without confirm."
                       (view (expand-file-name wl-summary-view-file dir)))
                  (when (file-exists-p cache)
                    (insert-file-contents-as-binary cache)
-                   (elmo-set-buffer-multibyte
+                   (set-buffer-multibyte
                     default-enable-multibyte-characters)
                    (decode-mime-charset-region
                     (point-min)(point-max)
@@ -2328,8 +2416,6 @@ If ARG, without confirm."
            (wl-summary-update-modeline)))
       (unless (eq wl-summary-buffer-view 'thread)
        (wl-summary-make-number-list))
-      (setq wl-summary-buffer-unsync-mark-number-list
-           (copy-sequence wl-summary-buffer-number-list))
       (when (and wl-summary-cache-use
                 (or (and wl-summary-check-line-format
                          (wl-summary-line-format-changed-p))
@@ -2355,7 +2441,7 @@ If ARG, without confirm."
               ((or (eq scan-type 'force-update)
                    (eq scan-type 'update))
                (setq mes (wl-summary-sync-force-update
-                          'unset-cursor 'no-check)))))
+                          'unset-cursor)))))
          (if interactive
              (switch-to-buffer buf)
            (set-buffer buf))
@@ -2372,15 +2458,15 @@ If ARG, without confirm."
                (cond ((and wl-auto-select-first
                            (wl-summary-auto-select-msg-p unreadp))
                       ;; wl-auto-select-first is non-nil and
-                      ;; unreadp is non-nil but not important
+                      ;; unreadp is non-nil but not flagged
                       (setq retval 'disp-msg))
                      ((and wl-auto-prefetch-first
                            (wl-summary-auto-select-msg-p unreadp))
                       ;; wl-auto-select-first is non-nil and
-                      ;; unreadp is non-nil but not important
+                      ;; unreadp is non-nil but not flagged
                       (setq retval 'prefetch-msg))
                      ((not (wl-summary-auto-select-msg-p unreadp))
-                      ;; unreadp is nil or important
+                      ;; unreadp is nil or flagged
                       (setq retval 'more-next))))
            (goto-char (point-max))
            (if (elmo-folder-plugged-p folder)
@@ -2407,7 +2493,8 @@ If ARG, without confirm."
              (wl-message-buffer-prefetch
               folder
               (wl-summary-message-number)
-              wl-message-buffer-prefetch-depth
+              (min (or wl-message-buffer-prefetch-depth 0)
+                   (1- wl-message-buffer-cache-size))
               (current-buffer)
               wl-summary-buffer-mime-charset))
          (if mes (message "%s" mes))
@@ -2426,6 +2513,11 @@ If ARG, without confirm."
     (when (and wl-summary-buffer-window-scroll-functions
               wl-on-xemacs)
       (sit-for 0))
+    (when (or (eq t wl-summary-force-prefetch-folder-list)
+             (wl-string-match-member
+              (elmo-folder-name-internal wl-summary-buffer-elmo-folder)
+              wl-summary-force-prefetch-folder-list))
+      (wl-summary-force-prefetch))
     (unwind-protect
        (run-hooks 'wl-summary-prepared-hook)
       (set-buffer-modified-p nil))
@@ -2493,7 +2585,7 @@ If ARG, without confirm."
 (defun wl-summary-default-subject-filter (subject)
   (setq subject (elmo-replace-in-string subject "[ \t]*\\(re\\|was\\)[:>]" ""))
   (setq subject (elmo-replace-in-string subject "[ \t]" ""))
-  (elmo-replace-in-string subject "^\\[.*\\]" ""))
+  (elmo-replace-in-string subject "^\\[[^]]*\\]" ""))
 
 (defun wl-summary-subject-equal (subject1 subject2)
   (string= (funcall wl-summary-subject-filter-function subject1)
@@ -2515,7 +2607,7 @@ If ARG, without confirm."
     (make-local-variable 'wl-summary-alike-hashtb)
     (setq wl-summary-alike-hashtb (elmo-make-hash (* (length numbers) 2)))
     (when mime-decode
-      (elmo-set-buffer-multibyte default-enable-multibyte-characters))
+      (set-buffer-multibyte default-enable-multibyte-characters))
     (while (setq ov (elmo-message-entity folder (pop numbers)))
       (setq this (funcall func ov))
       (and this (setq this (std11-unfold-string this)))
@@ -2709,14 +2801,20 @@ If ARG, without confirm."
     i))
 
 (defun wl-summary-pick (&optional from-list delete-marks)
-  (interactive)
+  (interactive "i\nP")
   (save-excursion
-    (let* ((condition (car (elmo-parse-search-condition
-                           (elmo-read-search-condition
+    (let* ((messages (or from-list
+                        (elmo-folder-list-messages
+                         wl-summary-buffer-elmo-folder
+                         'visible
+                         'in-msgdb)
+                        (error "No messages")))
+          (condition (car (elmo-parse-search-condition
+                           (wl-read-search-condition
                             wl-summary-pick-field-default))))
           (result (elmo-folder-search wl-summary-buffer-elmo-folder
                                       condition
-                                      from-list))
+                                      messages))
           num)
       (if delete-marks
          (let ((mlist wl-summary-buffer-target-mark-list))
@@ -2753,7 +2851,7 @@ If ARG, exit virtual folder."
   (if arg
       (wl-summary-unvirtual)
     (wl-summary-goto-folder-subr (concat "/"
-                                        (elmo-read-search-condition
+                                        (wl-read-search-condition
                                          wl-summary-pick-field-default)
                                         "/"
                                         (wl-summary-buffer-folder-name))
@@ -2789,34 +2887,70 @@ If ARG, exit virtual folder."
        (wl-summary-get-score-mark number)
        " ")))
 
+(defun wl-summary-persistent-mark-invalid-p ()
+  (not
+   (equal
+    ;; mey be nil.
+    (get-text-property (point) 'wl-summary-persistent-mark-version)
+    wl-summary-buffer-persistent-mark-version)))
+
+(defun wl-summary-validate-persistent-mark (beg end)
+  (let ((inhibit-read-only t)
+       (buffer-read-only nil))
+    (put-text-property beg end
+                      'wl-summary-persistent-mark-version
+                      wl-summary-buffer-persistent-mark-version)
+    (set-buffer-modified-p nil)))
+
+(defun wl-summary-validate-persistent-mark-string (string)
+  (put-text-property 0 (length string)
+                    'wl-summary-persistent-mark-version
+                    wl-summary-buffer-persistent-mark-version
+                    string))
+
+(defun wl-summary-invalidate-persistent-mark ()
+  (setq wl-summary-buffer-persistent-mark-version
+       (1+ wl-summary-buffer-persistent-mark-version)))
+
 (defsubst wl-summary-persistent-mark-string (folder flags cached)
   "Return the persistent mark string.
 The mark is decided according to the FOLDER, FLAGS and CACHED."
-  (let ((priorities wl-summary-flag-priority-list)
+  (let ((priorities wl-summary-persistent-mark-priority-list)
        mark)
     (while (and (null mark) priorities)
-      (when (memq (car priorities) flags)
-       (setq mark
-             (case (car priorities)
-               (new
-                (if cached
-                    wl-summary-new-cached-mark
-                  wl-summary-new-uncached-mark))
-               (important
-                wl-summary-important-mark)
-               (answered
-                (if cached
-                    wl-summary-answered-cached-mark
-                  wl-summary-answered-uncached-mark))
-               (unread
-                (if cached
-                    wl-summary-unread-cached-mark
-                  wl-summary-unread-uncached-mark)))))
+      (if (and (eq (car priorities) 'flag)
+              (elmo-get-global-flags flags 'ignore-preserved))
+         (let ((specs wl-summary-flag-alist)
+               spec)
+           (while (setq spec (car specs))
+             (if (memq (car spec) flags)
+                 (setq mark (or (nth 2 spec) wl-summary-flag-mark)
+                       specs nil)
+               (setq specs (cdr specs))))
+           (unless mark
+             (setq mark wl-summary-flag-mark)))
+       (when (memq (car priorities) flags)
+         (setq mark
+               (let ((var
+                      (intern
+                       (if cached
+                           (format
+                            "wl-summary-%s-cached-mark" (car priorities))
+                         (format
+                          "wl-summary-%s-uncached-mark" (car priorities))))))
+                 (if (and (boundp var)
+                          (symbol-value var))
+                     (symbol-value var)
+                   (if cached
+                       (downcase (substring (symbol-name (car priorities))
+                                            0 1))
+                     (upcase (substring (symbol-name (car priorities))
+                                        0 1))))))))
       (setq priorities (cdr priorities)))
     (or mark
        (if (or cached (elmo-folder-local-p folder))
            nil
-         wl-summary-read-uncached-mark))))
+         wl-summary-uncached-mark))))
 
 (defsubst wl-summary-message-mark (folder number &optional flags)
   "Return mark of the message."
@@ -2867,8 +3001,13 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
      (or (cadr (memq (current-buffer) buffers))
         (car buffers)))))
 
+(defun wl-summary-check-target-mark ()
+  (when (null wl-summary-buffer-target-mark-list)
+    (error "No marked message")))
+
 (defun wl-summary-target-mark-mark-as-read ()
   (interactive)
+  (wl-summary-check-target-mark)
   (save-excursion
     (goto-char (point-min))
     (let ((inhibit-read-only t)
@@ -2880,6 +3019,7 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-mark-as-unread ()
   (interactive)
+  (wl-summary-check-target-mark)
   (save-excursion
     (goto-char (point-min))
     (let ((inhibit-read-only t)
@@ -2889,21 +3029,42 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
       (dolist (number wl-summary-buffer-target-mark-list)
        (wl-summary-unset-mark number)))))
 
-(defun wl-summary-target-mark-mark-as-important ()
-  (interactive)
+(defun wl-summary-target-mark-operation (flag &optional inverse)
+  (wl-summary-check-target-mark)
   (save-excursion
-    (goto-char (point-min))
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
          wl-summary-buffer-disp-msg)
-      (dolist (number wl-summary-buffer-target-mark-list)
-       (wl-summary-unset-mark number)
-       (wl-summary-mark-as-important number))
+      (funcall
+       (intern (format "wl-summary-mark-as-%s-internal" flag))
+       inverse
+       wl-summary-buffer-target-mark-list)
+      (wl-summary-delete-all-target-marks))))
+
+(defun wl-summary-target-mark-mark-as-important (&optional remove)
+  (interactive "P")
+  (wl-summary-target-mark-operation 'important remove))
+
+(defun wl-summary-target-mark-mark-as-answered (&optional remove)
+  (interactive "P")
+  (wl-summary-target-mark-operation 'answered remove))
+
+(defun wl-summary-target-mark-set-flags (&optional remove)
+  (interactive "P")
+  (wl-summary-check-target-mark)
+  (save-excursion
+    (let ((inhibit-read-only t)
+         (buffer-read-only nil)
+         wl-summary-buffer-disp-msg)
+      (wl-summary-set-flags-internal wl-summary-buffer-target-mark-list
+                                    nil nil remove)
+      (wl-summary-delete-all-target-marks)
       (wl-summary-count-unread)
       (wl-summary-update-modeline))))
 
 (defun wl-summary-target-mark-save ()
   (interactive)
+  (wl-summary-check-target-mark)
   (let ((wl-save-dir
         (wl-read-directory-name "Save to directory: "
                                 wl-temporary-file-directory))
@@ -2917,11 +3078,13 @@ The mark is decided according to the FOLDER, FLAGS and CACHED."
 
 (defun wl-summary-target-mark-pick ()
   (interactive)
+  (wl-summary-check-target-mark)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
 (defun wl-summary-update-persistent-mark (&optional number flags)
   "Synch up persistent mark of current line with msgdb's.
 Return non-nil if the mark is updated"
+  (interactive)
   (prog1
       (when wl-summary-buffer-persistent-mark-column
        (save-excursion
@@ -2930,11 +3093,14 @@ Return non-nil if the mark is updated"
                (buffer-read-only nil)
                (mark (buffer-substring (- (point) 1) (point)))
                (new-mark (wl-summary-persistent-mark number flags)))
-           (unless (string= new-mark mark)
-             (delete-backward-char 1)
-             (insert new-mark)
-             (wl-summary-set-message-modified)
-             t))))
+           (prog1
+               (unless (string= new-mark mark)
+                 (delete-backward-char 1)
+                 (insert new-mark)
+                 (wl-summary-set-message-modified)
+                 t)
+             (wl-summary-validate-persistent-mark (point-at-bol)
+                                                  (point-at-eol))))))
     (when wl-summary-highlight
       (wl-highlight-summary-current-line))
     (set-buffer-modified-p nil)))
@@ -2946,7 +3112,7 @@ Return non-nil if the mark is updated"
   (save-excursion
     (let ((folder wl-summary-buffer-elmo-folder)
          unread-message number
-         number-list visible)
+         number-list)
       (setq number-list (cond ((numberp number-or-numbers)
                               (setq unread-message
                                     (elmo-message-flagged-p
@@ -2968,24 +3134,20 @@ Return non-nil if the mark is updated"
       (if (null number-list)
          (message "No message.")
        (if inverse
-           (elmo-folder-unset-flag folder number-list 'read no-folder-mark)
-         (elmo-folder-set-flag folder number-list 'read no-folder-mark))
-       (dolist (number number-list)
-         (setq visible (wl-summary-jump-to-msg number))
-         (unless inverse
-           (when unread-message
-             (run-hooks 'wl-summary-unread-message-hook)))
-         ;; set mark on buffer
-         (when visible
-           (wl-summary-update-persistent-mark)))
+           (elmo-folder-set-flag folder number-list 'unread no-folder-mark)
+         (elmo-folder-unset-flag folder number-list 'unread no-folder-mark))
+       (when (and unread-message
+                  (not inverse))
+         (dolist (number number-list)
+           (wl-summary-jump-to-msg number)
+           (run-hooks 'wl-summary-unread-message-hook)))
        (unless no-modeline-update
          ;; Update unread numbers.
          (wl-summary-count-unread)
          (wl-summary-update-modeline)
          (wl-folder-update-unread
           (wl-summary-buffer-folder-name)
-          (+ wl-summary-buffer-unread-count
-             wl-summary-buffer-new-count)))))))
+          wl-summary-buffer-unread-count))))))
 
 (defun wl-summary-mark-as-read (&optional number-or-numbers
                                          no-folder-mark
@@ -3005,13 +3167,16 @@ Return non-nil if the mark is updated"
                                    no-folder-mark
                                    no-modeline-update))
 
-(defsubst wl-summary-mark-as-answered-internal (inverse
-                                               &optional
-                                               number-or-numbers
-                                               no-modeline-update)
+(defsubst wl-summary-set-persistent-mark-internal (inverse
+                                                  flag
+                                                  &optional number-or-numbers
+                                                  no-modeline-update
+                                                  no-server
+                                                  interactive)
+  "Set persistent mark."
   (save-excursion
     (let ((folder wl-summary-buffer-elmo-folder)
-         number number-list visible)
+         number number-list)
       (setq number-list (cond ((numberp number-or-numbers)
                               (list number-or-numbers))
                              ((and (not (null number-or-numbers))
@@ -3022,51 +3187,153 @@ Return non-nil if the mark is updated"
                               (list number))))
       (if (null number-list)
          (message "No message.")
-       (if inverse
-           (elmo-folder-unset-flag folder number-list 'answered)
-         (elmo-folder-set-flag folder number-list 'answered))
-       (dolist (number number-list)
-         (setq visible (wl-summary-jump-to-msg number))
-         ;; set mark on buffer
-         (when visible
-           (wl-summary-update-persistent-mark)))
-       (unless no-modeline-update
-         ;; Update unread numbers.
-         ;; should elmo-flag-mark-as-read return unread numbers?
-         (wl-summary-count-unread)
-         (wl-summary-update-modeline)
-         (wl-folder-update-unread
-          (wl-summary-buffer-folder-name)
-          (+ wl-summary-buffer-unread-count
-             wl-summary-buffer-new-count)))))))
+       ;; XXX Only the first element of the list is checked.
+       (if (elmo-message-flag-available-p folder (car number-list) flag)
+           (progn
+             (if inverse
+                 (elmo-folder-unset-flag folder number-list flag no-server)
+               (elmo-folder-set-flag folder number-list flag no-server))
+             (unless no-modeline-update
+               ;; Update unread numbers.
+               ;; should elmo-flag-mark-as-read return unread numbers?
+               (wl-summary-count-unread)
+               (wl-summary-update-modeline)
+               (wl-folder-update-unread
+                (wl-summary-buffer-folder-name)
+                wl-summary-buffer-unread-count)))
+         (if interactive
+             (error "Flag `%s' is not available in this folder" flag)))))))
+
+(defun wl-summary-unset-persistent-mark (&optional flag
+                                                  number-or-numbers
+                                                  no-modeline-update
+                                                  no-server)
+  "Unset persistent mark."
+  (interactive)
+  (when (interactive-p)
+    (let ((completion-ignore-case t))
+      (setq flag (intern (downcase
+                         (completing-read
+                          "Mark name: "
+                          (mapcar (lambda (flag)
+                                    (list (capitalize (symbol-name flag))))
+                                  (wl-summary-get-available-flags))
+                          nil
+                          'require-match))))))
+  (wl-summary-set-persistent-mark-internal 'inverse
+                                          flag
+                                          number-or-numbers
+                                          no-modeline-update
+                                          no-server
+                                          (interactive-p)))
+
+(defun wl-summary-set-persistent-mark (&optional flag
+                                                number-or-numbers
+                                                no-modeline-update
+                                                no-server)
+  "Set persistent mark."
+  (interactive)
+  (when (interactive-p)
+    (let ((completion-ignore-case t))
+      (setq flag (intern (downcase
+                         (completing-read
+                          "Mark name: "
+                          (mapcar (lambda (flag)
+                                    (list (capitalize (symbol-name flag))))
+                                  (wl-summary-get-available-flags))
+                          nil
+                          'require-match))))))
+  (wl-summary-set-persistent-mark-internal nil
+                                          flag
+                                          number-or-numbers
+                                          no-modeline-update
+                                          no-server
+                                          (interactive-p)))
+
+(defun wl-summary-toggle-persistent-mark (&optional force)
+  "Toggle persistent mark."
+  (interactive "P")
+  (let ((completion-ignore-case t)
+       flag)
+    (setq flag (intern (downcase
+                       (completing-read
+                        "Mark name: "
+                        (mapcar (lambda (flag)
+                                  (list (capitalize (symbol-name flag))))
+                                (wl-summary-get-available-flags))
+                        nil
+                        'require-match))))
+    (if (and (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                                    (wl-summary-message-number)
+                                    flag)
+            (not force))
+       (wl-summary-unset-persistent-mark flag)
+      (wl-summary-set-persistent-mark flag))))
 
 (defun wl-summary-mark-as-answered (&optional number-or-numbers
                                              no-modeline-update)
   (interactive)
-  (wl-summary-mark-as-answered-internal
+  (wl-summary-set-persistent-mark-internal
    (and (interactive-p)
        (elmo-message-flagged-p wl-summary-buffer-elmo-folder
                                (wl-summary-message-number)
                                'answered))
+   'answered
    number-or-numbers
-   no-modeline-update))
+   no-modeline-update
+   nil
+   (interactive-p)))
 
 (defun wl-summary-mark-as-unanswered (&optional number-or-numbers
                                                no-modeline-update)
-  (wl-summary-mark-as-answered-internal 'inverse
-                                       number-or-numbers
-                                       no-modeline-update))
+  (wl-summary-set-persistent-mark-internal
+   'inverse
+   'answered
+   number-or-numbers
+   no-modeline-update))
 
-(defsubst wl-summary-mark-as-important-internal (inverse
-                                                &optional
-                                                number-or-numbers
-                                                no-server-update)
+(defun wl-summary-decide-flag (folder number)
+  (let ((flags (elmo-get-global-flags (elmo-message-flags
+                                      folder number)))
+       (completion-ignore-case t)
+       new-flags)
+    (setq new-flags
+         (delq nil
+               (mapcar
+                (lambda (flag)
+                  (and (> (length flag) 0)
+                       (intern (downcase flag))))
+                (wl-completing-read-multiple
+                 "Flags: "
+                 (mapcar (lambda (flag)
+                           (list (capitalize (symbol-name flag))))
+                         elmo-global-flags)
+                 nil nil (mapconcat (lambda (flag)
+                                      (capitalize (symbol-name flag)))
+                                    flags
+                                    ",")))))
+    (dolist (flag new-flags)
+      (unless (memq flag elmo-global-flags)
+       (when (elmo-local-flag-p flag)
+         (error "Cannot treat `%s'." flag))
+       (unless (elmo-flag-valid-p flag)
+         (error "Invalid char in `%s'" flag))
+       (if (y-or-n-p (format "Flag `%s' is not registered yet. Register?"
+                             (capitalize (symbol-name flag))))
+           (setq elmo-global-flags (append
+                                    elmo-global-flags
+                                    (list flag)))
+         (error "Stopped"))))
+    new-flags))
+
+(defsubst wl-summary-set-flags-internal (&optional
+                                       number-or-numbers
+                                       flags
+                                       local
+                                       remove-all)
   (save-excursion
     (let ((folder wl-summary-buffer-elmo-folder)
-         number number-list visible)
-      (when (and (eq (elmo-folder-type-internal folder) 'flag)
-                (eq (elmo-flag-folder-flag-internal folder) 'important))
-       (error "Cannot process mark in this folder"))
+         number number-list)
       (setq number-list (cond ((numberp number-or-numbers)
                               (list number-or-numbers))
                              ((and (not (null number-or-numbers))
@@ -3075,36 +3342,31 @@ Return non-nil if the mark is updated"
                              ((setq number (wl-summary-message-number))
                               ;; interactive
                               (list number))))
+      (if remove-all
+         (setq flags nil)
+       (unless flags
+         (setq flags (wl-summary-decide-flag folder (car number-list)))))
       (if (null number-list)
          (message "No message.")
-       (if inverse
-           (elmo-folder-unset-flag folder number-list
-                                   'important no-server-update)
-         (elmo-folder-set-flag folder number-list
-                               'important no-server-update))
        (dolist (number number-list)
-         (setq visible (wl-summary-jump-to-msg number))
-         ;; set mark on buffer
-         (when visible
-           (wl-summary-update-persistent-mark)))))))
+         (elmo-message-set-global-flags folder number flags local)))
+      flags)))
 
-(defun wl-summary-mark-as-important (&optional number-or-numbers
-                                              no-server-update)
-  (interactive)
-  (wl-summary-mark-as-important-internal
-   (and (interactive-p)
-       (elmo-message-flagged-p wl-summary-buffer-elmo-folder
-                               (wl-summary-message-number)
-                               'important))
-   number-or-numbers
-   no-server-update))
+(defun wl-summary-set-flags (&optional remove)
+  (interactive "P")
+  (wl-summary-set-flags-internal nil nil nil remove))
 
-(defun wl-summary-mark-as-unimportant (&optional number-or-numbers
-                                                no-server-update)
-  (interactive)
-  (wl-summary-mark-as-important-internal 'inverse
-                                        number-or-numbers
-                                        no-server-update))
+(defun wl-summary-mark-as-important (&optional prompt)
+  (interactive "P")
+  (if prompt
+      (wl-summary-set-flags-internal)
+    (wl-summary-set-persistent-mark-internal
+     (and (interactive-p)
+         (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                                 (wl-summary-message-number)
+                                 'important))
+     'important
+     nil nil nil (interactive-p))))
 
 ;;; Summary line.
 (defvar wl-summary-line-formatter nil)
@@ -3272,6 +3534,7 @@ Return non-nil if the mark is updated"
                       (number-to-string
                        (elmo-message-entity-number
                         wl-message-entity))))
+    (wl-summary-validate-persistent-mark-string line)
     (if wl-summary-highlight
        (wl-highlight-summary-line-string
         (elmo-message-entity-number wl-message-entity)
@@ -3291,10 +3554,10 @@ Return non-nil if the mark is updated"
   '((new . ((t . nil)
            (p . new)
            (p . unread)
-           (p . important)))
+           (p . digest)))
     (unread . ((t . nil)
               (p . unread)
-              (p . important)))))
+              (p . digest)))))
 
 (defsubst wl-summary-next-message (num direction hereto)
   (if wl-summary-buffer-next-message-function
@@ -3315,7 +3578,7 @@ Return non-nil if the mark is updated"
                     (if (setq flagged-list
                               (elmo-folder-list-flagged
                                wl-summary-buffer-elmo-folder
-                               (cdr (car cur-spec))))
+                               (cdr (car cur-spec)) t))
                         (while nums
                           (if (and (memq (car nums) flagged-list)
                                    (elmo-message-accessible-p
@@ -3345,7 +3608,7 @@ Return non-nil if the mark is updated"
          (wl-thread-jump-to-msg num))
       t)))
 ;;
-;; Goto unread or important
+;; Goto unread or global flag message
 ;; returns t if next message exists in this folder.
 (defun wl-summary-cursor-down (&optional hereto)
   (interactive "P")
@@ -3398,11 +3661,9 @@ Return non-nil if the mark is updated"
                  (write-region-as-binary (point-min)(point-max)
                                          cache nil 'no-msg)))
              (when (file-writable-p view) ; 'thread or 'sequence
-               (save-excursion
-                 (set-buffer tmp-buffer)
-                 (erase-buffer)
-                 (prin1 save-view tmp-buffer)
-                 (princ "\n" tmp-buffer)
+               (with-temp-buffer
+                 (prin1 save-view (current-buffer))
+                 (princ "\n" (current-buffer))
                  (write-region (point-min) (point-max) view nil 'no-msg))))
          ;; kill tmp buffer.
          (kill-buffer tmp-buffer))))))
@@ -3580,6 +3841,21 @@ Return non-nil if the mark is updated"
        )))
     (run-hooks 'wl-summary-buffer-window-scroll-functions)))
 
+(defun wl-summary-enter-handler (&optional arg)
+  "A command for `enter' key in the summary.
+Basically, it shows next line of the message.
+If optional argument ARG is specified, behave as followed.
+If ARG is number, jump to the message.
+Otherwise it shows previous line of the message."
+  (interactive "P")
+  (cond ((numberp arg)
+        (unless (wl-thread-jump-to-msg arg)
+          (message "Message (#%d) was not found." arg)))
+       (arg
+        (wl-summary-prev-line-content))
+       (t
+        (wl-summary-next-line-content))))
+
 (defun wl-summary-next-line-content ()
   "Show next line of the message."
   (interactive)
@@ -3626,6 +3902,7 @@ Return t if message exists."
        cur-folder cur-number message-last-pos)
     (when (buffer-live-p wl-message-buffer)
       (save-window-excursion
+       (setq wl-current-summary-buffer (current-buffer))
        (wl-message-select-buffer wl-message-buffer)
        (setq cur-folder wl-message-buffer-cur-folder)
        (setq cur-number wl-message-buffer-cur-number)))
@@ -3634,16 +3911,15 @@ Return t if message exists."
        (progn
          (set-buffer wl-message-buffer)
          t)
-      (if (wl-summary-no-mime-p folder)
-         (wl-summary-redisplay-no-mime-internal folder number)
-       (wl-summary-redisplay-internal folder number))
+      (wl-summary-redisplay-internal folder number)
       (when (buffer-live-p wl-message-buffer)
        (set-buffer wl-message-buffer))
       nil)))
 
 (defun wl-summary-target-mark-forward (&optional arg)
   (interactive "P")
-  (let ((mlist (nreverse wl-summary-buffer-target-mark-list))
+  (wl-summary-check-target-mark)
+  (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list)))
        (summary-buf (current-buffer))
        (wl-draft-forward t)
        start-point
@@ -3668,12 +3944,13 @@ Return t if message exists."
       (goto-char start-point)
       (save-excursion
        (set-buffer summary-buf)
-       (wl-summary-delete-all-temp-marks)))
+       (wl-summary-delete-all-target-marks)))
     (run-hooks 'wl-mail-setup-hook)))
 
 (defun wl-summary-target-mark-reply-with-citation (&optional arg)
   (interactive "P")
-  (let ((mlist (nreverse wl-summary-buffer-target-mark-list))
+  (wl-summary-check-target-mark)
+  (let ((mlist (nreverse (copy-sequence wl-summary-buffer-target-mark-list)))
        (summary-buf (current-buffer))
        change-major-mode-hook
        start-point
@@ -3696,7 +3973,7 @@ Return t if message exists."
        (goto-char start-point)
        (save-excursion
          (set-buffer summary-buf)
-         (wl-summary-delete-all-temp-marks)))
+         (wl-summary-delete-all-target-marks)))
       (wl-draft-reply-position wl-draft-reply-default-position)
       (run-hooks 'wl-mail-setup-hook))))
 
@@ -3907,9 +4184,7 @@ Reply to author if invoked with ARG."
     (when number
       (save-excursion
        (wl-summary-set-message-buffer-or-redisplay))
-      (setq mes-buf wl-message-buffer)
       (wl-message-select-buffer wl-message-buffer)
-      (set-buffer mes-buf)
       (condition-case err
          (when (setq mes-buf (wl-message-get-original-buffer))
            (wl-draft-reply mes-buf arg summary-buf number)
@@ -3918,9 +4193,7 @@ Reply to author if invoked with ARG."
              (run-hooks 'wl-mail-setup-hook)))
        (error (set-window-configuration winconf)
               (signal (car err)(cdr err))))
-      (with-current-buffer summary-buf
-       (elmo-folder-set-flag folder (list number) 'answered)
-       (wl-summary-update-persistent-mark))
+      (with-current-buffer summary-buf (run-hooks 'wl-summary-reply-hook))
       t)))
 
 (defun wl-summary-write ()
@@ -3974,7 +4247,6 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (number (wl-summary-message-number))
        (summary-buf (current-buffer))
        (wl-draft-forward t)
-       mes-buf
        entity subject num)
     (if (null number)
        (message "No message.")
@@ -3986,18 +4258,12 @@ Use function list is `wl-summary-write-current-folder-functions'."
          ;; Reload.
          (wl-summary-redisplay-internal nil nil 'force-reload)
        (wl-summary-redisplay-internal folder number))
-      (setq mes-buf wl-message-buffer)
-      (wl-message-select-buffer mes-buf)
-      ;; get original subject.
-      (if summary-buf
-         (save-excursion
-           (set-buffer summary-buf)
-           (setq subject
-                 (or (elmo-message-entity-field
-                      (elmo-message-entity folder number) 'subject 'decode)
-                     ""))))
-      (set-buffer mes-buf)
-      (wl-draft-forward subject summary-buf)
+      (wl-message-select-buffer wl-message-buffer)
+      (setq subject (with-current-buffer
+                       wl-message-buffer-original-buffer
+                     (std11-field-body "Subject")))
+      (wl-draft-forward subject summary-buf number)
+      (with-current-buffer summary-buf (run-hooks 'wl-summary-forward-hook))
       (unless without-setup-hook
        (run-hooks 'wl-mail-setup-hook)))))
 
@@ -4032,9 +4298,10 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (forward-line -1))
       (setq skip (or (string-match skip-tmark-regexp
                                   (wl-summary-temp-mark))
-                    (not (elmo-message-accessible-p
-                          wl-summary-buffer-elmo-folder
-                          (wl-summary-message-number))))))
+                    (not (and (wl-summary-message-number)
+                              (elmo-message-accessible-p
+                               wl-summary-buffer-elmo-folder
+                               (wl-summary-message-number)))))))
     (if (if downward (eobp) (and (bobp) skip)) (setq goto-next t))
     (if (or (eobp) (and (bobp) skip))
        (goto-char start))
@@ -4167,20 +4434,102 @@ Use function list is `wl-summary-write-current-folder-functions'."
            (wl-summary-redisplay)))
     (message "No last message.")))
 
+(defun wl-summary-message-display-type ()
+  (when (and wl-summary-buffer-disp-msg
+            (buffer-live-p wl-message-buffer)
+            wl-summary-buffer-current-msg
+            (wl-summary-message-number)
+            (= (wl-summary-message-number) wl-summary-buffer-current-msg))
+    (wl-message-buffer-display-type wl-message-buffer)))
+
+(defun wl-summary-buffer-display-mime-mode ()
+  (or (wl-message-display-type-property (wl-summary-message-display-type)
+                                       :mime)
+      wl-summary-buffer-display-mime-mode))
+
+(defun wl-summary-buffer-display-header-mode ()
+  (or (wl-message-display-type-property (wl-summary-message-display-type)
+                                       :header)
+      wl-summary-buffer-display-header-mode))
+
+(defun wl-summary-toggle-mime (&optional arg)
+  "Toggle MIME decoding.
+If ARG is non-nil, ask coding-system to display the message in the current
+MIME analysis mode.
+
+If ARG is numeric number, decode message as following:
+1: Enable MIME analysis.
+2: Enable MIME analysis only for headers.
+3: Disable MIME analysis."
+  (interactive "P")
+  (let ((mime-mode (wl-summary-buffer-display-mime-mode))
+       (elmo-mime-display-as-is-coding-system
+        elmo-mime-display-as-is-coding-system))
+    (if (and (consp arg) (> (prefix-numeric-value arg) 4))
+       (progn
+         (setq wl-summary-buffer-display-mime-mode mime-mode)
+         (wl-summary-update-modeline))
+      (cond
+       ((numberp arg)
+       (setq mime-mode (case arg
+                         (1 'mime)
+                         (2 'header-only)
+                         (3 'as-is)
+;;;                      (4 'decode-only)
+                         (5 'no-merge))))
+       (arg
+       ;; Specify coding-system (doesn't change the MIME mode).
+       (setq elmo-mime-display-as-is-coding-system
+             (if (and arg
+                      (not (wl-message-mime-analysis-p
+                            (wl-summary-message-display-type))))
+                 (or (read-coding-system "Coding system: ")
+                     elmo-mime-display-as-is-coding-system)
+               elmo-mime-display-as-is-coding-system)))
+       (t
+       ;; Change the MIME mode.
+       (setq mime-mode (or (cadr (memq mime-mode
+                                       wl-summary-display-mime-mode-list))
+                           (car wl-summary-display-mime-mode-list)))))
+      (wl-summary-redisplay-internal nil nil arg mime-mode))
+    (message "MIME decoding: %s%s"
+            (upcase (symbol-name mime-mode))
+            (if (and (not (eq mime-mode 'mime))
+                     (not (eq elmo-mime-display-as-is-coding-system
+                              wl-cs-autoconv)))
+                (concat " ("
+                        (symbol-name elmo-mime-display-as-is-coding-system)
+                        ")")
+              ""))))
+
 (defun wl-summary-redisplay (&optional arg)
+  "Redisplay message."
   (interactive "P")
-  (if (and (not arg)
-          (wl-summary-no-mime-p wl-summary-buffer-elmo-folder))
-      (wl-summary-redisplay-no-mime)
-    (wl-summary-redisplay-internal nil nil arg)))
+  (apply #'wl-summary-redisplay-internal nil nil arg
+        (unless (and (consp arg) (> (prefix-numeric-value arg) 4))
+          (list wl-summary-buffer-display-mime-mode
+                wl-summary-buffer-display-header-mode))))
 
-(defsubst wl-summary-redisplay-internal (&optional folder number force-reload)
-  (interactive)
+(defun wl-summary-toggle-all-header (&optional arg)
+  "Toggle displaying message with all header."
+  (interactive "P")
+  (let ((header-mode (wl-summary-buffer-display-header-mode)))
+    (if (and (consp arg) (> (prefix-numeric-value arg) 4))
+       (setq wl-summary-buffer-display-header-mode header-mode)
+      (wl-summary-redisplay-internal
+       nil nil arg nil
+       (if (eq header-mode 'all) 'partial 'all)))))
+
+(defun wl-summary-redisplay-internal (&optional folder number force-reload
+                                               mime-mode header-mode)
   (let* ((folder (or folder wl-summary-buffer-elmo-folder))
         (num (or number (wl-summary-message-number)))
         (wl-mime-charset      wl-summary-buffer-mime-charset)
         (default-mime-charset wl-summary-buffer-mime-charset)
-        no-folder-mark fld-buf fld-win thr-entity)
+        fld-buf fld-win thr-entity
+        (elmo-message-fetch-confirm (or elmo-message-fetch-confirm
+                                        (and force-reload
+                                             elmo-message-fetch-threshold))))
     (if (and wl-thread-open-reading-thread
             (eq wl-summary-buffer-view 'thread)
             (not (wl-thread-entity-get-opened
@@ -4199,104 +4548,39 @@ Use function list is `wl-summary-write-current-folder-functions'."
              (if (setq fld-win (get-buffer-window fld-buf))
                  (delete-window fld-win)))
          (setq wl-current-summary-buffer (current-buffer))
-         (setq no-folder-mark
-               ;; If cache is used, change folder-mark.
-               (if (wl-message-redisplay folder num
-                                         'mime
-                                         (or
-                                          force-reload
-                                          (string= (elmo-folder-name-internal
-                                                    folder)
-                                                   wl-draft-folder)))
-                   nil
-                 ;; plugged, then leave folder-mark.
-                 (if (and (not (elmo-folder-local-p
-                                wl-summary-buffer-elmo-folder))
-                          (elmo-folder-plugged-p
-                           wl-summary-buffer-elmo-folder))
-                     'leave)))
+         (wl-message-redisplay folder num
+                               (wl-message-make-display-type
+                                (or mime-mode
+                                    (wl-summary-buffer-display-mime-mode))
+                                (or header-mode
+                                    (wl-summary-buffer-display-header-mode)))
+                               (or force-reload
+                                   (string= (elmo-folder-name-internal folder)
+                                            wl-draft-folder)))
          (when (elmo-message-use-cache-p folder num)
            (elmo-message-set-cached folder num t))
          (ignore-errors
            (if (elmo-message-flagged-p wl-summary-buffer-elmo-folder
                                        num
                                        'unread)
-               (wl-summary-mark-as-read num no-folder-mark)
-             (wl-summary-update-persistent-mark)))
-         (setq wl-summary-buffer-current-msg num)
-         (when wl-summary-recenter
-           (recenter (/ (- (window-height) 2) 2))
-           (if (not wl-summary-indent-length-limit)
-               (wl-horizontal-recenter)))
-         (wl-highlight-summary-displaying)
-         (wl-message-buffer-prefetch-next folder num
-                                          wl-message-buffer-prefetch-depth
-                                          (current-buffer)
-                                          wl-summary-buffer-mime-charset)
-         (run-hooks 'wl-summary-redisplay-hook))
-      (message "No message to display."))))
-
-(defun wl-summary-redisplay-no-mime (&optional ask-coding)
-  "Display message without MIME decoding.
-If ASK-CODING is non-nil, coding-system for the message is asked."
-  (interactive "P")
-  (let ((elmo-mime-display-as-is-coding-system
-        (if ask-coding
-            (or (read-coding-system "Coding system: ")
-                elmo-mime-display-as-is-coding-system)
-          elmo-mime-display-as-is-coding-system)))
-    (wl-summary-redisplay-no-mime-internal)))
-
-(defun wl-summary-redisplay-no-mime-internal (&optional folder number)
-  (let* ((fld (or folder wl-summary-buffer-elmo-folder))
-        (num (or number (wl-summary-message-number)))
-        wl-break-pages)
-    (if num
-       (progn
-         (setq wl-summary-buffer-disp-msg t)
-         (setq wl-summary-buffer-last-displayed-msg
-               wl-summary-buffer-current-msg)
-         (setq wl-current-summary-buffer (current-buffer))
-         (wl-message-redisplay fld num 'as-is
-                               (string= (elmo-folder-name-internal fld)
-                                        wl-draft-folder))
-         (ignore-errors
-           (if (elmo-message-flagged-p fld num 'unread)
-               (wl-summary-mark-as-read num); no-folder-mark)
-             (wl-summary-update-persistent-mark)))
-         (setq wl-summary-buffer-current-msg num)
-         (when wl-summary-recenter
-           (recenter (/ (- (window-height) 2) 2))
-           (if (not wl-summary-indent-length-limit)
-               (wl-horizontal-recenter)))
-         (wl-highlight-summary-displaying)
-         (run-hooks 'wl-summary-redisplay-hook))
-      (message "No message to display.")
-      (wl-ask-folder 'wl-summary-exit
-                    "No more messages. Type SPC to go to folder mode."))))
-
-(defun wl-summary-redisplay-all-header (&optional folder number)
-  (interactive)
-  (let* ((fld (or folder wl-summary-buffer-elmo-folder))
-        (num (or number (wl-summary-message-number)))
-        (wl-mime-charset      wl-summary-buffer-mime-charset)
-        (default-mime-charset wl-summary-buffer-mime-charset))
-    (if num
-       (progn
-         (setq wl-summary-buffer-disp-msg t)
-         (setq wl-summary-buffer-last-displayed-msg
-               wl-summary-buffer-current-msg)
-         (setq wl-current-summary-buffer (current-buffer))
-         (if (wl-message-redisplay fld num 'all-header
-                                   (string= (elmo-folder-name-internal fld)
-                                            wl-draft-folder))
-             (wl-summary-mark-as-read num))
+               (wl-summary-mark-as-read num)
+             (wl-summary-count-unread)
+             (wl-summary-update-modeline)
+             (wl-folder-update-unread
+              (wl-summary-buffer-folder-name)
+              wl-summary-buffer-unread-count)))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))
            (if (not wl-summary-indent-length-limit)
                (wl-horizontal-recenter)))
          (wl-highlight-summary-displaying)
+         (wl-message-buffer-prefetch-next
+          folder num
+          (min (or wl-message-buffer-prefetch-depth 0)
+               (1- wl-message-buffer-cache-size))
+          (current-buffer)
+          wl-summary-buffer-mime-charset)
          (run-hooks 'wl-summary-redisplay-hook))
       (message "No message to display."))))
 
@@ -4401,24 +4685,23 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
   (interactive)
   (let ((filename)
        (num (wl-summary-message-number)))
-    (if (null wl-save-dir)
-       (setq wl-save-dir wl-temporary-file-directory))
+    (unless wl-save-dir
+      (setq wl-save-dir wl-temporary-file-directory))
     (if num
        (save-excursion
          (setq filename (expand-file-name
-                         (int-to-string num)
+                         (concat (int-to-string num)
+                                 wl-summary-save-file-suffix)
                          wl-save-dir))
-         (if (null (and arg
-                        (null (file-exists-p filename))))
-             (setq filename
-                   (read-file-name "Save to file: " filename)))
-
+         (when (or (null arg)
+                   (file-exists-p filename))
+           (setq filename (read-file-name "Save to file: " filename)))
          (wl-summary-set-message-buffer-or-redisplay)
          (set-buffer (wl-message-get-original-buffer))
-         (if (and (null arg) (file-exists-p filename))
-             (if (y-or-n-p "File already exists.  override it? ")
-                 (write-region (point-min) (point-max) filename))
-           (write-region (point-min) (point-max) filename)))
+         (when (or arg
+                   (not (file-exists-p filename))
+                   (y-or-n-p "File already exists.  override it? "))
+           (write-region-as-binary (point-min) (point-max) filename)))
       (message "No message to save."))
     num))
 
@@ -4512,7 +4795,6 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
              wl-break-pages)
          (save-excursion
            (wl-summary-set-message-buffer-or-redisplay)
-           ;; (wl-summary-redisplay-internal)
            (let* ((buffer (generate-new-buffer " *print*"))
                   (entity (progn
                             (set-buffer summary-buffer)
@@ -4550,21 +4832,19 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
 
 (defun wl-summary-target-mark-print ()
   (interactive)
-  (if (null wl-summary-buffer-target-mark-list)
-      (message "No marked message.")
-    (when (y-or-n-p "Print all marked messages. OK? ")
-      (while (car wl-summary-buffer-target-mark-list)
-       (let ((num (car wl-summary-buffer-target-mark-list)))
-         (wl-thread-jump-to-msg num)
-         (wl-summary-print-message)
-         (wl-summary-unmark))))))
+  (wl-summary-check-target-mark)
+  (when (y-or-n-p "Print all marked messages. OK? ")
+    (while (car wl-summary-buffer-target-mark-list)
+      (let ((num (car wl-summary-buffer-target-mark-list)))
+       (wl-thread-jump-to-msg num)
+       (wl-summary-print-message)
+       (wl-summary-unmark)))))
 
 (defun wl-summary-folder-info-update ()
   (wl-folder-set-folder-updated
    (elmo-string (wl-summary-buffer-folder-name))
    (list 0
-        (+ wl-summary-buffer-unread-count
-           wl-summary-buffer-new-count)
+        wl-summary-buffer-unread-count
         (elmo-folder-length
          wl-summary-buffer-elmo-folder))))
 
@@ -4578,10 +4858,11 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
   (interactive "P")
   (elmo-folder-pack-numbers wl-summary-buffer-elmo-folder)
   (let (wl-use-scoring)
-    (wl-summary-rescan nil nil t)))
+    (wl-summary-rescan nil nil nil t)))
 
 (defun wl-summary-target-mark-uudecode ()
   (interactive)
+  (wl-summary-check-target-mark)
   (let ((mlist (reverse wl-summary-buffer-target-mark-list))
        (summary-buf (current-buffer))
        (tmp-buf (get-buffer-create "*WL UUENCODE*"))
@@ -4643,7 +4924,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
                                 filename nil 'no-msg))))
            (save-excursion
              (set-buffer summary-buf)
-             (wl-summary-delete-all-temp-marks))
+             (wl-summary-delete-all-target-marks))
            (if (file-exists-p filename)
                (message "Saved as %s" filename)))
        (kill-buffer tmp-buf)))))
@@ -4727,8 +5008,6 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
          (wl-message-header-narrowing-toggle)
          (and wpos (set-window-start mwin wpos)))))))
 
-(autoload 'elmo-folder-list-global-flag-messages "elmo-flag")
-
 (require 'product)
 (product-provide (provide 'wl-summary) (require 'wl-version))