* wl-summary.el (wl-summary-update-mark-and-highlight-window): New function.
[elisp/wanderlust.git] / wl / wl-summary.el
index 4333652..2c6c870 100644 (file)
   (` (and wl-summary-buffer-elmo-folder
          (elmo-folder-name-internal wl-summary-buffer-elmo-folder))))
 
-(defmacro wl-summary-buffer-msgdb ()
-  (` (and wl-summary-buffer-elmo-folder
-         (elmo-folder-msgdb wl-summary-buffer-elmo-folder))))
-
 (defvar wl-summary-buffer-disp-msg    nil)
 (defvar wl-summary-buffer-disp-folder nil)
 (defvar wl-summary-buffer-temp-mark-list nil)
@@ -94,6 +90,8 @@
 (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 nil)
 (defvar wl-summary-buffer-thread-nodes nil)
 (defvar wl-summary-buffer-target-mark-list nil)
 (defvar wl-summary-buffer-exit-function nil)
 (defvar wl-summary-buffer-next-message-function nil)
 (defvar wl-summary-buffer-number-list nil)
-(defvar wl-summary-buffer-msgdb nil)
 (defvar wl-summary-buffer-folder-name nil)
 (defvar wl-summary-buffer-line-formatter nil)
 (defvar wl-summary-buffer-line-format nil)
 (defvar wl-thread-horizontal-str-internal nil)
 (defvar wl-thread-space-str-internal nil)
 (defvar wl-summary-last-visited-folder nil)
-(defvar wl-read-folder-hist nil)
+(defvar wl-read-folder-history nil)
 (defvar wl-summary-scored nil)
 (defvar wl-crosspost-alist-modified nil)
 (defvar wl-summary-alike-hashtb 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)
 (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-exit-function)
 (make-variable-buffer-local 'wl-summary-buffer-next-message-function)
 (make-variable-buffer-local 'wl-summary-buffer-number-list)
-(make-variable-buffer-local 'wl-summary-buffer-msgdb)
 (make-variable-buffer-local 'wl-summary-buffer-folder-name)
 (make-variable-buffer-local 'wl-summary-buffer-line-formatter)
 (make-variable-buffer-local 'wl-summary-buffer-line-format)
@@ -539,6 +536,8 @@ See also variable `wl-use-petname'."
   (define-key wl-summary-mode-map "hm"  'wl-score-set-mark-below)
   (define-key wl-summary-mode-map "hx"   'wl-score-set-expunge-below)
 
+  ;; misc
+  (define-key wl-summary-mode-map "\C-c\C-f" 'wl-summary-toggle-header-narrowing)
   (define-key wl-summary-mode-map "\M-t" 'wl-toggle-plugged)
   (define-key wl-summary-mode-map "\C-t" 'wl-plugged-change)
   ;;
@@ -550,6 +549,51 @@ See also variable `wl-use-petname'."
    "Menu used in Summary mode."
    wl-summary-mode-menu-spec))
 
+(defsubst wl-summary-message-visible-p (number)
+  "Return non-nil if the message with NUMBER is visible."
+  (or (eq wl-summary-buffer-view 'sequence)
+      (not (wl-thread-entity-parent-invisible-p
+           (wl-thread-get-entity number)))))
+
+(defvar wl-summary-window-scroll-functions nil)
+
+(defun wl-summary-update-mark-and-highlight-window (&optional win beg)
+  "A function to be called as window-scroll-functions."
+  (with-current-buffer (window-buffer win)
+    (when (eq major-mode 'wl-summary-mode)
+      (let ((start (window-start win))
+           (end (condition-case nil
+                    (window-end win t) ; old emacsen doesn't support 2nd arg.
+                  (error (window-end win))))
+           number flags
+           wl-summary-highlight)
+       (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)
+             (wl-highlight-summary-current-line number flags))
+           (forward-line 1)))))))
+
+(defun wl-summary-window-scroll-functions ()
+  (or wl-summary-window-scroll-functions
+      (setq wl-summary-window-scroll-functions
+           (cond
+            ((and wl-summary-lazy-highlight
+                  wl-summary-lazy-update-mark)
+             (list 'wl-summary-update-mark-and-highlight-window))
+            (t
+             (append
+              (and wl-summary-lazy-highlight
+                   '(wl-highlight-summary-window))
+              (and wl-summary-lazy-update-mark
+                   '(wl-summary-update-mark-window))))))))
+
 (defun wl-status-update ()
   (interactive)
   (wl-address-init))
@@ -663,7 +707,9 @@ you."
   (let ((column wl-summary-buffer-number-column)
        (formatter wl-summary-buffer-line-formatter)
        (dummy-temp (char-to-string 200))
-       (dummy-persistent (char-to-string 201))
+       (wl-summary-new-mark (char-to-string 201)) ; bind only for the check.
+       (wl-summary-flag-priority-list '(new))     ; ditto.
+       wl-summary-highlight
        temp persistent)
     (with-temp-buffer
       (setq wl-summary-buffer-number-column column
@@ -671,20 +717,22 @@ you."
       (insert
        (wl-summary-create-line
        (elmo-msgdb-make-message-entity
+        (luna-make-entity 'modb-entity-handler)
         :number 10000
         :from "foo"
         :subject "bar"
         :size 100)
        nil
        dummy-temp
-       dummy-persistent))
+       '(new)
+       nil))
       (goto-char (point-min))
       (setq temp (save-excursion
-                  (search-forward dummy-temp nil t)
-                  (current-column))
+                  (when (search-forward dummy-temp nil t)
+                    (current-column)))
            persistent (save-excursion
-                        (search-forward dummy-persistent nil t)
-                        (current-column))))
+                        (when (search-forward wl-summary-new-mark nil t)
+                          (current-column)))))
     (setq wl-summary-buffer-temp-mark-column temp
          wl-summary-buffer-persistent-mark-column persistent)))
 
@@ -722,7 +770,6 @@ you."
    wl-summary-buffer-mode-line-formatter
    wl-summary-mode-line-format
    wl-summary-mode-line-format-spec-alist)
-  (wl-summary-detect-mark-position)
   (setq wl-summary-buffer-persistent
        (wl-folder-persistent-p (elmo-folder-name-internal folder)))
   (elmo-folder-set-persistent-internal folder wl-summary-buffer-persistent)
@@ -775,13 +822,12 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
        selective-display-ellipses nil)
   (wl-mode-line-buffer-identification '(wl-summary-buffer-mode-line))
   (easy-menu-add wl-summary-mode-menu)
-  (when wl-summary-lazy-highlight
-    (if wl-on-xemacs
-       (progn
-         (make-local-variable 'pre-idle-hook)
-         (add-hook 'pre-idle-hook 'wl-highlight-summary-window))
-      (make-local-variable 'window-scroll-functions)
-      (add-hook 'window-scroll-functions 'wl-highlight-summary-window)))
+  (when (wl-summary-window-scroll-functions)
+    (let ((variable (if wl-on-xemacs
+                       (make-local-variable 'pre-idle-hook)
+                     (make-local-variable 'window-scroll-functions))))
+      (dolist (function (wl-summary-window-scroll-functions))
+       (add-hook variable function))))
   ;; 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))
@@ -807,10 +853,10 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   "Compare entity X and Y by from."
   (string<
    (wl-address-header-extract-address
-    (or (elmo-message-entity-field x 'from)
+    (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)
+    (or (elmo-message-entity-field y 'from t)
        wl-summary-no-from-message))))
 
 (defun wl-summary-overview-entity-compare-by-subject (x y)
@@ -913,6 +959,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
          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-target-mark-list nil
          wl-summary-buffer-temp-mark-list nil
          wl-summary-delayed-update nil)
@@ -934,7 +981,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
       (while wl-summary-delayed-update
        (message "Parent (%d) of message %d is no entity"
                 (caar wl-summary-delayed-update)
-                (elmo-msgdb-overview-entity-get-number
+                (elmo-message-entity-number
                  (cdar wl-summary-delayed-update)))
        (wl-summary-insert-message
         (cdar wl-summary-delayed-update)
@@ -1002,18 +1049,9 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
       "folder mode"))
 
 (defun wl-summary-set-message-modified ()
-  (elmo-folder-set-message-modified
-   wl-summary-buffer-elmo-folder t)
-  (setq wl-summary-buffer-message-modified t)
-  (wl-summary-set-mark-modified))
+  (setq wl-summary-buffer-message-modified t))
 (defun wl-summary-message-modified-p ()
   wl-summary-buffer-message-modified)
-(defun wl-summary-set-mark-modified ()
-  (elmo-folder-set-mark-modified-internal
-   wl-summary-buffer-elmo-folder t))
-(defun wl-summary-mark-modified-p ()
-  (elmo-folder-mark-modified-internal
-   wl-summary-buffer-elmo-folder))
 (defun wl-summary-set-thread-modified ()
   (setq wl-summary-buffer-thread-modified t))
 (defun wl-summary-thread-modified-p ()
@@ -1040,7 +1078,6 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
     ;; save the current summary buffer view.
     (if (and wl-summary-cache-use
             (or (wl-summary-message-modified-p)
-                (wl-summary-mark-modified-p)
                 (wl-summary-thread-modified-p)))
        (wl-summary-save-view-cache))))
 
@@ -1174,8 +1211,9 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
           (let ((msg (wl-summary-message-number)))
             (wl-summary-resume-cache-status)
             (and msg (wl-summary-jump-to-msg msg))))
-         ((or (string-match "last:" range)
-              (string-match "first:" range))
+         ((string= range "no-sync"))
+         ((or (string-match "^last:" range)
+              (string-match "^first:" range))
           (wl-summary-goto-folder-subr (concat "/" range "/"
                                                (elmo-folder-name-internal
                                                 folder))
@@ -1347,8 +1385,10 @@ If ARG is non-nil, checking is omitted."
                               ?\"
                               (or
                                (elmo-message-field
-                                wl-summary-buffer-elmo-folder
-                                number 'from)
+                                (elmo-message-entity
+                                 wl-summary-buffer-elmo-folder
+                                 number)
+                                'from t)
                                "??")))))) " ]")
                        size))))
              (message ""))             ; flush.
@@ -1374,6 +1414,17 @@ If ARG is non-nil, checking is omitted."
                  t)
              nil))))))
 
