+ (let ((deletable-articles
+ (if force
+ articles
+ (gnus-sorted-intersection
+ articles
+ (nnimap-find-expired-articles group)))))
+ (if (null deletable-articles)
+ articles
+ (if (eq nnmail-expiry-target 'delete)
+ (nnimap-delete-article deletable-articles)
+ (setq deletable-articles
+ (nnimap-process-expiry-targets
+ deletable-articles group server)))
+ ;; Return the articles we didn't delete.
+ (gnus-sorted-complement articles deletable-articles))))))
+
+(defun nnimap-process-expiry-targets (articles group server)
+ (let ((deleted-articles nil))
+ (dolist (article articles)
+ (let ((target nnmail-expiry-target))
+ (with-temp-buffer
+ (when (nnimap-request-article article group server (current-buffer))
+ (message "Expiring article %s:%d" group article)
+ (when (functionp target)
+ (setq target (funcall target group)))
+ (when (and target
+ (not (eq target 'delete)))
+ (if (or (gnus-request-group target t)
+ (gnus-request-create-group target))
+ (nnmail-expiry-target-group target group)
+ (setq target nil)))
+ (when target
+ (push article deleted-articles))))))
+ ;; Change back to the current group again.
+ (nnimap-possibly-change-group group server)
+ (setq deleted-articles (nreverse deleted-articles))
+ (nnimap-delete-article deleted-articles)
+ deleted-articles))
+
+(defun nnimap-find-expired-articles (group)
+ (let ((cutoff (nnmail-expired-article-p group nil nil)))
+ (with-current-buffer (nnimap-buffer)
+ (let ((result
+ (nnimap-command
+ "UID SEARCH SENTBEFORE %s"
+ (format-time-string
+ (format "%%d-%s-%%Y"
+ (upcase
+ (car (rassoc (nth 4 (decode-time cutoff))
+ parse-time-months))))
+ cutoff))))
+ (and (car result)
+ (delete 0 (mapcar #'string-to-number
+ (cdr (assoc "SEARCH" (cdr result))))))))))
+