Changes
[emacs.git] / .emacs.d / elisp / icicle / icicles-cmd1.el
index 86749bc..3a08e9a 100644 (file)
@@ -4,27 +4,31 @@
 ;; Description: Top-level commands for Icicles
 ;; Author: Drew Adams
 ;; Maintainer: Drew Adams (concat "drew.adams" "@" "oracle" ".com")
-;; Copyright (C) 1996-2014, Drew Adams, all rights reserved.
+;; Copyright (C) 1996-2015, Drew Adams, all rights reserved.
 ;; Created: Mon Feb 27 09:25:04 2006
-;; Last-Updated: Sun Mar  9 09:59:48 2014 (-0700)
+;; Last-Updated: Mon Jan  5 13:47:54 2015 (-0800)
 ;;           By: dradams
-;;     Update #: 26878
+;;     Update #: 27373
 ;; URL: http://www.emacswiki.org/icicles-cmd1.el
 ;; Doc URL: http://www.emacswiki.org/Icicles
 ;; Keywords: extensions, help, abbrev, local, minibuffer,
 ;;           keys, apropos, completion, matching, regexp, command
-;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x
+;; Compatibility: GNU Emacs: 20.x, 21.x, 22.x, 23.x, 24.x, 25.x
 ;;
 ;; Features that might be required by this library:
 ;;
-;;   `apropos', `apropos-fn+var', `avoid', `cl', `cus-edit',
-;;   `cus-face', `cus-load', `cus-start', `cus-theme', `doremi',
-;;   `easymenu', `el-swank-fuzzy', `ffap', `ffap-', `frame-cmds',
-;;   `frame-fns', `fuzzy', `fuzzy-match', `hexrgb', `icicles-fn',
-;;   `icicles-mcmd', `icicles-opt', `icicles-var', `image-dired',
-;;   `kmacro', `levenshtein', `misc-fns', `mouse3', `mwheel',
-;;   `naked', `regexp-opt', `ring', `second-sel', `strings',
-;;   `thingatpt', `thingatpt+', `wid-edit', `wid-edit+', `widget'.
+;;   `apropos', `apropos+', `apropos-fn+var', `avoid', `bookmark',
+;;   `bookmark+', `bookmark+-1', `bookmark+-bmu', `bookmark+-key',
+;;   `bookmark+-lit', `cl', `cmds-menu', `cus-edit', `cus-face',
+;;   `cus-load', `cus-start', `cus-theme', `doremi', `easymenu',
+;;   `el-swank-fuzzy', `ffap', `ffap-', `fit-frame', `frame-cmds',
+;;   `frame-fns', `fuzzy', `fuzzy-match', `help+20', `hexrgb',
+;;   `icicles-fn', `icicles-mcmd', `icicles-opt', `icicles-var',
+;;   `image-dired', `info', `info+20', `kmacro', `levenshtein',
+;;   `menu-bar', `menu-bar+', `misc-cmds', `misc-fns', `mouse3',
+;;   `mwheel', `naked', `package', `pp', `pp+', `regexp-opt', `ring',
+;;   `second-sel', `strings', `thingatpt', `thingatpt+', `unaccent',
+;;   `w32browser-dlgopen', `wid-edit', `wid-edit+', `widget'.
 ;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;
@@ -73,6 +77,7 @@
 ;;    (+)`icicle-bookmark-all-tags-other-window',
 ;;    (+)`icicle-bookmark-all-tags-regexp',
 ;;    (+)`icicle-bookmark-all-tags-regexp-other-window',
+;;    `icicle-bookmark-annotated-narrow',
 ;;    (+)`icicle-bookmark-autofile',
 ;;    (+)`icicle-bookmark-autofile-all-tags',
 ;;    (+)`icicle-bookmark-autofile-all-tags-other-window',
 ;;    (+)`icicle-bookmark-cmd', (+)`icicle-bookmark-desktop',
 ;;    `icicle-bookmark-desktop-narrow', (+)`icicle-bookmark-dired',
 ;;    `icicle-bookmark-dired-narrow',
+;;    `icicle-bookmark-dired-this-dir-narrow',
+;;    `icicle-bookmark-dired-wildcards-narrow',
 ;;    (+)`icicle-bookmark-dired-other-window',
 ;;    (+)`icicle-bookmarked-buffer-list',
 ;;    (+)`icicle-bookmarked-file-list', (+)`icicle-bookmark-file',
 ;;    (+)`icicle-bookmark-local-file-other-window',
 ;;    (+)`icicle-bookmark-man', `icicle-bookmark-man-narrow',
 ;;    (+)`icicle-bookmark-man-other-window',
-;;    (+)`icicle-bookmark-non-file',
+;;    `icicle-bookmark-navlist-narrow', (+)`icicle-bookmark-non-file',
 ;;    `icicle-bookmark-non-file-narrow',
 ;;    (+)`icicle-bookmark-non-file-other-window',
 ;;    (+)`icicle-bookmark-other-window', (+)`icicle-bookmark-region',
 ;;    (+)`icicle-buffer-no-search',
 ;;    (+)`icicle-buffer-no-search-other-window',
 ;;    (+)`icicle-buffer-other-window', `icicle-cd-for-abs-files',
-;;    `icicle-cd-for-loc-files', (+)`icicle-clear-history',
-;;    (+)`icicle-clear-current-history', (+)`icicle-color-theme',
-;;    `icicle-comint-dynamic-complete',
+;;    `icicle-cd-for-loc-files', `icicle-choose-window-by-name',
+;;    `icicle-choose-window-for-buffer-display',
+;;    (+)`icicle-clear-history', (+)`icicle-clear-current-history',
+;;    (+)`icicle-color-theme', `icicle-comint-dynamic-complete',
 ;;    `icicle-comint-dynamic-complete-filename',
 ;;    `icicle-comint-replace-by-expanded-filename',
 ;;    (+)`icicle-command-abbrev', (+)`icicle-command-abbrev-command',
 ;;  Non-interactive functions defined here:
 ;;
 ;;    `custom-variable-p', `icicle-apropos-opt-action',
-;;    `icicle-binary-option-p', `icicle-bookmark-act-on-prop',
+;;    `icicle-bookmark-act-on-prop',
 ;;    `icicle-bookmark-bind-narrow-commands',
 ;;    `icicle-bookmark-cleanup', `icicle-bookmark-cleanup-on-quit',
 ;;    `icicle-bookmark-delete-action', `icicle-bookmark-help',
 ;;    `icicle-bookmark-propertize-candidate',
 ;;    `icicle-pp-display-expression',
 ;;    `icicle-read-args-w-val-satisfying',
+;;    `icicle-read-choose-window-args',
 ;;    (+)`icicle-recent-file-of-content-1',
 ;;    `icicle-recent-files-without-buffers.',
 ;;    `icicle-remove-buffer-candidate-action',
 ;;    `icicle-remove-buffer-config-action',
 ;;    `icicle-remove-from-recentf-candidate-action',
 ;;    `icicle-remove-saved-set-action',
+;;    `icicle-repeat-complex-command--called-interactively-skip',
 ;;    `icicle-shell-command-on-file',
 ;;    `icicle-shell-dynamic-complete-as-command',
 ;;    `icicle-shell-dynamic-complete-as-environment-variable',
 ;;  ***** NOTE: The following functions defined in `dabbrev.el' have
 ;;              been REDEFINED HERE:
 ;;
-;;  `dabbrev-completion' - Use Icicles minibuffer completion when there
-;;                         are multiple candidates.
+;;    `dabbrev-completion' - Use Icicles minibuffer completion when
+;;                           there are multiple candidates.
 ;;
 ;;
 ;;  ***** NOTE: The following functions defined in `bbdb-com.el' have
 ;;              been REDEFINED HERE:
