 	     (memq (svn-file-status pos) '(?\  ?D)))
 	   (svn-can-undo-deletion-p (cdr actions)))))
 
+(defun svn-plural (count noun)
+  (format "%d %s" count
+	  (if (= count 1)
+	      noun
+	    (if (equal (substring noun -1) "y")
+		(concat (substring noun 0 -1) "ies")
+	      (concat noun "s")))))
+
+(defun svn-delete-dir-tree (file)
+  "Remove a file or directory tree."
+  (if (file-directory-p file)
+      (progn
+	(mapc #'(lambda (f)
+		  (unless (or (equal f ".") (equal f ".."))
+		    (svn-delete-dir-tree (concat file "/" f))))
+	      (directory-files file))
+	(delete-directory file))
+    (delete-file file)))
+
 (defun svn-remove-file ()
-  "Remove the selected files."
-  (interactive)
-  (let ((actions (svn-actions))
-        (inhibit-read-only t))
+  "Remove the selected files and directories."
+  (interactive)
+  (let* ((actions (svn-actions))
+	 (dir-count
+	  (length (delq nil (mapcar (lambda (fp)
+				      (file-directory-p (car fp)))
+				    actions))))
+	 (nondir-count (- (length actions) dir-count))
+	 (inhibit-read-only t))
     (when (or (svn-can-undo-deletion-p actions)
-	      (y-or-n-p (format "Really remove %d %s? "
-				(length actions)
-				(if (> (length actions) 1)
-				    "files"
-				  "file"))))
+	      (y-or-n-p
+	       (format "Really remove %s? "
+		       (cond ((zerop dir-count)
+			      (svn-plural nondir-count "file"))
+			     ((zerop nondir-count)
+			      (svn-plural dir-count "directory"))
+			     (t
+			      (concat 
+			       (svn-plural dir-count "directory")
+			       " and "
+			       (svn-plural nondir-count "file")))))))
       (let ((svn-files ()))
         (mapc (lambda (fp)
 		(let ((file (car fp))
 		      (pos (cadr fp)))
 		  (if (/= (svn-file-status pos) ?\?)
 		      (setq svn-files (cons file svn-files))
-		    (delete-file file)
+		    (svn-delete-dir-tree file)
 		    (svn-remove-line pos))))
 	      ;; traverse the list backwards, to keep buffer positions of
 	      ;; remaining files valid

      (insert str)
      (goto-char svn-output-marker)
      (while (looking-at
              "\\([ ACDGIMRX?!~][ CM][ L][ +][ S][ KOTB]\\) \\([\\* ]\\) \\(........\\) \\(........\\) \\(............\\) \\(.*\\)\n")
        (let ((status (match-string 1))
              (filename (match-string 6)))
          (delete-region (match-beginning 0)

    (apply 'call-process svn-program nil buf nil (symbol-name command) args)
    buf))

(defun svn-run-for-stdout (command args)
  "Run `svn', and return standard output as a string, discarding stderr.
Argument COMMAND is the svn subcommand to run.
Optional argument ARGS is a list of arguments."
  (let ((output-buffer (generate-new-buffer "*svn-stdout*")))
    (apply 'call-process svn-program nil (list output-buffer nil) nil
	   (symbol-name command) args)
    (let ((stdout (with-current-buffer output-buffer (buffer-string))))
      (kill-buffer output-buffer)
      stdout)))

(defun svn-output-filter (proc str)
  "Output filter for svn output.
