diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index 821b7d7..b98c008 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -1590,11 +1590,68 @@ If `ask', ask for user confirmation."
 	       dired-create-files-failures)
 	 (dired-log "Can't set date on %s:\n%s\n" from err))))))
 
+;;; (setq mylist '("apple" "pear" "peach" "nectarine" "watermelon"))
+;;; (ar-replace--in-list "apple" "cherry" mylist)
+;;; Written by @Andreas Röhler:  https://emacs.stackexchange.com/a/41631/2287
+(defun ar-replace--in-list (elem replacement list)
+  "Expects a LIST of strings.
+ELEM: element to replace by arg REPLACEMENT"
+  (let (newlist)
+    (dolist (ele list)
+      (if (string= ele elem)
+        (push replacement newlist)
+        (push ele newlist)))
+    (nreverse newlist)))
+
+(defun replace-directory-name-in-files (old new list)
+"Replace in file-names/directory-names all occurrences of OLD directory name
+with NEW directory name in the LIST."
+  (let ((regexp-old (concat "^" (regexp-quote old)))
+        newlist)
+    (dolist (file list)
+      ;;; `dired-noselect' may set the first element of `dired-directory' with a leading ~
+      ;;;   (abbreviate-file-name (expand-file-name (directory-file-name "/Users/Home/foo"))) => "~/foo"
+      ;;;
+      ;;; We use NEW to test for `file-directory-p' because the directory
+      ;;; has already been renamed by the time we get here.  Alternatively,
+      ;;; we could test the OLD filename to see if it is a directory at the
+      ;;; the outset of `dired-rename-file' and save the result.
+      ;;;
+      ;;; FIXME:  We need an additional test and then deal with a home directory ~.
+      ;;; The code does not presently deal with a "~/foo/bar" file when the
+      ;;; directory `foo` is renamed.  `rename-file' will error.
+      (if (and (file-directory-p new)
+               (string-match regexp-old file)
+               ;;; Because we have already processed `ar-replace--in-list',
+               ;;; the NEW name is already in `dired-directory'.
+               (not (equal new file)))
+         (push (replace-regexp-in-string regexp-old new file) newlist)
+         (push file newlist)))
+    (nreverse newlist)))
+
 ;;;###autoload
 (defun dired-rename-file (file newname ok-if-already-exists)
   (dired-handle-overwrite newname)
   (dired-maybe-create-dirs (file-name-directory newname))
   (rename-file file newname ok-if-already-exists) ; error is caught in -create-files
+  ;;; In the context of `wdired-finish-edit', it calls `wdired-do-renames' and
+  ;;; that function contains a `condition-case' section that counts the number of errors.
+  ;;; For purposes of `dired-rename-file', the function exists as soon as `rename-file'
+  ;;; throws an error, so we never get to the rest of this function below when a renaming error occurs.
+  ;;;
+  ;;; Update the `dired-directory' by replacing FILE with NEWNAME.
+  (when (and (listp dired-directory)
+             (member file dired-directory))
+    (setq dired-directory
+      (ar-replace--in-list file newname dired-directory)))
+  ;;; If FILE is a directory, then update the `dired-directory' by
+  ;;; replacing all occurrences of that directory name within any filenames.
+  (when (and (listp dired-directory)
+               ;;; Because we have already processed `ar-replace--in-list',
+               ;;; the NEWNAME is already in `dired-directory'.
+             (member newname dired-directory))
+    (setq dired-directory
+           (replace-directory-name-in-files file newname dired-directory)))
   ;; Silently rename the visited file of any buffer visiting this file.
   (and (get-file-buffer file)
        (with-current-buffer (get-file-buffer file)
diff --git a/lisp/dired.el b/lisp/dired.el
index 1348df6..5c45764 100644
--- a/lisp/dired.el
+++ b/lisp/dired.el
@@ -3119,6 +3119,11 @@ non-empty directories is allowed."
 	      (let ((inhibit-read-only t))
 		(condition-case err
 		    (let ((fn (car (car l))))
+		      ;;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=31601
+		      ;;; FIXME:  @lawlist could use some help figuring out how/when to
+		      ;;; update the `lawlist-dired-directory' when it is a list.  There are
+		      ;;; a few different options that @lawlist does not fully understand
+		      ;;; such as RECURSIVE deletions.
 		      (dired-delete-file fn dired-recursive-deletes trash)
 		      ;; if we get here, removing worked
 		      (setq succ (1+ succ))
diff --git a/lisp/wdired.el b/lisp/wdired.el
index bb60e77..ed75a8f 100644
--- a/lisp/wdired.el
+++ b/lisp/wdired.el
@@ -76,6 +76,67 @@
 (require 'dired)
 (autoload 'dired-do-create-files-regexp "dired-aux")
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; http://debbugs.gnu.org/cgi/bugreport.cgi?bug=31601
+
+;;; Written by Tino Calancha
+;;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=31601#8
+(defun wdired-find-dired-buffer-p ()
+  "Return non-nil if the dired buffer comes from a `find-dired' command."
+  (save-excursion
+    (goto-char (point-min))
+    (forward-line 1)
+    ;;; The line we are looking for is:    /usr/bin/find . \( -iname \* \) -ls
+    (re-search-forward (format "^\\s-*%s " find-program) nil t)))
+
+(defun dired-list-files-folders ()
+"Produce a dired-mode buffer of all files/folders recursively."
+(interactive)
+  (let* ((path (read-directory-name "Directory:  "))
+         (directory (file-name-as-directory path)))
+    (unless (file-directory-p path)
+      (let ((debug-on-quit nil)
+            (msg (format "Not a directory: %s" path)))
+        (signal 'quit `(,msg))))
+    (let* ((default-directory directory)
+           (include-directories (when (y-or-n-p "Include directories?") t))
+           (lst (directory-files-recursively default-directory "" include-directories)))
+      ;;; The first element is taken as the directory name.
+      (push default-directory lst)
+      (dired lst))))
+
+;;; Written by Drew Adams from his dired+ library; see also the example posted to
+;;; https://emacs.stackexchange.com/a/41669/2287
+(defun diredp-root-directory-p (file)
+  "Return non-nil if FILE is a root directory."
+  (if (fboundp 'ange-ftp-root-dir-p)
+      (ange-ftp-root-dir-p (file-name-as-directory file))
+    ;; This is essentially `ange-ftp-root-dir-p' applied to `file-name-as-directory'.
+    ;; If `ange-ftp-root-dir-p' changes, update this code.
+    (or (and (eq system-type 'windows-nt)
+             (string-match-p "\\`[a-zA-Z]:[/\\]\\'" (file-name-as-directory file)))
+        (string= "/" file))))
+
+;;; Written by Drew Adams from his dired+ library; see also the example posted to
+;;; https://emacs.stackexchange.com/a/41669/2287
+(defun diredp-parent-dir (file &optional relativep)
+  "Return the parent directory of FILE, or nil if none.
+Optional arg RELATIVEP non-nil means return a relative name, that is,
+just the parent component."
+  (let ((parent  (file-name-directory (directory-file-name (expand-file-name file))))
+        relparent)
+    (when relativep
+      (setq relparent  (file-name-nondirectory (directory-file-name parent))))
+    (and (not (equal parent file))  (or relparent  parent))))
+
+(define-key dired-mode-map "r" 'wdired-change-to-wdired-mode)
+
+(define-key ctl-x-map "f" 'dired-list-files-folders)
+
+(define-key ctl-x-map "F" 'find-name-dired)
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
 (defgroup wdired nil
   "Mode to rename files by editing their names in dired buffers."
   :group 'dired)
@@ -203,7 +264,7 @@ nonexistent directory will fail."
 (defvar wdired-col-perm) ;; Column where the permission bits start
 (defvar wdired-old-content)
 (defvar wdired-old-point)
-(defvar wdired-old-marks)
+(defvar wdired-old-marks nil)
 
 (defun wdired-mode ()
   "Writable Dired (WDired) mode.
@@ -257,7 +318,8 @@ See `wdired-mode'."
   (add-hook 'kill-buffer-hook 'wdired-check-kill-buffer nil t)
   (setq major-mode 'wdired-mode)
   (setq mode-name "Editable Dired")
-  (setq revert-buffer-function 'wdired-revert)
+  (unless (wdired-find-dired-buffer-p)
+    (setq revert-buffer-function 'wdired-revert))
   ;; I temp disable undo for performance: since I'm going to clear the
   ;; undo list, it can save more than a 9% of time with big
   ;; directories because setting properties modify the undo-list.
@@ -287,19 +349,79 @@ or \\[wdired-abort-changes] to abort changes")))
   (save-excursion
     (goto-char (point-min))
     (let ((b-protection (point))
-	  filename)
+          filename p1 p2 p3 file absolute-p)
       (while (not (eobp))
 	(setq filename (dired-get-filename nil t))
         (when (and filename
-		   (not (member (file-name-nondirectory filename) '("." ".."))))
-	  (dired-move-to-filename)
-	  ;; The rear-nonsticky property below shall ensure that text preceding
-	  ;; the filename can't be modified.
-	  (add-text-properties
-	   (1- (point)) (point) `(old-name ,filename rear-nonsticky (read-only)))
-	  (put-text-property b-protection (point) 'read-only t)
-	  (setq b-protection (dired-move-to-end-of-filename t))
-	  (put-text-property (point) (1+ (point)) 'end-name t))
+                   (not (member (file-name-nondirectory filename) '("." ".."))))
+          (setq p1 (dired-move-to-filename)
+                p3 (dired-move-to-end-of-filename 'no-error)
+                file (buffer-substring p1 p3))
+          ;;; BEGIN code borrowed from `dired-get-filename'.
+          ;; Unquote names quoted by ls or by dired-insert-directory.
+          ;; This code was written using `read' to unquote, because
+          ;; it's faster than substituting \007 (4 chars) -> ^G (1
+          ;; char) etc. in a lisp loop.  Unfortunately, this decision
+          ;; has necessitated hacks such as dealing with filenames
+          ;; with quotation marks in their names.
+          (while (string-match "\\(?:[^\\]\\|\\`\\)\\(\"\\)" file)
+            (setq file (replace-match "\\\"" nil t file 1)))
+          ;; Unescape any spaces escaped by ls -b (bug#10469).
+          ;; Other -b quotes, eg \t, \n, work transparently.
+          (if (dired-switches-escape-p dired-actual-switches)
+            (let ((start 0)
+                  (rep "")
+                  (shift -1))
+              ;; (if (eq localp 'verbatim)
+              ;;     (setq rep "\\\\"
+              ;;           shift +1))
+              (while (string-match "\\(\\\\\\) " file start)
+                (setq file (replace-match rep nil t file 1)
+                      start (+ shift (match-end 0))))))
+          (when (eq system-type 'windows-nt)
+            (save-match-data
+              (let ((start 0))
+                (while (string-match "\\\\" file start)
+                  (aset file (match-beginning 0) ?/)
+                  (setq start (match-end 0))))))
+          ;; Hence we don't need to worry about converting `\\' back to `\'.
+          (setq file (read (concat "\"" file "\"")))
+          ;; The above `read' will return a unibyte string if FILE
+          ;; contains eight-bit-control/graphic characters.
+          (if (and enable-multibyte-characters
+                   (not (multibyte-string-p file)))
+            (setq file (string-to-multibyte file)))
+          (and file
+               (file-name-absolute-p file)
+               ;; A relative file name can start with ~.
+               ;; Don't treat it as absolute in this context.
+               (not (eq (aref file 0) ?~))
+               (setq absolute-p t))
+          ;;; END code borrowed from `dired-get-filename'.
+          (if (and absolute-p
+                   ;; Test whether absolute file/directory is in the root of the hard drive.
+                   (not (diredp-root-directory-p (diredp-parent-dir file))))
+            (setq p2 (- p3 (length (file-name-nondirectory file))))
+            ;;; FIXME:  First attempt at dealing with relative paths
+            ;;; Will this always be the same as when dealing with an absolute path (above)?
+            (setq p2 (- p3 (length (file-name-nondirectory file)))))
+          ;;; `wdired-get-filename' relies upon the original location of the
+          ;;; of the OLD-NAME and FILENAME text properties.
+          (add-text-properties (1- p1) p1 `(old-name ,filename))
+          ;;; Make the beginning of the `file-name-nondirectory' the read-only boundary.
+          ;; The rear-nonsticky property below shall ensure that text preceding
+          ;; the filename can't be modified.
+          (add-text-properties (1- p2) p2 `(rear-nonsticky (read-only)))
+          ;;; Except for the initial loop where B-PROTECTION is set to `point-min',
+          ;;; B-PROTECTION is the end of the preceding filename from the previous loop.
+          (put-text-property b-protection p2 'read-only t)
+          (if (= (point) (point-max))
+            (put-text-property (1- p3) p3 'end-name t)
+            (put-text-property p3 (1+ p3) 'end-name t)))
+        ;;; Except for the initial loop where B-PROTECTION is set to `point-min',
+        ;;; B-PROTECTION is the end of the preceding filename from the previous loop.
+        (when p3
+          (setq b-protection p3))
         (forward-line))
       (put-text-property b-protection (point-max) 'read-only t))))
 
@@ -344,9 +466,17 @@ non-nil means return old filename."
         (and file (setq file (wdired-normalize-filename file (not old)))))
       (if (or no-dir old)
 	  file
-	(and file (> (length file) 0)
-             (concat (dired-current-directory) file))))))
-
+        (cond
+          ;;; When FILE is relative, concatenate default-directory to beginning.
+          ((and file
+                (> (length file) 0)
+                (not (file-name-absolute-p file))
+                (concat (dired-current-directory) file)))
+          ;;; When FILE is absolute, no need to concatenate the default-directory.
+          ((and file
+                (> (length file) 0)
+                (file-name-absolute-p file)
+                file)))))))
 
 (defun wdired-change-to-dired-mode ()
   "Change the mode back to dired."
@@ -363,7 +493,8 @@ non-nil means return old filename."
   (setq mode-name "Dired")
   (dired-advertise)
   (remove-hook 'kill-buffer-hook 'wdired-check-kill-buffer t)
-  (set (make-local-variable 'revert-buffer-function) 'dired-revert))
+  (unless (wdired-find-dired-buffer-p)
+    (set (make-local-variable 'revert-buffer-function) 'dired-revert)))
 
 
 (defun wdired-abort-changes ()
@@ -457,6 +588,16 @@ non-nil means return old filename."
         (progress nil)
         (errors 0)
         (overwrite (or (not wdired-confirm-overwrite) 1)))
+    ;;; We must process the deepest directories first in time, and gradually
+    ;;; work our way backwards.  See:  https://emacs.stackexchange.com/a/41682/2287
+    ;;; Sorting function written by @Tobias on emacs.stackexchange.com (supra)
+    ;;; RENAMES are in the format of (cons file-old (substitute-in-file-name file-new))
+    ;;; Files/directories with the greatest depth are sorted first in time.
+    ;;; The function `pop' (used hereinbelow) uses the first element of the list.
+    (require 'cl-seq)
+    (setq renames (cl-stable-sort renames (lambda (path1 path2)
+                                             (> (cl-count ?/ (car path1))
+                                                (cl-count ?/ (car path2))))))
     (while (or renames
                ;; We've done one round through the renames, we have found
                ;; some residue, but we also made some progress, so maybe
