Update to version 2003-01-27.08.
[elisp/wanderlust.git] / wl / wl-summary.el
index 900a169..24ad93a 100644 (file)
 (defvar wl-summary-buffer-current-msg nil)
 (defvar wl-summary-buffer-unread-count 0)
 (defvar wl-summary-buffer-new-count    0)
-(defvar wl-summary-buffer-answered-count 0)
 (defvar wl-summary-buffer-mime-charset  nil)
 (defvar wl-summary-buffer-weekday-name-lang  nil)
 (defvar wl-summary-buffer-thread-indent-set-alist  nil)
 (defvar wl-summary-buffer-view nil)
 (defvar wl-summary-buffer-message-modified nil)
+(defvar wl-summary-buffer-mark-modified nil)
 (defvar wl-summary-buffer-thread-modified nil)
 
 (defvar wl-summary-buffer-number-column nil)
 (make-variable-buffer-local 'wl-summary-buffer-last-displayed-msg)
 (make-variable-buffer-local 'wl-summary-buffer-unread-count)
 (make-variable-buffer-local 'wl-summary-buffer-new-count)
-(make-variable-buffer-local 'wl-summary-buffer-answered-count)
 (make-variable-buffer-local 'wl-summary-buffer-mime-charset)
 (make-variable-buffer-local 'wl-summary-buffer-weekday-name-lang)
 (make-variable-buffer-local 'wl-summary-buffer-thread-indent-set)
 (make-variable-buffer-local 'wl-summary-buffer-view)
 (make-variable-buffer-local 'wl-summary-buffer-message-modified)
+(make-variable-buffer-local 'wl-summary-buffer-mark-modified)
 (make-variable-buffer-local 'wl-summary-buffer-thread-modified)
 (make-variable-buffer-local 'wl-summary-buffer-number-column)
 (make-variable-buffer-local 'wl-summary-buffer-temp-mark-column)
 (defvar wl-temp-mark)
 (defvar wl-persistent-mark)
 
+;; internal functions (dummy)
+(unless (fboundp 'wl-summary-append-message-func-internal)
+  (defun wl-summary-append-message-func-internal (entity msgdb update
+                                                        &optional force-insert)))
+
 (defmacro wl-summary-sticky-buffer-name (name)
   (` (concat wl-summary-buffer-name ":" (, name))))
 
@@ -567,12 +572,15 @@ See also variable `wl-use-petname'."
       (wl-summary-redisplay)))
 
 (defun wl-summary-count-unread ()
-  (let ((lst (elmo-msgdb-count-marks (wl-summary-buffer-msgdb))))
+  (let ((pair
+        (elmo-msgdb-count-marks (wl-summary-buffer-msgdb)
+                                wl-summary-new-mark
+                                (list wl-summary-unread-uncached-mark
+                                      wl-summary-unread-cached-mark))))
     (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))
+       (setq wl-summary-buffer-new-count (car pair)
+             wl-summary-buffer-unread-count (cdr pair)))
+    pair))
 
 (defun wl-summary-message-string (&optional use-cache)
   "Return full body string of current message.
@@ -817,7 +825,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   (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
+    (if wl-on-xemacs 
        (progn
          (make-local-variable 'pre-idle-hook)
          (add-hook 'pre-idle-hook 'wl-highlight-summary-window))
@@ -942,6 +950,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
         (inhibit-read-only t)
         (buffer-read-only nil)
         expunged)
+    (fset 'wl-summary-append-message-func-internal
+         (wl-summary-get-append-message-func))
     (erase-buffer)
     (message "Re-scanning...")
     (setq i 0)
@@ -968,7 +978,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
     (elmo-kill-buffer wl-summary-search-buf-name)
     (while curp
       (setq entity (car curp))
-      (wl-summary-insert-message entity msgdb nil)
+      (wl-summary-append-message-func-internal entity msgdb nil)
       (setq curp (cdr curp))
       (when (> num elmo-display-progress-threshold)
        (setq i (+ i 1))
@@ -982,7 +992,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
                 (caar wl-summary-delayed-update)
                 (elmo-msgdb-overview-entity-get-number
                  (cdar wl-summary-delayed-update)))
-       (wl-summary-insert-message
+       (wl-summary-append-message-func-internal
         (cdar wl-summary-delayed-update) msgdb nil t)
        (setq wl-summary-delayed-update (cdr wl-summary-delayed-update))))
     (message "Constructing summary structure...done")
@@ -991,7 +1001,8 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
        (progn
          (message "Inserting thread...")
          (wl-thread-insert-top)
-         (message "Inserting thread...done")))
+         (message "Inserting thread...done"))
+      (wl-summary-make-number-list))
     (when wl-use-scoring
       (setq wl-summary-scored nil)
       (wl-summary-score-headers nil msgdb
@@ -1058,10 +1069,10 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   wl-summary-buffer-message-modified)
 (defun wl-summary-set-mark-modified ()
   (elmo-folder-set-mark-modified-internal
-   wl-summary-buffer-elmo-folder t))
+   wl-summary-buffer-elmo-folder t)
+  (setq wl-summary-buffer-mark-modified t))
 (defun wl-summary-mark-modified-p ()
-  (elmo-folder-mark-modified-internal
-   wl-summary-buffer-elmo-folder))
+  wl-summary-buffer-mark-modified)
 (defun wl-summary-set-thread-modified ()
   (setq wl-summary-buffer-thread-modified t))
 (defun wl-summary-thread-modified-p ()
@@ -1111,7 +1122,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   (elmo-folder-commit wl-summary-buffer-elmo-folder)
   (elmo-folder-check wl-summary-buffer-elmo-folder)
   (if wl-use-scoring (wl-score-save))
-  (if (interactive-p) (message "Saving summary status...done.")))
+  (if (interactive-p) (message "Saving summary status...done")))
 
 (defun wl-summary-force-exit ()
   "Exit current summary.  Buffer is deleted even the buffer is sticky."
@@ -1199,6 +1210,7 @@ Entering Folder mode calls the value of `wl-summary-mode-hook'."
   (wl-summary-cleanup-temp-marks)
   (erase-buffer)
   (wl-summary-set-message-modified)
+  (wl-summary-set-mark-modified)
   (setq wl-thread-entity-hashtb (elmo-make-hash
                                 (* (length (elmo-msgdb-get-number-alist
                                             (wl-summary-buffer-msgdb))) 2)))
@@ -1412,7 +1424,7 @@ If ARG is non-nil, checking is omitted."
                                "??")))))) " ]")
                        size))))
              (message ""))             ; flush.
-           (setq mark (or (elmo-msgdb-get-mark msgdb number) " "))
+           (setq mark (elmo-msgdb-get-mark msgdb number))
            (if force-read
                (save-excursion
                  (save-match-data
@@ -1421,21 +1433,35 @@ If ARG is non-nil, checking is omitted."
                        (elmo-message-encache
                         wl-summary-buffer-elmo-folder
                         number))
-                   (elmo-message-set-cached wl-summary-buffer-elmo-folder
-                                            number t)
                    (setq new-mark
-                         (or (elmo-message-mark wl-summary-buffer-elmo-folder
-                                                number)
-                             " "))
-                   (unless (string= new-mark mark)
-                     (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))))
+                         (cond
+                          ((string= mark
+                                    wl-summary-unread-uncached-mark)
+                           wl-summary-unread-cached-mark)
+                          ((string= mark wl-summary-new-mark)
+                           (setq wl-summary-buffer-new-count
+                                 (- wl-summary-buffer-new-count 1))
+                           (setq wl-summary-buffer-unread-count
+                                 (+ wl-summary-buffer-unread-count 1))
+                           wl-summary-unread-cached-mark)
+                          ((string= mark wl-summary-read-uncached-mark)
+                           nil)
+                          (t mark)))
+                   (elmo-msgdb-set-mark msgdb number new-mark)
+                   (or new-mark (setq new-mark " "))
+                   (wl-summary-set-mark-modified)
+                   (wl-summary-update-modeline)
+                   (wl-folder-update-unread
+                    (wl-summary-buffer-folder-name)
+                    (+ wl-summary-buffer-unread-count
+                       wl-summary-buffer-new-count)))
                  new-mark)))))))
 
+;;(defvar wl-summary-message-uncached-marks
+;;  (list wl-summary-new-mark
+;;     wl-summary-unread-uncached-mark
+;;     wl-summary-read-uncached-mark))
+
 (defun wl-summary-prefetch-region (beg end &optional prefetch-marks)
   (interactive "r")
   (let ((count 0)
@@ -1481,8 +1507,8 @@ If ARG is non-nil, checking is omitted."
                           (wl-summary-prefetch))
                       (wl-summary-prefetch-msg (car targets))))
          (if (if prefetch-marks
-                 (string= mark elmo-msgdb-unread-cached-mark)
-               (or (string= mark elmo-msgdb-unread-cached-mark)
+                 (string= mark wl-summary-unread-cached-mark)
+               (or (string= mark wl-summary-unread-cached-mark)
                    (string= mark " ")))
              (message "Prefetching... %d/%d message(s)"
                       (setq count (+ 1 count)) length))
@@ -1651,24 +1677,44 @@ If ARG is non-nil, checking is omitted."
             (inhibit-read-only t)
             (buffer-read-only nil)
             (case-fold-search nil)
-            msg mark new-mark)
+            msg mark)
        (message "Setting all msgs as read...")
        (elmo-folder-mark-as-read folder
                                  (elmo-folder-list-unreads
-                                  folder))
+                                  folder
+                                  (list wl-summary-unread-cached-mark
+                                        wl-summary-unread-uncached-mark
+                                        wl-summary-new-mark)))
        (save-excursion
          (goto-char (point-min))
          (while (not (eobp))
-           (setq msg (wl-summary-message-number)
-                 mark (wl-summary-persistent-mark)
-                 new-mark (or (elmo-message-mark folder msg) " "))
-           (unless (string= mark new-mark)
+           (setq msg (wl-summary-message-number))
+           (setq mark (wl-summary-persistent-mark))
+           (when (and (not (string= mark " "))
+                      (not (string= mark wl-summary-important-mark))
+                      (not (string= mark wl-summary-read-uncached-mark)))
              (delete-backward-char 1)
-             ;; New mark and unread-uncached mark
-             (insert new-mark)
+             (if (or (not (elmo-message-use-cache-p folder msg))
+                     (string= mark wl-summary-unread-cached-mark))
+                 (progn
+                   (insert " ")
+                   (elmo-msgdb-set-mark msgdb msg nil))
+               ;; New mark and unread-uncached mark
+               (insert wl-summary-read-uncached-mark)
+               (elmo-msgdb-set-mark
+                msgdb msg wl-summary-read-uncached-mark))
              (if wl-summary-highlight
                  (wl-highlight-summary-current-line nil nil t)))
            (forward-line 1)))
+       (elmo-folder-replace-marks
+        folder
+        (list (cons wl-summary-unread-cached-mark
+                    nil)
+              (cons wl-summary-unread-uncached-mark
+                    wl-summary-read-uncached-mark)
+              (cons wl-summary-new-mark
+                    wl-summary-read-uncached-mark)))
+       (wl-summary-set-mark-modified)
        (wl-folder-update-unread (wl-summary-buffer-folder-name) 0)
        (setq wl-summary-buffer-unread-count 0)
        (setq wl-summary-buffer-new-count    0)
@@ -1686,12 +1732,20 @@ If ARG is non-nil, checking is omitted."
           (msgdb (wl-summary-buffer-msgdb))
           (number-alist (elmo-msgdb-get-number-alist msgdb))
           (case-fold-search nil)
-          new-mark mark number unread)
-      (setq number (wl-summary-message-number))
-      (elmo-message-set-cached folder number nil)
-      (setq new-mark (elmo-message-mark folder number)
-           mark (wl-summary-persistent-mark))
-      (unless (string= new-mark mark)
+          mark number unread new-mark)
+      (setq mark (wl-summary-persistent-mark))
+      (cond
+       ((or (string= mark wl-summary-new-mark)
+           (string= mark wl-summary-unread-uncached-mark)
+           (string= mark wl-summary-important-mark))
+       ;; noop
+       )
+       ((string= mark wl-summary-unread-cached-mark)
+       (setq new-mark wl-summary-unread-uncached-mark))
+       (t
+       (setq new-mark wl-summary-read-uncached-mark)))
+      (when new-mark
+       (setq number (wl-summary-message-number))
        (delete-backward-char 1)
        (insert new-mark)
        (elmo-file-cache-delete
@@ -1699,6 +1753,8 @@ If ARG is non-nil, checking is omitted."
          (elmo-message-field wl-summary-buffer-elmo-folder
                              number
                              'message-id)))
+       (elmo-msgdb-set-mark msgdb number new-mark)
+       (wl-summary-set-mark-modified)
        (if wl-summary-highlight
            (wl-highlight-summary-current-line nil nil t))
        (set-buffer-modified-p nil)))))
@@ -1706,31 +1762,44 @@ If ARG is non-nil, checking is omitted."
 (defun wl-summary-resume-cache-status ()
   "Resume the cache status of all messages in the current folder."
   (interactive)
-  (let ((folder wl-summary-buffer-elmo-folder)
-       (buffer-read-only nil)
-       (case-fold-search nil)
-       number msgid set-mark mark)
+  (let* ((folder wl-summary-buffer-elmo-folder)
+        (cur-buf (current-buffer))
+        (msgdb (wl-summary-buffer-msgdb))
+        (number-alist (elmo-msgdb-get-number-alist msgdb))
+        (inhibit-read-only t)
+        (buffer-read-only nil)
+        (case-fold-search nil)
+        msg mark msgid set-mark)
     (message "Resuming cache status...")
     (save-excursion
       (goto-char (point-min))
       (while (not (eobp))
-       (setq number (wl-summary-message-number))
+       (setq msg (wl-summary-message-number))
        (setq mark (wl-summary-persistent-mark))
-       (setq msgid (elmo-message-field folder number 'message-id))
+       (setq msgid (elmo-msgdb-get-field msgdb msg 'message-id))
        (setq set-mark nil)
        (if (elmo-file-cache-exists-p msgid)
-           (when (member mark (elmo-msgdb-uncached-marks))
-             (elmo-message-set-cached folder number t)
-             (setq set-mark (elmo-message-mark folder number)))
-         (unless (member mark (elmo-msgdb-uncached-marks))
-           (elmo-message-set-cached folder number nil)
-           (setq set-mark (or (elmo-message-mark folder number) " "))))
+           (if (or
+                (string= mark wl-summary-unread-uncached-mark) ; U -> !
+                (string= mark wl-summary-new-mark)             ; N -> !
+                )
+               (setq set-mark wl-summary-unread-cached-mark)
+             (if (string= mark wl-summary-read-uncached-mark)  ; u -> ' '
+                 (setq set-mark " ")))
+         (if (string= mark " ")
+             (setq set-mark wl-summary-read-uncached-mark)     ;' ' -> u
+           (if (string= mark wl-summary-unread-cached-mark)
+               (setq set-mark wl-summary-unread-uncached-mark) ; !  -> U
+             )))
        (when set-mark
          (delete-backward-char 1)
          (insert set-mark)
+         (elmo-msgdb-set-mark msgdb msg
+                              (if (string= set-mark " ") nil set-mark))
          (if wl-summary-highlight
              (wl-highlight-summary-current-line)))
        (forward-line 1))
+      (wl-summary-set-mark-modified)
       (wl-summary-count-unread)
       (wl-summary-update-modeline)
       (message "Resuming cache status...done")
@@ -1794,25 +1863,6 @@ If ARG is non-nil, checking is omitted."
              (wl-highlight-summary-current-line)))
        (forward-line 1)))))
 
-(defun wl-summary-update-status-marks ()
-  "Synchronize status marks on current buffer to the msgdb."
-  (interactive)
-  (save-excursion
-    (goto-char (point-min))
-    (let ((inhibit-read-only t)
-         (buffer-read-only nil)
-         mark)
-      (while (not (eobp))
-       (unless (string= (wl-summary-persistent-mark)
-                        (setq mark (or (elmo-message-mark
-                                        wl-summary-buffer-elmo-folder
-                                        (wl-summary-message-number))
-                                       " ")))
-         (delete-backward-char 1)
-         (insert mark)
-         (if wl-summary-highlight (wl-highlight-summary-current-line)))
-       (forward-line 1)))))
-
 (defun wl-summary-get-delete-folder (folder)
   (if (string= folder wl-trash-folder)
       'null
@@ -1832,10 +1882,10 @@ If ARG is non-nil, checking is omitted."
                   (error "Trash Folder is not created"))))
               wl-trash-folder)))))
 
-(defun wl-summary-insert-message (&rest args)
+(defun wl-summary-get-append-message-func ()
   (if (eq wl-summary-buffer-view 'thread)
-      (apply 'wl-summary-insert-thread-entity args)
-    (apply 'wl-summary-insert-sequential args)))
+      'wl-summary-insert-thread-entity
+    'wl-summary-insert-sequential))
 
 (defun wl-summary-sort ()
   (interactive)
@@ -1851,9 +1901,8 @@ If ARG is non-nil, checking is omitted."
   "Update marks in summary."
   (interactive)
   (let ((last-progress 0)
-       (folder wl-summary-buffer-elmo-folder)
        (i 0)
-       importants unreads
+       unread-marks importants unreads
        importants-in-db unreads-in-db diff diffs
        mes progress)
     ;; synchronize marks.
@@ -1861,27 +1910,27 @@ If ARG is non-nil, checking is omitted."
                    wl-summary-buffer-elmo-folder)
                   'internal))
       (message "Updating marks...")
-      (setq importants-in-db (elmo-folder-list-messages-mark-match
+      (setq unread-marks (list wl-summary-unread-cached-mark
+                              wl-summary-unread-uncached-mark
+                              wl-summary-new-mark)
+           importants-in-db (elmo-folder-list-messages-mark-match
                              wl-summary-buffer-elmo-folder
-                             (regexp-quote elmo-msgdb-important-mark))
+                             (regexp-quote wl-summary-important-mark))
            unreads-in-db (elmo-folder-list-messages-mark-match
                           wl-summary-buffer-elmo-folder
-                          (wl-regexp-opt (elmo-msgdb-unread-marks)))
-           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)))
+                          (wl-regexp-opt unread-marks))
+           importants (elmo-folder-list-importants
+                       wl-summary-buffer-elmo-folder
+                       wl-summary-important-mark)
            unreads (elmo-folder-list-unreads
-                    wl-summary-buffer-elmo-folder))
+                    wl-summary-buffer-elmo-folder
+                    unread-marks))
       (setq diff (elmo-list-diff importants importants-in-db))
       (setq diffs (cadr diff)) ; important-deletes
       (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
@@ -1893,12 +1942,12 @@ If ARG is non-nil, checking is omitted."
       (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)
+       (wl-summary-mark-as-read (car diffs) 'no-folder)
        (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)
+       (wl-summary-mark-as-unread (car diffs) 'no-server 'no-modeline)
        (setq diffs (cdr diffs)))
       (if (interactive-p) (message mes)))))
 
@@ -1912,22 +1961,34 @@ If ARG is non-nil, checking is omitted."
         (buffer-read-only nil)
         gc-message
         overview number-alist
-        curp num i diff
+        curp num i new-msgdb
         append-list delete-list crossed
         update-thread update-top-list
-        expunged mes entity)
+        expunged mes sync-result entity)
     (unwind-protect
        (progn
          (unless wl-summary-buffer-elmo-folder
            (error "(Internal error) Folder is not set:%s" (buffer-name
                                                            (current-buffer))))
+         (fset 'wl-summary-append-message-func-internal
+               (wl-summary-get-append-message-func))
          ;; Flush pending append operations (disconnected operation).
          ;;(setq seen-list
          ;;(wl-summary-flush-pending-append-operations seen-list))
          (goto-char (point-max))
          (wl-folder-confirm-existence folder (elmo-folder-plugged-p folder))
-         (setq crossed (elmo-folder-synchronize folder sync-all no-check))
-         (if crossed
+         (setq sync-result (elmo-folder-synchronize
+                            folder
+                            wl-summary-new-mark
+                            wl-summary-unread-uncached-mark
+                            wl-summary-unread-cached-mark
+                            wl-summary-read-uncached-mark
+                            wl-summary-important-mark
+                            sync-all no-check))
+         (setq new-msgdb (nth 0 sync-result))
+         (setq delete-list (nth 1 sync-result))
+         (setq crossed (nth 2 sync-result))
+         (if sync-result
              (progn
                ;; Setup sync-all
                (if sync-all (wl-summary-sync-all-init))
@@ -1938,24 +1999,19 @@ If ARG is non-nil, checking is omitted."
 ;            (wl-summary-delete-canceled-msgs-from-list
 ;             delete-list
 ;             (wl-summary-buffer-msgdb))))
-               (setq diff (elmo-list-diff (elmo-folder-list-messages
-                                           folder
-                                           'visible-only
-                                           'in-msgdb)
-                                          wl-summary-buffer-number-list))
-               (setq append-list (car diff))
-               (setq delete-list (cadr diff))
-               
                (when delete-list
-                 (wl-summary-delete-messages-on-buffer
-                  delete-list "Deleting...")
+                 (wl-summary-delete-messages-on-buffer delete-list "Deleting...")
                  (message "Deleting...done"))
-               (wl-summary-update-status-marks)
+               (when new-msgdb
+                 (wl-summary-replace-status-marks
+                  wl-summary-new-mark
+                  wl-summary-unread-uncached-mark))
+               (setq append-list (elmo-msgdb-get-overview new-msgdb))
                (setq curp append-list)
                (setq num (length curp))
                (when append-list
                  (setq i 0)
-                 
+
                  ;; set these value for append-message-func
                  (setq overview (elmo-msgdb-get-overview
                                  (elmo-folder-msgdb folder)))
@@ -1965,10 +2021,9 @@ If ARG is non-nil, checking is omitted."
                  (setq wl-summary-delayed-update nil)
                  (elmo-kill-buffer wl-summary-search-buf-name)
                  (while curp
-                   (setq entity (elmo-msgdb-overview-get-entity
-                                 (car curp) (elmo-folder-msgdb folder)))
+                   (setq entity (car curp))
                    (when (setq update-thread
-                               (wl-summary-insert-message
+                               (wl-summary-append-message-func-internal
                                 entity (elmo-folder-msgdb folder)
                                 (not sync-all)))
                      (wl-append update-top-list update-thread))
@@ -1981,10 +2036,7 @@ If ARG is non-nil, checking is omitted."
                      (setq i (+ i 1))
                      (if (or (zerop (% i 5)) (= i num))
                          (elmo-display-progress
-                          'wl-summary-sync-update
-                          (if (eq wl-summary-buffer-view 'thread)
-                              "Making thread..."
-                            "Inserting message...")
+                          'wl-summary-sync-update "Updating thread..."
                           (/ (* i 100) num)))))
                  (when wl-summary-delayed-update
                    (while wl-summary-delayed-update
@@ -1993,7 +2045,7 @@ If ARG is non-nil, checking is omitted."
                               (elmo-msgdb-overview-entity-get-number
                                (cdar wl-summary-delayed-update)))
                      (when (setq update-thread
-                                 (wl-summary-insert-message
+                                 (wl-summary-append-message-func-internal
                                   (cdar wl-summary-delayed-update)
                                   (elmo-folder-msgdb folder)
                                   (not sync-all) t))
@@ -2004,15 +2056,16 @@ If ARG is non-nil, checking is omitted."
                             update-top-list)
                    (wl-thread-update-indent-string-thread
                     (elmo-uniq-list update-top-list)))
-                 (message (if (eq wl-summary-buffer-view 'thread)
-                              "Making thread...done"
-                            "Inserting message...done")))
+                 (message "Updating thread...done"))
+               (unless (eq wl-summary-buffer-view 'thread)
+                 (wl-summary-make-number-list))
                (wl-summary-set-message-modified)
+               (wl-summary-set-mark-modified)
                (when (and sync-all (eq wl-summary-buffer-view 'thread))
                  (elmo-kill-buffer wl-summary-search-buf-name)
-                 (message "Inserting message...")
+                 (message "Inserting thread...")
                  (wl-thread-insert-top)
-                 (message "Inserting message...done"))
+                 (message "Inserting thread...done"))
                (if elmo-use-database
                    (elmo-database-close))
                (run-hooks 'wl-summary-sync-updated-hook)
@@ -2026,7 +2079,7 @@ If ARG is non-nil, checking is omitted."
                                (length delete-list) num))))
            (setq mes "Quit updating.")))
       ;; synchronize marks.
-      (if (and crossed wl-summary-auto-sync-marks)
+      (if (and wl-summary-auto-sync-marks sync-result)
          (wl-summary-sync-marks))
       ;; scoring
       (when wl-use-scoring
@@ -2051,8 +2104,8 @@ If ARG is non-nil, checking is omitted."
       (wl-folder-set-folder-updated
        (elmo-folder-name-internal folder)
        (list 0
-            (let ((lst (wl-summary-count-unread)))
-              (+ (car lst) (nth 1 lst)))
+            (let ((pair (wl-summary-count-unread)))
+              (+ (car pair) (cdr pair)))
             (elmo-folder-messages folder)))
       (wl-summary-update-modeline)
       ;;
@@ -2162,6 +2215,7 @@ If ARG is non-nil, checking is omitted."
                                    dels)
 ;;;        (elmo-msgdb-save (wl-summary-buffer-folder-name) nil)
            (wl-summary-set-message-modified)
+           (wl-summary-set-mark-modified)
            (wl-folder-set-folder-updated (wl-summary-buffer-folder-name)
                                          (list 0 0 0))
 ;;; for thread.
@@ -2272,6 +2326,7 @@ If ARG, without confirm."
                   wl-summary-buffer-temp-mark-column
                   wl-summary-buffer-persistent-mark-column
                   wl-summary-buffer-message-modified
+                  wl-summary-buffer-mark-modified
                   wl-summary-buffer-thread-modified
                   wl-summary-buffer-number-list
                   wl-summary-buffer-msgdb
@@ -2327,15 +2382,10 @@ If ARG, without confirm."
        (get-buffer-create wl-summary-buffer-name))))
 
 (defun wl-summary-make-number-list ()
-  (save-excursion
-    (goto-char (point-min))
-    (while (not (eobp))
-      (setq wl-summary-buffer-number-list
-           (cons (wl-summary-message-number)
-                 wl-summary-buffer-number-list))
-      (forward-line 1))
-    (setq wl-summary-buffer-number-list
-         (nreverse wl-summary-buffer-number-list))))
+  (setq wl-summary-buffer-number-list
+       (mapcar
+        (lambda (x) (elmo-msgdb-overview-entity-get-number x))
+        (elmo-msgdb-get-overview (wl-summary-buffer-msgdb)))))
 
 (defun wl-summary-auto-select-msg-p (unread-msg)
   (and unread-msg
@@ -2343,7 +2393,7 @@ If ARG, without confirm."
             (elmo-msgdb-get-mark
              (wl-summary-buffer-msgdb)
              unread-msg)
-            elmo-msgdb-important-mark))))
+            wl-summary-important-mark))))
 
 (defsubst wl-summary-open-folder (folder)
   ;; Select folder
@@ -2523,15 +2573,15 @@ If ARG, without confirm."
          (if (and interactive wl-summary-recenter)
              (recenter (/ (- (window-height) 2) 2))))))
     ;; set current entity-id
-    (if (and (not folder)
-            (setq entity
-                  (wl-folder-search-entity-by-name (elmo-folder-name-internal
-                                                    folder)
-                                                   wl-folder-entity
-                                                   'folder)))
-       ;; entity-id is unknown.
-       (wl-folder-set-current-entity-id
-        (wl-folder-get-entity-id entity)))
+    (when (and folder
+              (setq entity
+                    (wl-folder-search-entity-by-name
+                     (elmo-folder-name-internal folder)
+                     wl-folder-entity
+                     'folder)))
+      ;; entity-id is unknown.
+      (wl-folder-set-current-entity-id
+       (wl-folder-get-entity-id entity)))
     (when (and wl-summary-lazy-highlight
               wl-on-xemacs)
       (sit-for 0))
@@ -2589,11 +2639,7 @@ If ARG, without confirm."
                             (elmo-msgdb-get-mark
                              msgdb
                              (elmo-msgdb-overview-entity-get-number
-                              entity))))
-    (setq wl-summary-buffer-number-list
-         (wl-append wl-summary-buffer-number-list
-                    (list (elmo-msgdb-overview-entity-get-number entity))))
-    nil))
+                              entity))))))
 
 (defun wl-summary-default-subject-filter (subject)
   (let ((case-fold-search t))
@@ -2615,7 +2661,6 @@ If ARG, without confirm."
                        wl-summary-alike-hashtb)))
 
 (defun wl-summary-insert-headers (overview func mime-decode)
-  (message "Creating subject cache...")
   (let (ov this last alike)
     (buffer-disable-undo (current-buffer))
     (make-local-variable 'wl-summary-alike-hashtb)
@@ -2626,7 +2671,7 @@ If ARG, without confirm."
       (setq this (funcall func ov))
       (and this (setq this (std11-unfold-string this)))
       (if (equal last this)
-         (wl-append alike (list ov))
+         (setq alike (cons ov alike))
        (when last
          (wl-summary-put-alike alike)
          (insert last ?\n))
@@ -2640,54 +2685,59 @@ If ARG, without confirm."
                                  elmo-mime-charset)
       (when (eq mime-decode 'mime)
        (eword-decode-region (point-min) (point-max))))
-    (message "Creating subject cache...done")
     (run-hooks 'wl-summary-insert-headers-hook)))
 
 (defun wl-summary-search-by-subject (entity overview)
   (let ((summary-buf (current-buffer))
        (buf (get-buffer-create wl-summary-search-buf-name))
        (folder-name (wl-summary-buffer-folder-name))
-       match founds found-entity)
+       match founds cur result)
     (with-current-buffer buf
       (let ((case-fold-search t))
        (when (or (not (string= wl-summary-search-buf-folder-name folder-name))
                  (zerop (buffer-size)))
          (setq wl-summary-search-buf-folder-name folder-name)
+         (message "Creating subject cache...")
          (wl-summary-insert-headers
           overview
           (function
            (lambda (x)
              (funcall wl-summary-subject-filter-function
-              (elmo-msgdb-overview-entity-get-subject-no-decode x))))
-          t))
+                      (elmo-msgdb-overview-entity-get-subject-no-decode x))))
+          t)
+         (message "Creating subject cache...done"))
        (setq match (funcall wl-summary-subject-filter-function
                             (elmo-msgdb-overview-entity-get-subject entity)))
        (if (string= match "")
            (setq match "\n"))
-       (goto-char (point-min))
-       (while (and (not founds)
-                   (not (= (point) (point-max)))
-                   (search-forward match nil t))
+       (goto-char (point-max))
+       (while (and (null result)
+                   (not (= (point) (point-min)))
+                   (search-backward match nil t))
          ;; check exactly match
-         (when (and (eolp)
-                    (= (point-at-bol)
-                       (match-beginning 0)))
-           (setq found-entity (wl-summary-get-alike))
-           (if (and found-entity
-                    ;; Is founded entity myself or children?
-                    (not (string=
-                          (elmo-msgdb-overview-entity-get-id entity)
-                          (elmo-msgdb-overview-entity-get-id
-                           (car found-entity))))
-                    (with-current-buffer summary-buf
+         (when (and (bolp) (= (point-at-eol)(match-end 0)))
+           (setq founds (wl-summary-get-alike))
+           (with-current-buffer summary-buf
+             (while founds
+               (when (and
+                      ;; the first element of found-entity list exists on
+                      ;; thread tree.
+                      (wl-thread-get-entity
+                       (elmo-msgdb-overview-entity-get-number
+                        (car founds)))
+                      ;; message id is not same as myself.
+                      (not (string=
+                            (elmo-msgdb-overview-entity-get-id entity)
+                            (elmo-msgdb-overview-entity-get-id (car founds))))
+                      ;; not a descendant.
                       (not (wl-thread-descendant-p
                             (elmo-msgdb-overview-entity-get-number entity)
                             (elmo-msgdb-overview-entity-get-number
-                             (car found-entity))))))
-               ;; return matching entity
-               (setq founds found-entity))))
-       (if founds
-           (car founds))))))
+                             (car founds)))))
+                 (setq result (car founds)
+                       founds nil))
+               (setq founds (cdr founds))))))
+       result))))
 
 (defun wl-summary-insert-thread-entity (entity msgdb update
                                               &optional force-insert)
@@ -2766,60 +2816,94 @@ If ARG, without confirm."
         (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-number (elmo-msgdb-overview-entity-get-number parent-entity))
+        insert-line)
     (cond
      ((or (not parent-id)
          (string= this-id parent-id))
       (goto-char (point-max))
-      (beginning-of-line))
+      (beginning-of-line)
+      (setq insert-line t))
      ;; parent already exists in buffer.
      ((wl-summary-jump-to-msg parent-number)
-      (wl-thread-goto-bottom-of-sub-thread)))
-    (let ((inhibit-read-only t)
-         (buffer-read-only nil))
-      (wl-summary-insert-line
-       (wl-summary-create-line
-       entity
-       parent-entity
-       nil
-       (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) number)
-       (wl-thread-maybe-get-children-num number)
-       (wl-thread-make-indent-string thr-entity)
-       (wl-thread-entity-get-linked thr-entity))))))
+      (wl-thread-goto-bottom-of-sub-thread)
+      (setq insert-line t)))
+    (when insert-line
+      (let (buffer-read-only)
+       (wl-summary-insert-line
+        (wl-summary-create-line
+         entity
+         parent-entity
+         nil
+         (elmo-msgdb-get-mark (wl-summary-buffer-msgdb) 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-mark-as-unread (&optional number
-                                           no-folder-mark
+                                           no-server-update
                                            no-modeline-update)
   (interactive)
   (save-excursion
-    (let ((buffer-read-only nil)
+    (let* (eol
+         (inhibit-read-only t)
+         (buffer-read-only nil)
          (folder wl-summary-buffer-elmo-folder)
-         mark new-mark visible)
-      (setq visible (if number
-                       (wl-summary-jump-to-msg number)
-                     t)
-           number (or number (wl-summary-message-number))
-           mark (elmo-message-mark folder number))
-      (unless (member mark (elmo-msgdb-unread-marks))
-       (elmo-folder-unmark-read folder (list number) no-folder-mark))
-      (setq new-mark (elmo-message-mark folder number))
-      (unless no-modeline-update
-       ;; Update unread numbers.
-       ;; should elmo-folder-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)))
+         (msgdb (wl-summary-buffer-msgdb))
+;;;      (number-alist (elmo-msgdb-get-number-alist msgdb))
+         new-mark visible mark cur-mark)
+      (if number
+         (progn
+           (setq visible (wl-summary-jump-to-msg number))
+           (unless (setq mark (elmo-msgdb-get-mark msgdb number))
+             (setq mark " ")))
+       ;; interactive
+       (setq visible t))
       (when visible
-       (unless (string= (wl-summary-persistent-mark) new-mark)
-         (delete-backward-char 1)
-         (insert (or new-mark " "))
-         (if (and visible wl-summary-highlight)
-             (wl-highlight-summary-current-line))
-         (set-buffer-modified-p nil)))
-      number)))
+       (if (null (wl-summary-message-number))
+           (message "No message.")
+         (end-of-line)
+         (setq eol (point))
+         (wl-summary-goto-previous-message-beginning)))
+      (if (or (and (not visible)
+                  ;; already exists in msgdb.
+                  (elmo-msgdb-overview-get-entity number msgdb))
+             (progn
+               ;; visible.
+               (setq cur-mark (wl-summary-persistent-mark))
+               (or (string= cur-mark " ")
+                   (string= cur-mark wl-summary-read-uncached-mark))))
+         (progn
+           (setq number (or number (wl-summary-message-number)))
+           (setq mark (or mark cur-mark))
+           (save-match-data
+             (setq new-mark (if (string= mark
+                                         wl-summary-read-uncached-mark)
+                                wl-summary-unread-uncached-mark
+                              (if (elmo-message-use-cache-p folder number)
+                                  wl-summary-unread-mark
+                                wl-summary-unread-uncached-mark))))
+           ;; server side mark
+           (unless no-server-update
+             (save-match-data
+               (unless (elmo-folder-unmark-read folder (list number))
+                 (error "Setting mark failed"))))
+           (when visible
+             (delete-backward-char 1)
+             (insert new-mark))
+           (elmo-msgdb-set-mark msgdb number new-mark)
+           (unless no-modeline-update
+             (setq wl-summary-buffer-unread-count
+                   (+ 1 wl-summary-buffer-unread-count))
+             (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-set-mark-modified)
+           (if (and visible wl-summary-highlight)
+               (wl-highlight-summary-current-line))))))
+  (set-buffer-modified-p nil))
 
 (defun wl-summary-delete (&optional number)
   "Mark a delete mark 'D'.
@@ -2910,7 +2994,8 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
          (while (not (eobp))
            (when (string= (wl-summary-temp-mark) mark)
              (setq msglist (cons (wl-summary-message-number) msglist)))
-           (forward-line 1)))))))
+           (forward-line 1))
+         (nreverse msglist))))))
 
 (defun wl-summary-exec ()
   (interactive)
@@ -2920,7 +3005,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
 
 (defun wl-summary-exec-region (beg end)
   (interactive "r")
-  (message "Collecting marks ...")
+  (message "Collecting marks...")
   (save-excursion
     (goto-char beg)
     (beginning-of-line)
@@ -2939,6 +3024,9 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
       (let ((del-fld (wl-summary-get-delete-folder
                      (wl-summary-buffer-folder-name)))
            (start (point))
+           (unread-marks (list wl-summary-unread-cached-mark
+                               wl-summary-unread-uncached-mark
+                               wl-summary-new-mark))
            (refiles (append moves dels))
            (refile-failures 0)
            (copy-failures 0)
@@ -2946,7 +3034,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
            refile-len
            dst-msgs                    ; loop counter
            result)
-       (message "Executing ...")
+       (message "Executing...")
        (while dels
          (when (not (assq (car dels) wl-summary-buffer-refile-list))
            (wl-append wl-summary-buffer-refile-list
@@ -2977,6 +3065,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
                            (not (null (cdr dst-msgs)))
                            nil ; no-delete
                            nil ; same-number
+                           unread-marks
                            t))
            (error nil))
          (if result                    ; succeeded.
@@ -3009,6 +3098,7 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
                            (not (null (cdr dst-msgs)))
                            t ; t is no-delete (copy)
                            nil ; same number
+                           unread-marks
                            t))
            (error nil))
          (if result                    ; succeeded.
@@ -3027,14 +3117,17 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
        ;; end cOpy
        (wl-summary-folder-info-update)
        (wl-summary-set-message-modified)
+       (wl-summary-set-mark-modified)
        (run-hooks 'wl-summary-exec-hook)
+       ;; message buffer is not up-to-date
        (unless (and wl-message-buffer
                     (eq (wl-summary-message-number)
                         (with-current-buffer wl-message-buffer
                           wl-message-buffer-cur-number)))
-         (wl-summary-toggle-disp-msg 'off))
+         (wl-summary-toggle-disp-msg 'off)
+         (setq wl-message-buffer nil))
        (set-buffer-modified-p nil)
-       (message (concat "Executing ... done"
+       (message (concat "Executing...done"
                         (if (> refile-failures 0)
                             (format " (%d refiling failed)" refile-failures)
                           "")
@@ -3091,7 +3184,8 @@ If optional argument NUMBER is specified, mark message specified by NUMBER."
        (setq c (+ c (char-width (following-char)))))
       (and (> c len) (setq folder (concat " " folder)))
       (setq rs (point))
-      (put-text-property rs re 'invisible t)
+      (when wl-summary-width
+         (put-text-property rs re 'invisible t))
       (put-text-property rs re 'wl-summary-destination t)
       (goto-char re)
       (wl-highlight-refile-destination-string folder)
@@ -3674,7 +3768,7 @@ If ARG, exit virtual folder."
          (setq skipped (cons (car mlist) skipped)))
        (setq mlist (cdr mlist)))
       (setq wl-summary-buffer-target-mark-list skipped)
-      (message "Prefetching... %d/%d message(s)." count length)
+      (message "Prefetching... %d/%d message(s)" count length)
       (set-buffer-modified-p nil))))
 
 (defun wl-summary-target-mark-refile-subr (copy-or-refile)
@@ -3856,44 +3950,69 @@ If ARG, exit virtual folder."
   (interactive)
   (wl-summary-pick wl-summary-buffer-target-mark-list 'delete))
 
-(defun wl-summary-mark-as-read (&optional number
-                                         no-folder-mark
-                                         no-modeline-update)
+(defun wl-summary-mark-as-read (&optional number no-folder-mark)
   (interactive)
   (save-excursion
     (let ((buffer-read-only nil)
          (folder wl-summary-buffer-elmo-folder)
          (msgdb (wl-summary-buffer-msgdb))
          (case-fold-search nil)
-         mark visible new-mark)
-      (setq visible (if number
+         cur-mark mark stat visible uncached new-mark marked)
+      (setq number (or number (wl-summary-message-number))
+           visible (if number
                        (wl-summary-jump-to-msg number)
                      ;; interactive
                      t)
-           number (or number (wl-summary-message-number))
-           mark (elmo-message-mark folder number))
-      (when (member mark (elmo-msgdb-unread-marks))
-       ;; folder mark.
-       (elmo-folder-mark-as-read folder (list number) no-folder-mark))
-      (setq new-mark (elmo-message-mark folder number))
-      (unless no-modeline-update
-       ;; Update unread numbers.
-       ;; should elmo-folder-mark-as-read return unread numbers?
-       (wl-summary-count-unread)
+           mark (elmo-msgdb-get-mark msgdb number))
+      (cond
+       ((string= mark wl-summary-new-mark) ; N
+       (setq stat 'new))
+       ((string= mark wl-summary-unread-uncached-mark) ; U
+       (setq stat 'unread))
+       ((string= mark wl-summary-unread-cached-mark)  ; !
+       (setq stat 'unread))
+       ((string= mark wl-summary-read-uncached-mark)  ; u
+       (setq stat 'read))
+       (t
+       ;; no need to mark server.
+       (setq no-folder-mark t)))
+      (setq new-mark
+           (if (and (if (elmo-message-use-cache-p folder number)
+                        (not (elmo-folder-local-p folder)))
+                    (not (elmo-file-cache-exists-p
+                          (elmo-message-field wl-summary-buffer-elmo-folder
+                                              number 'message-id))))
+               wl-summary-read-uncached-mark
+             nil))
+      ;; folder mark.
+      (unless no-folder-mark
+       (setq marked (elmo-folder-mark-as-read folder (list number))))
+      (when (or no-folder-mark marked)
+       (cond ((eq stat 'unread)
+              (setq wl-summary-buffer-unread-count
+                    (1- wl-summary-buffer-unread-count)))
+             ((eq stat 'new)
+              (setq wl-summary-buffer-new-count
+                    (1- wl-summary-buffer-new-count))))
        (wl-summary-update-modeline)
        (wl-folder-update-unread
         (wl-summary-buffer-folder-name)
         (+ wl-summary-buffer-unread-count
-           wl-summary-buffer-new-count)))
-      ;; set mark on buffer
-      (when visible
-       (unless (string= (wl-summary-persistent-mark) new-mark)
-         (delete-backward-char 1)
-         (insert (or new-mark " ")))
+           wl-summary-buffer-new-count))
+       (when stat
+         ;; set mark on buffer
+         (when visible
+           (unless (string= (wl-summary-persistent-mark) new-mark)
+             (delete-backward-char 1)
+             (insert (or new-mark " "))))
+         ;; set msgdb mark.
+         (unless (string= mark new-mark)
+           (elmo-msgdb-set-mark msgdb number new-mark))
+         (wl-summary-set-mark-modified))
        (if (and visible wl-summary-highlight)
-           (wl-highlight-summary-current-line nil nil t))
-       (set-buffer-modified-p nil))
-      (if (member mark (elmo-msgdb-unread-marks))
+           (wl-highlight-summary-current-line nil nil t)))
+      (set-buffer-modified-p nil)
+      (if stat
          (run-hooks 'wl-summary-unread-message-hook))
       number ;return value
       )))
@@ -3937,7 +4056,7 @@ If ARG, exit virtual folder."
                              wl-summary-buffer-elmo-folder
                              number
                              'message-id))
-           (if (string= mark elmo-msgdb-important-mark)
+           (if (string= mark wl-summary-important-mark)
                (progn
                  ;; server side mark
                  (save-match-data
@@ -3960,16 +4079,17 @@ If ARG, exit virtual folder."
                  (elmo-folder-mark-as-important folder (list number))))
              (when visible
                (delete-backward-char 1)
-               (insert elmo-msgdb-important-mark))
+               (insert wl-summary-important-mark))
              (elmo-msgdb-set-mark msgdb number
-                                  elmo-msgdb-important-mark)
+                                  wl-summary-important-mark)
              (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)))))
+                                           wl-summary-important-mark)))
+           (wl-summary-set-mark-modified)))
       (if (and visible wl-summary-highlight)
          (wl-highlight-summary-current-line nil nil t))))
   (set-buffer-modified-p nil)
@@ -3989,7 +4109,7 @@ If ARG, exit virtual folder."
   "Return non-nil when summary line format is changed."
   (not (string=
        wl-summary-buffer-line-format
-       (or (elmo-object-load (expand-file-name
+       (or (elmo-object-load (expand-file-name 
                               wl-summary-line-format-file
                               (elmo-folder-msgdb-path
                                wl-summary-buffer-elmo-folder))
@@ -4039,7 +4159,6 @@ If ARG, exit virtual folder."
         (t (format "%dB" size)))
       "")))
 
-(defvar wl-summary-line-subject-minimum-length nil)
 (defun wl-summary-line-subject ()
   (let (no-parent subject parent-raw-subject parent-subject)
     (if (string= wl-thr-indent-string "")
@@ -4054,24 +4173,12 @@ If ARG, exit virtual folder."
     (setq parent-subject
          (if parent-raw-subject
              (elmo-delete-char ?\n parent-raw-subject)))
-    (setq subject
-         (if (or no-parent
-                 (null parent-subject)
-                 (not (wl-summary-subject-equal
-                       subject parent-subject)))
-             (funcall wl-summary-subject-function subject)
-           ""))
-    (when (and wl-summary-line-subject-minimum-length
-              (< (string-width subject)
-                 wl-summary-line-subject-minimum-length))
-      (while (< (string-width subject)
-               wl-summary-line-subject-minimum-length)
-       (setq subject (concat subject " "))))
-    (if (and (not wl-summary-width)
-            wl-summary-subject-length-limit)
-       (truncate-string subject
-                        wl-summary-subject-length-limit)
-      subject)))
+    (if (or no-parent
+           (null parent-subject)
+           (not (wl-summary-subject-equal
+                 subject parent-subject)))
+       (funcall wl-summary-subject-function subject)
+      "")))
 
 (defun wl-summary-line-from ()
   (elmo-delete-char ?\n
@@ -4082,7 +4189,7 @@ If ARG, exit virtual folder."
 (defun wl-summary-line-list-info ()
   (let ((list-info (wl-summary-get-list-info wl-message-entity)))
     (if (car list-info)
-       (format (if (cdr list-info) "(%s %05d)" "(%s)")
+       (format (if (cdr list-info) "(%s %05.0f)" "(%s)")
                (car list-info) (cdr list-info))
       "")))
 
@@ -4153,25 +4260,25 @@ If ARG, exit virtual folder."
 
 (defvar wl-summary-move-spec-plugged-alist
   (` ((new . ((t . nil)
-             (p . (, elmo-msgdb-new-mark))
+             (p . (, wl-summary-new-mark))
              (p . (, (wl-regexp-opt
-                      (list elmo-msgdb-unread-uncached-mark
-                            elmo-msgdb-unread-cached-mark))))
-             (p . (, (regexp-quote elmo-msgdb-important-mark)))))
+                      (list wl-summary-unread-uncached-mark
+                            wl-summary-unread-cached-mark))))
+             (p . (, (regexp-quote wl-summary-important-mark)))))
       (unread . ((t . nil)
                 (p . (, (wl-regexp-opt
-                         (list elmo-msgdb-new-mark
-                               elmo-msgdb-unread-uncached-mark
-                               elmo-msgdb-unread-cached-mark))))
-                (p . (, (regexp-quote elmo-msgdb-important-mark))))))))
+                         (list wl-summary-new-mark
+                               wl-summary-unread-uncached-mark
+                               wl-summary-unread-cached-mark))))
+                (p . (, (regexp-quote wl-summary-important-mark))))))))
 
 (defvar wl-summary-move-spec-unplugged-alist
   (` ((new . ((t . nil)
-             (p . (, elmo-msgdb-unread-cached-mark))
-             (p . (, (regexp-quote elmo-msgdb-important-mark)))))
+             (p . (, wl-summary-unread-cached-mark))
+             (p . (, (regexp-quote wl-summary-important-mark)))))
       (unread . ((t . nil)
-                (p . (, elmo-msgdb-unread-cached-mark))
-                (p . (, (regexp-quote elmo-msgdb-important-mark))))))))
+                (p . (, wl-summary-unread-cached-mark))
+                (p . (, (regexp-quote wl-summary-important-mark))))))))
 
 (defsubst wl-summary-next-message (num direction hereto)
   (if wl-summary-buffer-next-message-function
@@ -4270,7 +4377,7 @@ If ARG, exit virtual folder."
                (wl-summary-delete-all-temp-marks)
                (encode-coding-region
                 (point-min) (point-max)
-                (or (and wl-on-mule ; one in mcs-ltn1 cannot take 2 arg.
+                (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)))
@@ -4886,8 +4993,8 @@ Use function list is `wl-summary-write-current-folder-functions'."
        ()
       (setq skip-pmark-regexp
            (wl-regexp-opt (list " "
-                                elmo-msgdb-unread-cached-mark
-                                elmo-msgdb-important-mark))))
+                                wl-summary-unread-cached-mark
+                                wl-summary-important-mark))))
     (while (and skip
                (not (if downward (eobp) (bobp))))
       (if downward
@@ -4912,8 +5019,12 @@ Use function list is `wl-summary-write-current-folder-functions'."
        (if wl-summary-buffer-disp-msg
            (wl-summary-redisplay))
       (if interactive
-         (if wl-summary-buffer-next-folder-function
-             (funcall wl-summary-buffer-next-folder-function)
+         (cond
+          ((and (not downward) wl-summary-buffer-prev-folder-function)
+           (funcall wl-summary-buffer-prev-folder-function))
+          ((and downward wl-summary-buffer-next-folder-function)
+           (funcall wl-summary-buffer-next-folder-function))
+          (t
            (when wl-auto-select-next
              (setq next-entity
                    (if downward
@@ -4925,7 +5036,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
             '(lambda () (wl-summary-next-folder-or-exit next-entity))
             (format
              "No more messages. Type SPC to go to %s."
-             (wl-summary-entity-info-msg next-entity finfo))))))))
+             (wl-summary-entity-info-msg next-entity finfo)))))))))
 
 (defun wl-summary-prev (&optional interactive)
   (interactive)
@@ -5045,7 +5156,7 @@ Use function list is `wl-summary-write-current-folder-functions'."
         (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)
     (if (and wl-thread-open-reading-thread
             (eq wl-summary-buffer-view 'thread)
             (not (wl-thread-entity-get-opened
@@ -5064,25 +5175,23 @@ 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)))
-         (if (elmo-message-use-cache-p folder num)
-             (elmo-message-set-cached folder num t))
-         (wl-summary-mark-as-read num no-folder-mark)
+         (wl-summary-mark-as-read
+          num
+          ;; not fetched, then change server-mark.
+          (if (wl-message-redisplay folder num 'mime
+                                    (or force-reload
+                                        (string= (elmo-folder-name-internal
+                                                  folder)
+                                                 wl-draft-folder)))
+              nil
+            ;; plugged, then leave server-mark.
+            (if (and
+                 (not
+                  (elmo-folder-local-p
+                   wl-summary-buffer-elmo-folder))
+                 (elmo-folder-plugged-p
+                  wl-summary-buffer-elmo-folder))
+                'leave)))
          (setq wl-summary-buffer-current-msg num)
          (when wl-summary-recenter
            (recenter (/ (- (window-height) 2) 2))