* elmo.el (elmo-generic-folder-append-messages): Set flag as nil
[elisp/wanderlust.git] / elmo / elmo-multi.el
1 ;;; elmo-multi.el --- Multiple Folder Interface for ELMO.
2
3 ;; Copyright (C) 1998,1999,2000 Yuuichi Teranishi <teranisi@gohome.org>
4
5 ;; Author: Yuuichi Teranishi <teranisi@gohome.org>
6 ;; Keywords: mail, net news
7
8 ;; This file is part of ELMO (Elisp Library for Message Orchestration).
9
10 ;; This program is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 2, or (at your option)
13 ;; any later version.
14 ;;
15 ;; This program is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
19 ;;
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
22 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
23 ;; Boston, MA 02111-1307, USA.
24 ;;
25
26 ;;; Commentary:
27 ;;
28
29 ;;; Code:
30 ;;
31
32 (require 'elmo)
33 (require 'luna)
34
35 (defvar elmo-multi-divide-number 100000
36   "*Multi divider number.")
37
38 ;;; ELMO Multi folder
39 (eval-and-compile
40   (luna-define-class elmo-multi-folder (elmo-folder)
41                      (children divide-number))
42   (luna-define-internal-accessors 'elmo-multi-folder))
43
44 (luna-define-method elmo-folder-initialize ((folder
45                                              elmo-multi-folder)
46                                             name)
47   (while (> (length (car (setq name (elmo-parse-token name ",")))) 0)
48     (elmo-multi-folder-set-children-internal
49      folder
50      (nconc (elmo-multi-folder-children-internal
51              folder)
52             (list (elmo-make-folder (car name)))))
53     (setq name (cdr name))
54     (when (and (> (length name) 0)
55                (eq (aref name 0) ?,))
56       (setq name (substring name 1))))
57   (elmo-multi-folder-set-divide-number-internal
58    folder
59    elmo-multi-divide-number)
60   folder)
61
62 (luna-define-method elmo-folder-open-internal ((folder elmo-multi-folder))
63   (dolist (fld (elmo-multi-folder-children-internal folder))
64     (elmo-folder-open-internal fld)))
65
66 (luna-define-method elmo-folder-check ((folder elmo-multi-folder))
67   (dolist (fld (elmo-multi-folder-children-internal folder))
68     (elmo-folder-check fld)))
69
70 (luna-define-method elmo-folder-close-internal ((folder elmo-multi-folder))
71   (dolist (fld (elmo-multi-folder-children-internal folder))
72     (elmo-folder-close-internal fld)))
73
74 (luna-define-method elmo-folder-close :after ((folder elmo-multi-folder))
75   (dolist (fld (elmo-multi-folder-children-internal folder))
76     (elmo-folder-set-msgdb-internal fld nil)))
77
78 (luna-define-method elmo-folder-synchronize ((folder elmo-multi-folder)
79                                              &optional ignore-msgdb
80                                              no-check)
81   (dolist (fld (elmo-multi-folder-children-internal folder))
82     (elmo-folder-synchronize fld ignore-msgdb no-check)))
83
84 (luna-define-method elmo-folder-expand-msgdb-path ((folder
85                                                     elmo-multi-folder))
86   (expand-file-name (elmo-replace-string-as-filename
87                      (elmo-folder-name-internal folder))
88                     (expand-file-name "multi"
89                                       elmo-msgdb-directory)))
90
91 (luna-define-method elmo-folder-newsgroups ((folder elmo-multi-folder))
92   (delq nil
93         (elmo-flatten
94          (mapcar
95           'elmo-folder-newsgroups
96           (elmo-flatten
97            (mapcar
98             'elmo-folder-get-primitive-list
99             (elmo-multi-folder-children-internal folder)))))))
100
101 (luna-define-method elmo-folder-get-primitive-list ((folder elmo-multi-folder))
102   (elmo-flatten
103    (mapcar
104     'elmo-folder-get-primitive-list
105     (elmo-multi-folder-children-internal folder))))
106
107 (luna-define-method elmo-folder-contains-type ((folder elmo-multi-folder) type)
108   (let ((children (elmo-multi-folder-children-internal folder))
109         match)
110     (while children
111       (when (elmo-folder-contains-type (car children) type)
112         (setq match t)
113         (setq children nil))
114       (setq children (cdr children)))
115     match))
116
117 (luna-define-method elmo-message-folder ((folder elmo-multi-folder)
118                                          number)
119   (nth (- (/ number (elmo-multi-folder-divide-number-internal folder)) 1)
120        (elmo-multi-folder-children-internal folder)))
121
122 (luna-define-method elmo-message-entity ((folder elmo-folder) key)
123   (cond
124    ((numberp key)
125     (elmo-msgdb-message-entity (elmo-folder-msgdb
126                                 (elmo-message-folder folder key))
127                                key))
128    ((stringp key)
129     (let ((children (elmo-multi-folder-children-internal folder))
130           match)
131       (while children
132         (when (setq match (elmo-message-entity (car children) key))
133           (setq children nil))
134         (setq children (cdr children)))
135       match))))
136
137 (defun elmo-multi-msgdb (msgdb base)
138   (list (mapcar (function
139                  (lambda (x)
140                    (elmo-msgdb-overview-entity-set-number
141                     x
142                     (+ base
143                        (elmo-msgdb-overview-entity-get-number x)))))
144                 (nth 0 msgdb))
145         (mapcar (function
146                  (lambda (x) (cons
147                               (+ base (car x))
148                               (cdr x))))
149                 (nth 1 msgdb))
150         (mapcar (function
151                  (lambda (x) (cons
152                               (+ base (car x))
153                               (cdr x)))) (nth 2 msgdb))))
154
155 (defun elmo-multi-split-numbers (folder numlist &optional as-is)
156   (let ((numbers (sort numlist '<))
157         (divider (elmo-multi-folder-divide-number-internal folder))
158         (cur-number 0)
159         one-list numbers-list)
160     (while numbers
161       (setq cur-number (+ cur-number 1))
162       (setq one-list nil)
163       (while (and numbers
164                   (eq 0
165                       (/ (- (car numbers)
166                             (* divider cur-number))
167                          divider)))
168         (setq one-list (nconc
169                         one-list
170                         (list
171                          (if as-is
172                              (car numbers)
173                            (% (car numbers)
174                               (* divider cur-number))))))
175         (setq numbers (cdr numbers)))
176       (setq numbers-list (nconc numbers-list (list one-list))))
177     numbers-list))
178
179 (luna-define-method elmo-folder-msgdb-create ((folder elmo-multi-folder)
180                                               numbers flag-table)
181   (let* ((folders (elmo-multi-folder-children-internal folder))
182          overview number-alist mark-alist entity
183          numbers-list
184          cur-number
185          i percent num
186          msgdb)
187     (setq numbers-list (elmo-multi-split-numbers folder numbers))
188     (setq cur-number 0)
189     (while (< cur-number (length folders))
190       (if (nth cur-number numbers-list)
191           (setq msgdb
192                 (elmo-msgdb-append
193                  msgdb
194                  (elmo-multi-msgdb
195                   (elmo-folder-msgdb-create (nth cur-number folders)
196                                             (nth cur-number numbers-list)
197                                             flag-table)
198                   (* (elmo-multi-folder-divide-number-internal folder)
199                      (1+ cur-number))))))
200       (setq cur-number (1+ cur-number)))
201     (elmo-msgdb-sort-by-date msgdb)))
202
203 (luna-define-method elmo-folder-process-crosspost ((folder elmo-multi-folder))
204   (dolist (child (elmo-multi-folder-children-internal folder))
205     (elmo-folder-process-crosspost child)))
206
207 (defsubst elmo-multi-folder-append-msgdb (folder append-msgdb)
208   (if append-msgdb
209       (let* ((number-alist (elmo-msgdb-get-number-alist append-msgdb))
210              (all-alist (copy-sequence (append
211                                         (elmo-msgdb-get-number-alist
212                                          (elmo-folder-msgdb folder))
213                                         number-alist)))
214              (cur number-alist)
215              overview to-be-deleted
216              mark-alist same)
217         (while cur
218           (setq all-alist (delq (car cur) all-alist))
219           ;; same message id exists.
220           (if (setq same (rassoc (cdr (car cur)) all-alist))
221               (unless (= (/ (car (car cur))
222                             (elmo-multi-folder-divide-number-internal folder))
223                          (/ (car same)
224                             (elmo-multi-folder-divide-number-internal folder)))
225                 ;; base is also same...delete it!
226                 (setq to-be-deleted
227                       (append to-be-deleted (list (car (car cur)))))))
228           (setq cur (cdr cur)))
229         (cond ((eq (elmo-folder-process-duplicates-internal folder)
230                    'hide)
231                ;; Hide duplicates.
232                (elmo-msgdb-append-to-killed-list folder to-be-deleted)
233                (setq overview (elmo-delete-if
234                                (lambda (x)
235                                  (memq (elmo-msgdb-overview-entity-get-number
236                                         x)
237                                        to-be-deleted))
238                                (elmo-msgdb-get-overview append-msgdb)))
239                ;; Should be mark as read.
240                (elmo-folder-mark-as-read folder to-be-deleted)
241                (elmo-msgdb-set-overview append-msgdb overview))
242               ((eq (elmo-folder-process-duplicates-internal folder)
243                    'read)
244                ;; Mark as read duplicates.
245                (elmo-folder-mark-as-read folder to-be-deleted))
246               (t
247                ;; Do nothing.
248                (setq to-be-deleted nil)))
249         (elmo-folder-set-msgdb-internal folder
250                                         (elmo-msgdb-append
251                                          (elmo-folder-msgdb folder)
252                                          append-msgdb))
253         (length to-be-deleted))
254     0))
255
256 (luna-define-method elmo-folder-append-msgdb ((folder elmo-multi-folder)
257                                               append-msgdb)
258   (elmo-multi-folder-append-msgdb folder append-msgdb))
259
260 (defmacro elmo-multi-real-folder-number (folder number)
261   "Returns a cons cell of real FOLDER and NUMBER."
262   (` (cons (nth (- 
263                  (/ (, number)
264                     (elmo-multi-folder-divide-number-internal (, folder)))
265                  1) (elmo-multi-folder-children-internal (, folder)))
266            (% (, number) (elmo-multi-folder-divide-number-internal
267                           (, folder))))))
268
269 (defsubst elmo-multi-find-fetch-strategy (folder entity ignore-cache)
270   (if entity
271       (let ((pair (elmo-multi-real-folder-number
272                    folder
273                    (elmo-msgdb-overview-entity-get-number entity)))
274             (new-entity (elmo-msgdb-copy-overview-entity entity)))
275         (setq new-entity
276               (elmo-msgdb-overview-entity-set-number new-entity (cdr pair)))
277         (elmo-find-fetch-strategy (car pair) new-entity ignore-cache))
278     (elmo-make-fetch-strategy 'entire)))
279
280 (luna-define-method elmo-find-fetch-strategy
281   ((folder elmo-multi-folder)
282    entity &optional ignore-cache)
283   (elmo-multi-find-fetch-strategy folder entity ignore-cache))
284
285 (luna-define-method elmo-message-fetch ((folder elmo-multi-folder)
286                                         number strategy
287                                         &optional section outbuf unseen)
288   (let ((pair (elmo-multi-real-folder-number folder number)))
289     (elmo-message-fetch (car pair) (cdr pair) strategy section outbuf unseen)))
290
291 (luna-define-method elmo-folder-delete-messages ((folder elmo-multi-folder)
292                                                  numbers)
293   (let ((flds (elmo-multi-folder-children-internal folder))
294         one-list-list
295         (cur-number 0))
296     (setq one-list-list (elmo-multi-split-numbers folder numbers))
297     (while (< cur-number (length flds))
298       (elmo-folder-delete-messages (nth cur-number flds)
299                                    (nth cur-number one-list-list))
300       (setq cur-number (+ 1 cur-number)))
301     t))
302
303 (luna-define-method elmo-folder-diff ((folder elmo-multi-folder)
304                                       &optional numbers)
305   (elmo-multi-folder-diff folder numbers))
306
307 (defun elmo-multi-folder-diff (folder numbers)
308   (let ((flds (elmo-multi-folder-children-internal folder))
309         (numbers (mapcar 'car
310                          (elmo-msgdb-number-load
311                           (elmo-folder-msgdb-path folder))))
312         (killed (elmo-msgdb-killed-list-load (elmo-folder-msgdb-path folder)))
313         (count 0)
314         (unsync 0)
315         (messages 0)
316         num-list
317         diffs nums)
318     ;; If first time, dummy numbers is used as current number list.
319     (unless numbers
320       (let ((i 0)
321             (divider (elmo-multi-folder-divide-number-internal folder)))
322         (dolist (folder flds)
323           (setq i (+ i 1))
324           (setq numbers
325                 (cons (* i divider) numbers)))))
326     (setq num-list
327           (elmo-multi-split-numbers folder
328                                     (elmo-uniq-list
329                                      (nconc
330                                       (elmo-number-set-to-number-list killed)
331                                       numbers))))
332     (while flds
333       (setq nums (elmo-folder-diff (car flds) (car num-list))
334             nums (cons (or (elmo-diff-unread nums)
335                            (elmo-diff-new nums))
336                        (elmo-diff-all nums)))
337       (setq diffs (nconc diffs (list nums)))
338       (setq count (+ 1 count))
339       (setq num-list (cdr num-list))
340       (setq flds (cdr flds)))
341     (while diffs
342       (and (car (car diffs))
343            (setq unsync (+ unsync (car (car diffs)))))
344       (setq messages  (+ messages (cdr (car diffs))))
345       (setq diffs (cdr diffs)))
346     (elmo-folder-set-info-hashtb folder nil messages)
347     (cons unsync messages)))
348
349 (defun elmo-multi-split-number-alist (folder number-alist)
350   (let ((alist (sort (copy-sequence number-alist)
351                      (lambda (pair1 pair2)
352                        (< (car pair1)(car pair2)))))
353         (cur-number 0)
354         one-alist split num)
355     (while alist
356       (setq cur-number (+ cur-number 1))
357       (setq one-alist nil)
358       (while (and alist
359                   (eq 0
360                       (/ (- (setq num (car (car alist)))
361                             (* elmo-multi-divide-number cur-number))
362                          (elmo-multi-folder-divide-number-internal folder))))
363         (setq one-alist (nconc
364                          one-alist
365                          (list
366                           (cons
367                            (% num (* (elmo-multi-folder-divide-number-internal
368                                       folder) cur-number))
369                            (cdr (car alist))))))
370         (setq alist (cdr alist)))
371       (setq split (nconc split (list one-alist))))
372     split))
373
374 (defun elmo-multi-split-mark-alist (folder mark-alist)
375   (let ((cur-number 0)
376         (alist (sort (copy-sequence mark-alist)
377                      (lambda (pair1 pair2)
378                        (< (car pair1)(car pair2)))))
379         one-alist result)
380     (while alist
381       (setq cur-number (+ cur-number 1))
382       (setq one-alist nil)
383       (while (and alist
384                   (eq 0
385                       (/ (- (car (car alist))
386                             (* (elmo-multi-folder-divide-number-internal
387                                 folder) cur-number))
388                          (elmo-multi-folder-divide-number-internal folder))))
389         (setq one-alist (nconc
390                          one-alist
391                          (list
392                           (list (% (car (car alist))
393                                    (* (elmo-multi-folder-divide-number-internal
394                                        folder) cur-number))
395                                 (cadr (car alist))))))
396         (setq alist (cdr alist)))
397       (setq result (nconc result (list one-alist))))
398     result))
399
400 (luna-define-method elmo-folder-list-unreads ((folder elmo-multi-folder))
401   (let ((cur-number 0)
402         unreads)
403     (dolist (child (elmo-multi-folder-children-internal folder))
404       (setq cur-number (+ cur-number 1))
405       (setq unreads
406             (nconc
407              unreads
408              (mapcar (lambda (x)
409                        (+ x (* cur-number
410                                (elmo-multi-folder-divide-number-internal
411                                 folder))))
412                      (elmo-folder-list-unreads child)))))
413     unreads))
414
415 (luna-define-method elmo-folder-list-answereds ((folder elmo-multi-folder))
416   (let ((cur-number 0)
417         answereds)
418     (dolist (child (elmo-multi-folder-children-internal folder))
419       (setq cur-number (+ cur-number 1))
420       (setq answereds
421             (nconc
422              answereds
423              (mapcar (lambda (x)
424                        (+ x (* cur-number
425                                (elmo-multi-folder-divide-number-internal
426                                 folder))))
427                      (elmo-folder-list-answereds child)))))
428     answereds))
429
430 (luna-define-method elmo-folder-list-importants ((folder elmo-multi-folder))
431   (let ((cur-number 0)
432         importants)
433     (dolist (child (elmo-multi-folder-children-internal folder))
434       (setq cur-number (+ cur-number 1))
435       (setq importants
436             (nconc
437              importants
438              (mapcar (lambda (x)
439                        (+ x (* cur-number
440                                (elmo-multi-folder-divide-number-internal
441                                 folder))))
442                      (elmo-folder-list-importants child)))))
443     (elmo-uniq-list
444      (nconc importants
445             (elmo-folder-list-messages-with-global-mark
446              folder elmo-msgdb-important-mark)))))
447
448 (luna-define-method elmo-folder-list-messages-internal
449   ((folder elmo-multi-folder) &optional nohide)
450   (let* ((flds (elmo-multi-folder-children-internal folder))
451          (cur-number 0)
452          list numbers)
453     (while flds
454       (setq cur-number (+ cur-number 1))
455       (setq list (elmo-folder-list-messages-internal (car flds)))
456       (setq numbers
457             (append
458              numbers
459              (if (listp list)
460                  (mapcar
461                   (function
462                    (lambda (x)
463                      (+
464                       (* (elmo-multi-folder-divide-number-internal
465                           folder) cur-number) x)))
466                   list)
467                ;; Use current list.
468                (elmo-delete-if
469                 (lambda (num)
470                   (not
471                    (eq cur-number (/ num
472                                      (elmo-multi-folder-divide-number-internal
473                                       folder)))))
474                 (mapcar
475                  'car
476                  (elmo-msgdb-get-number-alist
477                   (elmo-folder-msgdb folder)))))))
478       (setq flds (cdr flds)))
479     numbers))
480
481 (luna-define-method elmo-folder-exists-p ((folder elmo-multi-folder))
482   (let ((flds (elmo-multi-folder-children-internal folder)))
483     (catch 'exists
484       (while flds
485         (unless (elmo-folder-exists-p (car flds))
486           (throw 'exists nil))
487         (setq flds (cdr flds)))
488       t)))
489
490 (luna-define-method elmo-folder-creatable-p ((folder elmo-multi-folder))
491   (let ((flds (elmo-multi-folder-children-internal folder)))
492     (catch 'creatable
493       (while flds
494         (when (and (elmo-folder-creatable-p (car flds))
495                    (not (elmo-folder-exists-p (car flds))))
496           ;; If folder already exists, don't to `creatable'.
497           ;; Because this function is called, when folder doesn't exists.
498           (throw 'creatable t))
499         (setq flds (cdr flds)))
500       nil)))
501
502 (luna-define-method elmo-folder-create ((folder elmo-multi-folder))
503   (let ((flds (elmo-multi-folder-children-internal folder)))
504     (catch 'create
505       (while flds
506         (unless (or (elmo-folder-exists-p (car flds))
507                     (elmo-folder-create (car flds)))
508           (throw 'create nil))
509         (setq flds (cdr flds)))
510       t)))
511
512 (luna-define-method elmo-folder-search ((folder elmo-multi-folder)
513                                         condition &optional numlist)
514   (let* ((flds (elmo-multi-folder-children-internal folder))
515          (cur-number 0)
516          numlist-list cur-numlist ; for filtered search.
517          ret-val)
518     (if numlist
519         (setq numlist-list
520               (elmo-multi-split-numbers folder numlist t)))
521     (while flds
522       (setq cur-number (+ cur-number 1))
523       (when numlist
524         (setq cur-numlist (car numlist-list))
525         (if (null cur-numlist)
526             ;; t means filter all.
527             (setq cur-numlist t)))
528       (setq ret-val (append
529                      ret-val
530                      (elmo-list-filter
531                       cur-numlist
532                       (mapcar
533                        (function
534                         (lambda (x)
535                           (+
536                            (* (elmo-multi-folder-divide-number-internal
537                                folder) cur-number) x)))
538                        (elmo-folder-search
539                         (car flds) condition)))))
540       (when numlist
541         (setq numlist-list (cdr numlist-list)))
542       (setq flds (cdr flds)))
543     ret-val))
544
545 (luna-define-method elmo-message-use-cache-p ((folder elmo-multi-folder)
546                                               number)
547   (let ((pair (elmo-multi-real-folder-number folder number)))
548     (elmo-message-use-cache-p (car pair) (cdr pair))))
549
550 (luna-define-method elmo-message-file-p ((folder elmo-multi-folder) number)
551   (let ((pair (elmo-multi-real-folder-number folder number)))
552     (elmo-message-file-p (car pair) (cdr pair))))
553
554 (luna-define-method elmo-message-file-name ((folder elmo-multi-folder) number)
555   (let ((pair (elmo-multi-real-folder-number folder number)))
556     (elmo-message-file-name (car pair) (cdr pair))))
557
558 (luna-define-method elmo-folder-plugged-p ((folder elmo-multi-folder))
559   (let ((flds (elmo-multi-folder-children-internal folder)))
560     (catch 'plugged
561       (while flds
562         (unless (elmo-folder-plugged-p (car flds))
563           (throw 'plugged nil))
564         (setq flds (cdr flds)))
565       t)))
566
567 (luna-define-method elmo-folder-set-plugged ((folder elmo-multi-folder)
568                                              plugged add)
569   (let ((flds  (elmo-multi-folder-children-internal folder)))
570     (dolist (fld flds)
571       (elmo-folder-set-plugged fld plugged add))))
572
573 (defun elmo-multi-folder-numbers-list-assoc (folder folder-numbers)
574   (let (ent)
575     (while folder-numbers
576       (when (string= (elmo-folder-name-internal (car (car folder-numbers)))
577                      (elmo-folder-name-internal folder))
578         (setq ent (car folder-numbers)
579               folder-numbers nil))
580       (setq folder-numbers (cdr folder-numbers)))
581     ent))
582
583 (defun elmo-multi-make-folder-numbers-list (folder msgs)
584   (let ((msg-list msgs)
585         pair fld-list
586         ret-val)
587     (while msg-list
588       (when (and (numberp (car msg-list))
589                  (> (car msg-list) 0))
590         (setq pair (elmo-multi-real-folder-number folder (car msg-list)))
591         (if (setq fld-list (elmo-multi-folder-numbers-list-assoc
592                             (car pair)
593                             ret-val))
594             (setcdr fld-list (cons (cdr pair) (cdr fld-list)))
595           (setq ret-val (cons (cons (car pair) (list (cdr pair))) ret-val))))
596       (setq msg-list (cdr msg-list)))
597     ret-val))
598
599 (luna-define-method elmo-folder-mark-as-important :before ((folder
600                                                             elmo-multi-folder)
601                                                            numbers
602                                                            &optional
603                                                            ignore-flags)
604   (dolist (folder-numbers (elmo-multi-make-folder-numbers-list folder numbers))
605     (elmo-folder-mark-as-important (car folder-numbers)
606                                    (cdr folder-numbers)
607                                    ignore-flags)))
608
609 (luna-define-method elmo-folder-unmark-important :before ((folder
610                                                            elmo-multi-folder)
611                                                           numbers
612                                                           &optional
613                                                           ignore-flags)
614   (dolist (folder-numbers (elmo-multi-make-folder-numbers-list folder numbers))
615     (elmo-folder-unmark-important (car folder-numbers)
616                                   (cdr folder-numbers)
617                                   ignore-flags)))
618
619 (luna-define-method elmo-folder-mark-as-read :before ((folder
620                                                        elmo-multi-folder)
621                                                       numbers
622                                                       &optional ignore-flag)
623   (dolist (folder-numbers (elmo-multi-make-folder-numbers-list folder numbers))
624     (elmo-folder-mark-as-read (car folder-numbers)
625                               (cdr folder-numbers)
626                               ignore-flag)))
627
628 (luna-define-method elmo-folder-unmark-read :before ((folder
629                                                       elmo-multi-folder)
630                                                      numbers
631                                                      &optional ignore-flag)
632   (dolist (folder-numbers (elmo-multi-make-folder-numbers-list folder numbers))
633     (elmo-folder-unmark-read (car folder-numbers)
634                              (cdr folder-numbers)
635                              ignore-flag)))
636
637 (luna-define-method elmo-folder-mark-as-answered :before ((folder
638                                                            elmo-multi-folder)
639                                                           numbers)
640   (dolist (folder-numbers (elmo-multi-make-folder-numbers-list folder numbers))
641     (elmo-folder-mark-as-answered (car folder-numbers)
642                                   (cdr folder-numbers))))
643
644 (luna-define-method elmo-folder-unmark-answered :before ((folder
645                                                           elmo-multi-folder)
646                                                          numbers)
647   (dolist (folder-numbers (elmo-multi-make-folder-numbers-list folder numbers))
648     (elmo-folder-unmark-answered (car folder-numbers)
649                                  (cdr folder-numbers))))
650
651 (require 'product)
652 (product-provide (provide 'elmo-multi) (require 'elmo-version))
653
654 ;;; elmo-multi.el ends here