+(defsubst wl-summary-narrow-to-region (beg end)
+  (narrow-to-region
+   (save-excursion
+     (goto-char beg)
+     (beginning-of-line)
+     (point))
+   (save-excursion
+     (goto-char end)
+     (if (eq (current-column) 0) (beginning-of-line) (end-of-line))
+     (point))))
+
 (defun wl-summary-prefetch-region-no-mark (beg end &optional prefetch-marks)
   (interactive "r")
   (let ((count 0)
@@ -1384,7 +1435,7 @@ If ARG is non-nil, checking is omitted."
     (save-excursion
       (setq start-pos (point))
       (save-restriction
-       (narrow-to-region beg end)
+       (wl-summary-narrow-to-region beg end)
        ;; collect prefetch targets.
        (message "Collecting marks...")
        (goto-char (point-min))
@@ -1440,7 +1491,7 @@ If ARG is non-nil, checking is omitted."
   (interactive "r")
   (save-excursion
     (save-restriction
-      (narrow-to-region beg end)
+      (wl-summary-narrow-to-region beg end)
       (goto-char (point-min))
       (if (eq wl-summary-buffer-view 'thread)
          (let (number-list)
@@ -1465,7 +1516,7 @@ If ARG is non-nil, checking is omitted."
   (interactive "r")
   (save-excursion
     (save-restriction
-      (narrow-to-region beg end)
+      (wl-summary-narrow-to-region beg end)
       (goto-char (point-min))
       (if (eq wl-summary-buffer-view 'thread)
          (let (number-list)
@@ -1490,8 +1541,7 @@ If ARG is non-nil, checking is omitted."
   (interactive "r")
   (save-excursion
     (save-restriction
-      (narrow-to-region beg end);(save-excursion (goto-char end)
-                                       ;    (end-of-line) (point)))
+      (wl-summary-narrow-to-region beg end)
       (goto-char (point-min))
       (if (eq wl-summary-buffer-view 'thread)
          (progn
@@ -1508,7 +1558,7 @@ If ARG is non-nil, checking is omitted."
                  (setq children
                        (delq number (wl-thread-get-children-msgs number)))
                  (while children
-                   (wl-thread-msg-mark-as-important (car children))
+                   (wl-summary-mark-as-important (car children))
                    (setq children (cdr children))))
                (forward-line 1))))
        (while (not (eobp))
@@ -1524,7 +1574,7 @@ 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-mark-as-read folder
+       (elmo-folder-flag-as-read folder
                                  (elmo-folder-list-unreads
                                   folder))
        (save-excursion
@@ -1611,21 +1661,35 @@ If ARG is non-nil, checking is omitted."
       ;;(message (concat deleting-info "done"))
       (wl-summary-count-unread)
       (wl-summary-update-modeline)
-      (wl-folder-set-folder-updated
-       (elmo-folder-name-internal wl-summary-buffer-elmo-folder)
-       (list 0
-            (+ wl-summary-buffer-unread-count wl-summary-buffer-new-count)
-            (elmo-folder-length wl-summary-buffer-elmo-folder))))))
+      (wl-summary-folder-info-update))))
 
-(defun wl-summary-update-status-marks ()
+(defun wl-summary-update-status-marks (beg end &optional check)
   "Synchronize status marks on current buffer to the msgdb."
-  (interactive)
+  (interactive "r")
   (save-excursion
-    (goto-char (point-min))
-    (while (not (eobp))
-      (wl-summary-update-persistent-mark)
+    (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-update-persistent-mark))
       (forward-line 1))))
 
+(defun wl-summary-update-mark-window (&optional win beg)
+  "Update persistent mark in visible summary window.
+This function is defined for `window-scroll-functions'"
+  (with-current-buffer (window-buffer win)
+    (when (eq major-mode 'wl-summary-mode)
+      (let ((start (window-start win))
+           (end (condition-case nil
+                    (window-end win t) ; old emacsen doesn't support 2nd arg.
+                  (error (window-end win)))))
+       (wl-summary-update-status-marks start end 'check)))))
+
 (defun wl-summary-insert-message (&rest args)
   (if (eq wl-summary-buffer-view 'thread)
       (apply 'wl-summary-insert-thread args)
@@ -1655,12 +1719,14 @@ If ARG is non-nil, checking is omitted."
                   'internal))
       (message "Updating marks...")
       (setq importants (elmo-uniq-list
-                       (nconc
-                        (elmo-folder-list-importants
-                         wl-summary-buffer-elmo-folder)
-                        (elmo-folder-list-messages-with-global-mark
-                         wl-summary-buffer-elmo-folder
-                         elmo-msgdb-important-mark)))
+                       (nconc (elmo-folder-list-importants
+                               wl-summary-buffer-elmo-folder)
+                              ;; XXX Temporal implementation.
+                              ;; It should be merged to the
+                              ;; elmo-folder-list-flagged.
+                              (elmo-folder-list-global-flag-messages
+                               wl-summary-buffer-elmo-folder
+                               'important)))
            unreads (elmo-folder-list-unreads
                     wl-summary-buffer-elmo-folder)
            answereds (elmo-folder-list-answereds
@@ -1673,7 +1739,7 @@ If ARG is non-nil, checking is omitted."
       (setq mes (format "Updated (-%d" (length diffs)))
       (while diffs
        (wl-summary-mark-as-important (car diffs)
-                                     elmo-msgdb-important-mark
+                                     wl-summary-important-mark
                                      'no-server)
        (setq diffs (cdr diffs)))
       (setq diffs (car diff)) ; important-appends
@@ -1757,7 +1823,8 @@ If ARG is non-nil, checking is omitted."
 
                (when delete-list
                  (wl-summary-delete-messages-on-buffer delete-list))
-               (wl-summary-update-status-marks)
+               (unless wl-summary-lazy-update-mark
+                 (wl-summary-update-status-marks (point-min) (point-max)))
                (setq num (length append-list))
                (setq i 0)
                (setq wl-summary-delayed-update nil)
@@ -1772,7 +1839,7 @@ If ARG is non-nil, checking is omitted."
                  (if elmo-use-database
                      (elmo-database-msgid-put
                       (car entity) (elmo-folder-name-internal folder)
-                      (elmo-msgdb-overview-entity-get-number entity)))
+                      (elmo-message-entity-number entity)))
                  (when (> num elmo-display-progress-threshold)
                    (setq i (+ i 1))
                    (if (or (zerop (% i 5)) (= i num))
@@ -1786,7 +1853,7 @@ If ARG is non-nil, checking is omitted."
                  (while wl-summary-delayed-update
                    (message "Parent (%d) of message %d is no entity"
                             (caar wl-summary-delayed-update)
-                            (elmo-msgdb-overview-entity-get-number
+                            (elmo-message-entity-number
                              (cdar wl-summary-delayed-update)))
                    (when (setq update-thread
                                (wl-summary-insert-message
@@ -1868,7 +1935,6 @@ If ARG is non-nil, checking is omitted."
                                  wl-summary-partial-highlight-above-lines
                                  wl-summary-highlight-partial-threshold)))
                (wl-highlight-summary (point) (point-max))))))
-      (setq wl-summary-buffer-msgdb (elmo-folder-msgdb folder))
       (wl-delete-all-overlays)
       (set-buffer-modified-p nil)
       (if mes (message "%s" mes)))))
@@ -1876,17 +1942,11 @@ If ARG is non-nil, checking is omitted."
 (defun wl-summary-set-score-mark (mark)
   (save-excursion
     (beginning-of-line)
-    (let ((inhibit-read-only t)
-         (buffer-read-only nil)
-         msg-num
-         cur-mark)
-      (setq msg-num (wl-summary-message-number))
-      (setq cur-mark (wl-summary-temp-mark))
+    (let ((cur-mark (wl-summary-temp-mark)))
       (when (member cur-mark (list " "
                                   wl-summary-score-below-mark
                                   wl-summary-score-over-mark))
-       (delete-backward-char 1)
-       (insert mark)
+       (wl-summary-put-temp-mark mark)
        (if wl-summary-highlight
            (wl-highlight-summary-current-line))
        (set-buffer-modified-p nil)))))
@@ -1954,8 +2014,8 @@ If ARG is non-nil, checking is omitted."
                            (length dels)))
          (progn
            (message "Deleting...")
-           (elmo-folder-delete-messages wl-summary-buffer-elmo-folder dels)
-           (elmo-folder-detach-messages wl-summary-buffer-elmo-folder dels)
+           (elmo-folder-move-messages wl-summary-buffer-elmo-folder dels
+                                      'null)
            (wl-summary-set-message-modified)
            (wl-folder-set-folder-updated (wl-summary-buffer-folder-name)
                                          (list 0 0 0))
@@ -2067,7 +2127,7 @@ If ARG, without confirm."
                   wl-summary-buffer-message-modified
                   wl-summary-buffer-thread-modified
                   wl-summary-buffer-number-list
-                  wl-summary-buffer-msgdb
+                  wl-summary-buffer-unsync-mark-number-list
                   wl-summary-buffer-folder-name
                   wl-summary-buffer-line-formatter)
                 (and (eq wl-summary-buffer-view 'thread)
@@ -2133,11 +2193,9 @@ If ARG, without confirm."
 
 (defun wl-summary-auto-select-msg-p (unread-msg)
   (and unread-msg
-       (not (string=
-            (elmo-message-mark
-             wl-summary-buffer-elmo-folder
-             unread-msg)
-            elmo-msgdb-important-mark))))
+       (not (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                                   unread-msg
+                                   'important))))
 
 (defsubst wl-summary-open-folder (folder)
   ;; Select folder
@@ -2145,7 +2203,6 @@ If ARG, without confirm."
     (unwind-protect
        (elmo-folder-open folder 'load-msgdb)
       ;; For compatibility
-      (setq wl-summary-buffer-msgdb (elmo-folder-msgdb folder))
       (setq wl-summary-buffer-folder-name (elmo-folder-name-internal
                                           folder)))))
 
@@ -2220,17 +2277,21 @@ If ARG, without confirm."
                               (elmo-folder-name-internal folder))
                              wl-summary-default-view)))
                  (wl-thread-resume-entity folder)
-                 (wl-summary-open-folder folder))
+                 (wl-summary-open-folder folder)
+                 (wl-summary-detect-mark-position))
              (setq wl-summary-buffer-view
                    (wl-summary-load-file-object
                     (expand-file-name wl-summary-view-file
                                       (elmo-folder-msgdb-path folder))))
              (wl-summary-open-folder folder)
+             (wl-summary-detect-mark-position)
              (wl-summary-rescan))
            (wl-summary-count-unread)
            (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))
@@ -2251,6 +2312,8 @@ If ARG, without confirm."
               ((eq scan-type 'all)
                (wl-summary-sync 'unset-cursor "all"))
               ((eq scan-type 'no-sync))
+              ((eq scan-type 'rescan)
+               (wl-summary-rescan))
               ((or (eq scan-type 'force-update)
                    (eq scan-type 'update))
                (setq mes (wl-summary-sync-force-update
@@ -2322,7 +2385,7 @@ If ARG, without confirm."
       ;; entity-id is unknown.
       (wl-folder-set-current-entity-id
        (wl-folder-get-entity-id entity)))
-    (when (and wl-summary-lazy-highlight
+    (when (and (wl-summary-window-scroll-functions)
               wl-on-xemacs)
       (sit-for 0))
     (unwind-protect
@@ -2372,14 +2435,17 @@ If ARG, without confirm."
 
 (defun wl-summary-insert-sequential (entity folder &rest args)
   (let ((inhibit-read-only t)
+       (number (elmo-message-entity-number entity))
        buffer-read-only)
     (goto-char (point-max))
     (wl-summary-insert-line
      (wl-summary-create-line entity nil nil
-                            (elmo-message-mark
-                             folder
-                             (elmo-message-entity-number
-                              entity))))
+                            (elmo-message-flags
+                             wl-summary-buffer-elmo-folder
+                             number)
+                            (elmo-message-cached-p
+                             wl-summary-buffer-elmo-folder
+                             number)))
     (setq wl-summary-buffer-number-list
          (wl-append wl-summary-buffer-number-list
                     (list (elmo-message-entity-number entity))))
@@ -2404,7 +2470,7 @@ If ARG, without confirm."
                        wl-summary-alike-hashtb)))
 
 (defun wl-summary-insert-headers (folder func mime-decode)
-  (let ((numbers (elmo-folder-list-messages folder nil t))
+  (let ((numbers (elmo-folder-list-messages folder 'visible t))
        ov this last alike)
     (buffer-disable-undo (current-buffer))
     (make-local-variable 'wl-summary-alike-hashtb)
@@ -2520,7 +2586,7 @@ If ARG, without confirm."
                   wl-summary-search-parent-by-subject-regexp
                   (string-match
                    wl-summary-search-parent-by-subject-regexp
-                   (elmo-msgdb-overview-entity-get-subject entity)))
+                   (elmo-message-entity-field entity 'subject)))
          (let ((found (wl-summary-search-by-subject entity folder)))
            (when (and found
                       (not (member found wl-summary-delayed-update)))
@@ -2556,11 +2622,11 @@ If ARG, without confirm."
 (defun wl-summary-update-thread (entity
                                 thr-entity
                                 parent-entity)
-  (let* ((this-id (elmo-msgdb-overview-entity-get-id entity))
+  (let* ((this-id (elmo-message-entity-field entity 'message-id))
         (overview-entity entity)
-        (parent-id (elmo-msgdb-overview-entity-get-id parent-entity))
-        (number (elmo-msgdb-overview-entity-get-number entity))
-        (parent-number (elmo-msgdb-overview-entity-get-number parent-entity))
+        (parent-id (elmo-message-entity-field parent-entity 'message-id))
+        (number (elmo-message-entity-number entity))
+        (parent-number (elmo-message-entity-number parent-entity))
         insert-line)
     (cond
      ((or (not parent-id)
@@ -2579,23 +2645,18 @@ If ARG, without confirm."
          entity
          parent-entity
          nil
-         (elmo-message-mark wl-summary-buffer-elmo-folder number)
+         (elmo-message-flags wl-summary-buffer-elmo-folder number)
+         (elmo-message-cached-p wl-summary-buffer-elmo-folder number)
          (wl-thread-maybe-get-children-num number)
          (wl-thread-make-indent-string thr-entity)
          (wl-thread-entity-get-linked thr-entity)))))))
 
 (defun wl-summary-target-mark-msgs (msgs)
   "Return the number of marked messages."
-  (let ((i 0) num)
-    (while msgs
-      (if (eq wl-summary-buffer-view 'thread)
-         (wl-thread-jump-to-msg (car msgs))
-       (wl-summary-jump-to-msg (car msgs)))
-      (setq num (wl-summary-message-number))
-      (when (eq num (car msgs))
-       (wl-summary-target-mark num)
-       (setq i (1+ i)))
-      (setq msgs (cdr msgs)))
+  (let ((i 0))
+    (dolist (number msgs)
+      (when (wl-summary-target-mark number)
+       (setq i (1+ i))))
     i))
 
 (defun wl-summary-pick (&optional from-list delete-marks)
@@ -2650,42 +2711,88 @@ If ARG, exit virtual folder."
                                 'update nil nil t)
     (run-hooks 'wl-summary-virtual-hook)))
 
-(defun wl-summary-delete-all-temp-marks (&optional no-msg)
+(defun wl-summary-delete-all-temp-marks (&optional no-msg force)
   "Erase all temp marks from buffer."
   (interactive)
   (when (or wl-summary-buffer-target-mark-list
-           wl-summary-buffer-temp-mark-list)
+           wl-summary-buffer-temp-mark-list
+           wl-summary-scored)
     (save-excursion
       (goto-char (point-min))
       (unless no-msg
        (message "Unmarking..."))
       (while (not (eobp))
-       (wl-summary-unset-mark)
+       (wl-summary-unset-mark nil nil force)
        (forward-line 1))
       (unless no-msg
        (message "Unmarking...done"))
       (setq wl-summary-buffer-target-mark-list nil)
       (setq wl-summary-buffer-temp-mark-list nil))))
 
-(defsubst wl-summary-temp-mark ()
-  "Move to the temp-mark column and return mark string."
-  (move-to-column wl-summary-buffer-temp-mark-column)
-  (buffer-substring (- (point) 1) (point)))
-
-(defsubst wl-summary-persistent-mark ()
-  "Move to the persistent-mark column and return mark string."
-  (move-to-column wl-summary-buffer-persistent-mark-column)
-  (buffer-substring (- (point) 1) (point)))
-
-(defun wl-summary-mark-line (mark)
-  "Put MARK on current line."
-  (save-excursion
-    (beginning-of-line)
-    (let ((inhibit-read-only t)
-         (buffer-read-only nil))
-      (wl-summary-temp-mark) ; mark
-      (delete-backward-char 1)
-      (insert mark))))
+(defsubst wl-summary-temp-mark (&optional number)
+  "Return temp-mark string of current line."
+  (let ((number (or number (wl-summary-message-number)))
+       info)
+    (or (and (wl-summary-have-target-mark-p number)
+            "*")
+       (and (setq info (wl-summary-registered-temp-mark number))
+            (nth 1 info))
+       (wl-summary-get-score-mark number)
+       " ")))
+
+(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)
+       mark)
+    (while (and (null mark) priorities)
+      (when (memq (car priorities) flags)
+       (setq mark
+             (case (car priorities)
+               (new
+                wl-summary-new-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)))))
+      (setq priorities (cdr priorities)))
+    (or mark
+       (if (or cached (elmo-folder-local-p folder))
+           nil
+         wl-summary-read-uncached-mark))))
+
+(defsubst wl-summary-message-mark (folder number &optional flags)
+  "Return mark of the message."
+  (ignore-errors
+    (wl-summary-persistent-mark-string
+     folder
+     (or flags (setq flags (elmo-message-flags folder number)))
+     (memq 'cached flags) ; XXX for speed-up.
+     )))
+
+(defsubst wl-summary-persistent-mark (&optional number flags)
+  "Return persistent-mark string of current line."
+  (or (wl-summary-message-mark wl-summary-buffer-elmo-folder
+                              (or number (wl-summary-message-number))
+                              flags)
+      " "))
+
+(defun wl-summary-put-temp-mark (mark)
+  "Put temp MARK on current line."
+  (when wl-summary-buffer-temp-mark-column
+    (save-excursion
+      (beginning-of-line)
+      (let ((inhibit-read-only t)
+           (buffer-read-only nil))
+       (move-to-column wl-summary-buffer-temp-mark-column)
+       (delete-backward-char 1)
+       (insert mark)))))
 
 (defun wl-summary-next-buffer ()
   "Switch to next summary buffer."
@@ -2715,29 +2822,10 @@ If ARG, exit virtual folder."
     (goto-char (point-min))
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
-         wl-summary-buffer-disp-msg
-         number mlist)
-      (while (not (eobp))
-       (when (string= (wl-summary-temp-mark) "*")
-         ;; delete target-mark from buffer.
-         (delete-backward-char 1)
-         (insert " ")
-         (setq number (wl-summary-message-number))
-         (setq mlist (append mlist (list number)))
-         (if wl-summary-highlight
-             (wl-highlight-summary-current-line))
-         (if number
-             (setq wl-summary-buffer-target-mark-list
-                   (delq number wl-summary-buffer-target-mark-list))))
-       (forward-line 1))
-      (wl-summary-mark-as-read mlist)
-      ;; closed
-      (when (setq mlist wl-summary-buffer-target-mark-list)
-       (wl-summary-mark-as-read mlist)
-       (while mlist
-         (setq wl-summary-buffer-target-mark-list
-               (delq (car mlist) wl-summary-buffer-target-mark-list))
-         (setq mlist (cdr mlist)))))))
+         wl-summary-buffer-disp-msg)
+      (wl-summary-mark-as-read wl-summary-buffer-target-mark-list)
+      (dolist (number wl-summary-buffer-target-mark-list)
+       (wl-summary-unset-mark number)))))
 
 (defun wl-summary-target-mark-mark-as-unread ()
   (interactive)
@@ -2745,28 +2833,10 @@ If ARG, exit virtual folder."
     (goto-char (point-min))
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
-         wl-summary-buffer-disp-msg
-         number mlist)
-      (while (not (eobp))
-       (when (string= (wl-summary-temp-mark) "*")
-         (delete-backward-char 1)
-         (insert " ")
-         (setq number (wl-summary-message-number))
-         (setq mlist (append mlist (list number)))
-         (if wl-summary-highlight
-             (wl-highlight-summary-current-line))
-         (if number
-             (setq wl-summary-buffer-target-mark-list
-                   (delq number wl-summary-buffer-target-mark-list))))
-       (forward-line 1))
-      (wl-summary-mark-as-unread mlist)
-      ;; closed
-      (when (setq mlist wl-summary-buffer-target-mark-list)
-       (wl-summary-mark-as-unread mlist)
-       (while mlist
-         (setq wl-summary-buffer-target-mark-list
-               (delq (car mlist) wl-summary-buffer-target-mark-list))
-         (setq mlist (cdr mlist)))))))
+         wl-summary-buffer-disp-msg)
+      (wl-summary-mark-as-unread wl-summary-buffer-target-mark-list)
+      (dolist (number wl-summary-buffer-target-mark-list)
+       (wl-summary-unset-mark number)))))
 
 (defun wl-summary-target-mark-mark-as-important ()
   (interactive)
@@ -2774,27 +2844,10 @@ If ARG, exit virtual folder."
     (goto-char (point-min))
     (let ((inhibit-read-only t)
          (buffer-read-only nil)
-         wl-summary-buffer-disp-msg
-         number mlist)
-      (while (not (eobp))
-       (when (string= (wl-summary-temp-mark) "*")
-         ;; delete target-mark from buffer.
-         (delete-backward-char 1)
-         (insert " ")
-         (setq number (wl-summary-mark-as-important))
-         (if wl-summary-highlight
-             (wl-highlight-summary-current-line))
-         (if number
-             (setq wl-summary-buffer-target-mark-list
-                   (delq number wl-summary-buffer-target-mark-list))))
-       (forward-line 1))
-      (setq mlist wl-summary-buffer-target-mark-list)
-      (while mlist
-       (wl-summary-mark-as-important (car mlist))
-       (wl-thread-msg-mark-as-important (car mlist))
-       (setq wl-summary-buffer-target-mark-list
-             (delq (car mlist) wl-summary-buffer-target-mark-list))
-       (setq mlist (cdr mlist)))
+         wl-summary-buffer-disp-msg)
+      (dolist (number wl-summary-buffer-target-mark-list)
+       (wl-summary-unset-mark number)
+       (wl-summary-mark-as-important number))
       (wl-summary-count-unread)
       (wl-summary-update-modeline))))
 
@@ -2809,30 +2862,31 @@ If ARG, exit virtual folder."
     (while (setq number (car wl-summary-buffer-target-mark-list))
       (wl-thread-jump-to-msg number)
       (wl-summary-save t wl-save-dir)
-      (wl-summary-unmark number))))
+      (wl-summary-unmark))))
 
 (defun wl-summary-target-mark-pick ()
   (interactive)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
-(defun wl-summary-update-persistent-mark ()
+(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"
-  (ignore-errors
-    (save-excursion
-      (let ((inhibit-read-only t)
-           (buffer-read-only nil)
-           (new-mark
-            (or (elmo-message-mark wl-summary-buffer-elmo-folder
-                                   (wl-summary-message-number))
-                " "))
-           (mark (wl-summary-persistent-mark)))
-       (unless (string= new-mark mark)
-         (delete-backward-char 1)
-         (insert new-mark)
-         (if wl-summary-highlight (wl-highlight-summary-current-line))
-         (set-buffer-modified-p nil)
-         t)))))
+  (prog1
+      (when wl-summary-buffer-persistent-mark-column
+       (save-excursion
+         (move-to-column wl-summary-buffer-persistent-mark-column)
+         (let ((inhibit-read-only t)
+               (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))))
+    (when wl-summary-highlight
+      (wl-highlight-summary-current-line))
+    (set-buffer-modified-p nil)))
 
 (defsubst wl-summary-mark-as-read-internal (inverse
                                            number-or-numbers
@@ -2844,10 +2898,10 @@ Return non-nil if the mark is updated"
          number-list visible)
       (setq number-list (cond ((numberp number-or-numbers)
                               (setq unread-message
-                                    (member (elmo-message-mark
-                                             folder
-                                             number-or-numbers)
-                                            (elmo-msgdb-unread-marks)))
+                                    (elmo-message-flagged-p
+                                     folder
+                                     number-or-numbers
+                                     'unread))
                               (list number-or-numbers))
                              ((and (not (null number-or-numbers))
                                    (listp number-or-numbers))
@@ -2855,14 +2909,16 @@ Return non-nil if the mark is updated"
                              ((setq number (wl-summary-message-number))
                               ;; interactive
                               (setq unread-message
-                                    (member (elmo-message-mark folder number)
-                                            (elmo-msgdb-unread-marks)))
+                                    (elmo-message-flagged-p
+                                     folder
+                                     number
+                                     'unread))
                               (list number))))
       (if (null number-list)
          (message "No message.")
        (if inverse
-           (elmo-folder-unmark-read folder number-list no-folder-mark)
-         (elmo-folder-mark-as-read folder number-list no-folder-mark))
+           (elmo-folder-unflag-read folder number-list no-folder-mark)
+         (elmo-folder-flag-as-read folder number-list no-folder-mark))
        (dolist (number number-list)
          (setq visible (wl-summary-jump-to-msg number))
          (unless inverse
@@ -2873,7 +2929,7 @@ Return non-nil if the mark is updated"
            (wl-summary-update-persistent-mark)))
        (unless no-modeline-update
          ;; Update unread numbers.
-         ;; should elmo-folder-mark-as-read return unread numbers?
+         ;; should elmo-folder-flag-as-read return unread numbers?
          (wl-summary-count-unread)
          (wl-summary-update-modeline)
          (wl-folder-update-unread
@@ -2916,8 +2972,8 @@ Return non-nil if the mark is updated"
       (if (null number-list)
          (message "No message.")
        (if inverse
-           (elmo-folder-unmark-answered folder number-list)
-         (elmo-folder-mark-as-answered folder number-list))
+           (elmo-folder-unflag-answered folder number-list)
+         (elmo-folder-flag-as-answered folder number-list))
        (dolist (number number-list)
          (setq visible (wl-summary-jump-to-msg number))
          ;; set mark on buffer
@@ -2925,7 +2981,7 @@ Return non-nil if the mark is updated"
            (wl-summary-update-persistent-mark)))
        (unless no-modeline-update
          ;; Update unread numbers.
-         ;; should elmo-folder-mark-as-read return unread numbers?
+         ;; should elmo-flag-mark-as-read return unread numbers?
          (wl-summary-count-unread)
          (wl-summary-update-modeline)
          (wl-folder-update-unread
@@ -2938,9 +2994,9 @@ Return non-nil if the mark is updated"
   (interactive)
   (wl-summary-mark-as-answered-internal
    (and (interactive-p)
-       (member (elmo-message-mark wl-summary-buffer-elmo-folder
-                                  (wl-summary-message-number))
-               (elmo-msgdb-answered-marks)))
+       (elmo-message-flagged-p wl-summary-buffer-elmo-folder
+                               (wl-summary-message-number)
+                               'answered))
    number-or-numbers
    no-modeline-update))
 
@@ -2955,62 +3011,45 @@ Return non-nil if the mark is updated"
                                               no-server-update)
   (interactive)
   (if (eq (elmo-folder-type-internal wl-summary-buffer-elmo-folder)
-         'internal)
+         'flag)
       (error "Cannot process mark in this folder"))
   (save-excursion
-    (let* (eol
-         (folder wl-summary-buffer-elmo-folder)
-         message-id visible cur-mark)
-      (if number
-         (progn
-           (setq visible (wl-summary-jump-to-msg number))
-           (setq mark (or mark (elmo-message-mark
-                                wl-summary-buffer-elmo-folder number))))
-       (setq visible t))
-      (when visible
-       (if (null (setq number (wl-summary-message-number)))
+    (let* ((folder wl-summary-buffer-elmo-folder)
+          message-id visible cur-mark)
+      (cond (number
+            (setq visible (wl-summary-jump-to-msg number))
+            (setq cur-mark (or mark
+                               (wl-summary-message-mark
+                                wl-summary-buffer-elmo-folder number)
+                               " ")))
+           ((setq number (wl-summary-message-number))
+            (setq visible t)
+            (setq cur-mark (or mark (wl-summary-persistent-mark))))
+           (t
+            (error "No message")))
+      (when (or visible
+               ;; already exists in msgdb.
+               (elmo-message-entity wl-summary-buffer-elmo-folder
+                                    number))
+       (setq message-id (elmo-message-field
+                         wl-summary-buffer-elmo-folder
+                         number
+                         'message-id))
+       (if (string= cur-mark wl-summary-important-mark)
            (progn
-             (message "No message.")
-             (setq visible nil))
-         (end-of-line)
-         (setq eol (point))
-         (wl-summary-goto-previous-message-beginning)))
-      (if (or (and (not visible)
-                  ;; already exists in msgdb.
-                  (elmo-message-entity wl-summary-buffer-elmo-folder
-                                       number))
-             (setq cur-mark (wl-summary-persistent-mark)))
-         (progn
-           (setq number (or number (wl-summary-message-number)))
-           (setq mark (or mark cur-mark))
-           (setq message-id (elmo-message-field
-                             wl-summary-buffer-elmo-folder
-                             number
-                             'message-id))
-           (if (string= mark elmo-msgdb-important-mark)
-               (progn
-                 ;; server side mark
-                 (save-match-data
-                   (elmo-folder-unmark-important folder (list number)
-                                                 no-server-update)
-                   (unless no-server-update
-                     (elmo-msgdb-global-mark-delete message-id))
-                   ;; Remove cache if local folder.
-                   (if (and (elmo-folder-local-p folder)
-                            (not (eq 'mark
-                                     (elmo-folder-type-internal folder))))
-                       (elmo-file-cache-delete
-                        (elmo-file-cache-get-path message-id)))))
              ;; server side mark
-             (elmo-folder-mark-as-important folder (list number)
-                                            no-server-update)
-             (if (eq (elmo-file-cache-exists-p message-id) 'entire)
-                 (elmo-folder-mark-as-read folder (list number))
-               ;; Force cache message.
-               (elmo-message-encache folder number 'read))
-             (unless no-server-update
-               (elmo-msgdb-global-mark-set message-id
-                                           elmo-msgdb-important-mark)))))
+             (save-match-data
+               (elmo-folder-unflag-important folder (list number)
+                                             no-server-update)
+               ;; Remove cache if local folder.
+               (if (and (elmo-folder-local-p folder)
+                        (not (eq 'mark
+                                 (elmo-folder-type-internal folder))))
+                   (elmo-file-cache-delete
+                    (elmo-file-cache-get-path message-id)))))
+         ;; server side mark
+         (elmo-folder-flag-as-important folder (list number)
+                                        no-server-update)))
       (when visible
        (wl-summary-update-persistent-mark))))
   number)
@@ -3049,7 +3088,7 @@ Return non-nil if the mark is updated"
   (wl-set-string-width
    (- wl-summary-buffer-number-column)
    (number-to-string
-    (elmo-msgdb-overview-entity-get-number wl-message-entity))))
+    (elmo-message-entity-number wl-message-entity))))
 
 (defun wl-summary-line-year ()
   (aref wl-datevec 0))
@@ -3069,7 +3108,7 @@ Return non-nil if the mark is updated"
   (format "%02d" (aref wl-datevec 4)))
 
 (defun wl-summary-line-size ()
-  (let ((size (elmo-msgdb-overview-entity-get-size wl-message-entity)))
+  (let ((size (elmo-message-entity-field wl-message-entity 'size)))
     (if size
        (cond
         ((<= 1 (/ size 1048576))
@@ -3085,11 +3124,13 @@ Return non-nil if the mark is updated"
        (setq no-parent t)) ; no parent
     (setq subject
          (elmo-delete-char ?\n
-                           (or (elmo-msgdb-overview-entity-get-subject
-                                wl-message-entity)
+                           (or (elmo-message-entity-field
+                                wl-message-entity
+                                'subject t)
                                wl-summary-no-subject-message)))
     (setq parent-raw-subject
-         (elmo-msgdb-overview-entity-get-subject wl-parent-message-entity))
+         (elmo-message-entity-field wl-parent-message-entity
+                                    'subject t))
     (setq parent-subject
          (if parent-raw-subject
              (elmo-delete-char ?\n parent-raw-subject)))
@@ -3103,8 +3144,9 @@ Return non-nil if the mark is updated"
 (defun wl-summary-line-from ()
   (elmo-delete-char ?\n
                    (funcall wl-summary-from-function
-                            (elmo-msgdb-overview-entity-get-from
-                             wl-message-entity))))
+                            (elmo-message-entity-field
+                             wl-message-entity
+                             'from t))))
 
 (defun wl-summary-line-list-info ()
   (let ((list-info (wl-summary-get-list-info wl-message-entity)))
@@ -3120,29 +3162,42 @@ Return non-nil if the mark is updated"
       "")))
 
 (defun wl-summary-line-attached ()
-  (let ((content-type (elmo-msgdb-overview-entity-get-extra-field
-                      wl-message-entity "content-type"))
+  (let ((content-type (elmo-message-entity-field
+                      wl-message-entity 'content-type))
        (case-fold-search t))
     (if (and content-type
             (string-match "multipart/mixed" content-type))
        "@"
       "")))
 
+;;; For future use.
+;;(defun wl-summary-line-cached ()
+;;  (if (elmo-message-cached-p wl-summary-buffer-elmo-folder
+;;                          (elmo-message-entity-number wl-message-entity))
+;;      " "
+;;    "u"))
+
 (defun wl-summary-create-line (wl-message-entity
                               wl-parent-message-entity
                               wl-temp-mark
-                              wl-persistent-mark
+                              wl-flags
+                              wl-cached
                               &optional
                               wl-thr-children-number
                               wl-thr-indent-string
                               wl-thr-linked)
   "Create a summary line."
   (let ((wl-mime-charset wl-summary-buffer-mime-charset)
+       (wl-persistent-mark (wl-summary-persistent-mark-string
+                            wl-summary-buffer-elmo-folder
+                            wl-flags
+                            wl-cached))
        (elmo-mime-charset wl-summary-buffer-mime-charset)
        (elmo-lang wl-summary-buffer-weekday-name-lang)
        (wl-datevec (or (ignore-errors (timezone-fix-time
-                                       (elmo-msgdb-overview-entity-get-date 
-                                        wl-message-entity)
+                                       (elmo-message-entity-field
+                                        wl-message-entity
+                                        'date)
                                        nil
                                        wl-summary-fix-timezone))
                        (make-vector 5 0)))
@@ -3163,13 +3218,15 @@ Return non-nil if the mark is updated"
     (setq line (concat line
                       "\r"
                       (number-to-string
-                       (elmo-msgdb-overview-entity-get-number 
+                       (elmo-message-entity-number
                         wl-message-entity))))
     (if wl-summary-highlight
-       (wl-highlight-summary-line-string line
-                                         wl-persistent-mark
-                                         wl-temp-mark
-                                         wl-thr-indent-string))
+       (wl-highlight-summary-line-string
+        (elmo-message-entity-number wl-message-entity)
+        line
+        wl-flags
+        wl-temp-mark
+        wl-thr-indent-string))
     line))
 
 (defsubst wl-summary-proc-wday (wday-str year month mday)
@@ -3257,44 +3314,46 @@ Return non-nil if the mark is updated"
           (tmp-buffer (get-buffer-create " *wl-summary-save-view-cache*"))
           (temp-column wl-summary-buffer-temp-mark-column)
           (charset wl-summary-buffer-mime-charset))
-      (if (file-directory-p dir)
-         (); ok.
-       (if (file-exists-p dir)
-           (error "File %s already exists" dir)
-         (elmo-make-directory dir)))
-      (if (eq save-view 'thread)
-         (wl-thread-save-entity dir))
-      (when wl-summary-check-line-format
-       (wl-summary-line-format-save))
-      (unwind-protect
-         (progn
-           (when (file-writable-p cache)
-             (copy-to-buffer tmp-buffer (point-min) (point-max))
-             (with-current-buffer tmp-buffer
-               (widen)
-               (make-local-variable 'wl-summary-highlight)
-               (setq wl-summary-highlight nil
-                     wl-summary-buffer-target-mark-list mark-list
-                     wl-summary-buffer-temp-mark-list temp-list
-                     wl-summary-buffer-temp-mark-column temp-column)
-               (wl-summary-delete-all-temp-marks 'no-msg)
-               (encode-coding-region
-                (point-min) (point-max)
-                (or (and wl-on-mule ; one in mcs-ltn1(apel<10.4) cannot take 2 arg.
-                         (mime-charset-to-coding-system charset 'LF))
-                    ;; Mule 2 doesn't have `*ctext*unix'.
-                    (mime-charset-to-coding-system charset)))
-               (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)
-               (write-region (point-min) (point-max) view nil 'no-msg))))
-       ;; kill tmp buffer.
-       (kill-buffer tmp-buffer)))))
+      (when dir
+       (if (file-directory-p dir)
+           (); ok.
+         (if (file-exists-p dir)
+             (error "File %s already exists" dir)
+           (elmo-make-directory dir)))
+       (if (eq save-view 'thread)
+           (wl-thread-save-entity dir))
+       (when wl-summary-check-line-format
+         (wl-summary-line-format-save))
+       (unwind-protect
+           (progn
+             (when (file-writable-p cache)
+               (copy-to-buffer tmp-buffer (point-min) (point-max))
+               (with-current-buffer tmp-buffer
+                 (widen)
+                 (make-local-variable 'wl-summary-highlight)
+                 (setq wl-summary-highlight nil
+                       wl-summary-buffer-target-mark-list mark-list
+                       wl-summary-buffer-temp-mark-list temp-list
+                       wl-summary-buffer-temp-mark-column temp-column)
+                 (wl-summary-delete-all-temp-marks 'no-msg 'force)
+                 (encode-coding-region
+                  (point-min) (point-max)
+                  (or (and wl-on-mule
+                           ;; one in mcs-ltn1(apel<10.4) cannot take 2 arg.
+                           (mime-charset-to-coding-system charset 'LF))
+                      ;; Mule 2 doesn't have `*ctext*unix'.
+                      (mime-charset-to-coding-system charset)))
+                 (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)
+                 (write-region (point-min) (point-max) view nil 'no-msg))))
+         ;; kill tmp buffer.
+         (kill-buffer tmp-buffer))))))
 
 (defsubst wl-summary-get-sync-range (folder)
   (intern (or (and
@@ -3807,7 +3866,7 @@ Reply to author if invoked with ARG."
        (error (set-window-configuration winconf)
               (signal (car err)(cdr err))))
       (with-current-buffer summary-buf
-       (elmo-folder-mark-as-answered folder (list number))
+       (elmo-folder-flag-as-answered folder (list number))
        (wl-summary-update-persistent-mark))
       t)))
 
@@ -3909,13 +3968,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (skip-tmark-regexp (wl-regexp-opt wl-summary-skip-mark-list))
        (skip t)
        (column (current-column))
-       skip-pmark-regexp goto-next next-entity finfo)
-    (if (elmo-folder-plugged-p wl-summary-buffer-elmo-folder)
-       ()
-      (setq skip-pmark-regexp
-           (wl-regexp-opt (list " "
-                                elmo-msgdb-unread-cached-mark
-                                elmo-msgdb-important-mark))))
+       goto-next next-entity finfo)
     (beginning-of-line)
     (while (and skip
                (not (if downward (eobp) (bobp))))
@@ -3923,13 +3976,10 @@ Use function list is `wl-summary-write-current-folder-functions'."
          (forward-line 1)
        (forward-line -1))
       (setq skip (or (string-match skip-tmark-regexp
-                                  (save-excursion
-                                    (wl-summary-temp-mark)))
-                    (and skip-pmark-regexp
-                         (not (string-match
-                               skip-pmark-regexp
-                               (save-excursion
-                                 (wl-summary-persistent-mark))))))))
+                                  (wl-summary-temp-mark))
+                    (not (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))
@@ -4113,9 +4163,9 @@ Use function list is `wl-summary-write-current-folder-functions'."
          (when (elmo-message-use-cache-p folder num)
            (elmo-message-set-cached folder num t))
          (ignore-errors
-           (if (member (elmo-message-mark wl-summary-buffer-elmo-folder
-                                          num)
-                       (elmo-msgdb-unread-marks))
+           (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)
@@ -4156,8 +4206,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
                                (string= (elmo-folder-name-internal fld)
                                         wl-draft-folder))
          (ignore-errors
-           (if (member (elmo-message-mark fld num)
-                       (elmo-msgdb-unread-marks))
+           (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)
@@ -4322,7 +4371,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
   (interactive "r")
   (save-excursion
     (save-restriction
-      (narrow-to-region beg end)
+      (wl-summary-narrow-to-region beg end)
       (goto-char (point-min))
       (let ((wl-save-dir
             (wl-read-directory-name "Save to directory: "
@@ -4366,7 +4415,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
        (let ((num (car wl-summary-buffer-target-mark-list)))
          (wl-thread-jump-to-msg num)
          (wl-summary-pipe-message-subr prefix command)
-         (wl-summary-unmark num))))))
+         (wl-summary-unmark))))))
 
 (defun wl-summary-pipe-message-subr (prefix command)
   (save-excursion
@@ -4417,14 +4466,14 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
                              (wl-summary-message-number))))
                   (wl-ps-subject
                    (and entity
-                        (or (elmo-msgdb-overview-entity-get-subject entity)
+                        (or (elmo-message-entity-field entity 'subject t)
                             "")))
                   (wl-ps-from
                    (and entity
-                        (or (elmo-msgdb-overview-entity-get-from entity) "")))
+                        (or (elmo-message-entity-field entity 'from t) "")))
                   (wl-ps-date
                    (and entity
-                        (or (elmo-msgdb-overview-entity-get-date entity) ""))))
+                        (or (elmo-message-entity-field entity 'date) ""))))
              (run-hooks 'wl-ps-preprint-hook)
              (set-buffer wl-message-buffer)
              (copy-to-buffer buffer (point-min) (point-max))
@@ -4453,7 +4502,7 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
        (let ((num (car wl-summary-buffer-target-mark-list)))
          (wl-thread-jump-to-msg num)
          (wl-summary-print-message)
-         (wl-summary-unmark num))))))
+         (wl-summary-unmark))))))
 
 (defun wl-summary-folder-info-update ()
   (wl-folder-set-folder-updated
@@ -4610,6 +4659,21 @@ If ASK-CODING is non-nil, coding-system for the message is asked."
          (setq  wl-summary-buffer-saved-message nil)))
     (message "There's no saved message.")))
 
+(defun wl-summary-toggle-header-narrowing ()
+  "Toggle message header narrowing."
+  (interactive)
+  (when wl-message-use-header-narrowing
+    (save-selected-window
+      (let* ((mbuf wl-message-buffer)
+            (mwin (when mbuf (get-buffer-window mbuf)))
+            (wpos (when mwin (window-start mwin))))
+       (when mbuf
+         (set-buffer mbuf)
+         (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))