-;;              (BBDB is available here: http://bbdb.sourceforge.net/.)
+;;              (BBDB is here: http://bbdb.sourceforge.net/.)
 ;;
-;;  `icicle-bbdb-complete-mail', `bbdb-complete-name' -
-;;                         Use Icicles minibuffer completion when there
-;;                         are multiple candidates.
+;;    `icicle-bbdb-complete-mail', `bbdb-complete-name' -
+;;                           Use Icicles minibuffer completion when
+;;                           there are multiple candidates.
 ;;
 ;;
 ;;  ***** NOTE: The following functions defined in `lisp.el' have
 ;;              been REDEFINED in Icicles:
 ;;
-;;  `lisp-complete-symbol' - Selects `*Completions*' window even if on
-;;                           another frame.
+;;    `lisp-complete-symbol' - Select `*Completions*' window even if
+;;                             on another frame.
 ;;
 ;;
 ;;  ***** NOTE: The following function defined in `simple.el' has
 ;;              been REDEFINED HERE:
 ;;
-;;  `repeat-complex-command' - Use `completing-read' to read command.
+;;    `repeat-complex-command' - Use `completing-read'.
 ;;
 ;;
 ;;  ***** NOTE: The following functions defined in `cus-edit.el' have
 ;;              been REDEFINED HERE:
 ;;
-;;  `customize-apropos', `customize-apropos-faces',
-;;  `customize-apropos-groups', `customize-apropos-options' -
-;;     Use `completing-read' to read the regexp.
-;;  `customize-face', `customize-face-other-window' - Multi-commands.
+;;    `customize-apropos', `customize-apropos-faces',
+;;    `customize-apropos-groups',
+;;    `customize-apropos-options' - Use `completing-read'.
+;;    `customize-face', `customize-face-other-window' - Multi-commands.
+;;
+;;
+;;  ***** NOTE: The following functions defined in `window.el' are
+;;              ADVISED HERE:
+;;
+;;    `display-buffer', `switch-to-buffer',
+;;    `switch-to-buffer-other-window'.
 ;;
 ;;
 ;;  Key bindings made by Icicles: See "Key Bindings" in
 ;;
 ;;; Code:
 
-(eval-when-compile (require 'cl)) ;; lexical-let[*], pushnew
+(eval-when-compile (require 'cl)) ;; lexical-let[*], case, pushnew
                                   ;; plus, for Emacs < 21: dolist, push
 (eval-when-compile (when (>= emacs-major-version 21) (require 'recentf))) ;; recentf-mode
 (require 'apropos-fn+var nil t) ;; (no error if not found):
   ;; icicle-bind-buffer-candidate-keys, icicle-bind-file-candidate-keys, icicle-unbind-buffer-candidate-keys,
   ;; icicle-unbind-file-candidate-keys, icicle-yank
 (require 'icicles-opt)                  ; (This is required anyway by `icicles-var.el'.)
-  ;; icicle-add-proxy-candidates-flag, icicle-buffer-configs, icicle-buffer-extras,
-  ;; icicle-buffer-ignore-space-prefix-flag, icicle-buffer-match-regexp,
+  ;; icicle-act-before-cycle-flag, icicle-add-proxy-candidates-flag, icicle-buffer-configs,
+  ;; icicle-buffer-extras, icicle-buffer-ignore-space-prefix-flag, icicle-buffer-match-regexp,
   ;; icicle-buffer-no-match-regexp, icicle-buffer-predicate, icicle-buffer-require-match-flag,
-  ;; icicle-buffer-sort, icicle-color-themes, icicle-kbd, icicle-saved-completion-sets,
-  ;; icicle-sort-comparer, icicle-transform-function
+  ;; icicle-buffer-sort, icicle-color-themes, icicle-delete-candidate-object, icicle-kbd, icicle-recenter,
+  ;; icicle-saved-completion-sets, icicle-shell-command-candidates-cache, icicle-sort-comparer,
+  ;; icicle-sort-orders-alist, icicle-transform-function
 (require 'icicles-var)                  ; (This is required anyway by `icicles-fn.el'.)
-  ;; icicle-abs-file-candidates, icicle-all-candidates-list-action-fn,
-  ;; icicle-all-candidates-list-alt-action-fn, icicle-bookmark-history,
-  ;; icicle-bookmark-list-names-only-p, icicle-bookmark-types, icicle-buffer-config-history,
-  ;; icicle-bufflist, icicle-candidate-action-fn, icicle-candidate-alt-action-fn,
-  ;; icicle-candidate-help-fn, icicle-candidate-nb, icicle-candidate-properties-alist,
-  ;; icicle-candidates-alist, icicle-color-theme-history, icicle-command-abbrev-history,
-  ;; icicle-commands-for-abbrev, icicle-comp-base-is-default-dir-p, icicle-completion-candidates,
-  ;; icicle-completion-set-history, icicle-current-input, icicle-delete-candidate-object,
-  ;; icicle-explore-final-choice, icicle-explore-final-choice-full,
-  ;; icicle-extra-candidates, icicle-face-name-history, icicle-frame-alist, icicle-frame-name-history,
-  ;; icicle-full-cand-fn, icicle-function-name-history, icicle-get-alist-candidate-function, icicle-hist-var,
+  ;; icicle-abs-file-candidates, icicle-all-candidates-action, icicle-all-candidates-list-action-fn,
+  ;; icicle-all-candidates-list-alt-action-fn, icicle-allowed-sort-predicate, icicle-apropos-complete-match-fn,
+  ;; icicle-apropos-value-last-initial-cand-set, icicle-bookmark-list-names-only-p, icicle-bookmark-types,
+  ;; icicle-buffer-complete-fn, icicle-bufflist, icicle-candidate-action-fn, icicle-candidate-alt-action-fn,
+  ;; icicle-candidate-help-fn, icicle-candidate-nb, icicle-candidate-properties-alist, icicle-candidates-alist,
+  ;; icicle-command-abbrev-history, icicle-commands-for-abbrev, icicle-comp-base-is-default-dir-p,
+  ;; icicle-completion-candidates, icicle-compute-narrowing-regexp-p, icicle-current-completion-mode,
+  ;; icicle-current-input, icicle-exclude-default-proxies, icicle-explore-final-choice,
+  ;; icicle-explore-final-choice-full, icicle-extra-candidates, icicle-fancy-candidates-p, icicle-frame-alist,
+  ;; icicle-frame-name-history, icicle-full-cand-fn, icicle-get-alist-candidate-function, icicle-hist-var,
   ;; icicle-incremental-completion-p, icicle-inhibit-sort-p, icicle-inhibit-try-switch-buffer,
-  ;; icicle-kill-history, icicle-kmacro-alist, icicle-kmacro-history,icicle-list-use-nth-parts,
-  ;; icicle-must-match-regexp, icicle-must-not-match-regexp, icicle-must-pass-after-match-predicate,
-  ;; icicle-new-last-cmd, icicle-orig-buff, icicle-orig-must-pass-after-match-pred, icicle-orig-pt-explore,
-  ;; icicle-orig-window, icicle-orig-win-explore, icicle-pref-arg, icicle-previous-raw-file-name-inputs,
+  ;; icicle-kmacro-alist, icicle-last-apropos-complete-match-fn, icicle-last-transform-function,
+  ;; icicle-list-use-nth-parts, icicle-multi-completing-p, icicle-must-match-regexp,
+  ;; icicle-must-not-match-regexp, icicle-must-pass-after-match-predicate, icicle-narrow-regexp,
+  ;; icicle-new-last-cmd, icicle-next-window-for-display-buffer, icicle-orig-buff,
+  ;; icicle-orig-must-pass-after-match-pred, icicle-orig-pt-explore, icicle-orig-window,
+  ;; icicle-orig-win-explore, icicle-other-window, icicle-path-variables, icicle-predicate-types-alist,
+  ;; icicle-pref-arg, icicle-pre-minibuffer-buffer, icicle-previous-raw-file-name-inputs,
   ;; icicle-previous-raw-non-file-name-inputs, icicle-prompt, icicle-proxy-candidates,
   ;; icicle-read-expression-map, icicle-remove-icicles-props-p, icicle-re-no-dot,
   ;; icicle-saved-completion-candidates, icicle-search-history, icicle-transform-before-sort-p,
-  ;; icicle-use-candidates-only-once-alt-p, icicle-whole-candidate-as-text-prop-p,
-  ;; icicle-variable-name-history
+  ;; icicle-use-candidates-only-once-alt-p, icicle-whole-candidate-as-text-prop-p
 (require 'icicles-fn)                   ; (This is required anyway by `icicles-mcmd.el'.)
   ;; icicle-delete-dups, icicle-highlight-lighter, icicle-multi-comp-apropos-complete-match,
   ;; icicle-read-from-minibuf-nil-default, icicle-read-regexp, icicle-string-match-p
   (defvar minibuffer-local-filename-syntax))
 
 (defvar apropos-do-all)                 ; In `apropos.el'
-(defvar bbdb-complete-mail-allow-cycling) ; In `bbdb-com.el'
+(defvar bbdb-complete-mail-allow-cycling) ; In `bbdb.el'
 (defvar bbdb-complete-name-allow-cycling) ; In `bbdb-com.el', older BBDB versions
 (defvar bbdb-completion-list)           ; In `bbdb-come.el'
 (defvar bbdb-extract-address-components-func) ; In `bbdb-com.el'
 (defvar bbdb-expand-mail-aliases)       ; In `bbdb-com.el'
+(defvar bbdb-complete-mail-allow-cycling) ; In `bbdb.el'
 (defvar bbdb-complete-name-hooks)       ; In `bbdb-com.el', older BBDB versions
 (defvar bbdb-completion-display-record) ; In `bbdb.el'
 (defvar bbdb-completion-type)           ; In `bbdb.el'
 (defvar bbdb-hashtable)                 ; In `bbdb.el'
+(defvar bbdb-quoted-string-syntax-table) ; In `bbdb-com.el'
 (defvar bbdb-version)                   ; In `bbdb.el'
 (defvar bmkp-non-file-filename)         ; In `bookmark+-1.el'
 (defvar bmkp-prompt-for-tags-flag)      ; In `bookmark+-1.el'
@@ -1126,7 +1147,7 @@ Return t if successful."
     (let ((success  (let ((comint-completion-addsuffix  nil)
                           (icicle-candidate-help-fn
                            (lambda (cand)
-                             (with-output-to-temp-buffer "*Help*"
+                             (icicle-with-help-window "*Help*"
                                (princ (shell-command-to-string (concat "apropos "
                                                                        (shell-quote-argument cand))))))))
                       (icicle-comint-dynamic-simple-complete filenondir completions))))
@@ -1477,174 +1498,246 @@ Vanilla `dabbrev--abbrev-at-point' raises an error if no match."
       abv))
 
 
-;; REPLACE ORIGINAL `bbdb-complete-mail' defined in `bbdb-com.el', version 3.02
+;; REPLACE ORIGINAL `bbdb-complete-mail' defined in `bbdb.el', version 3.1
 ;; saving it for restoration when you toggle `icicle-mode'.
 ;;
-;; BBDB Version 3.02, the Insidious Big Brother Database, is available here: http://melpa.milkbox.net/.
+;; BBDB Version 3.1, the Insidious Big Brother Database, is available from these locations:
+;; * http://download.savannah.gnu.org/releases/bbdb/
+;; * http://melpa.milkbox.net/
 ;;
 ;; Uses Icicles completion when there are multiple candidates.
 ;;
-;; Free vars here: `bbdb-*' are bound in `bbdb-com.el'.
-(defun icicle-bbdb-complete-mail (&optional start-pos cycle-completion-buffer)
-  "In a mail buffer, complete the user name or mail address before point.
-Completes up to the preceding newline, colon or comma, or the value of
-START-POS.
+;; Free vars here: `bbdb-*' are bound in `bbdb.el'.
+(defun icicle-bbdb-complete-mail (&optional beg cycle-completion-buffer)
+  "In a mail buffer, complete the user name or mail before point.
+Completes up to the preceeding colon, comma, or BEG.
 Return non-nil if there is a valid completion, else return nil.
+
 You can control completion behaviour using `bbdb-completion-list'
 \(`bbdb-completion-type' in older BBDB versions).
 
-If what has been typed is unique, insert an entry \"User Name
-<mail-address>\" - but see `bbdb-mail-allow-redundancy'
-\(`bbdb-dwim-net-address-allow-redundancy' in older BBDB versions).
-If it is a valid completion but not unique, you can choose from the
-list of completions using Icicles completion.
+If what you have typed matches a unique BBDB record then insert an
+address formatted by `bbdb-dwim-mail'.  Display this record if
+`bbdb-completion-display-record' is non-nil.
+
+If what you have typed is a valid completion but not unique, you can
+choose from the list of completions using Icicles completion.
 
 If your input is completed and `bbdb-complete-mail-allow-cycling' is
-true (`bbdb-complete-name-allow-cycling' for older BBDB versions),
-you can repeat to cycle through the nets for the matching record.
+true (`bbdb-complete-name-allow-cycling' for older BBDB versions)then
+you can repeat to cycle through mail messages for the matching record.
+
+If BBDB would format a given address different from what is in the
+mail buffer, the first round of cycling reformats the address
+accordingly, then you cycle through the mails for the matching record.
 
 When called with a prefix arg, display a list of all mail messages
 available for cycling.
 
-See your version of BBDB for more information."
+Set variable `bbdb-complete-mail' to non-nil to enable this feature as
+part of your MUA setup."
   (interactive (list nil current-prefix-arg))
-  (unless (and (require 'bbdb nil t)  (require 'bbdb-com nil t)
-               (fboundp 'bbdb-complete-mail))
-    (icicle-user-error "`icicle-bbdb-complete-mail' requires a BBDB version such as 3.02"))
-  (bbdb-buffer)                         ; Make sure database is initialized.
-  (lexical-let* ((end                     (point))
-                 (beg                     (or start-pos  (save-excursion
-                                                           (re-search-backward "\\(\\`\\|[\n:,]\\)[ \t]*")
-                                                           (goto-char (match-end 0)) (point))))
-                 (orig                    (buffer-substring beg end))
-                 (typed                   (downcase orig))
-                 (pattern                 (bbdb-string-trim typed))
-                 (completion-ignore-case  t)
-                 (completion              (try-completion pattern bbdb-hashtable #'bbdb-completion-predicate))
-                 (all-the-completions     ())
-                 dwim-completions  one-record  done)
-    ;; [:,] match would be interpreted as START-POS (e.g., a comma in LF-NAME).  Compensate.
-    (when (and (stringp completion)  (string-match "[:,]" completion))
-      (setq completion  (substring completion 0 (match-beginning 0))))
-    ;; Cannot use `all-completions' to set `all-the-completions' because it converts symbols to strings.
-    (all-completions pattern bbdb-hashtable (lambda (sym)
-                                              (when (bbdb-completion-predicate sym)
-                                                (push sym all-the-completions))))
-    ;; Resolve records matching pattern.  Multiple completions could match the same record.
-    (let ((records  (icicle-delete-dups (apply #'append (mapcar #'symbol-value all-the-completions)))))
-      (setq one-record  (and (not (cdr records))  (car records)))) ; Only one matching record.
-    (icicle-remove-Completions-window)
-    (cond (one-record
-           ;; Only one matching record.
-           ;; Determine mail address of ONE-RECORD to use for ADDRESS.
-           ;; Do we have a preferential order for the following tests?
-           (let ((completion-list  (if (eq t bbdb-completion-list)
-                                       '(fl-name lf-name mail aka organization)
-                                     bbdb-completion-list))
-                 (mails            (bbdb-record-mail one-record))
-                 mail elt)
-             (unless mails (error "Matching record has no `mail' field"))
-             ;; (1) If PATTERN matches name, AKA, or organization of ONE-RECORD,
-             ;;     then ADDRESS is the first mail address of ONE-RECORD.
-             (when (try-completion pattern (append (and (memq 'fl-name completion-list)
-                                                        (list (or (bbdb-record-name one-record)  "")))
-                                                   (and (memq 'lf-name completion-list)
-                                                        (list (or (bbdb-record-name-lf one-record)  "")))
-                                                   (and (memq 'aka completion-list)
-                                                        (bbdb-record-field one-record 'aka-all))
-                                                   (and (memq 'organization completion-list)
-                                                        (bbdb-record-organization one-record))))
-               (setq mail  (car mails)))
-             ;; (2) If PATTERN matches one or multiple mail addresses of ONE-RECORD,
-             ;;     then we take the first one matching PATTERN.
-             (unless mail (while (setq elt  (pop mails))
-                            (if (try-completion pattern (list elt))
-                                (setq mail   elt
-                                      mails  ()))))
-             (unless mail (error "`icicle-bbdb-complete-mail': No match for `%s'" pattern)) ; Indicates a bug!
-             (let ((address  (bbdb-dwim-mail one-record mail)))
-               (if (string= address (buffer-substring-no-properties beg end))
-                   (unless (and bbdb-complete-mail-allow-cycling  (< 1 (length (bbdb-record-mail one-record))))
-                     (setq done  'UNCHANGED))
-                 (delete-region beg end) ; Replace text with expansion.
-                 (insert address)
-                 (bbdb-complete-mail-cleanup address)
-                 (setq done  'UNIQUE)))))
-          ;; Completed partially.
-          ;; Cannot use trimmed version of pattern here, else recurse infinitely on, e.g., common first names.
-          ((and (stringp completion)  (not (string= typed completion)))
-           (delete-region beg end)
-           (insert completion)
-           (setq done  'PARTIAL))
-          ;; Partial match not allowing further partial completion.
-          (completion
-           (let ((completion-list  (if (eq t bbdb-completion-list)
-                                       '(fl-name lf-name mail aka organization)
-                                     bbdb-completion-list))
-                 sname  records)
-             ;; Collect dwim-addresses for each completion, but only once for each record!
-             ;; Add if mail is part of the completions.
-             (dolist (sym  all-the-completions)
-               (setq sname  (symbol-name sym))
-               (dolist (record  (symbol-value sym))
-                 (unless (memq record records)
-                   (push record records)
+  (unless (and (require 'bbdb nil t)  (require 'bbdb-com nil t)  (fboundp 'bbdb-complete-mail))
+    (icicle-user-error "`icicle-bbdb-complete-mail' requires a BBDB version such as 3.1"))
+  (bbdb-buffer)                         ; Make sure the database is initialized.
+  ;; Completion should begin after the preceding comma (separating
+  ;; two addresses) or colon (separating the header field name
+  ;; from the header field body).  We want to ignore these characters
+  ;; if they appear inside a quoted string (RFC 5322, Sec. 3.2.4).
+  ;; Note also that a quoted string may span multiple lines
+  ;; (RFC 5322, Sec. 2.2.3).
+  ;; So to be save, we go back to the beginning of the header field body
+  ;; (past the colon, when we are certainly not inside a quoted string),
+  ;; then we parse forward, looking for commas not inside a quoted string
+  ;; and positioned before END.  - This fails with an unbalanced quote.
+  ;; But an unbalanced quote is bound to fail anyway.
+  (when (and (not beg)  (<= (point) (save-restriction ; `mail-header-end'
+                                      (widen)
+                                      (save-excursion (rfc822-goto-eoh) (point)))))
+    (let ((end  (point))
+          start pnt state)
+      (save-excursion
+        ;; A header field name must appear at the beginning of a line,
+        ;; and it must be terminated by a colon.
+        (re-search-backward "^[^ \t\n:][^:]*:[ \t\n]+")
+        (setq beg    (match-end 0)
+              start  beg)
+        (goto-char beg)
+        ;; If we are inside a syntactically correct header field,
+        ;; all continuation lines in between the field name and point
+        ;; must begin with a white space character.
+        (if (re-search-forward "\n[^ \t]" end t)
+            ;; An invalid header is identified via BEG set to nil.
+            (setq beg  nil)
+          ;; Parse field body up to END
+          (with-syntax-table bbdb-quoted-string-syntax-table
+            (while (setq pnt  (re-search-forward ",[ \t\n]*" end t))
+              (setq state  (parse-partial-sexp start pnt nil nil state)
+                    start  pnt)
+              (unless (nth 3 state) (setq beg  pnt))))))))
+  ;; Noa meaningful way to set BEG if we are not in a message header.
+  (unless beg (message "Not a valid buffer position for mail completion") (sit-for 1))
+  (let* ((end                     (point))
+         (done                    (and (not beg)  'NOTHING))
+         (orig                    (and beg  (buffer-substring beg end)))
+         (completion-ignore-case  t)
+         (completion              (and orig  (try-completion orig bbdb-hashtable
+                                                             #'bbdb-completion-predicate)))
+         all-comps dwim-completions one-record)
+    (unless done
+      ;; We get fooled if a partial COMPLETION matches "," (for example,
+      ;; a comma in lf-name).  Such a partial COMPLETION cannot be protected
+      ;; by quoting.  Then the comma gets interpreted as BEG.
+      ;; So we never perform partial completion beyond the first comma.
+      ;; This works even if we have just one record matching ORIG (thus
+      ;; allowing dwim-completion) because ORIG is a substring of COMPLETION
+      ;; even after COMPLETION got truncated; and ORIG by itself must be
+      ;; sufficient to identify this record.
+      ;; Yet if multiple records match ORIG we can only offer a *Completions* buffer.
+      (when (and (stringp completion)  (string-match "," completion))
+        (setq completion  (substring completion 0 (match-beginning 0))))
+      ;; We cannot use the return value of function `all-completions' to set
+      ;; var ALL-COMPS because that function converts all symbols into strings
+      (all-completions orig bbdb-hashtable (lambda (sym)
+                                             (when (bbdb-completion-predicate sym)
+                                               (push sym all-comps))))
+      ;; Resolve the records matching ORIG:
+      ;; Multiple completions may match the same record
+      (let ((records  (icicle-delete-dups (apply #'append (mapcar #'symbol-value all-comps)))))
+        ;; Is there only one matching record?
+        (setq one-record  (and (not (cdr records))  (car records))))
+      (icicle-remove-Completions-window)
+      (cond (one-record                 ; Only one matching record.
+             (let ((completion-list  (if (eq t bbdb-completion-list)
+                                         '(fl-name lf-name mail aka organization)
+                                       bbdb-completion-list))
+                   (mails            (bbdb-record-mail one-record))
+                   mail elt)
+               (if (not mails)
+                   (progn (message "Matching record has no `mail' field") (sit-for 1)
+                          (setq done  'NOTHING))
+                 ;; Determine the mail address of ONE-RECORD to use for ADDRESS.
+                 ;; Do we have a preferential order for the following tests?
+
+                 ;; (1) If ORIG matches name, AKA, or organization of ONE-RECORD,
+                 ;;     then ADDRESS will be the first mail address of ONE-RECORD.
+                 (when (try-completion orig (append (and (memq 'fl-name completion-list)
+                                                         (list (or (bbdb-record-name one-record)  "")))
+                                                    (and (memq 'lf-name completion-list)
+                                                         (list (or (bbdb-record-name-lf one-record)  "")))
+                                                    (and (memq 'aka completion-list)
+                                                         (bbdb-record-field one-record 'aka-all))
+                                                    (and (memq 'organization completion-list)
+                                                         (bbdb-record-organization one-record))))
+                   (setq mail  (car mails)))
+                 ;; (2) If ORIG matches one or multiple mail addresses of ONE-RECORD,
+                 ;;     then we take the first one matching ORIG.
+                 ;;     We got here with MAIL nil only if `bbdb-completion-list'
+                 ;;     includes 'mail or 'primary.
+                 (unless mail (while (setq elt  (pop mails))
+                                (when (try-completion orig (list elt))
+                                  (setq mail   elt
+                                        mails  ()))))
+                 (unless mail (error "`icicle-bbdb-complete-mail': No match for `%s'" orig)) ; Indicates a bug!
+                 (let ((dwim-mail  (bbdb-dwim-mail one-record mail)))
+                   (if (string= dwim-mail orig)
+                       ;; We get here if `bbdb-mail-avoid-redundancy' is 'mail-only
+                       ;; and `bbdb-completion-list' includes 'mail.
+                       (unless (and bbdb-complete-mail-allow-cycling
+                                    (< 1 (length (bbdb-record-mail one-record))))
+                         (setq done  'UNCHANGED))
+                     (delete-region beg end) ; Replace text with expansion.
+                     (insert dwim-mail)
+                     (bbdb-complete-mail-cleanup dwim-mail beg)
+                     (setq done  'UNIQUE))))))
+            ((and (stringp completion)  (not (bbdb-string= orig completion))) ; Complete partially
+             (delete-region beg end)
+             (insert completion)
+             (setq done  'PARTIAL))
+            (completion                 ; Partial match not allowing further partial completion
+             (let ((completion-list  (if (eq t bbdb-completion-list)
+                                         '(fl-name lf-name mail aka organization)
+                                       bbdb-completion-list))
+                   sname)
+               ;; Now collect all the dwim-addresses for each completion.
+               ;; Add it if the mail is part of the completions
+               (dolist (sym  all-comps)
+                 (setq sname  (symbol-name sym))
+                 (dolist (record  (symbol-value sym))
                    (let ((mails  (bbdb-record-mail record))
                          accept)
                      (when mails
                        (dolist (field  completion-list)
                          (if (case field
-                               (fl-name (bbdb-string= sname (bbdb-record-name record)))
-                               (lf-name (bbdb-string= sname (bbdb-cache-lf-name (bbdb-record-cache record))))
-                               (aka (member-ignore-case sname (bbdb-record-field record 'aka-all)))
+                               (fl-name      (bbdb-string= sname (bbdb-record-name record)))
+                               (lf-name      (bbdb-string= sname (bbdb-cache-lf-name
+                                                                  (bbdb-record-cache record))))
+                               (aka          (member-ignore-case sname (bbdb-record-field record 'aka-all)))
                                (organization (member-ignore-case sname (bbdb-record-organization record)))
-                               (primary (bbdb-string= sname (car mails)))
-                               (otherwise nil))
+                               (primary      (bbdb-string= sname (car mails)))
+                               (otherwise    nil))
                              (push (car mails) accept)
                            (when (eq field 'mail)
-                             (dolist (mail  mails)
-                               (when (bbdb-string= sname mail) (push mail accept))))))
-                       (when accept
-                         ;; If DWIM-COMPLETIONS contains only one element, set DONE to `UNIQUE' (see below)
-                         ;;  and we want to know ONE-RECORD.
-                         (setq one-record  record)
-                         (dolist (mail  (delete-dups accept))
-                           (push (bbdb-dwim-mail record mail) dwim-completions))))))))
-             (cond ((not dwim-completions) (error "No mail address for \"%s\"" orig))
-                   ;; DWIM-COMPLETIONS might contain only one element, if multiple completions match the
-                   ;; same record.  In that case proceed with DONE set to `UNIQUE'.
-                   ((eq 1 (length dwim-completions))
-                    (delete-region beg end)
-                    (insert (car dwim-completions))
-                    (bbdb-complete-mail-cleanup (car dwim-completions))
-                    (setq done  'UNIQUE))
-                   (t
-                    (setq done  'CHOOSE))))))
+                             (dolist (mail  mails) (when (bbdb-string= sname mail) (push mail accept))))))
+                       (dolist (mail  (icicle-delete-dups accept))
+                         (push (bbdb-dwim-mail record mail) dwim-completions))))))
+               (setq dwim-completions  (sort (icicle-delete-dups dwim-completions) 'string<))
+               (cond ((not dwim-completions)
+                      (message "Matching record has no mail field") (sit-for 1)
+                      (setq done 'NOTHING))
+                     ;; DWIM-COMPLETIONS may contain only one element,
+                     ;; if multiple completions match the same record.
+                     ;; Then we may proceed with DONE set to `UNIQUE'.
+                     ((eq 1 (length dwim-completions))
+                      (delete-region beg end)
+                      (insert (car dwim-completions))
+                      (bbdb-complete-mail-cleanup (car dwim-completions) beg)
+                      (setq done  'UNIQUE))
+                     (t
+                      (setq done  'CHOOSE)))))))
+
     ;; If no completion so far, consider cycling.
     ;; Completion is controlled by option `bbdb-completion-list'.  Cycling assumes that ORIG already holds
     ;; a valid RFC 822 mail address.  So cycling can consider different records than completion.
     (when (and (not done)  bbdb-complete-mail-allow-cycling)
       ;; Find the record we are working on.
-      (let* ((address  (mail-extract-address-components orig))
-             (record   (and (listp address)  (car (bbdb-message-search (nth 0 address) (nth 1 address)))))
-             (mails    (and record  (bbdb-record-mail record))))
-        (when mails
-          ;; Cycle, even if MAILS has only one address. `bbdb-dwim-mail' can give something different.
-          ;; E.g., header "JOHN SMITH <FOO@BAR.COM>" can be replaced by "John Smith <foo@bar.com>".
-          (cond ((and (= 1 (length mails))  (string= (bbdb-dwim-mail record (car mails))
-                                                     (buffer-substring-no-properties beg end)))
+      (let* ((address  (bbdb-extract-address-components orig))
+             (record   (car (bbdb-message-search (car address) (cadr address)))))
+        (when (and record  (setq dwim-completions  (mapcar (lambda (m) (bbdb-dwim-mail record m))
+                                                           (bbdb-record-mail record))))
+          (cond ((and (= 1 (length dwim-completions))  (string= orig (car dwim-completions)))
                  (setq done  'UNCHANGED))
-                (cycle-completion-buffer ; Use completion buffer.
-                 (setq dwim-completions  (mapcar (lambda (n) (bbdb-dwim-mail record n)) mails)
-                       done              'CHOOSE))
-                (t                      ; Use next mail
-                 (let ((mail  (or (nth 1 (or (icicle-member-ignore-case (nth 1 address) mails)
-                                             (icicle-member-ignore-case orig mails)))
-                                  (nth 0 mails))))
+                (cycle-completion-buffer (setq done  'CYCLE-CHOOSE)) ; Use completion buffer
+                ;; Reformatting / Clean up:
+                ;; If the canonical mail address (nth 1 address)
+                ;; matches the Nth canonical mail address of RECORD,
+                ;; but ORIG is not `equal' to (bbdb-dwim-mail record n),
+                ;; then we replace ORIG by (bbdb-dwim-mail record n).
+                ;; For example, the address "JOHN SMITH <FOO@BAR.COM>"
+                ;; gets reformatted as "John Smith <foo@bar.com>".
+                ;; We attempt this reformatting before the yet more
+                ;; aggressive proper cycling.
+                ((let* ((cmails  (bbdb-record-mail-canon record))
+                        (len     (length cmails))
+                        mail dwim-mail)
+                   (while (and (not done)  (setq mail  (pop cmails)))
+                     (when (and (bbdb-string= mail (nth 1 address)) ; ignore case
+                                (not (string= orig (setq dwim-mail  (nth (- len 1 (length cmails))
+                                                                         dwim-completions)))))
+                       (delete-region beg end)
+                       (insert dwim-mail)
+                       (bbdb-complete-mail-cleanup dwim-mail beg)
+                       (setq done  'REFORMAT)))
+                   done))
+                (t
+                 ;; ORIG is `equal' to an element of DWIM-COMPLETIONS
+                 ;; Use the next element of DWIM-COMPLETIONS.
+                 (let ((dwim-mail  (or (nth 1 (member orig dwim-completions))  (nth 0 dwim-completions))))
                    (delete-region beg end) ; Replace with new mail address
-                   (insert (bbdb-dwim-mail record mail))
+                   (insert dwim-mail)
+                   (bbdb-complete-mail-cleanup dwim-mail beg)
                    (setq done  'CYCLE)))))))
-    (when (eq done 'CHOOSE)
+    (when (member done '(CHOOSE CYCLE-CHOOSE))
       ;; Icicles completion.  `completion-in-region' does not work here, as `dwim-completions' is not a
       ;; collection for completion in the usual sense.  It is really a list of replacements.
       (unless (eq (selected-window) (minibuffer-window)) (message "Making completion list..."))
@@ -1655,13 +1748,209 @@ See your version of BBDB for more information."
                  (completion-ignore-case                      t)
                  (choice
                   (save-excursion (completing-read "Complete: " (mapcar #'list dwim-completions)
-                                                   nil t pattern nil pattern))))
+                                                   nil t orig nil orig))))
             (when choice
               (delete-region beg end)
               (insert choice)))
         (error nil))
       (unless (eq (selected-window) (minibuffer-window)) (message "Making completion list...done")))
-    done))
+    ;; If DONE is `NOTHING' return nil so that possibly some other code can take over.
+    (and (not (eq done 'NOTHING))  done)))
+
+
+;;; If you have BBDB version 3.0.2, not 3.1, then uncomment this code.
+
+;;; ;; REPLACE ORIGINAL `bbdb-complete-mail' defined in `bbdb-com.el', version 3.02
+;;; ;; saving it for restoration when you toggle `icicle-mode'.
+;;; ;;
+;;; ;; BBDB Version 3.02, the Insidious Big Brother Database, is available here: http://melpa.milkbox.net/.
+;;; ;;
+;;; ;; Uses Icicles completion when there are multiple candidates.
+;;; ;;
+;;; ;; Free vars here: `bbdb-*' are bound in `bbdb-com.el'.
+;;; (defun icicle-bbdb-complete-mail (&optional start-pos cycle-completion-buffer)
+;;;   "In a mail buffer, complete the user name or mail address before point.
+;;; Completes up to the preceding newline, colon or comma, or the value of
+;;; START-POS.
+;;; Return non-nil if there is a valid completion, else return nil.
+;;; You can control completion behaviour using `bbdb-completion-list'
+;;; \(`bbdb-completion-type' in older BBDB versions).
+
+;;; If what has been typed is unique, insert an entry \"User Name
+;;; <mail-address>\" - but see `bbdb-mail-allow-redundancy'
+;;; \(`bbdb-dwim-net-address-allow-redundancy' in older BBDB versions).
+;;; If it is a valid completion but not unique, you can choose from the
+;;; list of completions using Icicles completion.
+
+;;; If your input is completed and `bbdb-complete-mail-allow-cycling' is
+;;; true (`bbdb-complete-name-allow-cycling' for older BBDB versions),
+;;; you can repeat to cycle through the nets for the matching record.
+
+;;; When called with a prefix arg, display a list of all mail messages
+;;; available for cycling.
+
+;;; See your version of BBDB for more information."
+;;;   (interactive (list nil current-prefix-arg))
+;;;   (unless (and (require 'bbdb nil t)  (require 'bbdb-com nil t)
+;;;                (fboundp 'bbdb-complete-mail))
+;;;     (icicle-user-error "`icicle-bbdb-complete-mail' requires a BBDB version such as 3.02"))
+;;;   (bbdb-buffer)                         ; Make sure database is initialized.
+;;;   (lexical-let* ((end                     (point))
+;;;                  (beg                     (or start-pos  (save-excursion
+;;;                                                            (re-search-backward "\\(\\`\\|[\n:,]\\)[ \t]*")
+;;;                                                            (goto-char (match-end 0)) (point))))
+;;;                  (orig                    (buffer-substring beg end))
+;;;                  (typed                   (downcase orig))
+;;;                  (pattern                 (bbdb-string-trim typed))
+;;;                  (completion-ignore-case  t)
+;;;                  (completion              (try-completion pattern bbdb-hashtable
+;;;                                                           #'bbdb-completion-predicate))
+;;;                  (all-the-completions     ())
+;;;                  dwim-completions  one-record  done)
+;;;     ;; [:,] match would be interpreted as START-POS (e.g., a comma in LF-NAME).  Compensate.
+;;;     (when (and (stringp completion)  (string-match "[:,]" completion))
+;;;       (setq completion  (substring completion 0 (match-beginning 0))))
+;;;     ;; Cannot use `all-completions' to set `all-the-completions' because it converts symbols to strings.
+;;;     (all-completions pattern bbdb-hashtable (lambda (sym)
+;;;                                               (when (bbdb-completion-predicate sym)
+;;;                                                 (push sym all-the-completions))))
+;;;     ;; Resolve records matching pattern.  Multiple completions could match the same record.
+;;;     (let ((records  (icicle-delete-dups (apply #'append (mapcar #'symbol-value all-the-completions)))))
+;;;       (setq one-record  (and (not (cdr records))  (car records)))) ; Only one matching record.
+;;;     (icicle-remove-Completions-window)
+;;;     (cond (one-record
+;;;            ;; Only one matching record.
+;;;            ;; Determine mail address of ONE-RECORD to use for ADDRESS.
+;;;            ;; Do we have a preferential order for the following tests?
+;;;            (let ((completion-list  (if (eq t bbdb-completion-list)
+;;;                                        '(fl-name lf-name mail aka organization)
+;;;                                      bbdb-completion-list))
+;;;                  (mails            (bbdb-record-mail one-record))
+;;;                  mail elt)
+;;;              (unless mails (error "Matching record has no `mail' field"))
+;;;              ;; (1) If PATTERN matches name, AKA, or organization of ONE-RECORD,
+;;;              ;;     then ADDRESS is the first mail address of ONE-RECORD.
+;;;              (when (try-completion pattern (append (and (memq 'fl-name completion-list)
+;;;                                                         (list (or (bbdb-record-name one-record)  "")))
+;;;                                                    (and (memq 'lf-name completion-list)
+;;;                                                         (list (or (bbdb-record-name-lf one-record)  "")))
+;;;                                                    (and (memq 'aka completion-list)
+;;;                                                         (bbdb-record-field one-record 'aka-all))
+;;;                                                    (and (memq 'organization completion-list)
+;;;                                                         (bbdb-record-organization one-record))))
+;;;                (setq mail  (car mails)))
+;;;              ;; (2) If PATTERN matches one or multiple mail addresses of ONE-RECORD,
+;;;              ;;     then we take the first one matching PATTERN.
+;;;              (unless mail (while (setq elt  (pop mails))
+;;;                             (if (try-completion pattern (list elt))
+;;;                                 (setq mail   elt
+;;;                                       mails  ()))))
+;;;              (unless mail
+;;;                (error "`icicle-bbdb-complete-mail': No match for `%s'" pattern)) ; Indicates a bug!
+;;;              (let ((address  (bbdb-dwim-mail one-record mail)))
+;;;                (if (string= address (buffer-substring-no-properties beg end))
+;;;                    (unless (and bbdb-complete-mail-allow-cycling
+;;;                                 (< 1 (length (bbdb-record-mail one-record))))
+;;;                      (setq done  'UNCHANGED))
+;;;                  (delete-region beg end) ; Replace text with expansion.
+;;;                  (insert address)
+;;;                  (bbdb-complete-mail-cleanup address)
+;;;                  (setq done  'UNIQUE)))))
+;;;           ;; Completed partially.
+;;;           ;; Cannot use trimmed version of pattern here, else recurse infinitely on,
+;;;           ;; e.g., common first names.
+;;;           ((and (stringp completion)  (not (string= typed completion)))
+;;;            (delete-region beg end)
+;;;            (insert completion)
+;;;            (setq done  'PARTIAL))
+;;;           ;; Partial match not allowing further partial completion.
+;;;           (completion
+;;;            (let ((completion-list  (if (eq t bbdb-completion-list)
+;;;                                        '(fl-name lf-name mail aka organization)
+;;;                                      bbdb-completion-list))
+;;;                  sname  records)
+;;;              ;; Collect dwim-addresses for each completion, but only once for each record!
+;;;              ;; Add if mail is part of the completions.
+;;;              (dolist (sym  all-the-completions)
+;;;                (setq sname  (symbol-name sym))
+;;;                (dolist (record  (symbol-value sym))
+;;;                  (unless (memq record records)
+;;;                    (push record records)
+;;;                    (let ((mails  (bbdb-record-mail record))
+;;;                          accept)
+;;;                      (when mails
+;;;                        (dolist (field  completion-list)
+;;;                          (if (case field
+;;;                                (fl-name (bbdb-string= sname (bbdb-record-name record)))
+;;;                                (lf-name (bbdb-string= sname (bbdb-cache-lf-name
+;;;                                                              (bbdb-record-cache record))))
+;;;                                (aka (member-ignore-case sname (bbdb-record-field record 'aka-all)))
+;;;                                (organization (member-ignore-case sname (bbdb-record-organization record)))
+;;;                                (primary (bbdb-string= sname (car mails)))
+;;;                                (otherwise nil))
+;;;                              (push (car mails) accept)
+;;;                            (when (eq field 'mail)
+;;;                              (dolist (mail  mails)
+;;;                                (when (bbdb-string= sname mail) (push mail accept))))))
+;;;                        (when accept
+;;;                          ;; If DWIM-COMPLETIONS contains only one element, set DONE to `UNIQUE' (see below)
+;;;                          ;;  and we want to know ONE-RECORD.
+;;;                          (setq one-record  record)
+;;;                          (dolist (mail  (delete-dups accept))
+;;;                            (push (bbdb-dwim-mail record mail) dwim-completions))))))))
+;;;              (cond ((not dwim-completions) (error "No mail address for \"%s\"" orig))
+;;;                    ;; DWIM-COMPLETIONS might contain only one element, if multiple completions match the
+;;;                    ;; same record.  In that case proceed with DONE set to `UNIQUE'.
+;;;                    ((eq 1 (length dwim-completions))
+;;;                     (delete-region beg end)
+;;;                     (insert (car dwim-completions))
+;;;                     (bbdb-complete-mail-cleanup (car dwim-completions))
+;;;                     (setq done  'UNIQUE))
+;;;                    (t
+;;;                     (setq done  'CHOOSE))))))
+;;;     ;; If no completion so far, consider cycling.
+;;;     ;; Completion is controlled by option `bbdb-completion-list'.  Cycling assumes that ORIG already holds
+;;;     ;; a valid RFC 822 mail address.  So cycling can consider different records than completion.
+;;;     (when (and (not done)  bbdb-complete-mail-allow-cycling)
+;;;       ;; Find the record we are working on.
+;;;       (let* ((address  (mail-extract-address-components orig))
+;;;              (record   (and (listp address)  (car (bbdb-message-search (nth 0 address) (nth 1 address)))))
+;;;              (mails    (and record  (bbdb-record-mail record))))
+;;;         (when mails
+;;;           ;; Cycle, even if MAILS has only one address. `bbdb-dwim-mail' can give something different.
+;;;           ;; E.g., header "JOHN SMITH <FOO@BAR.COM>" can be replaced by "John Smith <foo@bar.com>".
+;;;           (cond ((and (= 1 (length mails))  (string= (bbdb-dwim-mail record (car mails))
+;;;                                                      (buffer-substring-no-properties beg end)))
+;;;                  (setq done  'UNCHANGED))
+;;;                 (cycle-completion-buffer ; Use completion buffer.
+;;;                  (setq dwim-completions  (mapcar (lambda (n) (bbdb-dwim-mail record n)) mails)
+;;;                        done              'CHOOSE))
+;;;                 (t                      ; Use next mail
+;;;                  (let ((mail  (or (nth 1 (or (icicle-member-ignore-case (nth 1 address) mails)
+;;;                                              (icicle-member-ignore-case orig mails)))
+;;;                                   (nth 0 mails))))
+;;;                    (delete-region beg end) ; Replace with new mail address
+;;;                    (insert (bbdb-dwim-mail record mail))
+;;;                    (setq done  'CYCLE)))))))
+;;;     (when (eq done 'CHOOSE)
+;;;       ;; Icicles completion.  `completion-in-region' does not work here, as `dwim-completions' is not a
+;;;       ;; collection for completion in the usual sense.  It is really a list of replacements.
+;;;       (unless (eq (selected-window) (minibuffer-window)) (message "Making completion list..."))
+;;;       (icicle-condition-case-no-debug nil
+;;;           (let* ((icicle-show-Completions-initially-flag      t)
+;;;                  (icicle-incremental-completion-p             'display)
+;;;                  (icicle-top-level-when-sole-completion-flag  t)
+;;;                  (completion-ignore-case                      t)
+;;;                  (choice
+;;;                   (save-excursion (completing-read "Complete: " (mapcar #'list dwim-completions)
+;;;                                                    nil t pattern nil pattern))))
+;;;             (when choice
+;;;               (delete-region beg end)
+;;;               (insert choice)))
+;;;         (error nil))
+;;;       (unless (eq (selected-window) (minibuffer-window)) (message "Making completion list...done")))
+;;;     done))
+
 
 
 ;; REPLACE ORIGINAL `bbdb-complete-name' defined in `bbdb-com.el' version 2.35,
@@ -2017,17 +2306,29 @@ considered."
     (insert new)))
 
 
-;; REPLACE ORIGINAL `lisp-completion-at-point' (>= Emacs 23.2),
+;; REPLACE ORIGINAL `lisp-completion-at-point' (>= Emacs 23.2 and <= Emacs 24.3),
 ;; defined in `lisp.el', saving it for restoration when you toggle `icicle-mode'.
 ;;
 ;; Select `*Completions*' window even if on another frame.
 ;;
-(when (fboundp 'completion-at-point)    ; Emacs 23.2+.
+(when (and (fboundp 'completion-at-point)  (not (fboundp 'elisp-completion-at-point))) ; Emacs 23.2 through 24.4.
   (unless (fboundp 'icicle-ORIG-lisp-completion-at-point)
     (defalias 'icicle-ORIG-lisp-completion-at-point (symbol-function 'lisp-completion-at-point))
     ;; Return a function that does all of the completion.
     (defun icicle-lisp-completion-at-point () #'icicle-lisp-complete-symbol)))
 
+
+;; REPLACE ORIGINAL `elisp-completion-at-point' (>= Emacs 25),
+;; defined in `elisp-mode.el', saving it for restoration when you toggle `icicle-mode'.
+;;
+;; Select `*Completions*' window even if on another frame.
+;;
+(when (fboundp 'elisp-completion-at-point) ; Emacs 25+.
+  (unless (fboundp 'icicle-ORIG-lisp-completion-at-point)
+    (defalias 'icicle-ORIG-elisp-completion-at-point (symbol-function 'elisp-completion-at-point))
+    ;; Return a function that does all of the completion.
+    (defun icicle-elisp-completion-at-point () #'icicle-lisp-complete-symbol)))
+
 (defun icicle-customize-icicles-group ()
   "Customize Icicles options and faces.  View their documentation."
   (interactive)
@@ -2059,6 +2360,7 @@ Same as `icicle-customize-face' except it uses a different window."
   (interactive
    (list (let* ((icicle-multi-completing-p             t)
                 (icicle-list-use-nth-parts             '(1))
+                (icicle-face-completing-p              t)
                 (icicle-candidate-action-fn
                  (lambda (fc)
                    (let ((proxy  (car (member fc icicle-proxy-candidates))))
@@ -2144,6 +2446,7 @@ This is an Icicles command - see command `icicle-mode'."
   (interactive
    (list (let* ((icicle-multi-completing-p             t)
                 (icicle-list-use-nth-parts             '(1))
+                (icicle-face-completing-p              t)
                 (icicle-candidate-action-fn
                  (lambda (fc)
                    (let ((proxy  (car (member fc icicle-proxy-candidates))))
@@ -2176,7 +2479,6 @@ This is an Icicles command - see command `icicle-mode'."
   "Open Customize buffer on all faces in list FACES."
   (let ((icicle-list-nth-parts-join-string  ": ")
         (icicle-list-join-string            ": ")
-        ;; $$$$$$ (icicle-list-end-string   "")
         (icicle-list-use-nth-parts          '(1)))
     (custom-buffer-create
      (custom-sort-items
@@ -2223,7 +2525,16 @@ This handling of \"words\" is for compatibility with vanilla Emacs,
 and is only approximative.  It can include \"matches\" that you do not
 expect.  For better matching use Icicles progressive completion, i.e.,
 separate the words (any strings, in fact, including regexps) using
-`S-SPC', not just `SPC'."
+`S-SPC', not just `SPC'.
+
+See also the commands for individual TYPEs:
+ `icicle-customize-apropos-options'
+ `icicle-customize-apropos-faces'
+ `icicle-customize-apropos-groups'
+
+Note that unlike `icicle-customize-apropos', command
+`icicle-customize-apropos-faces' shows you WYSIWYG face candidates, if
+option `icicle-WYSIWYG-Completions-flag' is non-nil."
   (interactive
    (let* ((pref-arg                                current-prefix-arg)
           (pred                                    `(lambda (s)
@@ -2246,11 +2557,11 @@ separate the words (any strings, in fact, including regexps) using
                (string= (regexp-quote pattern) pattern)
                (not (string= "" pattern)))
       (setq pattern  (split-string pattern "[ \t]+" 'OMIT-NULLS)))
-    (when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern)) ; Emacs 22+
+    (when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern)) ; Emacs 22+.  Updates `apropos-*'.
     (when msgp (message "Gathering apropos data for customize `%s'..." pattern))
     (mapatoms `(lambda (symbol)         ; FREE here: APROPOS-REGEXP.
-                (when (string-match ,(and (> emacs-major-version 21)  apropos-regexp pattern)
-                                    (symbol-name symbol))
+                (when (icicle-string-match-p ,(if (> emacs-major-version 21)  apropos-regexp  pattern)
+                                             (symbol-name symbol))
                   (when (and (not (memq ,type '(faces options))) ; groups or t
                              (get symbol 'custom-group))
                     (push (list symbol 'custom-group) found))
@@ -2282,21 +2593,28 @@ separate the words (any strings, in fact, including regexps) using
          (or (get variable 'standard-value)  (get variable 'custom-autoload)))))
 
 ;; Icicles replacement for `customize-apropos-faces', defined in `cus-edit.el'.
-;; 1. Uses `completing-read' to read the regexp.
+;;
+;; 1. Uses `completing-read' to read the regexp, and uses `icicle-make-face-candidate', to provide WYSIWYG.
 ;; 2. Fixes Emacs bug #11124.
 ;;
 (defun icicle-customize-apropos-faces (pattern &optional msgp)
   "Customize all loaded faces matching PATTERN.
 See `icicle-customize-apropos'."
   (interactive
-   (let* ((pred                                    (lambda (s)
-                                                     (unless (symbolp s) (setq s  (intern s)))
-                                                     (custom-facep s)))
-          (icompletep                              (and (featurep 'icomplete)  icomplete-mode))
-          (icicle-must-pass-after-match-predicate  (and (not icompletep)  pred)))
-     (list (completing-read "Customize faces (pattern): " obarray (and icompletep  pred)
-                            nil nil 'regexp-history)
-           t)))
+   (let* ((prompt                                  "Customize faces (pattern): ")
+          (face-list                               (face-list))
+          (icicle-multi-completing-p               t)
+          (icicle-list-nth-parts-join-string       ": ")
+          (icicle-list-join-string                 ": ")
+          (icicle-list-use-nth-parts               '(1))
+          (icicle-face-completing-p                t))
+     (put-text-property 0 1 'icicle-fancy-candidates t prompt)
+     (let ((input  (icicle-transform-multi-completion
+                    (completing-read prompt (mapcar #'icicle-make-face-candidate face-list)
+                                     nil nil nil 'regexp-history))))
+       (when (and (fboundp 'apropos-read-pattern)  (string= (regexp-quote input) input))
+         (setq input  (or (split-string input "[ \t]+" t)  (user-error "No word list given"))))
+       (list input  t))))
   (when msgp (message "Gathering apropos data for customizing faces..."))
   (customize-apropos pattern 'faces))
 
@@ -2442,10 +2760,10 @@ separate the words (any strings, in fact, including regexps) using
   (apropos pattern do-all))
 
 (cond
-  ;; Use my versions of the `apropos*' commands, defined in `apropos-fn+var.el'.
-  ;; Note that unlike my versions of `apropos-option' and `apropos-command', the `icicle-'
-  ;; versions here do not respect `apropos-do-all': they always work with options and commands.
-  ((fboundp 'apropos-option)
+  ;; Use `apropos-variable' and `apropos-option' from `apropos-fn+var.el',
+  ;; or use Emacs 24.4+ `apropos-variable' and `apropos-user-option'.
+  ;; Note that `icicle-apropos-option' does not respect `apropos-do-all': it always works with only options.
+  ((or (featurep 'apropos-fn+var)  (fboundp 'apropos-user-option)) ; Emacs 24.4 defines `apropos-user-option'.
    (defun icicle-apropos-variable (pattern &optional msgp)
      "Show variables that match PATTERN.
 This includes variables that are not user options.
@@ -2464,6 +2782,7 @@ See `icicle-apropos' for a description of PATTERN."
                                                                        (get s 'variable-documentation))))
                      (icompletep                                (and (featurep 'icomplete)  icomplete-mode))
                      (icicle-must-pass-after-match-predicate    (and (not icompletep)  pred))
+                     (icicle-variable-completing-p              t)
                      (icicle-candidate-alt-action-fn            (or icicle-candidate-alt-action-fn
                                                                     (icicle-alt-act-fn-for-type "variable")))
                      (icicle-all-candidates-list-alt-action-fn ; `M-|'
@@ -2493,8 +2812,8 @@ See `icicle-apropos' for a description of PATTERN."
              (icompletep                              (and (featurep 'icomplete)  icomplete-mode))
              (icicle-must-pass-after-match-predicate  (and (not icompletep)  pred)))
         (list (completing-read
-               (concat "Apropos user option (regexp" (and (>= emacs-major-version 22)  " or words")
-                       "): ") obarray (and icompletep  pred) nil nil 'regexp-history)
+               (concat "Apropos user option (regexp" (and (>= emacs-major-version 22)  " or words") "): ")
+               obarray (and icompletep  pred) nil nil 'regexp-history)
               t)))
      (let ((apropos-do-all  nil)
            (icicle-candidate-alt-action-fn
@@ -2507,8 +2826,69 @@ See `icicle-apropos' for a description of PATTERN."
          (setq pattern  (split-string pattern "[ \t]+" 'OMIT-NULLS)))
        (when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern)) ; Emacs 22+
        (when msgp (message "Gathering data apropos user options..."))
-       (apropos-option pattern)))
+       (apropos-option pattern))))
+
+  ;; `apropos-fn+var.el' not available, and Emacs < 24.4.  Use pre-24.4 vanilla Emacs versions.
+  (t
+   (defun icicle-apropos-variable (pattern &optional do-all msgp)
+     "Show variables that match PATTERN.
+You can see the list of matches with `S-TAB'.
+See `icicle-apropos' for a description of PATTERN.
 
+By default, only user options are candidates.  With optional prefix
+DO-ALL, or if `apropos-do-all' is non-nil, all variables are
+candidates.  In that case, the user-option candidates are highlighted
+using face `icicle-special-candidate'."
+     (interactive
+      (list
+       (unwind-protect
+            (progn
+              (unless (or (boundp 'apropos-do-all)  (require 'apropos nil t))
+                (error "Library `apropos' not found"))
+              (when (or current-prefix-arg  apropos-do-all)
+                (mapatoms (lambda (symb)
+                            (when (user-variable-p symb) (put symb 'icicle-special-candidate t)))))
+              (let* ((icicle-fancy-candidates-p               (or current-prefix-arg  apropos-do-all))
+                     (pred                                    (if (or current-prefix-arg  apropos-do-all)
+                                                                  (lambda (s)
+                                                                    (unless (symbolp s)
+                                                                      (setq s  (intern s)))
+                                                                    (and (boundp s)
+                                                                         (get s 'variable-documentation)))
+                                                                (lambda (s)
+                                                                  (unless (symbolp s) (setq s  (intern s)))
+                                                                  (user-variable-p s))))
+                     (icompletep                              (and (featurep 'icomplete)  icomplete-mode))
+                     (icicle-must-pass-after-match-predicate  (and (not icompletep)  pred))
+                     (icicle-variable-completing-p            t)
+                     (icicle-candidate-alt-action-fn          (or icicle-candidate-alt-action-fn
+                                                                  (icicle-alt-act-fn-for-type
+                                                                   (if icicle-fancy-candidates-p
+                                                                       "variable"
+                                                                     "option"))))
+                     (icicle-all-candidates-list-alt-action-fn ; `M-|'
+                      (or icicle-all-candidates-list-alt-action-fn
+                          (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p "variable" "option")))))
+                (completing-read
+                 (concat "Apropos " (if (or current-prefix-arg  apropos-do-all) "variable" "user option")
+                         " (regexp" (and (>= emacs-major-version 22)  " or words") "): ")
+                 obarray (and icompletep  pred) nil nil 'regexp-history)))
+         (when (or current-prefix-arg  apropos-do-all)
+           (mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil)))))
+       current-prefix-arg
+       t))
+     (when (and (> emacs-major-version 21)  (require 'apropos nil t)
+                (string= (regexp-quote pattern) pattern)
+                (not (string= "" pattern)))
+       (setq pattern  (split-string pattern "[ \t]+" 'OMIT-NULLS)))
+     (when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern)) ; Emacs 22+
+     (when msgp (message (format "Gathering data apropos %s..." (if do-all "variables" "options"))))
+     (apropos-variable pattern do-all))))
+
+(cond
+  ;; Use `apropos-function' and `apropos-command' from `apropos-fn+var.el'.
+  ;; Note that `icicle-apropos-command' does not respect `apropos-do-all': it always works with only commands.
+  ((featurep 'apropos-fn+var)
    (defun icicle-apropos-function (pattern &optional msgp)
      "Show functions that match PATTERN.
 This includes functions that are not commands.
@@ -2532,8 +2912,8 @@ See `icicle-apropos' for a description of PATTERN."
                       (or icicle-all-candidates-list-alt-action-fn
                           (icicle-alt-act-fn-for-type "function"))))
                 (completing-read
-                 (concat "Apropos function (regexp" (and (>= emacs-major-version 22)  " or words")
-                         "): ") obarray (and icompletep  pred) nil nil 'regexp-history)))
+                 (concat "Apropos function (regexp" (and (>= emacs-major-version 22)  " or words") "): ")
+                 obarray (and icompletep  pred) nil nil 'regexp-history)))
          (mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil))))
        t))
      (when (and (> emacs-major-version 21)  (require 'apropos nil t)
@@ -2559,8 +2939,8 @@ See `icicle-apropos' for a description of PATTERN."
              (icicle-all-candidates-list-alt-action-fn  (or icicle-all-candidates-list-alt-action-fn ; `M-|'
                                                             (icicle-alt-act-fn-for-type "command"))))
         (list (completing-read
-               (concat "Apropos command (regexp" (and (>= emacs-major-version 22)  " or words")
-                       "): ") obarray (and icompletep  pred) nil nil 'regexp-history)
+               (concat "Apropos command (regexp" (and (>= emacs-major-version 22)  " or words") "): ")
+               obarray (and icompletep  pred) nil nil 'regexp-history)
               t)))
      (when (and (> emacs-major-version 21)  (require 'apropos nil t)
                 (string= (regexp-quote pattern) pattern)
@@ -2570,62 +2950,8 @@ See `icicle-apropos' for a description of PATTERN."
      (when msgp (message "Gathering data apropos commands..."))
      (let ((apropos-do-all  nil))  (apropos-command pattern))))
 
-  ;; My versions are not available.  Use the vanilla Emacs versions of the `apropos...' commands.
+  ;; `apropos-fn+var.el' not available.  Use vanilla Emacs `apropos-command'.
   (t
-   (defun icicle-apropos-variable (pattern &optional do-all msgp)
-     "Show variables that match PATTERN.
-You can see the list of matches with `S-TAB'.
-See `icicle-apropos' for a description of PATTERN.
-
-By default, only user options are candidates.  With optional prefix
-DO-ALL, or if `apropos-do-all' is non-nil, all variables are
-candidates.  In that case, the user-option candidates are highlighted
-using face `icicle-special-candidate'."
-     (interactive
-      (list
-       (unwind-protect
-            (progn
-              (unless (or (boundp 'apropos-do-all)  (require 'apropos nil t))
-                (error "Library `apropos' not found"))
-              (when (or current-prefix-arg  apropos-do-all)
-                (mapatoms (lambda (symb)
-                            (when (user-variable-p symb) (put symb 'icicle-special-candidate t)))))
-              (let* ((icicle-fancy-candidates-p               (or current-prefix-arg  apropos-do-all))
-                     (pred                                    (if (or current-prefix-arg  apropos-do-all)
-                                                                  (lambda (s)
-                                                                    (unless (symbolp s)
-                                                                      (setq s  (intern s)))
-                                                                    (and (boundp s)
-                                                                         (get s 'variable-documentation)))
-                                                                (lambda (s)
-                                                                  (unless (symbolp s) (setq s  (intern s)))
-                                                                  (user-variable-p s))))
-                     (icompletep                              (and (featurep 'icomplete)  icomplete-mode))
-                     (icicle-must-pass-after-match-predicate  (and (not icompletep)  pred))
-                     (icicle-candidate-alt-action-fn          (or icicle-candidate-alt-action-fn
-                                                                  (icicle-alt-act-fn-for-type
-                                                                   (if icicle-fancy-candidates-p
-                                                                       "variable"
-                                                                     "option"))))
-                     (icicle-all-candidates-list-alt-action-fn ; `M-|'
-                      (or icicle-all-candidates-list-alt-action-fn
-                          (icicle-alt-act-fn-for-type (if icicle-fancy-candidates-p "variable" "option")))))
-                (completing-read
-                 (concat "Apropos " (if (or current-prefix-arg  apropos-do-all) "variable" "user option")
-                         " (regexp" (and (>= emacs-major-version 22)  " or words") "): ")
-                 obarray (and icompletep  pred) nil nil 'regexp-history)))
-         (when (or current-prefix-arg  apropos-do-all)
-           (mapatoms (lambda (symb) (put symb 'icicle-special-candidate nil)))))
-       current-prefix-arg
-       t))
-     (when (and (> emacs-major-version 21)  (require 'apropos nil t)
-                (string= (regexp-quote pattern) pattern)
-                (not (string= "" pattern)))
-       (setq pattern  (split-string pattern "[ \t]+" 'OMIT-NULLS)))
-     (when (fboundp 'apropos-parse-pattern) (apropos-parse-pattern pattern)) ; Emacs 22+
-     (when msgp (message (format "Gathering data apropos %s..." (if do-all "variables" "options"))))
-     (apropos-variable pattern do-all))
-
    (defun icicle-apropos-command (pattern &optional do-all var-predicate msgp)
      "Show commands (interactively callable functions) that match PATTERN.
 You can see the list of matches with `S-TAB'.
@@ -2737,7 +3063,7 @@ Return the list of matches."
                                                nil nil nil 'regexp-history)))))
   (let ((matches  (apropos-zippy icicle-current-input)))
     (when (interactive-p)
-      (with-output-to-temp-buffer "*Zippy Apropos*"
+      (icicle-with-help-window "*Zippy Apropos*"
         (while matches
           (princ (car matches))
           (setq matches  (cdr matches))
@@ -2899,9 +3225,10 @@ by default.  (`^G' here means the Control-g character, input using
 
 Remember that you can insert `icicle-list-join-string' using `C-M-j'.
 
-This command binds option `icicle-dot-string' to the value of
-`icicle-anychar-regexp' for the duration, which means that `.' in your
-input to this command matches any character, including a newline char.
+This command binds option `icicle-dot-string' to the value returned by
+function `icicle-anychar-regexp', for the duration, which means that
+`.' in your input to this command matches any character, including a
+newline char.
 
 This is for convenience because `defcustom' type sexps are often
 multiline.  This is particularly important for progressive completion,
@@ -3005,7 +3332,7 @@ default for this command:
   ((prompt                                 "OPTION `C-M-j' TYPE: ") ; Bindings
    (icicle-multi-completing-p              t)
    (icicle-candidate-properties-alist      '((1 (face icicle-candidate-part))))
-   (icicle-dot-string                      icicle-anychar-regexp)
+   (icicle-dot-string                      (icicle-anychar-regexp))
    ;; Bind `icicle-apropos-complete-match-fn' to nil to prevent automatic input matching
    ;; in `icicle-unsorted-apropos-candidates' etc., because `icicle-describe-opt-of-type-complete'
    ;; does everything.
@@ -3077,9 +3404,7 @@ This is used as the value of `minibuffer-completion-table'."
           ;; FREE here: ICICLE-HELP-IN-MODE-LINE-DELAY, ICICLE-LIST-JOIN-STRING, TOOLTIP-MODE.
           (mapcar (lambda (entry)
                     (let* ((opt+typ-string
-                            ;; $$$$$$ (concat (mapconcat (lambda (e) (pp-to-string e))
-                            ;;                           entry icicle-list-join-string)
-                            ;;                icicle-list-end-string)) ; $$$$$$
+                            ;; $$$$$$ (mapconcat (lambda (e) (pp-to-string e)) entry icicle-list-join-string))
                             (mapconcat (lambda (e) (pp-to-string e))  entry  icicle-list-join-string))
                            (doc         ; Don't bother to look up doc, if user won't see it.
                             (and (or (> icicle-help-in-mode-line-delay 0)
@@ -3235,13 +3560,34 @@ and `\\[repeat-matching-complex-command]' to match regexp input, but Icicles inp
                     (and (stringp (car command-history))
                          (setq command-history  (cdr command-history))))))
           ;; If command to be redone does not match front of history, add it to the history.
-          (or (equal newcmd (car command-history))
-              (setq command-history  (cons newcmd command-history)))
-          (eval newcmd))
+          (unless (equal newcmd (car command-history))
+            (setq command-history  (cons newcmd command-history)))
+          ;; Trick `called-interactively-p' into thinking that this is an interactive call of NEWCMD
+          ;; (Emacs bug #14136).
+          (if (or (> emacs-major-version 24)
+                  (and (= emacs-major-version 24)  (not (version< emacs-version "24.3.50"))))
+              (unwind-protect
+                   (progn (add-hook 'called-interactively-p-functions
+                                    #'icicle-repeat-complex-command--called-interactively-skip)
+                          (eval newcmd))
+                (remove-hook 'called-interactively-p-functions
+                             #'icicle-repeat-complex-command--called-interactively-skip))
+            (eval newcmd)))
       (if command-history
           (icicle-user-error "Argument %d is beyond length of command history" arg)
         (icicle-user-error "There are no previous complex commands to repeat")))))
 
+;; Same as `repeat-complex-command--called-interactively-skip' in `simple.el', but tests for
+;; `icicle-repeat-complex-command', not `repeat-complex-command'.
+(when (or (> emacs-major-version 24)
+          (and (= emacs-major-version 24)  (not (version< emacs-version "24.3.50"))))
+  (defun icicle-repeat-complex-command--called-interactively-skip (i _frame1 frame2)
+    "If currently `icicle-repeat-complex-command', return 1 to skip over it."
+    (and (eq 'eval (cadr frame2))  (eq 'icicle-repeat-complex-command
+                                       (cadr (backtrace-frame i #'called-interactively-p)))
+         1))
+  (byte-compile 'icicle-repeat-complex-command))
+
 (defun icicle-add-entry-to-saved-completion-set (set-name entry type)
   "Add ENTRY to saved completion-candidates set SET-NAME.
 ENTRY is normally a single candidate (a string).
@@ -3902,7 +4248,14 @@ To use `icicle-explore' to define a multi-command, you must also bind
 Though `icicle-explore' is typically used to define navigation
 commands, it need not be.  It can be useful anytime you need to use
 `completing-read' and also provide specific behavior for quitting
-\(`C-g'), completion errors, and final actions."
+\(`C-g'), completion errors, and final actions.
+
+Note: `icicle-explore' binds user option
+`icicle-incremental-completion' to `always', because I think you
+typically want to start it out with incremental completion turned on.
+Functions that call `icicle-explore' thus also turn on incremental
+completion.  Remember that you can use `C-#' (once or twice) to turn
+incremental completion off."
   (let ((icicle-incremental-completion          'always)
         (icicle-whole-candidate-as-text-prop-p  t)
         (icicle-transform-function              (and (not (interactive-p))  icicle-transform-function))
@@ -4320,7 +4673,7 @@ an action uses the base prefix arg you used for `icicle-kmacro'."
     (lexical-let ((count  0))
       (setq icicle-kmacro-alist
             (mapcar (lambda (x) (cons (format "%d" (setq count  (1+ count))) x)) ; FREE here: COUNT.
-                    ;; @@@@@@@ Why the (if nil...) here?
+                    ;; $$$$$$ Why the (if nil...) here?
                     (reverse (if nil kmacro-ring (cons (kmacro-ring-head) kmacro-ring))))))
     nil 'NO-EXIT-WO-MATCH nil 'icicle-kmacro-history
     (and (kmacro-ring-head)  (null kmacro-ring)  "1") nil
@@ -4534,10 +4887,6 @@ candidates, as follows:
    (icicle-all-candidates-list-alt-action-fn ; `M-|'
     (or icicle-all-candidates-list-alt-action-fn  alt-fn  (icicle-alt-act-fn-for-type "option")))))
 
-(defun icicle-binary-option-p (symbol)
-  "Non-nil if SYMBOL is a user option that has custom-type `boolean'."
-  (eq (icicle-get-safe symbol 'custom-type) 'boolean))
-
 (icicle-define-command icicle-increment-option ; Command name
   "Increment option's value using the arrow keys (`up', `down').
 Completion candidates are limited to options that have `integer',
@@ -4750,10 +5099,8 @@ instead of those for the current buffer."
                (icicle-list-use-nth-parts              '(1))
                (icicle-candidate-properties-alist      (if (not icicle-multi-completing-p)
                                                            ()
-                                                         (if (facep 'file-name-shadow)
-                                                             '((2 (face file-name-shadow))
-                                                               (3 (face bookmark-menu-heading)))
-                                                           '((3 (face bookmark-menu-heading))))))
+                                                         '((2 (face icicle-annotation))
+                                                           (3 (face icicle-msg-emphasis)))))
                (icicle-transform-function              (and (not (interactive-p))  icicle-transform-function))
                (icicle-whole-candidate-as-text-prop-p  t)
                (icicle-transform-before-sort-p         t)
@@ -5056,36 +5403,53 @@ If you also use library `Bookmark+', then:
    (Each `C-M-j' inserts `^G\n', which is `icicle-list-join-string'.)
 
  * You can narrow the current completion candidates to bookmarks of a
-   given type.  The keys for this are the same as the bookmark-jumping
-   keys at the top level.
-
-   `C-x j a'   - autofile bookmarks
-   `C-x j b'   - non-file (buffer) bookmarks
-   `C-x j B'   - bookmark-list bookmarks
-   `C-x j d'   - Dired bookmarks
-   `C-x j f'   - file bookmarks
-   `C-x j . f' - bookmarks to files in the current directory
-   `C-x j g'   - Gnus bookmarks
-   `C-x j i'   - Info bookmarks
-   `C-x j M-i' - image bookmarks
-   `C-x j K'   - desktop bookmarks
-   `C-x j l'   - local-file bookmarks
-   `C-x j m'   - `man' pages
-   `C-x j n'   - remote-file bookmarks
-   `C-x j r'   - bookmarks with regions
-   `C-x j u'   - URL bookmarks
-   `C-x j w'   - W3M (URL) bookmarks
-   `C-x j x'   - temporary bookmarks
-   `C-x j y'   - bookmark-file bookmarks
-   `C-x j #'   - autonamed bookmarks
-   `C-x j , #' - autonamed bookmarks for the current buffer
-   `C-x j , ,' - bookmarks for the current buffer
-   `C-x j = b' - bookmarks for specific buffers
-   `C-x j = f' - bookmarks for specific files
+   given type.  The keys for this are generally the same as the
+   bookmark-jumping keys at the top level.
+
+   `C-x j a'    - autofile bookmarks
+   `C-x j b'    - non-file (buffer) bookmarks
+   `C-x j B'    - bookmark-list bookmarks
+   `C-x j C-c ` - bookmarks that record Icicles search hits
+   `C-x j d'    - Dired bookmarks
+   `C-x j . d'  - Dired bookmarks for `default-directory'
+   `C-x j * d'  - bookmarks for Dired buffers with wildcards
+   `C-x j D'    - bookmarks flagged for deletion in `*Bookmark List*'
+   `C-x j f'    - file bookmarks
+   `C-x j . f'  - bookmarks to files in the current directory
+   `C-x j F'    - function bookmarks
+   `C-x j g'    - Gnus bookmarks
+   `C-x j h'    - bookmarks that are currently highlighted
+   `C-x j i'    - Info bookmarks
+   `C-x j M-i'  - image bookmarks
+   `C-x j K'    - desktop bookmarks
+   `C-x j l'    - local-file bookmarks
+   `C-x j m'    - `man' pages
+   `C-x j M'    - modified (unsaved) bookmarks
+   `C-x j n'    - remote-file bookmarks
+   `C-x j N'    - bookmarks currently in the navigation list
+   `C-x j o f'  - orphaned file bookmarks
+   `C-x j o l'  - orphaned local-file bookmarks
+   `C-x j r'    - bookmarks with regions
+   `C-x j C-t'  - tagged bookmarks
+   `C-x j v'    - variable-list bookmarks
+   `C-x j u'    - URL bookmarks
+   `C-x j w'    - W3M (URL) bookmarks
+   `C-x j M-w'  - snippet bookmarks
+   `C-x j x'    - temporary bookmarks
+   `C-x j y'    - bookmark-file bookmarks
+   `C-x j #'    - autonamed bookmarks
+   `C-x j , #'  - autonamed bookmarks for the current buffer
+   `C-x j , ,'  - bookmarks for the current buffer
+   `C-x j = b'  - bookmarks for specific buffers
+   `C-x j = f'  - bookmarks for specific files
+   `C-x j >'    - bookmarks marked in `*Bookmark List*'
 
    See also the individual multi-commands for different bookmark
    types: `icicle-bookmark-info-other-window' etc.
 
+ * You can also use `M-&' and choose a bookmark-narrowing predicate.
+   These are more or less the same narrowings provided by the keys.
+
  * `C-S-RET', the alternative candidate action, prompts you for a
    property of the candidate bookmark and a function, then applies the
    function to the property.  Completion is available for the
@@ -5102,13 +5466,12 @@ position is highlighted."               ; Doc string
    (completion-ignore-case                 bookmark-completion-ignore-case)
    (prompt                                 "Bookmark: ")
    (icicle-multi-completing-p              icicle-show-multi-completion-flag)
+   (icicle-bookmark-completing-p           t)
    (icicle-list-use-nth-parts              '(1))
    (icicle-candidate-properties-alist      (if (not icicle-multi-completing-p)
                                                ()
-                                             (if (facep 'file-name-shadow)
-                                                 '((2 (face file-name-shadow))
-                                                   (3 (face bookmark-menu-heading)))
-                                               '((3 (face bookmark-menu-heading))))))
+                                             '((2 (face icicle-annotation))
+                                               (3 (face icicle-msg-emphasis)))))
    (icicle-transform-function              (and (not (interactive-p))  icicle-transform-function))
    (icicle-whole-candidate-as-text-prop-p  t)
    (icicle-transform-before-sort-p         t)
@@ -5175,13 +5538,12 @@ Same as `icicle-bookmark', but uses another window." ; Doc string
    (completion-ignore-case                 bookmark-completion-ignore-case)
    (prompt                                 "Bookmark: ")
    (icicle-multi-completing-p              icicle-show-multi-completion-flag)
+   (icicle-bookmark-completing-p           t)
    (icicle-list-use-nth-parts              '(1))
    (icicle-candidate-properties-alist      (if (not icicle-multi-completing-p)
                                                ()
-                                             (if (facep 'file-name-shadow)
-                                                 '((2 (face file-name-shadow))
-                                                   (3 (face bookmark-menu-heading)))
-                                               '((3 (face bookmark-menu-heading))))))
+                                             '((2 (face icicle-annotation))
+                                               (3 (face icicle-msg-emphasis)))))
    (icicle-transform-function              (and (not (interactive-p))  icicle-transform-function))
    (icicle-whole-candidate-as-text-prop-p  t)
    (icicle-transform-before-sort-p         t)
@@ -5241,42 +5603,80 @@ Same as `icicle-bookmark', but uses another window." ; Doc string
   (when (featurep 'bookmark+)
     ;; Lax completion is for multi-completion case.
     (dolist (map  '(minibuffer-local-must-match-map  minibuffer-local-completion-map))
+      (define-key (symbol-value map) (icicle-kbd "C-x j >") ; `C-x j >'
+        'icicle-bookmark-marked-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j #") ; `C-x j #'
         'icicle-bookmark-autonamed-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j , #") ; `C-x j , #'
         'icicle-bookmark-autonamed-this-buffer-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j A") ; `C-x j A'
+        'icicle-bookmark-annotated-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j a") ; `C-x j a'
         'icicle-bookmark-autofile-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j b") ; `C-x j b'
         'icicle-bookmark-non-file-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j B") ; `C-x j B'
         'icicle-bookmark-bookmark-list-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j C-c `") ; `C-x j C-c `'
+        'icicle-bookmark-icicle-search-hits-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j d") ; `C-x j d'
         'icicle-bookmark-dired-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j . d") ; `C-x j . d'
+        'icicle-bookmark-dired-this-dir-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j * d") ; `C-x j * d'
+        'icicle-bookmark-dired-wildcards-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j D") ; `C-x j D'
+        'icicle-bookmark-flagged-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j f") ; `C-x j f'
         'icicle-bookmark-file-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j . f") ; `C-x j . f'
         'icicle-bookmark-file-this-dir-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j F") ; `C-x j F'
+        'icicle-bookmark-function-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j g") ; `C-x j g'
         'icicle-bookmark-gnus-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j h") ; `C-x j h'
+        'icicle-bookmark-lighted-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j i") ; `C-x j i'
         'icicle-bookmark-info-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j M-i") ; `C-x j M-i'
         'icicle-bookmark-image-narrow)
+;;;       (define-key (symbol-value map) (icicle-kbd "C-x j = b")
+;;;         'icicle-bookmark-last-specific-buffer-narrow)
+;;;       (define-key (symbol-value map) (icicle-kbd "C-x j = f")
+;;;         'icicle-bookmark-last-specific-file-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j K") ; `C-x j K'
         'icicle-bookmark-desktop-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j l") ; `C-x j l'
         'icicle-bookmark-local-file-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j m") ; `C-x j m'
         'icicle-bookmark-man-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j M") ; `C-x j M'
+        'icicle-bookmark-modified-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j n") ; `C-x j n'
         'icicle-bookmark-remote-file-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j N") ; `C-x j N'
+        'icicle-bookmark-navlist-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j o f") ; `C-x j o f'
+        'icicle-bookmark-orphaned-file-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j o l") ; `C-x j o l'
+        'icicle-bookmark-orphaned-local-file-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j o n") ; `C-x j o n'
+        'icicle-bookmark-orphaned-remote-file-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j r") ; `C-x j r'
         'icicle-bookmark-region-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j s") ; `C-x j s'
+        'icicle-bookmark-sequence-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j u") ; `C-x j u'
         'icicle-bookmark-url-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j C-t") ; `C-x j C-t' (`C-x j t' is prefix key for jumps)
+        'icicle-bookmark-tagged-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j v") ; `C-x j v'
+        'icicle-bookmark-variable-list-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j w") ; `C-x j w'
         'icicle-bookmark-w3m-narrow)
+      (define-key (symbol-value map) (icicle-kbd "C-x j M-w") ; `C-x j M-w'
+        'icicle-bookmark-snippet-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j x") ; `C-x j x'
         'icicle-bookmark-temporary-narrow)
       (define-key (symbol-value map) (icicle-kbd "C-x j y") ; `C-x j y'
@@ -5363,10 +5763,12 @@ You probably do not want to use this.  Use
 
 (defun icicle-bookmark-jump-1 (bookmark &optional other-window-p)
   "Helper function for `icicle-bookmark-jump(-other-window)'."
-  (unless bookmark (error "No bookmark specified"))
-  (bookmark-maybe-historicize-string bookmark)
-  ;; In case the jump renames it (as for an autonamed bookmark).
-  (setq bookmark  (bookmark-get-bookmark bookmark 'NOERROR))
+  (let ((input-bmk  bookmark))
+    (unless input-bmk (error "No bookmark specified"))
+    (bookmark-maybe-historicize-string bookmark)
+    ;; In case the jump renames it (as for an autonamed bookmark).
+    (setq bookmark  (bookmark-get-bookmark bookmark 'NOERROR))
+    (unless bookmark (error "No such bookmark: `%s'" input-bmk)))
   (if (fboundp 'bookmark--jump-via)
       (bookmark--jump-via bookmark (if other-window-p 'pop-to-buffer 'switch-to-buffer))
     (let ((cell  (bookmark-jump-noselect bookmark))) ; Emacs < 23 and without `Bookmark+'.
@@ -5423,128 +5825,233 @@ Remove crosshairs highlighting and unbind filtering keys."
 
 ;;; These are minibuffer commands, but we define them here instead of in `icicles-mcmd.el'.
 
+(defun icicle-bookmark-annotated-narrow () ; Bound to `C-x j A' in minibuffer for completion.
+  "Narrow the bookmark candidates to bookmarks that have annotations."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-annotated-p)))
+
 (defun icicle-bookmark-autofile-narrow () ; Bound to `C-x j a' in minibuffer for completion.
   "Narrow the bookmark candidates to autofile bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-autofile-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-autofile-p)))
 
 (defun icicle-bookmark-autonamed-narrow () ; Bound to `C-x j #' in minibuffer for completion.
   "Narrow the bookmark candidates to autonamed bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x)
-       (bmkp-autonamed-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-autonamed-p)))
 
 (defun icicle-bookmark-autonamed-this-buffer-narrow ()
                                         ; Bound to `C-x j , #' in minibuffer for completion.
   "Narrow bookmark candidates to autonamed bookmarks in current buffer."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x)                          ; FREE here: ICICLE-ORIG-BUFF.
-       (with-current-buffer icicle-orig-buff
-         (bmkp-autonamed-this-buffer-bookmark-p (icicle-transform-multi-completion (car x))))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-autonamed-this-buffer-p)))
 
 (defun icicle-bookmark-bookmark-file-narrow () ; Bound to `C-x j y' in minibuffer for completion.
   "Narrow the bookmark candidates to bookmark-file bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-bookmark-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-bookmark-file-p)))
 
 (defun icicle-bookmark-bookmark-list-narrow () ; Bound to `C-x j B' in minibuffer for completion.
   "Narrow the bookmark candidates to bookmark-list bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-bookmark-list-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-bookmark-list-p)))
 
 (defun icicle-bookmark-desktop-narrow ()   ; Bound to `C-x j K' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to desktop bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-desktop-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-desktop-p)))
 
 (defun icicle-bookmark-dired-narrow ()   ; Bound to `C-x j d' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to Dired bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-dired-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-dired-p)))
+
+(defun icicle-bookmark-dired-this-dir-narrow ()   ; Bound to `C-x j . d' in minibuffer for bmk completion.
+  "Narrow the bookmark candidates to Dired bookmarks for `default-directory'."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-dired-this-dir-p)))
+
+(defun icicle-bookmark-dired-wildcards-narrow ()   ; Bound to `C-x j * d' in minibuffer for bmk completion.
+  "Narrow the bookmark candidates to bookmarks for Dired with wildcards."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-dired-wildcards-p)))
 
 (defun icicle-bookmark-file-narrow ()   ; Bound to `C-x j f' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to file bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-file-p)))
 
 (defun icicle-bookmark-file-this-dir-narrow () ; Bound to `C-x j . f' in minibuffer for completion.
   "Narrow the bookmark candidates to bookmarked files in `default-directory'."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-file-this-dir-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-file-this-dir-p)))
+
+(defun icicle-bookmark-flagged-narrow ()   ; Bound to `C-x j D' in minibuffer for bookmark completion.
+  "Narrow the candidates to bookmarks flagged for deletion in `*Bookmark List*'."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-flagged-p)))
+
+(defun icicle-bookmark-function-narrow ()   ; Bound to `C-x j F' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to function bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-function-p)))
 
 (defun icicle-bookmark-gnus-narrow ()   ; Bound to `C-x j g' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to Gnus bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-gnus-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-gnus-p)))
+
+(defun icicle-bookmark-icicle-search-hits-narrow ()   ; Bound to `C-x j C-c `' in minibuf for bmk completion.
+  "Narrow the candidates to bookmarks that record Icicles search hits."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-icicle-search-hits-p)))
 
 (defun icicle-bookmark-image-narrow ()   ; Bound to `C-x j M-i' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to image bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-image-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-image-p)))
 
 (defun icicle-bookmark-info-narrow ()   ; Bound to `C-x j i' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to Info bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-info-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-info-p)))
+
+;;; (defun icicle-bookmark-last-specific-buffer-narrow ()
+;;;   "Narrow the candidates to bookmarks for buffer `bmkp-last-specific-buffer'.
+;;; That is the buffer last used by command `bmkp-this-buffer-bmenu-list'
+;;; to list bookmarks for a specific buffer in `*Bookmark List*'."
+;;;   (interactive)
+;;;   (when (featurep 'bookmark+)
+;;;     (icicle-narrow-candidates-with-predicate #'icicle-bookmark-last-specific-buffer-p)))
+
+;;; (defun icicle-bookmark-last-specific-file-narrow ()
+;;;   "Narrow the candidates to bookmarks for file `bmkp-last-specific-file'.
+;;; That is the file last used by command `bmkp-this-file-bmenu-list' to
+;;; list bookmarks for a specific file in `*Bookmark List*'."
+;;;   (interactive)
+;;;   (when (featurep 'bookmark+)
+;;;     (icicle-narrow-candidates-with-predicate #'icicle-bookmark-last-specific-file-p)))
+
+(defun icicle-bookmark-lighted-narrow () ; Bound to `C-x j h' for bookmark completion.
+  "Narrow the bookmark candidates to highlighted bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+-lit)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-lighted-p)))
+
+;;; (defun icicle-bookmark-local-directory-narrow ()
+;;;   "Narrow the bookmark candidates to local-directory bookmarks."
+;;;   (interactive)
+;;;   (when (featurep 'bookmark+)
+;;;     (icicle-narrow-candidates-with-predicate #'icicle-bookmark-local-directory-p)))
 
 (defun icicle-bookmark-local-file-narrow () ; Bound to `C-x j l' for bookmark completion.
   "Narrow the bookmark candidates to local-file bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-local-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-local-file-p)))
 
 (defun icicle-bookmark-man-narrow () ; Bound to `C-x j m' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to `man'-page bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-man-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-man-p)))
+
+(defun icicle-bookmark-marked-narrow ()   ; Bound to `C-x j >' in minibuffer for bookmark completion.
+  "Narrow the candidates to bookmarks marked in `*Bookmark List*'."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-marked-p)))
+
+(defun icicle-bookmark-modified-narrow ()   ; Bound to `C-x j M' in minibuffer for bookmark completion.
+  "Narrow the candidates to modified (unsaved) bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-modified-p)))
+
+(defun icicle-bookmark-navlist-narrow ()   ; Bound to `C-x j N' in minibuffer for bookmark completion.
+  "Narrow the candidates to bookmarks in the current navigation list."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-navlist-p)))
+
+;;; Not used yet.
+;;; (defun icicle-bookmark-non-dir-file-narrow ()   ; Not bound.
+;;;   "Narrow the bookmark candidates to non-directory file bookmarks."
+;;;   (interactive)
+;;;   (when (featurep 'bookmark+)
+;;;     (icicle-narrow-candidates-with-predicate #'icicle-bookmark-non-dir-file-p)))
 
 (defun icicle-bookmark-non-file-narrow () ; Bound to `C-x j b' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to non-file (buffer-only) bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-non-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-non-file-p)))
+
+;;; (defun icicle-bookmark-omitted-narrow ()
+;;;   "Narrow the candidates to bookmarks that are omitted in `*Bookmark List*'."
+;;;   (interactive)
+;;;   (when (featurep 'bookmark+)
+;;;     (icicle-narrow-candidates-with-predicate #'icicle-bookmark-omitted-p)))
+
+(defun icicle-bookmark-orphaned-file-narrow () ; Bound to `C-x j o f' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to orphaned-file bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-orphaned-file-p)))
+
+(defun icicle-bookmark-orphaned-local-file-narrow () ; Bound to `C-x j o l' in minibuffer for bmk completion.
+  "Narrow the bookmark candidates to orphaned-local-file bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-orphaned-local-file-p)))
+
+(defun icicle-bookmark-orphaned-remote-file-narrow () ; Bound to `C-x j o n' in minibuffer for bmk completion.
+  "Narrow the bookmark candidates to orphaned-remote-file bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-orphaned-remote-file-p)))
 
 (defun icicle-bookmark-region-narrow () ; Bound to `C-x j r' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to bookmarks with regions."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-region-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-region-p)))
 
 (defun icicle-bookmark-remote-file-narrow () ; Bound to `C-x j n' in minibuf for bookmark completion.
   "Narrow the bookmark candidates to remote-file bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-remote-file-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-remote-file-p)))
+
+(defun icicle-bookmark-sequence-narrow () ; Bound to `C-x j s' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to sequence (composite) bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-sequence-p)))
+
+(defun icicle-bookmark-snippet-narrow () ; Bound to `C-x j M-w' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to snippet bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-snippet-p)))
 
 (defun icicle-bookmark-specific-buffers-narrow (buffers) ; `C-x j = b' for bookmark completion.
   "Narrow the bookmark candidates to bookmarks for specific BUFFERS.
@@ -5565,35 +6072,48 @@ You are prompted for the FILES."
      `(lambda (x)
        (member (bookmark-get-filename (icicle-transform-multi-completion (car x))) ',files)))))
 
+(defun icicle-bookmark-tagged-narrow () ; Bound to `C-x j C-t' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to tagged bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-tagged-p)))
+
 (defun icicle-bookmark-temporary-narrow () ; Bound to `C-x j x' in minibuffer for completion.
   "Narrow the bookmark candidates to temporary bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-temporary-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-temporary-p)))
 
 (defun icicle-bookmark-this-buffer-narrow () ; `C-x j , ,' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to bookmarks for the current buffer."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x)                          ; FREE here: ICICLE-ORIG-BUFF.
-       (with-current-buffer icicle-orig-buff
-         (bmkp-this-buffer-p (icicle-transform-multi-completion (car x))))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-this-buffer-p)))
+
+;;; (defun icicle-bookmark-this-file-narrow ()
+;;;   "Narrow the bookmark candidates to bookmarks for the current file."
+;;;   (interactive)
+;;;   (when (featurep 'bookmark+)
+;;;     (icicle-narrow-candidates-with-predicate #'icicle-bookmark-this-file-p)))
 
 (defun icicle-bookmark-url-narrow ()    ; Bound to `C-x j u' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to URL bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
     (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-url-bookmark-p (icicle-transform-multi-completion (car x)))))))
+     (lambda (bmk) (or (icicle-bookmark-url-browse-p bmk)  (icicle-bookmark-url-p bmk))))))
+
+(defun icicle-bookmark-variable-list-narrow ()    ; Bound to `C-x j v' in minibuffer for bookmark completion.
+  "Narrow the bookmark candidates to variable-list bookmarks."
+  (interactive)
+  (when (featurep 'bookmark+)
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-variable-list-p)))
 
 (defun icicle-bookmark-w3m-narrow ()    ; Bound to `C-x j w' in minibuffer for bookmark completion.
   "Narrow the bookmark candidates to W3M (URL) bookmarks."
   (interactive)
   (when (featurep 'bookmark+)
-    (icicle-narrow-candidates-with-predicate
-     (lambda (x) (bmkp-w3m-bookmark-p (icicle-transform-multi-completion (car x)))))))
+    (icicle-narrow-candidates-with-predicate #'icicle-bookmark-w3m-p)))
 
 
 ;; The following sexps macro-expand to define these commands:
@@ -5626,10 +6146,13 @@ You are prompted for the FILES."
 ;;  `icicle-bookmark-image',                     `icicle-bookmark-image-other-window',
 ;;  `icicle-bookmark-info',                      `icicle-bookmark-info-other-window',
 ;;  `icicle-bookmark-local-file',                `icicle-bookmark-local-file-other-window',
+;;  `icicle-bookmark-local-non-dir-file',        `icicle-bookmark-local-non-dir-file-other-window',
 ;;  `icicle-bookmark-man',                       `icicle-bookmark-man-other-window',
+;;  `icicle-bookmark-non-dir-file',              `icicle-bookmark-non-dir-file-other-window',
 ;;  `icicle-bookmark-non-file',                  `icicle-bookmark-non-file-other-window',
 ;;  `icicle-bookmark-region',                    `icicle-bookmark-region-other-window',
 ;;  `icicle-bookmark-remote-file',               `icicle-bookmark-remote-file-other-window',
+;;  `icicle-bookmark-remote-non-dir-file',       `icicle-bookmark-remote-non-dir-file-other-window',
 ;;  `icicle-bookmark-specific-buffers',          `icicle-bookmark-specific-buffers-other-window'
 ;;  `icicle-bookmark-specific-files',            `icicle-bookmark-specific-files-other-window'
 ;;  `icicle-bookmark-all-tags',                  `icicle-bookmark-all-tags-other-window'
@@ -5695,10 +6218,16 @@ You are prompted for the FILES."
 (icicle-define-bookmark-command              "desktop")                                   ; `C-x j K'
 (icicle-define-bookmark-command              "local-file")                                ; `C-x j l'
 (icicle-define-bookmark-other-window-command "local-file")                                ; `C-x 4 j l'
-(icicle-define-bookmark-command              "man") ; `C-x j m'
+(icicle-define-bookmark-command              "local-non-dir-file")                        ; Not bound
+(icicle-define-bookmark-other-window-command "local-non-dir-file")                        ; Not bound
+(icicle-define-bookmark-command              "man")                                       ; `C-x j m'
 (icicle-define-bookmark-other-window-command "man")                                       ; `C-x 4 j m'
+(icicle-define-bookmark-command              "non-dir-file")                              ; Not bound
+(icicle-define-bookmark-other-window-command "non-dir-file")                              ; Not bound
 (icicle-define-bookmark-command              "remote-file")                               ; `C-x j n'
 (icicle-define-bookmark-other-window-command "remote-file")                               ; `C-x 4 j n'
+(icicle-define-bookmark-command              "remote-non-dir-file")                       ; Not bound
+(icicle-define-bookmark-other-window-command "remote-non-dir-file")                       ; Not bound
 (icicle-define-bookmark-command              "region" "Select region: ")                  ; `C-x j r'
 (icicle-define-bookmark-other-window-command "region" "Select region: ")                  ; `C-x 4 j r'
 (icicle-define-bookmark-command              "all-tags" nil                               ; `C-x j t *'
@@ -5761,21 +6290,25 @@ You are prompted for the FILES."
 
 (defalias 'icicle-select-bookmarked-region 'icicle-bookmark-region-other-window)
 
-(defun icicle-bookmarked-buffer-list ()
+(defun icicle-bookmarked-buffer-list (&optional msgp)
   "`icicle-buffer-list', but only for bookmarked buffers."
-  (interactive)
-  (let ((icicle-buffer-predicate  (lambda (buf) (member buf (bmkp-buffer-names))))
-        (icicle-prompt            "Choose bookmarked buffer (`RET' when done): "))
-    (icicle-buffer-list)))
+  (interactive "p")
+  (let* ((icicle-buffer-predicate  (lambda (buf) (member buf (bmkp-buffer-names))))
+         (icicle-prompt            "Choose bookmarked buffer (`RET' when done): ")
+         (buf-names                (icicle-buffer-list)))
+    (prog1 buf-names
+      (when msgp (message "Bookmarked buffers: %S" buf-names)))))
 
-(defun icicle-bookmarked-file-list ()
+(defun icicle-bookmarked-file-list (&optional msgp)
   "`icicle-file-list', but only for bookmarked files."
-  (interactive)
+  (interactive "p")
   (bookmark-maybe-load-default-file)
-  (let ((use-file-dialog        nil)
-        (icicle-file-predicate  (lambda (file) (member (expand-file-name file) (bmkp-file-names))))
-        (icicle-prompt          "Choose bookmarked file (`RET' when done): "))
-    (icicle-file-list)))
+  (let* ((use-file-dialog        nil)
+         (icicle-file-predicate  (lambda (file) (member (expand-file-name file) (bmkp-file-names))))
+         (icicle-prompt          "Choose bookmarked file (`RET' when done): ")
+         (file-names             (icicle-file-list)))
+    (prog1 file-names
+      (when msgp (message "Bookmarked files: %S" file-names)))))
 
 (icicle-define-command icicle-find-first-tag ; Command name
   "Find first tag in current tags table whose name matches your input.
@@ -6049,8 +6582,9 @@ Either LINE or POSITION can be nil.  POSITION is used if present."
 (defun icicle-other-window-or-frame (arg) ; Bound to `C-x o' in Icicle mode.
   "Select a window or frame, by name or by order.
 This command combines Emacs commands `other-window' and `other-frame',
-together with Icicles multi-commands `icicle-select-window', and
-`icicle-select-frame'.  Use the prefix argument to choose, as follows:
+together with Icicles commands `icicle-select-window',
+`icicle-select-frame', and `icicle-choose-window-for-buffer-display'.
+Use the prefix argument to choose the behavior, as follows:
 
  With no prefix arg or a non-zero numeric prefix arg:
   If the selected frame has multiple windows, then this is
@@ -6066,6 +6600,15 @@ together with Icicles multi-commands `icicle-select-window', and
   `icicle-select-window' with windows from all visible frames as
   candidates.  Otherwise, this is `icicle-select-frame'.
 
+ With plain `C-u C-u':
+  Same as `icicle-select-window' with a negative prefix arg: Select a
+  window from any frame, including iconified and invisible frames.
+  
+ With plain `C-u C-u C-u' (Emacs 24+):
+  This is `icicle-choose-window-for-buffer-display', with windows from
+  all frames (i.e., iconified and invisible) frames as candidates. 
+  (For Emacs prior to Emacs 24, this has the same effect as `C-u'.)
+
 If you use library `oneonone.el' with a standalone minibuffer frame,
 and if option `1on1-remap-other-frame-command-flag' is non-nil, then
 frame selection can include the standalone minibuffer frame.
@@ -6076,13 +6619,19 @@ not want this remapping, then customize option
 `icicle-top-level-key-bindings'."
   (interactive "P")
   (let ((numarg  (prefix-numeric-value arg)))
-    (cond ((consp arg)
+    (cond ((and (consp arg)  (or (< numarg 16)  (< emacs-major-version 24))) ; `C-u'
            (if (one-window-p) (icicle-select-frame) (icicle-select-window)))
-          ((zerop numarg)
+          ((and (consp arg)  (< numarg 64)) ; `C-u C-u'
+           (let ((current-prefix-arg  '-)) (icicle-select-window)))
+          ((consp arg)                  ; `C-u C-u C-u'
+           (let* ((win-alist  (icicle-make-window-alist (if (< numarg 64) 'visible t)))
+                  (args       (icicle-read-choose-window-args "Window for next buffer display: " win-alist)))
+             (icicle-choose-window-for-buffer-display (car args) win-alist)))
+          ((zerop numarg)               ; `C-o'
            (if (one-window-p)
                (icicle-select-frame)
              (let ((current-prefix-arg  nil)) (icicle-select-window))))
-          (t
+          (t                            ; No prefix arg
            (if (one-window-p)
                (if (and (fboundp '1on1-other-frame)
                         1on1-minibuffer-frame
@@ -6116,8 +6665,11 @@ Each element has the form (FNAME . FRAME), where FNAME names FRAME.
 See `icicle-make-frame-alist' for more about FNAME."
   (interactive (let* ((alist    (icicle-make-frame-alist))
                       (default  (car (rassoc (selected-frame) alist)))
-                      (input    (completing-read "Select frame: " alist nil t nil
-                                                 'frame-name-history default)))
+                      (input    (completing-read
+                                 "Select frame: " alist nil t nil (if (boundp 'frame-name-history)
+                                                                      'frame-name-history
+                                                                    'icicle-frame-name-history)
+                                 default)))
                  (list (if (= (length input) 0) default input)
                        alist)))
   (unless frame-alist (setq frame-alist  (or (and (boundp 'icicle-frame-alist)  icicle-frame-alist)
@@ -6152,7 +6704,10 @@ names that differ only by their [NUMBER] is arbitrary."
   ;; Free vars here: `icicle-window-alist' is bound in Bindings form.
   "Select window by its name.
 With no prefix arg, candidate windows are those of the selected frame.
-With a prefix arg, windows of all visible frames are candidates.
+With a prefix arg:
+* Non-negative means windows of all visible frames are candidates.
+* Negative means windows of all frames are candidates (i.e., including
+  iconified and invisible frames).
 
 A window name is the name of its displayed buffer, but suffixed as
 needed by [NUMBER], to make the name unique.  For example, if you have
@@ -6161,34 +6716,148 @@ two windows showing buffer *Help*, one of the windows will be called
   icicle-select-window-by-name          ; Action function
   "Select window: " icicle-window-alist nil t nil nil ; `completing-read' args
   (buffer-name (window-buffer (other-window 1))) nil
-  ((icicle-window-alist  (icicle-make-window-alist current-prefix-arg)))) ; Bindings
-
-;; Free vars here: `icicle-window-alist' is bound in `icicle-select-window'.
-;;
-(defun icicle-select-window-by-name (name &optional window-alist)
-  "Select the window named NAME.
-Optional argument WINDOW-ALIST is an alist of windows to choose from.
+  ((icicle-window-alist  (icicle-make-window-alist (and current-prefix-arg ; Bindings
+                                                        (if (< (prefix-numeric-value current-prefix-arg) 0)
+                                                            t
+                                                          'visible))))))
+
+(defun icicle-choose-window-by-name (win-name &optional window-alist noselect)
+  "Choose the window named WIN-NAME.
+Optional arg WINDOW-ALIST is an alist of windows to choose from.  Each
+alist element has the form (WNAME . WINDOW), where WNAME names WINDOW.
+See `icicle-make-window-alist' for more about WNAME.  If WINDOW-ALIST
+is nil then use `icicle-make-window-alist' to create an alist of the
+windows in the selected frame.
+
+Non-nil optional arg NOSELECT means do not select the window, just set
+`icicle-next-window-for-display-buffer' to it (Emacs 24+).
 
 Interactively:
- A prefix arg means windows from all visible frames are candidates.
- No prefix arg means windows from the selected frame are candidates.
-
-Each alist element has the form (WNAME . WINDOW), where WNAME names
-WINDOW.  See `icicle-make-window-alist' for more about WNAME.
-
-If `crosshairs.el' is loaded, then the target position is highlighted."
-  (interactive (let* ((alist    (icicle-make-window-alist current-prefix-arg))
-                      (default  (car (rassoc (selected-window) alist)))
-                      (input    (completing-read "Select window: " alist nil t nil nil default)))
-                 (list (if (= (length input) 0) default input) alist)))
+* No prefix arg means windows from the selected frame are candidates.
+* A non-negative prefix arg means include windows from visible frames.
+* A negative prefix arg means include windows from all frames
+  (including iconified and invisible).
+* (Emacs 24+) A prefix arg of 99 or -99 means do not select the
+  window, just make the next buffer-display operation use it.
+
+For Emacs versions prior to Emacs 24, this is the same as
+`icicle-select-window-by-name'."
+  (interactive
+   (let* ((parg   (prefix-numeric-value current-prefix-arg))
+          (nosel  (and (= 99 (abs parg))  (> emacs-major-version 23)))
+          (args   (icicle-read-choose-window-args (and nosel  "Window for next buffer display: ")
+                                                  (icicle-make-window-alist
+                                                   (and current-prefix-arg  (if (natnump parg) 'visible t))))))
+     (list (car args) (cadr args) nosel)))
   (unless window-alist
     (setq window-alist  (or (and (boundp 'icicle-window-alist)  icicle-window-alist)
                             (icicle-make-window-alist))))
-  (let ((window  (cdr (assoc name window-alist))))
-    (unless window (icicle-user-error "No such window: `%s'" name))
-    (select-window window)
-    (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
-    (select-frame-set-input-focus (selected-frame))))
+  (let ((window  (cdr (assoc win-name window-alist))))
+    (unless window (icicle-user-error "No such window: `%s'" win-name))
+    (cond ((and noselect  (> emacs-major-version 23))
+           (setq icicle-next-window-for-display-buffer  window))
+          (t
+           (select-window window)
+           (when (fboundp 'crosshairs-highlight) (crosshairs-highlight))
+           (select-frame-set-input-focus (selected-frame))))))
+
+(defun icicle-choose-window-for-buffer-display (win-name &optional window-alist)
+  "Read the name of the window to use for the next `display-buffer' call.
+Uses command `icicle-choose-window-by-name' with non-nil NOSELECT.
+Sets `icicle-next-window-for-display-buffer' to the chosen window.
+
+For Emacs versions prior to Emacs 24, this does only what
+`icicle-select-window-by-name' does."
+  (interactive (icicle-read-choose-window-args (and (> emacs-major-version 23)
+                                                    "Window for next buffer display: ")
+                                               (icicle-make-window-alist 'ALL)))
+  (icicle-choose-window-by-name win-name window-alist 'NOSELECT))
+
+(when (> emacs-major-version 23)
+  (defadvice display-buffer (around icicle-choose-window activate)
+    "Just display in `icicle-next-window-for-display-buffer', if non-nil.
+A no-op if not in Icicle mode."
+    (if (not (and (boundp 'icicle-mode)  icicle-mode  (boundp 'display-buffer-base-action))) ; Emacs 24+
+        ad-do-it
+      (unwind-protect
+           (let ((win  icicle-next-window-for-display-buffer))
+             (if (not win)
+                 ad-do-it
+               (let ((display-buffer-base-action
+                      '((lambda (buf alist)
+                          (unless (or (cdr (assq 'inhibit-same-window alist))
+                                      (window-minibuffer-p win)
+                                      (window-dedicated-p win))
+                            (window--display-buffer buffer win 'reuse alist)))
+                        .
+                        nil)))
+                 ad-do-it)))
+        (setq icicle-next-window-for-display-buffer  nil))))
+
+  (defadvice switch-to-buffer (around icicle-choose-window activate)
+    "Use `icicle-next-window-for-display-buffer', if non-nil.
+A no-op if not in Icicle mode."
+    (if (not (and (boundp 'icicle-mode)  icicle-mode  (boundp 'display-buffer-base-action))) ; Emacs 24+
+        ad-do-it
+      (unwind-protect
+           (let ((win  icicle-next-window-for-display-buffer))
+             (if (not win)
+                 ad-do-it
+               (let ((display-buffer-base-action
+                      '((lambda (buf alist)
+                          (unless (or (cdr (assq 'inhibit-same-window alist))
+                                      (window-minibuffer-p win)
+                                      (window-dedicated-p win))
+                            (window--display-buffer buffer win 'reuse alist)))
+                        .
+                        nil)))
+                 (pop-to-buffer (ad-get-arg 0) (ad-get-arg 1)))))
+        (setq icicle-next-window-for-display-buffer  nil))))
+
+  (defadvice switch-to-buffer-other-window (around icicle-choose-window activate)
+    "Use `icicle-next-window-for-display-buffer', if non-nil.
+A no-op if not in Icicle mode."
+    (if (not (and (boundp 'icicle-mode)  icicle-mode  (boundp 'display-buffer-base-action))) ; Emacs 24+
+        ad-do-it
+      (unwind-protect
+           (let ((win  icicle-next-window-for-display-buffer))
+             (if (not win)
+                 ad-do-it
+               (let ((display-buffer-base-action
+                      '((lambda (buf alist)
+                          (unless (or (cdr (assq 'inhibit-same-window alist))
+                                      (window-minibuffer-p win)
+                                      (window-dedicated-p win))
+                            (window--display-buffer buffer win 'reuse alist)))
+                        .
+                        nil)))
+                 (pop-to-buffer (ad-get-arg 0) (ad-get-arg 1)))))
+        (setq icicle-next-window-for-display-buffer  nil)))))
+
+;; Free vars here: `icicle-window-alist' is bound in `icicle-select-window'.
+;;
+(defun icicle-select-window-by-name (win-name &optional window-alist)
+  "Use `icicle-choose-window-by-name' to select a window by name.
+If library `crosshairs.el' is loaded, highlight the target position."
+  (interactive (icicle-read-choose-window-args))
+  (icicle-choose-window-by-name win-name window-alist))
+
+(defun icicle-read-choose-window-args (&optional prompt alist)
+  "Read a window name.
+Prompt with PROMPT, if non-nil, else with \"Window: \".
+Read using completion against ALIST, if non-nil, or using
+`icicle-make-window-alist' if nil.
+Empty user input chooses the selected window.
+Return a list of the chosen name and the alist used for completing.
+
+The list of windows returned by `icicle-make-window-alist' is governed
+by the prefix argument to the current command."
+  (unless prompt (setq prompt  "Window: "))
+  (let* ((alist    (or alist  (icicle-make-window-alist current-prefix-arg)))
+         (default  (car (rassoc (selected-window) alist)))
+         (input    (completing-read prompt alist nil t nil nil default)))
+    (list (if (= (length input) 0) default input)
+          alist)))
 
 (defun icicle-make-window-alist (&optional all-p)
   "Return an alist of entries (WNAME . WINDOW), where WNAME names WINDOW.
@@ -6198,8 +6867,13 @@ WNAME includes a suffix [NUMBER], to make it a unique name.  The
 NUMBER order among window names that differ only by their [NUMBER] is
 arbitrary.
 
-Non-nil argument ALL-P means use windows from all visible frames.
-Otherwise, use only windows from the selected frame."
+Argument ALL-P determines which frames to use when gathering windows,
+as follows:
+
+* `visible'         - include windows from all visible frames.
+* otherwise non-nil - include windows from all frames (including
+                      those that are iconified and invisible).
+* nil               - include only windows from the selected frame."
   (lexical-let ((win-alist  ())
                 (count      2)
                 wname new-name)
@@ -6214,7 +6888,10 @@ Otherwise, use only windows from the selected frame."
                       (push (cons new-name w) win-alist))
                     (setq count  2))
                   'no-mini
-                  (if all-p 'visible 'this-frame))
+                  (case all-p
+                    (visible 'visible)
+                    ((nil)   'this-frame)
+                    (otherwise  t)))
     win-alist))
 
 (icicle-define-command icicle-delete-windows ; Command name
@@ -6414,13 +7091,13 @@ Those are default key bindings, but you can change them using option
 
 These options, when non-nil, control candidate matching and filtering:
 
- `icicle-buffer-extras'             - Extra buffers to display
+ `icicle-buffer-extras'             - Extra buffer names to display
  `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
  `icicle-buffer-include-cached-files-nflag' - Include cached files
  `icicle-buffer-include-recent-files-nflag' - Include recent files
- `icicle-buffer-match-regexp'       - Regexp that buffers must match
- `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
- `icicle-buffer-predicate'          - Predicate buffer names satisfy
+ `icicle-buffer-match-regexp'       - Regexp buffer names must match
+ `icicle-buffer-no-match-regexp'    - Regexp names must not match
+ `icicle-buffer-predicate'          - Predicate names must satisfy
  `icicle-buffer-sort'               - Sort function for candidates
  `icicle-buffer-skip-functions'     - Exclude from content searching
  `icicle-file-skip-functions'       - Same, but cached/recent files
@@ -6428,7 +7105,7 @@ These options, when non-nil, control candidate matching and filtering:
 For example, to change the default behavior to show only buffers that
 are associated with files, set `icicle-buffer-predicate' to this:
 
- (lambda (buf) (buffer-file-name buf))
+ (lambda (bufname) (buffer-file-name (get-buffer bufname)))
 
 Option `icicle-buffer-require-match-flag' can be used to override
 option `icicle-require-match-flag'.
@@ -6557,7 +7234,13 @@ Used as the value of `icicle-buffer-complete-fn' and hence as
   (setq strg  icicle-current-input)
   (lexical-let* ((name-pat     (let ((icicle-list-use-nth-parts  '(1)))
                                  (icicle-transform-multi-completion strg)))
-                 (name-pat     (if (memq icicle-current-completion-mode '(nil apropos))
+                 ;; FIXME.  We want to prepend "^" here for any Icicles prefix completion method that needs it.
+                 ;;         For now, do not do it for a `vanilla' value of `icicle-current-TAB-method',
+                 ;;         regardless of the particular value of `completion-styles' or
+                 ;;         `completion-category-overrides'.  But really there are some such values for which it
+                 ;;         should be appropriate - `basic', `emacs-21', and `emacs-22', for instance.
+                 (name-pat     (if (or (memq icicle-current-completion-mode '(nil apropos))
+                                       (icicle-not-basic-prefix-completion-p))
                                    name-pat
                                  (concat "^" (regexp-quote name-pat))))
                  (content-pat  (let ((icicle-list-use-nth-parts  '(2)))
@@ -6566,13 +7249,16 @@ Used as the value of `icicle-buffer-complete-fn' and hence as
                  (bufs         (if icicle-buffer-ignore-space-prefix-flag
                                    (icicle-remove-if (lambda (buf) (icicle-string-match-p "^ " buf)) bufs)
                                  bufs))
+                 (bufpred      pred)    ; Prevent var capture in lambda: `icicle-remove-if' also uses PRED.
                  (bufs         (icicle-remove-if (lambda (buf)
                                                    (or (not (icicle-string-match-p name-pat buf))
+                                                       (and bufpred  (not (funcall bufpred buf)))
                                                        (run-hook-with-args-until-success
                                                         'icicle-buffer-skip-functions buf)))
                                                  bufs))
                  (bufs         (cond ((equal "" content-pat)
                                       (dolist (buf  bufs)
+                                        ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS-TO-KILL.
                                         ;; Bound in `icicle-visit-marked-file-of-content-1'.
                                         (unless (memq (setq buf  (get-buffer buf)) icicle-existing-bufs)
                                           (add-to-list 'icicle-new-bufs-to-kill buf)))
@@ -6580,13 +7266,19 @@ Used as the value of `icicle-buffer-complete-fn' and hence as
                                      (t
                                       (icicle-remove-if-not
                                        (lambda (buf)
-                                         (let ((found  (with-current-buffer buf
-                                                         (save-excursion
-                                                           (goto-char (point-min))
-                                                           (re-search-forward content-pat nil t)))))
-                                           ;; Bound in `icicle-visit-marked-file-of-content-1'.
-                                           (unless (memq (setq buf  (get-buffer buf)) icicle-existing-bufs)
-                                             (add-to-list 'icicle-new-bufs-to-kill buf))
+                                         (let* (;; Do this as soon as possible, in case of immediate `C-g'.
+                                                ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS-TO-KILL.
+                                                ;; Bound in `icicle-visit-marked-file-of-content-1'.
+                                                (IGNORE  (unless (memq (setq buf  (get-buffer buf))
+                                                                       icicle-existing-bufs)
+                                                          (add-to-list 'icicle-new-bufs-to-kill buf)))
+                                                (found   (with-current-buffer buf
+                                                           (save-excursion
+                                                             (goto-char (point-min))
+                                                             (re-search-forward content-pat nil t)))))
+;;; $$$$$$$$ I was doing this here, but advanced it to before searching, for possible `C-g'.
+;;;                                            (unless (memq (setq buf  (get-buffer buf)) icicle-existing-bufs)
+;;;                                              (add-to-list 'icicle-new-bufs-to-kill buf))
                                            (when (and found ; Don't do it just because incrementally complete.
                                                       (or (icicle-get-safe this-command
                                                                            'icicle-apropos-completing-command)
@@ -6616,16 +7308,21 @@ Used as the value of `icicle-buffer-complete-fn' and hence as
                                     ;; Avoid the error raised by calling `find-file-noselect' on a directory
                                     ;; when `find-file-run-dired' is nil.
                                     (and (or find-file-run-dired  (not (file-directory-p filname)))
-                                         (let* ((buf    (find-file-noselect filname))
-                                                (found  (with-current-buffer buf
-                                                          (message "Matching buffer contents...")
-                                                          (save-excursion
-                                                            (goto-char (point-min))
-                                                            (re-search-forward content-pat nil t)))))
-                                           ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS--TO-KILL.
-                                           ;; Bound in `icicle-visit-marked-file-of-content-1'.
-                                           (unless (memq buf icicle-existing-bufs)
-                                             (add-to-list 'icicle-new-bufs-to-kill buf))
+                                         (let* ((buf     (find-file-noselect filname))
+                                                ;; Do this as soon as possible, in case of immediate `C-g'.
+                                                ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS-TO-KILL.
+                                                ;; Bound in `icicle-visit-marked-file-of-content-1'.
+                                                (IGNORE  (unless (memq (setq buf  (get-buffer buf))
+                                                                       icicle-existing-bufs)
+                                                           (add-to-list 'icicle-new-bufs-to-kill buf)))
+                                                (found   (with-current-buffer buf
+                                                           (message "Matching buffer contents...")
+                                                           (save-excursion
+                                                             (goto-char (point-min))
+                                                             (re-search-forward content-pat nil t)))))
+;;; $$$$$$$$ I was doing this here, but advanced it to before searching, for possible `C-g'.
+;;;                                            (unless (memq buf icicle-existing-bufs)
+;;;                                              (add-to-list 'icicle-new-bufs-to-kill buf))
                                            (when (and found ; Don't do it just because incrementally complete.
                                                       (or (icicle-get-safe this-command
                                                                            'icicle-apropos-completing-command)
@@ -7332,7 +8029,7 @@ default separator."
   (defun icicle-describe-process (pid)
     "Describe the system process that has process id PID."
     (interactive "nPID: ")
-    (with-output-to-temp-buffer "*Help*"
+    (icicle-with-help-window "*Help*"
       (let* ((attributes  (process-attributes pid))
              (comm        (cdr-safe (assoc 'comm attributes)))
              (args        (cdr-safe (assoc 'args attributes)))
@@ -7351,6 +8048,7 @@ default separator."
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
  * C-x C-t *    - narrow to files with all of the tags you specify
  * C-x C-t +    - narrow to files with some of the tags you specify
@@ -7382,6 +8080,7 @@ can use the following keys:
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -7449,7 +8148,9 @@ or `mouse-2') - a prefix arg has no effect for that.
 
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
+   C-c C-d      - change the `default-directory' (with a prefix arg)
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -7539,6 +8240,7 @@ During completion (`*' means this requires library `Bookmark+')\\<minibuffer-loc
 can use the following keys:
    C-c C-d      - change the `default-directory' (a la `cd')
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -7712,6 +8414,7 @@ read-only mode.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -7973,6 +8676,7 @@ flips the behavior specified by that option.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -8076,6 +8780,7 @@ requires library `Bookmark+')\\<minibuffer-local-completion-map>:
 
    C-c C-d      - change the `default-directory' (a la `cd')
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -8188,8 +8893,8 @@ toggle this hiding using `\\[icicle-dispatch-C-x.]'."
     'NOT-INTERACTIVE-P)                 ; Not a real command - just a helper function.
 
 
-    (put 'icicle-recent-file-of-content 'icicle-hide-common-match t)
-    (put 'icicle-recent-file-of-content 'icicle-Completions-window-max-height 200)
+  (put 'icicle-recent-file-of-content 'icicle-hide-common-match t)
+  (put 'icicle-recent-file-of-content 'icicle-Completions-window-max-height 200)
   (defun icicle-recent-file-of-content ()
     "Open a recently used file.
 Completion candidates here are absolute, not relative, file names.
@@ -8223,11 +8928,12 @@ use this input pattern:
 
 quine.*^G^J.*^G^J.*curry
 
-A prefix argument has a different meaning when used when you act on an
+A prefix argument has a different meaning when you act on an
 individual completion candidate.  It means that you visit that file or
 directory in read-only mode.  This includes when you act on all
-candidates using \\<minibuffer-local-completion-map>`\\[icicle-all-candidates-action]': \
-precede the `\\[icicle-all-candidates-action]' with a prefix arg.
+candidates using
+\\<minibuffer-local-completion-map>`\\[icicle-all-candidates-action]':
+\ precede the `\\[icicle-all-candidates-action]' with a prefix arg.
 
 This does not apply to the final candidate chosen (using `RET' or
 `mouse-2') - a prefix arg has no effect for that.
@@ -8236,6 +8942,7 @@ During completion, you can use the following keys (`*' means this
 requires library `Bookmark+')\\<minibuffer-local-completion-map>:
 
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -8412,6 +9119,7 @@ During completion (`*' means this requires library `Bookmark+')\\<minibuffer-loc
 can use the following keys:
    C-c C-d      - change the `default-directory' (a la `cd')
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -8522,6 +9230,7 @@ remote file-name syntax.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -8824,7 +9533,7 @@ that command for more information."
 ;;;                                                             (save-excursion
 ;;;                                                               (goto-char (point-min))
 ;;;                                                               (re-search-forward content-pat nil t)))))
-;;;                                              ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS--TO-KILL
+;;;                                              ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS-TO-KILL
 ;;;                                              (unless (memq buf icicle-existing-bufs)
 ;;;                                                (add-to-list 'icicle-new-bufs-to-kill buf))
 ;;;                                              found))))))
@@ -8866,6 +9575,10 @@ Return non-nil if the current multi-completion INPUT matches FILE-NAME."
                                       ;; e.g., when using progressive completion: foo.el, foo.el<2>,...
                                       (or (setq exists  (find-buffer-visiting file))
                                           (create-file-buffer file))))
+                           ;; Do this as soon as BUF is created, in case of immediate `C-g' to exit etc.
+                           ;; Free vars here: EXISTING-BUFFERS, NEW-BUFS-TO-KILL
+                           (IGNORE  (unless (memq buf icicle-existing-bufs)
+                                      (add-to-list 'icicle-new-bufs-to-kill buf)))
                            (found   (with-current-buffer buf
                                       (message "Matching file contents...")
                                       (unless (or dir-p  exists) ; EXISTS prevents inserting it more than once.
@@ -8874,8 +9587,9 @@ Return non-nil if the current multi-completion INPUT matches FILE-NAME."
                                         (insert-file-contents file 'VISIT))
                                       (save-excursion (goto-char (point-min))
                                                       (re-search-forward content-pat nil t)))))
-                      (unless (memq buf icicle-existing-bufs)
-                        (add-to-list 'icicle-new-bufs-to-kill buf))
+;;; $$$$$$$$ I was doing this here, but advanced it to before searching, for possible `C-g'.
+;;;                       (unless (memq buf icicle-existing-bufs)
+;;;                         (add-to-list 'icicle-new-bufs-to-kill buf))
                       (when (and found  ; Don't do it just because incrementally complete.
                                  (or (icicle-get-safe this-command 'icicle-apropos-completing-command)
                                      (icicle-get-safe this-command 'icicle-cycling-command)
@@ -8902,6 +9616,7 @@ remote file-name syntax.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -9077,6 +9792,7 @@ During completion (`*' means this requires library `Bookmark+')\\<minibuffer-loc
 can use the following keys:
    C-c C-d      - change the `default-directory' (a la `cd')
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -9188,6 +9904,7 @@ remote file-name syntax.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -9366,7 +10083,8 @@ Optional arg NO-SYMLINKS-P non-nil means do not follow symbolic links."
   (interactive
    (save-selected-window
      ;; Should not need to bind `minibuffer-completion-predicate'.  Emacs 23.2 bug, per Stefan.
-     (let ((minibuffer-completion-predicate  minibuffer-completion-predicate))
+     (let ((enable-recursive-minibuffers     t)
+           (minibuffer-completion-predicate  minibuffer-completion-predicate))
        (list (funcall (if (fboundp 'read-directory-name)
                           #'read-directory-name
                         #'read-file-name)
@@ -9713,9 +10431,9 @@ and a final-choice key (e.g. `RET', `mouse-2') to choose the last one." ; Doc st
                                               "Choose face (`RET' when done): ")) ; Bindings
    (icicle-list-nth-parts-join-string     ": ")
    (icicle-list-join-string               ": ")
-   ;; $$$$$$ (icicle-list-end-string      "")
    (icicle-multi-completing-p             t)
    (icicle-list-use-nth-parts             '(1))
+   (icicle-face-completing-p              t)
    (icicle-use-candidates-only-once-flag  t)
    (icicle-candidate-alt-action-fn
     (or icicle-candidate-alt-action-fn  (icicle-alt-act-fn-for-type "face")))
@@ -9744,10 +10462,10 @@ The list of names (strings) is returned.
 These options, when non-nil, control candidate matching and filtering:
 
  `icicle-buffer-ignore-space-prefix-flag' - Ignore space-prefix names
- `icicle-buffer-extras'             - Extra buffers to display
- `icicle-buffer-match-regexp'       - Regexp that buffers must match
- `icicle-buffer-no-match-regexp'    - Regexp buffers must not match
- `icicle-buffer-predicate'          - Predicate buffer names satisfy
+ `icicle-buffer-extras'             - Extra buffer names to display
+ `icicle-buffer-match-regexp'       - Regexp that names must match
+ `icicle-buffer-no-match-regexp'    - Regexp names must not match
+ `icicle-buffer-predicate'          - Predicate names must satisfy
  `icicle-buffer-sort'               - Sort function for candidates
 
 Note: The prefix arg is tested, even when this is called
@@ -9858,13 +10576,12 @@ Non-interactively:
    (enable-recursive-minibuffers                t) ; In case we read input, e.g. File changed on disk...
    (completion-ignore-case                      bookmark-completion-ignore-case)
    (icicle-multi-completing-p                   icicle-show-multi-completion-flag)
+   (icicle-bookmark-completing-p                t)
    (icicle-list-use-nth-parts                   '(1))
    (icicle-candidate-properties-alist           (if (not icicle-multi-completing-p)
                                                     ()
-                                                  (if (facep 'file-name-shadow)
-                                                      '((2 (face file-name-shadow))
-                                                        (3 (face bookmark-menu-heading)))
-                                                    '((3 (face bookmark-menu-heading))))))
+                                                  '((2 (face icicle-annotation))
+                                                    (3 (face icicle-msg-emphasis)))))
    (icicle-transform-function                   (and (not (interactive-p))  icicle-transform-function))
    (icicle-whole-candidate-as-text-prop-p       t)
    (icicle-transform-before-sort-p              t)
@@ -9977,6 +10694,7 @@ list.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify
@@ -10054,6 +10772,7 @@ directory from the minibuffer when you want to match proxy candidates.
 During completion (`*' means this requires library `Bookmark+')\\<minibuffer-local-completion-map>, you
 can use the following keys:
    C-c +        - create a new directory
+   C-backspace  - go up one directory level
    \\[icicle-all-candidates-list-alt-action]          - open Dired on the currently matching file names
    \\[icicle-delete-candidate-object]     - delete candidate file or (empty) dir
  * C-x C-t *    - narrow to files with all of the tags you specify