changeset 110249:c3d85dc16abc

Merge from mainline.
author Katsumi Yamaoka <yamaoka@jpl.org>
date Sun, 05 Sep 2010 22:45:59 +0000
parents b0a4e30a5f31 (current diff) f5e7d094d9d8 (diff)
children 77821d09740a
files
diffstat 48 files changed, 1638 insertions(+), 873 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Fri Sep 03 06:22:01 2010 +0000
+++ b/ChangeLog	Sun Sep 05 22:45:59 2010 +0000
@@ -1,3 +1,8 @@
+2010-09-04  Eli Zaretskii  <eliz@gnu.org>
+
+	* config.bat: Produce lisp/gnus/_dir-locals.el from
+	lisp/gnus/.dir-locals.el.
+
 2010-08-23  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* configure.in: Fix check for librsvg, imagemagick and
--- a/admin/ChangeLog	Fri Sep 03 06:22:01 2010 +0000
+++ b/admin/ChangeLog	Sun Sep 05 22:45:59 2010 +0000
@@ -1,3 +1,11 @@
+2010-09-05  Juanma Barranquero  <lekktu@gmail.com>
+
+	* unidata/BidiMirroring.txt: Update from
+	http://www.unicode.org/Public/6.0.0/ucd/BidiMirroring-6.0.0d2.txt
+
+	* unidata/UnicodeData.txt: Update from
+	http://www.unicode.org/Public/6.0.0/ucd/UnicodeData-6.0.0d7.txt
+
 2010-08-09  Andreas Schwab  <schwab@linux-m68k.org>
 
 	* CPP-DEFINES (WORDS_BIG_ENDIAN): Remove.
--- a/admin/unidata/BidiMirroring.txt	Fri Sep 03 06:22:01 2010 +0000
+++ b/admin/unidata/BidiMirroring.txt	Sun Sep 05 22:45:59 2010 +0000
@@ -1,12 +1,12 @@
 # BidiMirroring-6.0.0.txt
-# Date: 2009-11-10, 17:09:00 PST [KW]
+# Date: 2010-06-21, 12:09:00 PDT [KW]
 #
 # Bidi_Mirroring_Glyph Property
 # 
 # This file is an informative contributory data file in the
 # Unicode Character Database.
 #
-# Copyright (c) 1991-2009 Unicode, Inc.
+# Copyright (c) 1991-2010 Unicode, Inc.
 # For terms of use, see http://www.unicode.org/terms_of_use.html
 #
 # This data file lists characters that have the Bidi_Mirrored=True property
@@ -473,8 +473,8 @@
 # 22FF; Z NOTATION BAG MEMBERSHIP
 # 2320; TOP HALF INTEGRAL
 # 2321; BOTTOM HALF INTEGRAL
+# 27C0; THREE DIMENSIONAL ANGLE
 # 27CC; LONG DIVISION
-# 27C0; THREE DIMENSIONAL ANGLE
 # 27D3; LOWER RIGHT CORNER WITH DOT
 # 27D4; UPPER LEFT CORNER WITH DOT
 # 27DC; LEFT MULTIMAP
--- a/admin/unidata/UnicodeData.txt	Fri Sep 03 06:22:01 2010 +0000
+++ b/admin/unidata/UnicodeData.txt	Sun Sep 05 22:45:59 2010 +0000
@@ -1699,7 +1699,7 @@
 06DB;ARABIC SMALL HIGH THREE DOTS;Mn;230;NSM;;;;;N;;;;;
 06DC;ARABIC SMALL HIGH SEEN;Mn;230;NSM;;;;;N;;;;;
 06DD;ARABIC END OF AYAH;Cf;0;AN;;;;;N;;;;;
-06DE;ARABIC START OF RUB EL HIZB;Me;0;NSM;;;;;N;;;;;
+06DE;ARABIC START OF RUB EL HIZB;So;0;ON;;;;;N;;;;;
 06DF;ARABIC SMALL HIGH ROUNDED ZERO;Mn;230;NSM;;;;;N;;;;;
 06E0;ARABIC SMALL HIGH UPRIGHT RECTANGULAR ZERO;Mn;230;NSM;;;;;N;;;;;
 06E1;ARABIC SMALL HIGH DOTLESS HEAD OF KHAH;Mn;230;NSM;;;;;N;;;;;
@@ -5640,9 +5640,9 @@
 19D7;NEW TAI LUE DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;;
 19D8;NEW TAI LUE DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;;
 19D9;NEW TAI LUE DIGIT NINE;Nd;0;L;;9;9;9;N;;;;;
-19DA;NEW TAI LUE THAM DIGIT ONE;Nd;0;L;;1;1;1;N;;;;;
-19DE;NEW TAI LUE SIGN LAE;Po;0;ON;;;;;N;;;;;
-19DF;NEW TAI LUE SIGN LAEV;Po;0;ON;;;;;N;;;;;
+19DA;NEW TAI LUE THAM DIGIT ONE;No;0;L;;;1;1;N;;;;;
+19DE;NEW TAI LUE SIGN LAE;So;0;ON;;;;;N;;;;;
+19DF;NEW TAI LUE SIGN LAEV;So;0;ON;;;;;N;;;;;
 19E0;KHMER SYMBOL PATHAMASAT;So;0;ON;;;;;N;;;;;
 19E1;KHMER SYMBOL MUOY KOET;So;0;ON;;;;;N;;;;;
 19E2;KHMER SYMBOL PII KOET;So;0;ON;;;;;N;;;;;
@@ -7119,6 +7119,7 @@
 20B6;LIVRE TOURNOIS SIGN;Sc;0;ET;;;;;N;;;;;
 20B7;SPESMILO SIGN;Sc;0;ET;;;;;N;;;;;
 20B8;TENGE SIGN;Sc;0;ET;;;;;N;;;;;
+20B9;INDIAN RUPEE SIGN;Sc;0;ET;;;;;N;;;;;
 20D0;COMBINING LEFT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING LEFT HARPOON ABOVE;;;;
 20D1;COMBINING RIGHT HARPOON ABOVE;Mn;230;NSM;;;;;N;NON-SPACING RIGHT HARPOON ABOVE;;;;
 20D2;COMBINING LONG VERTICAL LINE OVERLAY;Mn;1;NSM;;;;;N;NON-SPACING LONG VERTICAL BAR OVERLAY;;;;
@@ -7176,7 +7177,7 @@
 2115;DOUBLE-STRUCK CAPITAL N;Lu;0;L;<font> 004E;;;;N;DOUBLE-STRUCK N;;;;
 2116;NUMERO SIGN;So;0;ON;<compat> 004E 006F;;;;N;NUMERO;;;;
 2117;SOUND RECORDING COPYRIGHT;So;0;ON;;;;;N;;;;;
-2118;SCRIPT CAPITAL P;So;0;ON;;;;;N;SCRIPT P;;;;
+2118;SCRIPT CAPITAL P;Sm;0;ON;;;;;N;SCRIPT P;;;;
 2119;DOUBLE-STRUCK CAPITAL P;Lu;0;L;<font> 0050;;;;N;DOUBLE-STRUCK P;;;;
 211A;DOUBLE-STRUCK CAPITAL Q;Lu;0;L;<font> 0051;;;;N;DOUBLE-STRUCK Q;;;;
 211B;SCRIPT CAPITAL R;Lu;0;L;<font> 0052;;;;N;SCRIPT R;;;;
--- a/config.bat	Fri Sep 03 06:22:01 2010 +0000
+++ b/config.bat	Sun Sep 05 22:45:59 2010 +0000
@@ -250,6 +250,7 @@
 rem   ----------------------------------------------------------------------
 Echo Configuring the lisp directory...
 cd lisp
+If Exist gnus\.dir-locals.el update gnus/.dir-locals.el gnus/_dir-locals.el
 sed -f ../msdos/sedlisp.inp < Makefile.in > Makefile
 cd ..
 rem   ----------------------------------------------------------------------
--- a/doc/misc/ChangeLog	Fri Sep 03 06:22:01 2010 +0000
+++ b/doc/misc/ChangeLog	Sun Sep 05 22:45:59 2010 +0000
@@ -1,4 +1,13 @@
+2010-09-04  Julien Danjou  <julien@danjou.info>  (tiny change)
+
+	* gnus.texi (Adaptive Scoring): Fix typo.
+
+2010-09-03  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+	* gnus.texi (Article Display): Document gnus-html-show-images.
+
 2010-09-02  Jan Djärv  <jan.h.d@swipnet.se>
+
 	* cl.texi (Basic Setf): Remove x-get-cut-buffer and x-get-cutbuffer.
 
 2010-09-01  Lars Magne Ingebrigtsen  <larsi@gnus.org>
--- a/doc/misc/gnus.texi	Fri Sep 03 06:22:01 2010 +0000
+++ b/doc/misc/gnus.texi	Sun Sep 05 22:45:59 2010 +0000
@@ -10351,6 +10351,14 @@
 Remove all images from the article buffer
 (@code{gnus-article-remove-images}).
 
+@item W D W
+@kindex W D W (Summary)
+@findex gnus-html-show-images
+If you're reading an @acronym{HTML} article rendered with
+@code{gnus-article-html}, then you can insert any blocked images in
+the buffer with this command.
+(@code{gnus-html-show-images}).
+
 @end table
 
 
@@ -21566,7 +21574,7 @@
 @vindex gnus-adaptive-pretty-print
 Adaptive score files can get huge and are not meant to be edited by
 human hands.  If @code{gnus-adaptive-pretty-print} is @code{nil} (the
-deafult) those files will not be written in a human readable way.
+default) those files will not be written in a human readable way.
 
 @vindex gnus-score-exact-adapt-limit
 When doing adaptive scoring, substring or fuzzy matching would probably
--- a/etc/NEWS	Fri Sep 03 06:22:01 2010 +0000
+++ b/etc/NEWS	Sun Sep 05 22:45:59 2010 +0000
@@ -427,6 +427,8 @@
 
 * New Modes and Packages in Emacs 24.1
 
+** New global minor modes electric-pair-mode and electric-indent-mode.
+
 ** pcase.el provides the ML-style pattern matching macro `pcase'.
 
 ** smie.el is a package providing a simple generic indentation engine.
--- a/lisp/ChangeLog	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/ChangeLog	Sun Sep 05 22:45:59 2010 +0000
@@ -1,3 +1,97 @@
+2010-09-05  Chong Yidong  <cyd@stupidchicken.com>
+
+	* dired.el (dired-ls-sorting-switches, dired-sort-by-name-regexp):
+	Improve regexps (Bug#6987).
+	(dired-sort-toggle): Search more robustly for -t flag.
+
+	* files.el (get-free-disk-space): Search more robustly for
+	"available" column.  Suggested by Ehud Karni
+	<ehud@unix.mvs.co.il>.
+
+2010-09-05  Juanma Barranquero  <lekktu@gmail.com>
+
+	* international/uni-bidi.el:
+	* international/uni-category.el:
+	* international/uni-combining.el:
+	* international/uni-decimal.el:
+	* international/uni-mirrored.el:
+	* international/uni-name.el: Regenerate.
+
+2010-09-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	* electric.el (electric-indent-post-self-insert-function):
+	Don't reindent with a sloppy indentation function.
+
+	* emacs-lisp/syntax.el (syntax-ppss): More sanity check to catch
+	border case in change-log-mode.
+
+2010-09-04  Chong Yidong  <cyd@stupidchicken.com>
+
+	* progmodes/compile.el (compilation-error-regexp-alist-alist):
+	Remove ruby regexp; handle Ruby errors with gcc-include and gnu.
+	Recognize leading tab in gcc-include regexp.  Ignore names with
+	leading "from" or "in" in gnu regexp (Bug#6937).
+
+2010-09-04  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	Avoid global recursive calls to kill-buffer-hooks; fit into 80 cols.
+	* textmodes/ispell.el (ispell-process-buffer-name): Remove.
+	(ispell-start-process): Avoid setq and simplify logic.
+	(ispell-init-process): Setup kill-buffer-hook locally when needed.
+	(kill-buffer-hook): Don't use it globally with code that uses
+	expand-file-name since that may call kill-buffer via
+	code_conversion_restore.
+
+2010-09-04  Noorul Islam K M  <noorul@noorul.com>  (tiny change)
+
+	* emacs-lisp/package.el (package-directory-list): Only call
+	file-name-nondirectory on a string.
+
+2010-09-02  Chong Yidong  <cyd@stupidchicken.com>
+
+	* emacs-lisp/package.el (package--download-one-archive):
+	Ensure that archive-contents is valid before saving it.
+	(package-activate-1, package-mark-obsolete, define-package)
+	(package-compute-transaction, package-list-maybe-add): Use push.
+
+2010-09-03  Stefan Monnier  <monnier@iro.umontreal.ca>
+
+	Use SMIE's blink-paren for octave-mode.
+	* progmodes/octave-mod.el (octave-font-lock-close-quotes):
+	Backslashes do not escape single-quotes, single-quotes do.
+	(octave-block-else-regexp, octave-block-end-regexp)
+	(octave-block-match-alist): Remove.
+	(octave-smie-bnf-table): New var, with old content.
+	(octave-smie-op-levels): Use it.
+	(octave-smie-closer-alist): New var.
+	(octave-mode): Use it.  Setup smie-blink-matching and electric-indent.
+	(octave-blink-matching-block-open): Remove.
+	(octave-reindent-then-newline-and-indent, octave-electric-semi)
+	(octave-electric-space): Let self-insert-command run expand-abbrev and
+	blink parens.
+
+	* electric.el (electricity): New group.
+	(electric-indent-chars): New var.
+	(electric-indent-post-self-insert-function): New fun.
+	(electric-indent-mode): New minor mode.
+	(electric-pair-skip-self): New custom.
+	(electric-pair-post-self-insert-function): New function.
+	(electric-pair-mode): New minor mode.
+
+	* calc/calc-aent.el (calcAlg-blink-matching-check): New fun, to replace
+	calcAlg-blink-matching-open.
+	(calc-alg-ent-map, calc-alg-ent-esc-map): Initialize in the declaration.
+	(calc-do-alg-entry): Only touch the part of the keymap that varies.
+	Use the new blink-matching-check-function.
+
+	Provide blink-matching support to SMIE.
+	* emacs-lisp/smie.el (smie-bnf-closer-alist): New function.
+	(smie-blink-matching-triggers, smie-blink-matching-inners): New vars.
+	(smie-blink-matching-check, smie-blink-matching-open): New functions.
+
+	* simple.el (newline): Fix last change to properly remove itself from
+	the hook.
+
 2010-09-02  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* simple.el (newline): Eliminate optimization.
@@ -621,7 +715,7 @@
 	* mouse.el (mouse-yank-primary): Avoid setting primary when
 	deactivating the mark (Bug#6872).
 
-2010-08-23  Chris Foote <chris@foote.com.au>  (tiny change)
+2010-08-23  Chris Foote  <chris@foote.com.au>  (tiny change)
 
 	* progmodes/python.el (python-block-pairs): Allow use of "finally"
 	with "else" (Bug#3991).
@@ -1130,7 +1224,7 @@
 	* align.el (align-default-spacing): Doc fix.
 	(align-region-heuristic, align-regexp): Fix typos in docstrings.
 
-2010-08-08  Stephen Peters <speters@itasoftware.com>
+2010-08-08  Stephen Peters  <speters@itasoftware.com>
 
 	* calendar/icalendar.el
 	(icalendar--split-value): Fixed splitting regexp. (Bug#6766)
--- a/lisp/calc/calc-aent.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/calc/calc-aent.el	Sun Sep 05 22:45:59 2010 +0000
@@ -315,10 +315,24 @@
 		calc-dollar-used 0)))
       (calc-handle-whys))))
 
-(defvar calc-alg-ent-map nil
+(defvar calc-alg-ent-map
+  (let ((map (make-sparse-keymap)))
+    (set-keymap-parent map minibuffer-local-map)
+    (define-key map "'" 'calcAlg-previous)
+    (define-key map "`" 'calcAlg-edit)
+    (define-key map "\C-m" 'calcAlg-enter)
+    (define-key map "\C-j" 'calcAlg-enter)
+    map)
   "The keymap used for algebraic entry.")
 
-(defvar calc-alg-ent-esc-map nil
+(defvar calc-alg-ent-esc-map
+  (let ((map (make-keymap))
+        (i 33))
+    (set-keymap-parent map esc-map)
+    (while (< i 127)
+      (define-key map (vector i) 'calcAlg-escape)
+      (setq i (1+ i)))
+    map)
   "The keymap used for escapes in algebraic entry.")
 
 (defvar calc-alg-exp)
@@ -326,19 +340,8 @@
 ;;;###autoload
 (defun calc-do-alg-entry (&optional initial prompt no-normalize history)
   (let* ((calc-buffer (current-buffer))
-	 (blink-paren-function 'calcAlg-blink-matching-open)
+	 (blink-matching-check-function 'calcAlg-blink-matching-check)
 	 (calc-alg-exp 'error))
-    (unless calc-alg-ent-map
-      (setq calc-alg-ent-map (copy-keymap minibuffer-local-map))
-      (define-key calc-alg-ent-map "'" 'calcAlg-previous)
-      (define-key calc-alg-ent-map "`" 'calcAlg-edit)
-      (define-key calc-alg-ent-map "\C-m" 'calcAlg-enter)
-      (define-key calc-alg-ent-map "\C-j" 'calcAlg-enter)
-      (let ((i 33))
-        (setq calc-alg-ent-esc-map (copy-keymap esc-map))
-        (while (< i 127)
-          (aset (nth 1 calc-alg-ent-esc-map) i 'calcAlg-escape)
-          (setq i (1+ i)))))
     (define-key calc-alg-ent-map "\e" nil)
     (if (eq calc-algebraic-mode 'total)
 	(define-key calc-alg-ent-map "\e" calc-alg-ent-esc-map)
@@ -430,18 +433,9 @@
 		      exp))
       (exit-minibuffer))))
 
-(defun calcAlg-blink-matching-open ()
-  (let ((rightpt (point))
- 	(leftpt nil)
-        (rightchar (preceding-char))
-        leftchar
-        rightsyntax
-        leftsyntax)
-    (save-excursion
-      (condition-case ()
- 	  (setq leftpt (scan-sexps rightpt -1)
-                leftchar (char-after leftpt))
-  	(error nil)))
+(defun calcAlg-blink-matching-check (leftpt rightpt)
+  (let ((rightchar (char-before rightpt))
+        (leftchar (if leftpt (char-after leftpt))))
     (if (and leftpt
  	     (or (and (= rightchar ?\))
  		      (= leftchar ?\[))
@@ -450,20 +444,9 @@
  	     (save-excursion
  	       (goto-char leftpt)
  	       (looking-at ".+\\(\\.\\.\\|\\\\dots\\|\\\\ldots\\)")))
- 	(let ((leftsaved (aref (syntax-table) leftchar))
-              (rightsaved (aref (syntax-table) rightchar)))
- 	  (unwind-protect
- 	      (progn
-                (cond ((= leftchar ?\[)
-                       (aset (syntax-table) leftchar (cons 4 ?\)))
-                       (aset (syntax-table) rightchar (cons 5 ?\[)))
-                      (t
-                       (aset (syntax-table) leftchar (cons 4 ?\]))
-                       (aset (syntax-table) rightchar (cons 5 ?\())))
- 		(blink-matching-open))
-            (aset (syntax-table) leftchar leftsaved)
-            (aset (syntax-table) rightchar rightsaved)))
-      (blink-matching-open))))
+        ;; [2..5) perfectly valid!
+ 	nil
+      (blink-matching-check-mismatch leftpt rightpt))))
 
 ;;;###autoload
 (defun calc-alg-digit-entry ()
--- a/lisp/dired.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/dired.el	Sun Sep 05 22:45:59 2010 +0000
@@ -3249,12 +3249,16 @@
 format, use `\\[universal-argument] \\[dired]'.")
 
 (defvar dired-sort-by-date-regexp
-  (concat "^-[^" dired-ls-sorting-switches
-	  "]*t[^" dired-ls-sorting-switches "]*$")
+  (concat "\\(\\`\\| \\)-[^- ]*t"
+	  ;; `dired-ls-sorting-switches' after -t overrides -t.
+	  "[^ " dired-ls-sorting-switches "]*"
+	  "\\(\\(\\`\\| +\\)\\(--[^ ]+\\|-[^- t"
+	  dired-ls-sorting-switches "]+\\)\\)* *$")
   "Regexp recognized by Dired to set `by date' mode.")
 
 (defvar dired-sort-by-name-regexp
-  (concat "^-[^t" dired-ls-sorting-switches "]+$")
+  (concat "\\`\\(\\(\\`\\| +\\)\\(--[^ ]+\\|"
+	  "-[^- t" dired-ls-sorting-switches "]+\\)\\)* *$")
   "Regexp recognized by Dired to set `by name' mode.")
 
 (defvar dired-sort-inhibit nil
@@ -3280,8 +3284,8 @@
     (force-mode-line-update)))
 
 (defun dired-sort-toggle-or-edit (&optional arg)
-  "Toggle between sort by date/name and refresh the dired buffer.
-With a prefix argument you can edit the current listing switches instead."
+  "Toggle sorting by date, and refresh the Dired buffer.
+With a prefix argument, edit the current listing switches instead."
   (interactive "P")
   (when dired-sort-inhibit
     (error "Cannot sort this dired buffer"))
@@ -3292,24 +3296,24 @@
 
 (defun dired-sort-toggle ()
   ;; Toggle between sort by date/name.  Reverts the buffer.
-  (setq dired-actual-switches
-	(let (case-fold-search)
-	  (if (string-match " " dired-actual-switches)
-	      ;; New toggle scheme: add/remove a trailing " -t"
-	      (if (string-match " -t\\'" dired-actual-switches)
-		  (substring dired-actual-switches 0 (match-beginning 0))
-		(concat dired-actual-switches " -t"))
-	    ;; old toggle scheme: look for some 't' switch and add/remove it
-	    (concat
-	     "-l"
-	     (dired-replace-in-string (concat "[-lt"
-					      dired-ls-sorting-switches "]")
-				      ""
-				      dired-actual-switches)
-	     (if (string-match (concat "[t" dired-ls-sorting-switches "]")
-			       dired-actual-switches)
-		 ""
-	       "t")))))
+  (let ((sorting-by-date (string-match dired-sort-by-date-regexp
+				       dired-actual-switches))
+	;; Regexp for finding (possibly embedded) -t switches.
+	(switch-regexp "\\(\\`\\| \\)-\\([a-su-zA-Z]*\\)\\(t\\)\\([^ ]*\\)")
+	case-fold-search)
+    ;; Remove the -t switch.
+    (while (string-match switch-regexp dired-actual-switches)
+      (if (and (equal (match-string 2 dired-actual-switches) "")
+	       (equal (match-string 4 dired-actual-switches) ""))
+	  ;; Remove a stand-alone -t switch.
+	  (setq dired-actual-switches
+		(replace-match "" t t dired-actual-switches))
+	;; Remove a switch of the form -XtY for some X and Y.
+	(setq dired-actual-switches
+	      (replace-match "" t t dired-actual-switches 3))))
+    ;; Now, if we weren't sorting by date before, add the -t switch.
+    (unless sorting-by-date
+      (setq dired-actual-switches (concat dired-actual-switches " -t"))))
   (dired-sort-set-modeline)
   (revert-buffer))
 
--- a/lisp/electric.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/electric.el	Sun Sep 05 22:45:59 2010 +0000
@@ -24,10 +24,23 @@
 
 ;;; Commentary:
 
-; zaaaaaaap
+;; "Electric" has been used in Emacs to refer to different things.
+;; Among them:
+;;
+;; - electric modes and buffers: modes that typically pop-up in a modal kind of
+;;   way a transient buffer that automatically disappears as soon as the user
+;;   is done with it.
+;;
+;; - electric keys: self inserting keys which additionally perform some side
+;;   operation which happens to be often convenient at that time.  Examples of
+;;   such side operations are: reindenting code, inserting a newline,
+;;   ... auto-fill-mode and abbrev-mode can be considered as built-in forms of
+;;   electric key behavior.
 
 ;;; Code:
 
+(eval-when-compile (require 'cl))
+
 ;; This loop is the guts for non-standard modes which retain control
 ;; until some event occurs.  It is a `do-forever', the only way out is
 ;; to throw.  It assumes that you have set up the keymap, window, and
@@ -157,6 +170,135 @@
 	(fit-window-to-buffer win max-height))
       win)))
 
+;;; Electric keys.
+
+(defgroup electricity ()
+  "Electric behavior for self inserting keys."
+  :group 'editing)
+
+;; Electric indentation.
+
+(defvar electric-indent-chars '(?\n)
+  "Characters that should cause automatic reindentation.")
+
+(defun electric-indent-post-self-insert-function ()
+  ;; FIXME: This reindents the current line, but what we really want instead is
+  ;; to reindent the whole affected text.  That's the current line for simple
+  ;; cases, but not all cases.  We do take care of the newline case in an
+  ;; ad-hoc fashion, but there are still missing cases such as the case of
+  ;; electric-pair-mode wrapping a region with a pair of parens.
+  ;; There might be a way to get it working by analyzing buffer-undo-list, but
+  ;; it looks challenging.
+  (when (and (memq last-command-event electric-indent-chars)
+             ;; Don't reindent while inserting spaces at beginning of line.
+             (or (not (memq last-command-event '(?\s ?\t)))
+                 (save-excursion (skip-chars-backward " \t") (not (bolp))))
+             ;; Not in a string or comment.
+             (not (nth 8 (syntax-ppss))))
+    ;; For newline, we want to reindent both lines and basically behave like
+    ;; reindent-then-newline-and-indent (whose code we hence copied).
+    (when (and (eq last-command-event ?\n)
+               ;; Don't reindent the previous line if the indentation function
+               ;; is not a real one.
+               (not (memq indent-line-function
+                          '(indent-relative indent-relative-maybe)))
+               ;; Sanity check.
+               (eq (char-before) last-command-event))
+      (let ((pos (copy-marker (1- (point)) t)))
+        (save-excursion
+          (goto-char pos)
+          (indent-according-to-mode)
+          ;; We are at EOL before the call to indent-according-to-mode, and
+          ;; after it we usually are as well, but not always.  We tried to
+          ;; address it with `save-excursion' but that uses a normal marker
+          ;; whereas we need `move after insertion', so we do the
+          ;; save/restore by hand.
+          (goto-char pos)
+          ;; Remove the trailing whitespace after indentation because
+          ;; indentation may (re)introduce the whitespace.
+          (delete-horizontal-space t))))
+    (indent-according-to-mode)))
+
+;;;###autoload
+(define-minor-mode electric-indent-mode
+  "Automatically reindent lines of code when inserting particular chars.
+`electric-indent-chars' specifies the set of chars that should cause reindentation."
+  :global t
+  :group 'electricity
+  (if electric-indent-mode
+      (add-hook 'post-self-insert-hook
+                #'electric-indent-post-self-insert-function)
+    (remove-hook 'post-self-insert-hook
+                 #'electric-indent-post-self-insert-function)))
+
+;; Electric pairing.
+
+(defcustom electric-pair-skip-self t
+  "If non-nil, skip char instead of inserting a second closing paren.
+When inserting a closing paren character right before the same character,
+just skip that character instead, so that hitting ( followed by ) results
+in \"()\" rather than \"())\".
+This can be convenient for people who find it easier to hit ) than C-f."
+  :type 'boolean)
+
+(defun electric-pair-post-self-insert-function ()
+  (let* ((syntax (and (eq (char-before) last-command-event) ; Sanity check.
+                      (char-syntax last-command-event)))
+         ;; FIXME: when inserting the closer, we should maybe use
+         ;; self-insert-command, although it may prove tricky running
+         ;; post-self-insert-hook recursively, and we wouldn't want to trigger
+         ;; blink-matching-open.
+         (closer (if (eq syntax ?\()
+                     (cdr (aref (syntax-table) last-command-event))
+                   last-command-event)))
+    (cond
+     ;; Wrap a pair around the active region.
+     ((and (memq syntax '(?\( ?\" ?\$)) (use-region-p))
+      (if (> (mark) (point))
+          (goto-char (mark))
+        ;; We already inserted the open-paren but at the end of the region,
+        ;; so we have to remove it and start over.
+        (delete-char -1)
+        (save-excursion
+          (goto-char (mark))
+          (insert last-command-event)))
+      (insert closer))
+     ;; Backslash-escaped: no pairing, no skipping.
+     ((save-excursion
+        (goto-char (1- (point)))
+        (not (zerop (% (skip-syntax-backward "\\") 2))))
+      nil)
+     ;; Skip self.
+     ((and (memq syntax '(?\) ?\" ?\$))
+           electric-pair-skip-self
+           (eq (char-after) last-command-event))
+      ;; This is too late: rather than insert&delete we'd want to only skip (or
+      ;; insert in overwrite mode).  The difference is in what goes in the
+      ;; undo-log and in the intermediate state which might be visible to other
+      ;; post-self-insert-hook.  We'll just have to live with it for now.
+      (delete-char 1))
+     ;; Insert matching pair.
+     ((not (or (not (memq syntax `(?\( ?\" ?\$)))
+               overwrite-mode
+               ;; I find it more often preferable not to pair when the
+               ;; same char is next.
+               (eq last-command-event (char-after))
+               (eq last-command-event (char-before (1- (point))))
+               ;; I also find it often preferable not to pair next to a word.
+               (eq (char-syntax (following-char)) ?w)))
+      (save-excursion (insert closer))))))
+
+;;;###autoload
+(define-minor-mode electric-pair-mode
+  "Automatically pair-up parens when inserting an open paren."
+  :global t
+  :group 'electricity
+  (if electric-pair-mode
+      (add-hook 'post-self-insert-hook
+                #'electric-pair-post-self-insert-function)
+    (remove-hook 'post-self-insert-hook
+                 #'electric-pair-post-self-insert-function)))
+        
 (provide 'electric)
 
 ;; arch-tag: dae045eb-dc2d-4fb7-9f27-9cc2ce277be8
--- a/lisp/emacs-lisp/cl-loaddefs.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/emacs-lisp/cl-loaddefs.el	Sun Sep 05 22:45:59 2010 +0000
@@ -282,7 +282,7 @@
 ;;;;;;  do-all-symbols do-symbols dotimes dolist do* do loop return-from
 ;;;;;;  return block etypecase typecase ecase case load-time-value
 ;;;;;;  eval-when destructuring-bind function* defmacro* defun* gentemp
-;;;;;;  gensym) "cl-macs" "cl-macs.el" "c5a12d86541b5137054eccc43e4fc839")
+;;;;;;  gensym) "cl-macs" "cl-macs.el" "c10b5cbebb5267291ef15c782c0271a6")
 ;;; Generated autoloads from cl-macs.el
 
 (autoload 'gensym "cl-macs" "\
--- a/lisp/emacs-lisp/package.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/emacs-lisp/package.el	Sun Sep 05 22:45:59 2010 +0000
@@ -260,8 +260,9 @@
   ;; Defaults are subdirs named "elpa" in the site-lisp dirs.
   (let (result)
     (dolist (f load-path)
-      (if (equal (file-name-nondirectory f) "site-lisp")
-	  (push (expand-file-name "elpa" f) result)))
+      (and (stringp f)
+	   (equal (file-name-nondirectory f) "site-lisp")
+	   (push (expand-file-name "elpa" f) result)))
     (nreverse result))
   "List of additional directories containing Emacs Lisp packages.
 Each directory name should be absolute.
@@ -406,16 +407,15 @@
       (error "Internal error: could not find directory for %s-%s"
 	     name version-str))
     ;; Add info node.
-    (if (file-exists-p (expand-file-name "dir" pkg-dir))
-	(progn
-	  ;; FIXME: not the friendliest, but simple.
-	  (require 'info)
-	  (info-initialize)
-	  (setq Info-directory-list (cons pkg-dir Info-directory-list))))
+    (when (file-exists-p (expand-file-name "dir" pkg-dir))
+      ;; FIXME: not the friendliest, but simple.
+      (require 'info)
+      (info-initialize)
+      (push pkg-dir Info-directory-list))
     ;; Add to load path, add autoloads, and activate the package.
-    (setq load-path (cons pkg-dir load-path))
+    (push pkg-dir load-path)
     (load (expand-file-name (concat name "-autoloads") pkg-dir) nil t)
-    (setq package-activated-list (cons package package-activated-list))
+    (push package package-activated-list)
     ;; Don't return nil.
     t))
 
@@ -466,10 +466,9 @@
 	  (setcdr elt (cons (cons (package-desc-vers pkg-vec) pkg-vec)
 			    (cdr elt))))
       ;; Make a new association.
-      (setq package-obsolete-alist
-	    (cons (cons package (list (cons (package-desc-vers pkg-vec)
-					    pkg-vec)))
-		  package-obsolete-alist)))))
+      (push (cons package (list (cons (package-desc-vers pkg-vec)
+				      pkg-vec)))
+	    package-obsolete-alist))))
 
 (defun define-package (name-str version-string
 				&optional docstring requirements
@@ -505,7 +504,7 @@
 	    (setq package-alist (delq pkg-desc package-alist))
 	    (package-mark-obsolete (car pkg-desc) (cdr pkg-desc)))
 	  ;; Add package to the alist.
-	  (setq package-alist (cons new-pkg-desc package-alist)))
+	  (push new-pkg-desc package-alist))
       ;; You can have two packages with the same version, for instance
       ;; one in the system package directory and one in your private
       ;; directory.  We just let the first one win.
@@ -707,7 +706,7 @@
 	     (package-version-join (package-desc-vers (cdr pkg-desc)))))
 	  ;; Only add to the transaction if we don't already have it.
 	  (unless (memq next-pkg package-list)
-	    (setq package-list (cons next-pkg package-list)))
+	    (push next-pkg package-list))
 	  (setq package-list
 		(package-compute-transaction package-list
 					     (package-desc-reqs
@@ -992,17 +991,19 @@
       (re-search-forward "^$" nil 'move)
       (forward-char)
       (delete-region (point-min) (point))
-      (make-directory dir t)
-      (setq buffer-file-name (expand-file-name file dir))
-      (let ((version-control 'never))
-	(save-buffer)))
+      ;; Read the retrieved buffer to make sure it is valid (e.g. it
+      ;; may fetch a URL redirect page).
+      (when (listp (read buffer))
+	(make-directory dir t)
+	(setq buffer-file-name (expand-file-name file dir))
+	(let ((version-control 'never))
+	  (save-buffer))))
     (kill-buffer buffer)))
 
 (defun package-refresh-contents ()
   "Download the ELPA archive description if needed.
-Invoking this will ensure that Emacs knows about the latest versions
-of all packages.  This will let Emacs make them available for
-download."
+This informs Emacs about the latest versions of all packages, and
+makes them available for download."
   (interactive)
   (unless (file-exists-p package-user-dir)
     (make-directory package-user-dir t))
@@ -1301,11 +1302,9 @@
   (run-mode-hooks 'package-menu-mode-hook))
 
 (defun package-menu-refresh ()
-  "Download the ELPA archive.
-This fetches the file describing the current contents of
-the Emacs Lisp Package Archive, and then refreshes the
-package menu.  This lets you see what new packages are
-available for download."
+  "Download the Emacs Lisp package archive.
+This fetches the contents of each archive specified in
+`package-archives', and then refreshes the package menu."
   (interactive)
   (unless (eq major-mode 'package-menu-mode)
     (error "The current buffer is not a Package Menu"))
@@ -1460,8 +1459,7 @@
 
 (defun package-list-maybe-add (package version status description result)
   (unless (assoc (cons package version) result)
-    (setq result (cons (list (cons package version) status description)
-		       result)))
+    (push (list (cons package version) status description) result))
   result)
 
 (defvar package-menu-package-list nil
--- a/lisp/emacs-lisp/smie.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/emacs-lisp/smie.el	Sun Sep 05 22:45:59 2010 +0000
@@ -75,6 +75,26 @@
 
 ;;; Building precedence level tables from BNF specs.
 
+;; We have 4 different representations of a "grammar":
+;; - a BNF table, which is a list of BNF rules of the form
+;;   (NONTERM RHS1 ... RHSn) where each RHS is a list of terminals (tokens)
+;;   or nonterminals.  Any element in these lists which does not appear as
+;;   the `car' of a BNF rule is taken to be a terminal.
+;; - A list of precedences (key word "precs"), is a list, sorted
+;;   from lowest to highest precedence, of precedence classes that
+;;   have the form (ASSOCIATIVITY TERMINAL1 .. TERMINALn), where
+;;   ASSOCIATIVITY can be `assoc', `left', `right' or `nonassoc'.
+;; - a 2 dimensional precedence table (key word "prec2"), is a 2D
+;;   table recording the precedence relation (can be `<', `=', `>', or
+;;   nil) between each pair of tokens.
+;; - a precedence-level table (key word "levels"), while is a alist
+;;   giving for each token its left and right precedence level (a
+;;   number or nil).  This is used in `smie-op-levels'.
+;; The prec2 tables are only intermediate data structures: the source
+;; code normally provides a mix of BNF and precs tables, and then
+;; turns them into a levels table, which is what's used by the rest of
+;; the SMIE code.
+
 (defun smie-set-prec2tab (table x y val &optional override)
   (assert (and x y))
   (let* ((key (cons x y))
@@ -206,6 +226,87 @@
           (setq rhs (cdr rhs)))))
     prec2))
 
+;; (defun smie-prec2-closer-alist (prec2 include-inners)
+;;   "Build a closer-alist from a PREC2 table.
+;; The return value is in the same form as `smie-closer-alist'.
+;; INCLUDE-INNERS if non-nil means that inner keywords will be included
+;; in the table, e.g. the table will include things like (\"if\" . \"else\")."
+;;   (let* ((non-openers '())
+;;          (non-closers '())
+;;          ;; For each keyword, this gives the matching openers, if any.
+;;          (openers (make-hash-table :test 'equal))
+;;          (closers '())
+;;          (done nil))
+;;     ;; First, find the non-openers and non-closers.
+;;     (maphash (lambda (k v)
+;;                (unless (or (eq v '<) (member (cdr k) non-openers))
+;;                  (push (cdr k) non-openers))
+;;                (unless (or (eq v '>) (member (car k) non-closers))
+;;                  (push (car k) non-closers)))
+;;              prec2)
+;;     ;; Then find the openers and closers.
+;;     (maphash (lambda (k _)
+;;                (unless (member (car k) non-openers)
+;;                  (puthash (car k) (list (car k)) openers))
+;;                (unless (or (member (cdr k) non-closers)
+;;                            (member (cdr k) closers))
+;;                  (push (cdr k) closers)))
+;;              prec2)
+;;     ;; Then collect the matching elements.
+;;     (while (not done)
+;;       (setq done t)
+;;       (maphash (lambda (k v)
+;;                  (when (eq v '=)
+;;                    (let ((aopeners (gethash (car k) openers))
+;;                          (dopeners (gethash (cdr k) openers))
+;;                          (new nil))
+;;                      (dolist (o aopeners)
+;;                        (unless (member o dopeners)
+;;                          (setq new t)
+;;                          (push o dopeners)))
+;;                      (when new
+;;                        (setq done nil)
+;;                        (puthash (cdr k) dopeners openers)))))
+;;                prec2))
+;;     ;; Finally, dump the resulting table.
+;;     (let ((alist '()))
+;;       (maphash (lambda (k v)
+;;                  (when (or include-inners (member k closers))
+;;                    (dolist (opener v)
+;;                      (unless (equal opener k)
+;;                        (push (cons opener k) alist)))))
+;;                openers)
+;;       alist)))
+
+(defun smie-bnf-closer-alist (bnf &optional no-inners)
+  ;; We can also build this closer-alist table from a prec2 table,
+  ;; but it takes more work, and the order is unpredictable, which
+  ;; is a problem for smie-close-block.
+  ;; More convenient would be to build it from a levels table since we
+  ;; always have this table (contrary to the BNF), but it has all the
+  ;; disadvantages of the prec2 case plus the disadvantage that the levels
+  ;; table has lost some info which would result in extra invalid pairs.
+  "Build a closer-alist from a BNF table.
+The return value is in the same form as `smie-closer-alist'.
+NO-INNERS if non-nil means that inner keywords will be excluded
+from the table, e.g. the table will not include things like (\"if\" . \"else\")."
+  (let ((nts (mapcar #'car bnf))        ;non terminals.
+        (alist '()))
+    (dolist (nt bnf)
+      (dolist (rhs (cdr nt))
+        (unless (or (< (length rhs) 2) (member (car rhs) nts))
+          (if no-inners
+              (let ((last (car (last rhs))))
+                (unless (member last nts)
+                  (pushnew (cons (car rhs) last) alist :test #'equal)))
+            ;; Reverse so that the "real" closer gets there first,
+            ;; which is important for smie-close-block.
+            (dolist (term (reverse (cdr rhs)))
+              (unless (member term nts)
+                (pushnew (cons (car rhs) term) alist :test #'equal)))))))
+    (nreverse alist)))
+    
+
 (defun smie-prec2-levels (prec2)
   ;; FIXME: Rather than only return an alist of precedence levels, we should
   ;; also extract other useful data from it:
@@ -223,7 +324,7 @@
 `smie-bnf-precedence-table'."
   ;; For each operator, we create two "variables" (corresponding to
   ;; the left and right precedence level), which are represented by
-  ;; cons cells.  Those are the vary cons cells that appear in the
+  ;; cons cells.  Those are the very cons cells that appear in the
   ;; final `table'.  The value of each "variable" is kept in the `car'.
   (let ((table ())
         (csts ())
@@ -596,6 +697,81 @@
                               pos end))))
              (t)))))))
 
+(defvar smie-blink-matching-triggers '(?\s ?\n)
+  "Chars which might trigger `blink-matching-open'.
+These can include the final chars of end-tokens, or chars that are
+typically inserted right after an end token.
+I.e. a good choice can be:
+    (delete-dups
+     (mapcar (lambda (kw) (aref (cdr kw) (1- (length (cdr kw)))))
+             smie-closer-alist))")
+
+(defcustom smie-blink-matching-inners t
+  "Whether SMIE should blink to matching opener for inner keywords.
+If non-nil, it will blink not only for \"begin..end\" but also for \"if...else\"."
+  :type 'boolean)
+
+(defun smie-blink-matching-check (start end)
+  (save-excursion
+    (goto-char end)
+    (let ((ender (funcall smie-backward-token-function)))
+      (cond
+       ((not (and ender (rassoc ender smie-closer-alist)))
+        ;; This not is one of the begin..end we know how to check.
+        (blink-matching-check-mismatch start end))
+       ((not start) t)
+       (t
+        (goto-char start)
+        (let ((starter (funcall smie-forward-token-function)))
+          (not (member (cons starter ender) smie-closer-alist))))))))
+
+(defun smie-blink-matching-open ()
+  "Blink the matching opener when applicable.
+This uses SMIE's tables and is expected to be placed on `post-self-insert-hook'."
+  (when (and blink-matching-paren
+             smie-closer-alist                     ; Optimization.
+             (eq (char-before) last-command-event) ; Sanity check.
+             (memq last-command-event smie-blink-matching-triggers)
+             (save-excursion
+               ;; FIXME: Here we assume that closers all end
+               ;; with a word-syntax char.
+               (unless (eq ?\w (char-syntax last-command-event))
+		 (forward-char -1))
+               (and (looking-at "\\>")
+                    (not (nth 8 (syntax-ppss))))))
+    (save-excursion
+      (let ((pos (point))
+            (token (funcall smie-backward-token-function)))
+        (if (= 1 (length token))
+            ;; The trigger char is itself a token but is not
+            ;; one of the closers (e.g. ?\; in Octave mode),
+            ;; so go back to the previous token
+	    (setq token (save-excursion
+			  (funcall smie-backward-token-function)))
+	  (goto-char pos))
+	;; Here we assume that smie-backward-token-function
+	;; returns a token that is a string and whose content
+	;; match the buffer's representation of this token.
+	(when (and (> (length token) 1) (stringp token)
+		   (memq (aref token (1- (length token)))
+			 smie-blink-matching-triggers)
+		   (not (eq (aref token (1- (length token)))
+			    last-command-event)))
+	  ;; Token ends with a trigger char, so don't blink for
+	  ;; anything else than this trigger char, lest we'd blink
+	  ;; both when inserting the trigger char and when inserting a
+	  ;; subsequent SPC.
+	  (setq token nil))
+        (when (and (rassoc token smie-closer-alist)
+                   (or smie-blink-matching-inners
+                       (null (nth 2 (assoc token smie-op-levels)))))
+          ;; The major mode might set blink-matching-check-function
+          ;; buffer-locally so that interactive calls to
+          ;; blink-matching-open work right, but let's not presume
+          ;; that's the case.
+          (let ((blink-matching-check-function #'smie-blink-matching-check))
+            (blink-matching-open)))))))
+
 ;;; The indentation engine.
 
 (defcustom smie-indent-basic 4
--- a/lisp/emacs-lisp/syntax.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/emacs-lisp/syntax.el	Sun Sep 05 22:45:59 2010 +0000
@@ -209,7 +209,8 @@
 				(funcall syntax-begin-function)
 				;; Make sure it's better.
 				(> (point) pt-best))
-			 ;; Simple sanity check.
+			 ;; Simple sanity checks.
+                         (< (point) pos) ; backward-paragraph can fail here.
 			 (not (memq (get-text-property (point) 'face)
 				    '(font-lock-string-face font-lock-doc-face
 				      font-lock-comment-face))))
--- a/lisp/files.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/files.el	Sun Sep 05 22:45:59 2010 +0000
@@ -5563,12 +5563,14 @@
 
 (defun get-free-disk-space (dir)
   "Return the amount of free space on directory DIR's file system.
-The result is a string that gives the number of free 1KB blocks,
-or nil if the system call or the program which retrieve the information
-fail.  It returns also nil when DIR is a remote directory.
-
-This function calls `file-system-info' if it is available, or invokes the
-program specified by `directory-free-space-program' if that is non-nil."
+The return value is a string describing the amount of free
+space (normally, the number of free 1KB blocks).
+
+This function calls `file-system-info' if it is available, or
+invokes the program specified by `directory-free-space-program'
+and `directory-free-space-args'.  If the system call or program
+is unsuccessful, or if DIR is a remote directory, this function
+returns nil."
   (unless (file-remote-p dir)
     ;; Try to find the number of free blocks.  Non-Posix systems don't
     ;; always have df, but might have an equivalent system call.
@@ -5588,19 +5590,22 @@
 					 directory-free-space-args
 					 dir)
 			   0)))
-	    ;; Usual format is a header line followed by a line of
-	    ;; numbers.
+	    ;; Usual format is as follows:
+	    ;; Filesystem ...    Used  Available  Capacity ...
+	    ;; /dev/sda6  ...48106535   35481255  10669850 ...
 	    (goto-char (point-min))
-	    (forward-line 1)
-	    (if (not (eobp))
-		(progn
-		  ;; Move to the end of the "available blocks" number.
-		  (skip-chars-forward "^ \t")
-		  (forward-word 3)
-		  ;; Copy it into AVAILABLE.
-		  (let ((end (point)))
-		    (forward-word -1)
-		    (buffer-substring (point) end))))))))))
+	    (when (re-search-forward " +Avail[^ \n]*"
+				     (line-end-position) t)
+	      (let ((beg (match-beginning 0))
+		    (end (match-end 0))
+		    str)
+		(forward-line 1)
+		(setq str
+		      (buffer-substring-no-properties
+		       (+ beg (point) (- (point-min)))
+		       (+ end (point) (- (point-min)))))
+		(when (string-match "\\` *\\([^ ]+\\)" str)
+		  (match-string 1 str))))))))))
 
 ;; The following expression replaces `dired-move-to-filename-regexp'.
 (defvar directory-listing-before-filename-regexp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lisp/gnus/.dir-locals.el	Sun Sep 05 22:45:59 2010 +0000
@@ -0,0 +1,1 @@
+((emacs-lisp-mode . ((show-trailing-whitespace . t))))
--- a/lisp/gnus/ChangeLog	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/ChangeLog	Sun Sep 05 22:45:59 2010 +0000
@@ -1,3 +1,119 @@
+2010-09-05  Katsumi Yamaoka  <yamaoka@jpl.org>
+
+	* gnus-start.el (gnus-method-rank): Replace equalp with equal.
+
+	* nnmh.el (nnmh-request-list-1): Bind `file'.
+
+	* pop3.el (pop3-set-process-query-on-exit-flag): New function that's an
+	alias to set-process-query-on-exit-flag or process-kill-without-query.
+	(pop3-open-server): Use it.
+
+2010-09-04  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+	* mail-source.el (mail-source-delete-crash-box): Always move the crash
+	box to the Incoming file.  Fixes mistake in previous checkin.
+
+	* pop3.el (pop3-send-streaming-command): Off-by-one error on the
+	request loop (for debugging purposes) removed.
+
+	* nnml.el (nnml-save-nov): Message around nnml-save-nov so that the
+	culprit is more visible.
+	(nnml-save-incremental-nov, nnml-open-incremental-nov)
+	(nnml-add-incremental-nov): New functions to do "incremental" nov
+	updates, where we just append to the end of the existing nov files
+	without reading/writing them in full.
+
+	* mail-source.el (mail-source-delete-crash-box): Really only check the
+	incoming files once in a while.
+
+	* pop3.el (pop3-streaming-movemail): Always close the pop3 connection.
+
+	* mail-source.el (mail-source-delete-crash-box): Only check the
+	incoming files for deletion once per day to save a lot of file
+	accesses.
+
+	* pop3.el (pop3-logon): Fix up unbound variable typo.
+
+	* mail-source.el (pop3-streaming-movemail): Autoload.
+
+	* pop3.el (pop3-streaming-movemail): Respect
+	pop3-leave-mail-on-server.
+
+	* mail-source.el (mail-source-fetch-pop): Use streaming pop3
+	retrieval.
+
+	* pop3.el (pop3-process-filter): Removed unused function.
+	(pop3-streaming-movemail, pop3-send-streaming-command)
+	(pop3-wait-for-messages, pop3-write-to-file)
+	(pop3-number-of-responses): New functions for streaming pop3
+	retrieval.
+
+	* gnus-start.el (gnus-get-unread-articles): Protect against groups that
+	come from no known methods.
+	(gnus-make-hashtable-from-newsrc-alist): Remove duplicates from .newsrc
+	list.
+
+	* pop3.el (pop3-display-message-size-flag): Removed -- everybody wants
+	message sizes.
+	(pop3-movemail): Use erase-buffer instead of looping and deleting
+	regions, which seems rather odd.
+
+	* gnus-agent.el (gnus-agent-load-local): Only read the agent.lib/local
+	file once per `g' run.
+
+	* nnmh.el (nnmh-request-list-1): Output active lines also for empty
+	directories.  This makes the draft queue directory work.
+
+	* gnus-start.el (gnus-get-unread-articles): Rewrite the way we request
+	data from the backends, so that we only request the list of groups from
+	each method once.  This should speed things up considerably.
+
+	* nnvirtual.el (nnvirtual-request-list): Remove function so that we can
+	detect that it's not implemented.
+
+	* nnmh.el (nnmh-request-list-1): Fix up the recursion behavior so that
+	we actually do recurse down into the tree, but don't stat all leaf
+	nodes.
+
+	* gnus-html.el (gnus-html-show-images): If there are no images to show,
+	then say so instead of bugging out.
+
+	* gnus-agent.el (gnus-agent-load-alist): Check whether the agentview
+	files exist before trying to read them.
+
+	* gnus-html.el (gnus-html-wash-tags): Remove even more white space
+	around <pre_int>.
+
+	* gnus-art.el (gnus-article-copy-string): Say what data we copied.
+
+	* nnmh.el (nnmh-request-list-1): Optimize for speed.
+
+2010-09-03  Lars Magne Ingebrigtsen  <larsi@gnus.org>
+
+	* mm-util.el (mm-image-load-path): Just return the image directories,
+	not all directories in the path in addition to the image directories.
+	(mm-image-load-path): Maintain a cache of the image directories so that
+	the `g' command in Gnus doesn't have to stat dozens of directories each
+	time.
+
+	* gnus-html.el (gnus-html-put-image): Allow images to be removed.
+	(gnus-html-wash-tags): Add a new `i' command to insert images.
+	(gnus-html-insert-image): New command and keystroke.
+	(gnus-html-redisplay-with-images): New command and keystroke.
+	(gnus-html-show-images): Renamed command.
+	(gnus-html-wash-tags): Remove more white space before <pre_int> image
+	spacers.
+	(gnus-html-wash-tags): Decode entities at the end, so that entities
+	inside the tags don't mess up the rest of the "parsing".
+
+	* gnus-agent.el (gnus-agent-auto-agentize-methods): Change the default
+	so that nnimap methods aren't agentized by default.  There's apparently
+	many problems related to agent/imap behaviour.
+
+	* gnus-art.el (gnus-article-copy-string): New command and key binding.
+
+	* gnus-html.el: Doc fix.
+
 2010-09-03  Katsumi Yamaoka  <yamaoka@jpl.org>
 
 	* gnus-html.el (gnus-html-put-image): Use gnus-graphic-display-p,
--- a/lisp/gnus/gnus-agent.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-agent.el	Sun Sep 05 22:45:59 2010 +0000
@@ -184,7 +184,7 @@
   :type 'boolean
   :group 'gnus-agent)
 
-(defcustom gnus-agent-auto-agentize-methods '(nntp nnimap)
+(defcustom gnus-agent-auto-agentize-methods '(nntp)
   "Initially, all servers from these methods are agentized.
 The user may remove or add servers using the Server buffer.
 See Info node `(gnus)Server Buffer'."
@@ -2108,13 +2108,15 @@
 (defun gnus-agent-load-alist (group)
   "Load the article-state alist for GROUP."
   ;; Bind free variable that's used in `gnus-agent-read-agentview'.
-  (let ((gnus-agent-read-agentview group)
-	(file-name-coding-system nnmail-pathname-coding-system))
-    (setq gnus-agent-article-alist
-          (gnus-cache-file-contents
-           (gnus-agent-article-name ".agentview" group)
-           'gnus-agent-file-loading-cache
-           'gnus-agent-read-agentview))))
+  (let* ((gnus-agent-read-agentview group)
+	 (file-name-coding-system nnmail-pathname-coding-system)
+	 (agentview (gnus-agent-article-name ".agentview" group)))
+    (when (file-exists-p agentview)
+      (setq gnus-agent-article-alist
+	    (gnus-cache-file-contents
+	     agentview
+	     'gnus-agent-file-loading-cache
+	     'gnus-agent-read-agentview)))))
 
 (defun gnus-agent-read-agentview (file)
   "Load FILE and do a `read' there."
@@ -2230,23 +2232,28 @@
     (gnus-agent-update-view-total-fetched-for group nil)))
 
 (defvar gnus-agent-article-local nil)
+(defvar gnus-agent-article-local-times nil)
 (defvar gnus-agent-file-loading-local nil)
 
 (defun gnus-agent-load-local (&optional method)
   "Load the METHOD'S local file.  The local file contains min/max
 article counts for each of the method's subscribed groups."
   (let ((gnus-command-method (or method gnus-command-method)))
-    (setq gnus-agent-article-local
-          (gnus-cache-file-contents
-           (gnus-agent-lib-file "local")
-           'gnus-agent-file-loading-local
-           'gnus-agent-read-and-cache-local))))
+    (when (or (null gnus-agent-article-local-times)
+	      (zerop gnus-agent-article-local-times))
+      (setq gnus-agent-article-local
+	    (gnus-cache-file-contents
+	     (gnus-agent-lib-file "local")
+	     'gnus-agent-file-loading-local
+	     'gnus-agent-read-and-cache-local))
+      (when gnus-agent-article-local-times
+	(incf gnus-agent-article-local-times)))
+    gnus-agent-article-local))
 
 (defun gnus-agent-read-and-cache-local (file)
   "Load and read FILE then bind its contents to
 gnus-agent-article-local.  If that variable had `dirty' (also known as
 modified) original contents, they are first saved to their own file."
-
   (if (and gnus-agent-article-local
            (symbol-value (intern "+dirty" gnus-agent-article-local)))
       (gnus-agent-save-local))
--- a/lisp/gnus/gnus-art.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-art.el	Sun Sep 05 22:45:59 2010 +0000
@@ -4823,6 +4823,22 @@
 		(vector (caddr c) (car c) :active t))
 	      gnus-mime-button-commands)))
 
+(defvar gnus-url-button-commands
+  '((gnus-article-copy-string "u" "Copy URL to kill ring")))
+
+(defvar gnus-url-button-map
+  (let ((map (make-sparse-keymap)))
+    (dolist (c gnus-url-button-commands)
+      (define-key map (cadr c) (car c)))
+    map))
+
+(easy-menu-define
+  gnus-url-button-menu gnus-url-button-map "URL button menu."
+  `("Url Button"
+    ,@(mapcar (lambda (c)
+		(vector (caddr c) (car c) :active t))
+	      gnus-url-button-commands)))
+
 (defmacro gnus-bind-safe-url-regexp (&rest body)
   "Bind `mm-w3m-safe-url-regexp' according to `gnus-safe-html-newsgroups'."
   `(let ((mm-w3m-safe-url-regexp
@@ -7813,7 +7829,11 @@
 	      (unless (and (eq (car entry) 'gnus-button-url-regexp)
 			   (gnus-article-extend-url-button from start end))
 		(gnus-article-add-button start end
-					 'gnus-button-push from)))))))))
+					 'gnus-button-push from)
+		(gnus-put-text-property
+		 start end
+		 'gnus-string (buffer-substring-no-properties
+			       start end))))))))))
 
 (defun gnus-article-extend-url-button (beg start end)
   "Extend url button if url is folded into two or more lines.
@@ -7918,8 +7938,20 @@
 	  (and data (list 'gnus-data data))))
   (widget-convert-button 'link from to :action 'gnus-widget-press-button
 			 :help-echo (or text "Follow the link")
+			 :keymap gnus-url-button-map
 			 :button-keymap gnus-widget-button-keymap))
 
+(defun gnus-article-copy-string ()
+  "Copy the string in the button to the kill ring."
+  (interactive)
+  (gnus-article-check-buffer)
+  (let ((data (get-text-property (point) 'gnus-string)))
+    (when data
+      (with-temp-buffer
+	(insert data)
+	(copy-region-as-kill (point-min) (point-max))
+	(message "Copied %s" data)))))
+
 ;;; Internal functions:
 
 (defun gnus-article-set-globals ()
--- a/lisp/gnus/gnus-group.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-group.el	Sun Sep 05 22:45:59 2010 +0000
@@ -3982,23 +3982,13 @@
 			(>= arg gnus-use-nocem))
 		   (not arg)))
       (gnus-nocem-scan-groups))
-    ;; If ARG is not a number, then we read the active file.
-    (when (and arg (not (numberp arg)))
-      (let ((gnus-read-active-file t))
-	(gnus-read-active-file))
-      (setq arg nil)
-
-      ;; If the user wants it, we scan for new groups.
-      (when (eq gnus-check-new-newsgroups 'always)
-	(gnus-find-new-newsgroups)))
-
-    (setq arg (gnus-group-default-level arg t))
-    (if (and gnus-read-active-file (not arg))
-	(progn
-	  (gnus-read-active-file)
-	  (gnus-get-unread-articles arg))
-      (let ((gnus-read-active-file (if arg nil gnus-read-active-file)))
-	(gnus-get-unread-articles arg)))
+
+    (gnus-get-unread-articles arg)
+
+    ;; If the user wants it, we scan for new groups.
+    (when (eq gnus-check-new-newsgroups 'always)
+      (gnus-find-new-newsgroups))
+
     (gnus-check-reasonable-setup)
     (gnus-run-hooks 'gnus-after-getting-new-news-hook)
     (gnus-group-list-groups (and (numberp arg)
--- a/lisp/gnus/gnus-html.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-html.el	Sun Sep 05 22:45:59 2010 +0000
@@ -1,4 +1,4 @@
-;;; gnus-html.el --- Quoted-Printable functions
+;;; gnus-html.el --- Render HTML in a buffer.
 
 ;; Copyright (C) 2010  Free Software Foundation, Inc.
 
@@ -66,6 +66,12 @@
   :group 'gnus-art
   :type 'float)
 
+(defvar gnus-html-image-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map "u" 'gnus-article-copy-string)
+    (define-key map "i" 'gnus-html-insert-image)
+    map))
+
 ;;;###autoload
 (defun gnus-article-html (handle)
   (let ((article-buffer (current-buffer)))
@@ -105,9 +111,8 @@
 
 (defun gnus-html-wash-tags ()
   (let (tag parameters string start end images url)
-    (mm-url-decode-entities)
     (goto-char (point-min))
-    (while (re-search-forward "<pre_int> *</pre_int>\n" nil t)
+    (while (re-search-forward " *<pre_int> *</pre_int> *\n" nil t)
       (replace-match "" t t))
     (goto-char (point-min))
     (while (re-search-forward "<\\([^ />]+\\)\\([^>]*\\)>" nil t)
@@ -142,12 +147,28 @@
 		    (delete-region start end)
 		    (gnus-put-image image (gnus-string-or string "*")))))
 	    ;; Normal, external URL.
-	    (unless (gnus-html-image-url-blocked-p
-		     url
-		     (if (buffer-live-p gnus-summary-buffer)
-			 (with-current-buffer gnus-summary-buffer
-			   gnus-blocked-images)
-		       gnus-blocked-images))
+	    (if (gnus-html-image-url-blocked-p
+		 url
+		 (if (buffer-live-p gnus-summary-buffer)
+		     (with-current-buffer gnus-summary-buffer
+		       gnus-blocked-images)
+		   gnus-blocked-images))
+		(progn
+		  (widget-convert-button
+		   'link start end
+		   :action 'gnus-html-insert-image
+		   :help-echo url
+		   :keymap gnus-html-image-map
+		   :button-keymap gnus-html-image-map)
+		  (let ((overlay (gnus-make-overlay start end))
+			(spec (list url
+				    (set-marker (make-marker) start)
+				    (set-marker (make-marker) end))))
+		    (gnus-overlay-put overlay 'local-map gnus-html-image-map)
+		    (gnus-overlay-put overlay 'gnus-image spec)
+		    (gnus-put-text-property
+		     start end
+		     'gnus-image spec)))
 	      (let ((file (gnus-html-image-id url))
 		    width height)
 		(when (string-match "height=\"?\\([0-9]+\\)" parameters)
@@ -184,6 +205,7 @@
 	  (let ((overlay (gnus-make-overlay start end)))
 	    (gnus-overlay-put overlay 'evaporate t)
 	    (gnus-overlay-put overlay 'gnus-button-url url)
+	    (gnus-put-text-property start end 'gnus-string url)
 	    (when gnus-article-mouse-face
 	      (gnus-overlay-put overlay 'mouse-face gnus-article-mouse-face)))))
        ;; The upper-case IMG_ALT is apparently just an artifact that
@@ -200,7 +222,14 @@
     (while (re-search-forward "</pre_int>" nil t)
       (replace-match "" t t))
     (when images
-      (gnus-html-schedule-image-fetching (current-buffer) (nreverse images)))))
+      (gnus-html-schedule-image-fetching (current-buffer) (nreverse images)))
+    (mm-url-decode-entities)))
+
+(defun gnus-html-insert-image ()
+  "Fetch and insert the image under point."
+  (interactive)
+  (gnus-html-schedule-image-fetching
+   (current-buffer) (list (get-text-property (point) 'gnus-image))))
 
 (defun gnus-html-schedule-image-fetching (buffer images)
   (gnus-message 8 "gnus-html-schedule-image-fetching: buffer %s, images %s"
@@ -267,8 +296,11 @@
 			   (= (car size) 30)
 			   (= (cdr size) 30))))
 	    (progn
-	      (gnus-put-image (gnus-html-rescale-image image file size)
-			      (gnus-string-or string "*"))
+	      (setq image (gnus-html-rescale-image image file size))
+	      (gnus-put-image image
+			      (gnus-string-or string "*")
+			      'external)
+	      (gnus-add-image 'external image)
 	      t)
 	  (insert string)
 	  (when (fboundp 'find-image)
@@ -330,6 +362,20 @@
                     url blocked-images))
     ret))
 
+(defun gnus-html-show-images ()
+  "Show any images that are in the HTML-rendered article buffer.
+This only works if the article in question is HTML."
+  (interactive)
+  (gnus-with-article-buffer
+    (let ((overlays (overlays-in (point-min) (point-max)))
+	  overlay images)
+      (while (setq overlay (pop overlays))
+	(when (overlay-get overlay 'gnus-image)
+	  (push (overlay-get overlay 'gnus-image) images)))
+      (if (not images)
+	  (message "No images to show")
+	(gnus-html-schedule-image-fetching (current-buffer) images)))))
+
 ;;;###autoload
 (defun gnus-html-prefetch-images (summary)
   (let (blocked-images urls)
--- a/lisp/gnus/gnus-int.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-int.el	Sun Sep 05 22:45:59 2010 +0000
@@ -365,7 +365,7 @@
     (when (stringp gnus-command-method)
       (setq gnus-command-method
 	    (inline (gnus-server-to-method gnus-command-method))))
-	 (funcall (inline (gnus-get-function gnus-command-method 'request-group))
+    (funcall (inline (gnus-get-function gnus-command-method 'request-group))
 	     (gnus-group-real-name group) (nth 1 gnus-command-method)
 	     dont-check)))
 
@@ -544,7 +544,8 @@
 	 (if group (gnus-find-method-for-group group) gnus-command-method))
 	(gnus-inhibit-demon t)
 	(mail-source-plugged gnus-plugged))
-    (when (or gnus-plugged (not (gnus-agent-method-p gnus-command-method)))
+    (when (or gnus-plugged
+	      (not (gnus-agent-method-p gnus-command-method)))
       (setq gnus-internal-registry-spool-current-method gnus-command-method)
       (funcall (gnus-get-function gnus-command-method 'request-scan)
 	       (and group (gnus-group-real-name group))
--- a/lisp/gnus/gnus-start.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-start.el	Sun Sep 05 22:45:59 2010 +0000
@@ -1684,8 +1684,9 @@
 	   alevel))
 	 (methods-cache nil)
 	 (type-cache nil)
-	 scanned-methods info group active method retrieve-groups cmethod
-	 method-type)
+	 (gnus-agent-article-local-times 0)
+	 infos info group active method cmethod
+	 method-type method-group-list)
     (gnus-message 6 "Checking new news...")
 
     (while newsrc
@@ -1704,14 +1705,19 @@
       ;; nil for non-foreign groups that the user has requested not be checked
       ;; t for unchecked foreign groups or bogus groups, or groups that can't
       ;;   be checked, for one reason or other.
-      (when (setq method (gnus-info-method info))
+
+      ;; First go through all the groups, see what select methods they
+      ;; belong to, and then collect them into lists per unique select
+      ;; method.
+      (if (not (setq method (gnus-info-method info)))
+	  (setq method gnus-select-method)
 	(if (setq cmethod (assoc method methods-cache))
 	    (setq method (cdr cmethod))
 	  (setq cmethod (inline (gnus-server-get-method nil method)))
 	  (push (cons method cmethod) methods-cache)
 	  (setq method cmethod)))
-      (when (and method
-		 (not (setq method-type (cdr (assoc method type-cache)))))
+      (setq method-group-list (assoc method type-cache))
+      (unless method-group-list
 	(setq method-type
 	      (cond
 	       ((gnus-secondary-method-p method)
@@ -1720,98 +1726,74 @@
 		'primary)
 	       (t
 		'foreign)))
-	(push (cons method method-type) type-cache))
+	(push (setq method-group-list (list method method-type nil))
+	      type-cache))
+      (setcar (nthcdr 2 method-group-list)
+	      (cons info (nth 2 method-group-list))))
+
+    ;; Sort the methods based so that the primary and secondary
+    ;; methods come first.  This is done for legacy reasons to try to
+    ;; ensure that side-effect behaviour doesn't change from previous
+    ;; Gnus versions.
+    (setq type-cache
+	  (sort (nreverse type-cache)
+		(lambda (c1 c2)
+		  (< (gnus-method-rank (cadr c1) (car c1))
+		     (gnus-method-rank (cadr c2) (car c2))))))
+
+    (while type-cache
+      (setq method (nth 0 (car type-cache))
+	    method-type (nth 1 (car type-cache))
+	    infos (nth 2 (car type-cache)))
+      (pop type-cache)
 
-      (cond ((and method (eq method-type 'foreign))
-	     ;; These groups are foreign.  Check the level.
-	     (if (<= (gnus-info-level info) foreign-level)
-		 (when (setq active (gnus-activate-group group 'scan))
-		   ;; Let the Gnus agent save the active file.
-		   (when (and gnus-agent active (gnus-online method))
-		     (gnus-agent-save-group-info
-		      method (gnus-group-real-name group) active))
-		   (unless (inline (gnus-virtual-group-p group))
-		     (inline (gnus-close-group group)))
-		   (when (fboundp (intern (concat (symbol-name (car method))
-						  "-request-update-info")))
-		     (inline (gnus-request-update-info info method))))
-	       (if (and level
-			;; If `active' is nil that means the group has
-			;; never been read, the group should be marked
-			;; as having never been checked (see below).
-			active
-			(> (gnus-info-level info) level))
-		   ;; Don't check groups of which levels are higher
-		   ;; than the one that a user specified.
-		   (setq active 'ignore))))
-	    ;; These groups are native or secondary.
-	    ((> (gnus-info-level info) alevel)
-	     ;; We don't want these groups.
-	     (setq active 'ignore))
-	    ;; Activate groups.
-	    ((not gnus-read-active-file)
-	     (if (gnus-check-backend-function 'retrieve-groups group)
-		 ;; if server support gnus-retrieve-groups we push
-		 ;; the group onto retrievegroups for later checking
-		 (if (assoc method retrieve-groups)
-		     (setcdr (assoc method retrieve-groups)
-			     (cons group (cdr (assoc method retrieve-groups))))
-		   (push (list method group) retrieve-groups))
-	       ;; hack: `nnmail-get-new-mail' changes the mail-source depending
-	       ;; on the group, so we must perform a scan for every group
-	       ;; if the users has any directory mail sources.
-	       ;; hack: if `nnmail-scan-directory-mail-source-once' is non-nil,
-	       ;; for it scan all spool files even when the groups are
-	       ;; not required.
-	       (if (and
-		    (or nnmail-scan-directory-mail-source-once
-			(null (assq 'directory mail-sources)))
-		    (member method scanned-methods))
-		   (setq active (gnus-activate-group group))
-		 (setq active (gnus-activate-group group 'scan))
-		 (push method scanned-methods))
-	       (when active
-		 (gnus-close-group group)))))
+      (when method
+	;; See if any of the groups from this method require updating.
+	(when (block nil
+		(dolist (info infos)
+		  (when (<= (gnus-info-level info)
+			    (if (eq method-type 'foreign)
+				foreign-level
+			      alevel))
+		    (return t))))
+	  (gnus-read-active-for-groups method infos)
+	  (dolist (info infos)
+	    (inline (gnus-get-unread-articles-in-group
+		     info (gnus-active (gnus-info-group info))))))))
+    (gnus-message 6 "Checking new news...done")))
 
-      ;; Get the number of unread articles in the group.
-      (cond
-       ((eq active 'ignore)
-	;; Don't do anything.
-	)
-       (active
-	(inline (gnus-get-unread-articles-in-group info active t)))
-       (t
-	;; The group couldn't be reached, so we nix out the number of
-	;; unread articles and stuff.
-	(gnus-set-active group nil)
-	(let ((tmp (gnus-group-entry group)))
-	  (when tmp
-	    (setcar tmp t))))))
+(defun gnus-method-rank (type method)
+  (cond
+   ((eq type 'primary)
+    1)
+   ;; Compute the rank of the secondary methods based on where they
+   ;; are in the secondary select list.
+   ((eq type 'secondary)
+    (let ((i 2))
+      (block nil
+	(dolist (smethod gnus-secondary-select-methods)
+	  (when (equal method smethod)
+	    (return i))
+	  (incf i))
+	i)))
+   ;; Just say that all foreign groups have the same rank.
+   (t
+    100)))
 
-    ;; iterate through groups on methods which support gnus-retrieve-groups
-    ;; and fetch a partial active file and use it to find new news.
-    (dolist (rg retrieve-groups)
-      (let ((method (or (car rg) gnus-select-method))
-	    (groups (cdr rg)))
-	(when (gnus-check-server method)
-	  ;; Request that the backend scan its incoming messages.
-	  (when (gnus-check-backend-function 'request-scan (car method))
-	    (gnus-request-scan nil method))
-	  (gnus-read-active-file-2
-	   (mapcar (lambda (group) (gnus-group-real-name group)) groups)
-	   method)
-	  (dolist (group groups)
-	    (cond
-	     ((setq active (gnus-active (gnus-info-group
-					 (setq info (gnus-get-info group)))))
-	      (inline (gnus-get-unread-articles-in-group info active t)))
-	     (t
-	      ;; The group couldn't be reached, so we nix out the number of
-	      ;; unread articles and stuff.
-	      (gnus-set-active group nil)
-	      (setcar (gnus-group-entry group) t)))))))
-
-    (gnus-message 6 "Checking new news...done")))
+(defun gnus-read-active-for-groups (method infos)
+  (with-current-buffer nntp-server-buffer
+    (cond
+     ((gnus-check-backend-function 'retrieve-groups (car method))
+      (gnus-read-active-file-2
+       (mapcar (lambda (info)
+		 (gnus-group-real-name (gnus-info-group info)))
+	       infos)
+       method))
+     ((gnus-check-backend-function 'request-list (car method))
+      (gnus-read-active-file-1 method nil))
+     (t
+      (dolist (info infos)
+	(gnus-activate-group (gnus-info-group info) nil nil method))))))
 
 ;; Create a hash table out of the newsrc alist.  The `car's of the
 ;; alist elements are used as keys.
@@ -1833,14 +1815,18 @@
 	(if (setq rest (member method methods))
 	    (gnus-info-set-method info (car rest))
 	  (push method methods)))
-      (gnus-sethash
-       (car info)
-       ;; Preserve number of unread articles in groups.
-       (cons (and ohashtb (car (gnus-gethash (car info) ohashtb)))
-	     prev)
-       gnus-newsrc-hashtb)
-      (setq prev alist
-	    alist (cdr alist)))
+      ;; Check for duplicates.
+      (if (gnus-gethash (car info) gnus-newsrc-hashtb)
+	  ;; Remove this entry from the alist.
+	  (setcdr prev (cddr prev))
+	(gnus-sethash
+	 (car info)
+	 ;; Preserve number of unread articles in groups.
+	 (cons (and ohashtb (car (gnus-gethash (car info) ohashtb)))
+	       prev)
+	 gnus-newsrc-hashtb)
+	(setq prev alist))
+      (setq alist (cdr alist)))
     ;; Make the same select-methods in `gnus-server-alist' identical
     ;; as well.
     (while methods
@@ -2043,7 +2029,9 @@
     (gnus-message 5 mesg)
     (when (gnus-check-server method)
       ;; Request that the backend scan its incoming messages.
-      (when (gnus-check-backend-function 'request-scan (car method))
+      (when (and gnus-agent
+		 (gnus-online method)
+		 (gnus-check-backend-function 'request-scan (car method)))
 	(gnus-request-scan nil method))
       (cond
        ((and (eq gnus-read-active-file 'some)
@@ -3196,5 +3184,3 @@
 (provide 'gnus-start)
 
 ;;; gnus-start.el ends here
-
-
--- a/lisp/gnus/gnus-sum.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/gnus-sum.el	Sun Sep 05 22:45:59 2010 +0000
@@ -2110,6 +2110,7 @@
   "d" gnus-article-display-face
   "s" gnus-treat-smiley
   "D" gnus-article-remove-images
+  "W" gnus-html-show-images
   "f" gnus-treat-from-picon
   "m" gnus-treat-mail-picon
   "n" gnus-treat-newsgroups-picon)
--- a/lisp/gnus/mail-source.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/mail-source.el	Sun Sep 05 22:45:59 2010 +0000
@@ -34,7 +34,7 @@
   (require 'cl)
   (require 'imap))
 (autoload 'auth-source-user-or-password "auth-source")
-(autoload 'pop3-movemail "pop3")
+(autoload 'pop3-streaming-movemail "pop3")
 (autoload 'pop3-get-message-count "pop3")
 (autoload 'nnheader-cancel-timer "nnheader")
 (require 'mm-util)
@@ -536,7 +536,7 @@
    (t
     value)))
 
-(defun mail-source-fetch (source callback)
+(defun mail-source-fetch (source callback &optional method)
   "Fetch mail from SOURCE and call CALLBACK zero or more times.
 CALLBACK will be called with the name of the file where (some of)
 the mail from SOURCE is put.
@@ -544,6 +544,11 @@
   (mail-source-bind-common source
     (if (or mail-source-plugged plugged)
 	(save-excursion
+	  (nnheader-message 4 "%sReading incoming mail from %s..."
+			    (if method
+				(format "%s: " method)
+			      "")
+			    (car source))
 	  (let ((function (cadr (assq (car source) mail-source-fetcher-alist)))
 		(found 0))
 	    (unless function
@@ -619,6 +624,8 @@
 	0)
     (funcall callback mail-source-crash-box info)))
 
+(defvar mail-source-incoming-last-checked-time nil)
+
 (defun mail-source-delete-crash-box ()
   (when (file-exists-p mail-source-crash-box)
     ;; Delete or move the incoming mail out of the way.
@@ -634,9 +641,16 @@
 	(rename-file mail-source-crash-box incoming t)
 	;; remove old incoming files?
 	(when (natnump mail-source-delete-incoming)
-	  (mail-source-delete-old-incoming
-	   mail-source-delete-incoming
-	   mail-source-delete-old-incoming-confirm))))))
+	  ;; Don't check for old incoming files more than once per day to
+	  ;; save a lot of file accesses.
+	  (when (or (null mail-source-incoming-last-checked-time)
+		    (> (time-to-seconds
+			(time-since mail-source-incoming-last-checked-time))
+		       (* 24 60 60)))
+	    (setq mail-source-incoming-last-checked-time (current-time))
+	    (mail-source-delete-old-incoming
+	     mail-source-delete-incoming
+	     mail-source-delete-old-incoming-confirm)))))))
 
 (defun mail-source-movemail (from to)
   "Move FROM to TO using movemail."
@@ -820,9 +834,11 @@
 		     (if (eq authentication 'apop) 'apop 'pass))
 		    (pop3-stream-type stream))
 		(if (or debug-on-quit debug-on-error)
-		    (save-excursion (pop3-movemail mail-source-crash-box))
+		    (save-excursion (pop3-streaming-movemail
+				     mail-source-crash-box))
 		  (condition-case err
-		      (save-excursion (pop3-movemail mail-source-crash-box))
+		      (save-excursion (pop3-streaming-movemail
+				       mail-source-crash-box))
 		    (error
 		     ;; We nix out the password in case the error
 		     ;; was because of a wrong password being given.
--- a/lisp/gnus/mm-util.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/mm-util.el	Sun Sep 05 22:45:59 2010 +0000
@@ -1429,16 +1429,23 @@
 	;; Reset the umask.
 	(set-default-file-modes umask)))))
 
+(defvar mm-image-load-path-cache nil)
+
 (defun mm-image-load-path (&optional package)
-  (let (dir result)
-    (dolist (path load-path (nreverse result))
-      (when (and path
-		 (file-directory-p
-		  (setq dir (concat (file-name-directory
-				     (directory-file-name path))
-				    "etc/images/" (or package "gnus/")))))
-	(push dir result))
-      (push path result))))
+  (if (and mm-image-load-path-cache
+	   (equal load-path (car mm-image-load-path-cache)))
+      (cdr mm-image-load-path-cache)
+    (let (dir result)
+      (dolist (path load-path)
+	(when (and path
+		   (file-directory-p
+		    (setq dir (concat (file-name-directory
+				       (directory-file-name path))
+				      "etc/images/" (or package "gnus/")))))
+	  (push dir result)))
+      (setq result (nreverse result)
+	    mm-image-load-path-cache (cons load-path result))
+      result)))
 
 ;; Fixme: This doesn't look useful where it's used.
 (if (fboundp 'detect-coding-region)
--- a/lisp/gnus/nnmail.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/nnmail.el	Sun Sep 05 22:45:59 2010 +0000
@@ -1823,8 +1823,6 @@
       ;; The we go through all the existing mail source specification
       ;; and fetch the mail from each.
       (while (setq source (pop fetching-sources))
-	(nnheader-message 4 "%s: Reading incoming mail from %s..."
-			  method (car source))
 	(when (setq new
 		    (mail-source-fetch
 		     source
@@ -1842,8 +1840,9 @@
 	  (incf i)))
       ;; If we did indeed read any incoming spools, we save all info.
       (if (zerop total)
-	  (nnheader-message 4 "%s: Reading incoming mail (no new mail)...done"
-			    method (car source))
+	  (when mail-source-plugged
+	    (nnheader-message 4 "%s: Reading incoming mail (no new mail)...done"
+			      method (car source)))
 	(nnmail-save-active
 	 (nnmail-get-value "%s-group-alist" method)
 	 (nnmail-get-value "%s-active-file" method))
--- a/lisp/gnus/nnmh.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/nnmh.el	Sun Sep 05 22:45:59 2010 +0000
@@ -207,40 +207,48 @@
 (defun nnmh-request-list-1 (dir)
   (setq dir (expand-file-name dir))
   ;; Recurse down all directories.
-  (let ((dirs (and (file-readable-p dir)
-		   (nnheader-directory-files dir t nil t)))
-	rdir)
+  (let ((files (nnheader-directory-files dir t nil t))
+	(max 0)
+	min rdir num subdirectoriesp file)
     ;; Recurse down directories.
-    (while (setq rdir (pop dirs))
-      (when (and (file-directory-p rdir)
-		 (file-readable-p rdir)
-		 (not (equal (file-truename rdir)
-			     (file-truename dir))))
-	(nnmh-request-list-1 rdir))))
-  ;; For each directory, generate an active file line.
-  (unless (string= (expand-file-name nnmh-toplev) dir)
-    (let ((files (mapcar 'string-to-number
-			 (directory-files dir nil "^[0-9]+$" t))))
-      (when files
-	(with-current-buffer nntp-server-buffer
-	  (goto-char (point-max))
-	  (insert
-	   (format
-	    "%s %.0f %.0f y\n"
-	    (progn
-	      (string-match
-	       (regexp-quote
-		(file-truename (file-name-as-directory
-				(expand-file-name nnmh-toplev))))
-	       dir)
-	      (mm-string-to-multibyte   ;Why?  Isn't it multibyte already?
-	       (mm-encode-coding-string
-		(nnheader-replace-chars-in-string
-		 (substring dir (match-end 0))
-		 ?/ ?.)
-		nnmail-pathname-coding-system)))
-	    (apply 'max files)
-	    (apply 'min files)))))))
+    (setq subdirectoriesp (> (nth 1 (file-attributes dir)) 2))
+    (dolist (rdir files)
+      (if (or (not subdirectoriesp)
+	      (file-regular-p rdir))
+	  (progn
+	    (setq file (file-name-nondirectory rdir))
+	    (when (string-match "^[0-9]+$" file)
+	      (setq num (string-to-number file))
+	      (setq max (max max num))
+	      (when (or (null min)
+			(< num min))
+		(setq min num))))
+	;; This is a directory.
+	(when (and (file-readable-p rdir)
+		   (not (equal (file-truename rdir)
+			       (file-truename dir))))
+	  (nnmh-request-list-1 rdir))))
+    ;; For each directory, generate an active file line.
+    (unless (string= (expand-file-name nnmh-toplev) dir)
+      (with-current-buffer nntp-server-buffer
+	(goto-char (point-max))
+	(insert
+	 (format
+	  "%s %.0f %.0f y\n"
+	  (progn
+	    (string-match
+	     (regexp-quote
+	      (file-truename (file-name-as-directory
+			      (expand-file-name nnmh-toplev))))
+	     dir)
+	    (mm-string-to-multibyte ;Why?  Isn't it multibyte already?
+	     (mm-encode-coding-string
+	      (nnheader-replace-chars-in-string
+	       (substring dir (match-end 0))
+	       ?/ ?.)
+	      nnmail-pathname-coding-system)))
+	  (or max 0)
+	  (or min 1))))))
   t)
 
 (deffoo nnmh-request-newgroups (date &optional server)
--- a/lisp/gnus/nnml.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/nnml.el	Sun Sep 05 22:45:59 2010 +0000
@@ -283,7 +283,7 @@
 (deffoo nnml-request-scan (&optional group server)
   (setq nnml-article-file-alist nil)
   (nnml-possibly-change-directory group server)
-  (nnmail-get-new-mail 'nnml 'nnml-save-nov nnml-directory group))
+  (nnmail-get-new-mail 'nnml 'nnml-save-incremental-nov nnml-directory group))
 
 (deffoo nnml-close-group (group &optional server)
   (setq nnml-article-file-alist nil)
@@ -438,7 +438,7 @@
 	 (setq result (car (nnml-save-mail
 			    (list (cons group (nnml-active-number group
 								  server)))
-			    server)))
+			    server t)))
 	 (progn
 	   (nnmail-save-active nnml-group-alist nnml-active-file)
 	   (and last (nnml-save-nov))))
@@ -449,7 +449,7 @@
 				      (nnml-active-number group ,server)))))
 		(yes-or-no-p "Moved to `junk' group; delete article? "))
 	   (setq result 'junk)
-	 (setq result (car (nnml-save-mail result server))))
+	 (setq result (car (nnml-save-mail result server t))))
        (when last
 	 (nnmail-save-active nnml-group-alist nnml-active-file)
 	 (when nnmail-cache-accepted-message-ids
@@ -691,7 +691,7 @@
       (make-directory (directory-file-name dir) t)
       (nnheader-message 5 "Creating mail directory %s" dir))))
 
-(defun nnml-save-mail (group-art &optional server)
+(defun nnml-save-mail (group-art &optional server full-nov)
   "Save a mail into the groups GROUP-ART in the nnml server SERVER.
 GROUP-ART is a list that each element is a cons of a group name and an
 article number.  This function is called narrowed to an article."
@@ -742,11 +742,14 @@
     ;; header.
     (setq headers (nnml-parse-head chars))
     ;; Output the nov line to all nov databases that should have it.
-    (if nnmail-group-names-not-encoded-p
+    (let ((func (if full-nov
+		    'nnml-add-nov
+		  'nnml-add-incremental-nov)))
+      (if nnmail-group-names-not-encoded-p
+	  (dolist (ga group-art)
+	    (funcall func (pop dec) (cdr ga) headers))
 	(dolist (ga group-art)
-	  (nnml-add-nov (pop dec) (cdr ga) headers))
-      (dolist (ga group-art)
-	(nnml-add-nov (car ga) (cdr ga) headers))))
+	  (funcall func (car ga) (cdr ga) headers)))))
   group-art)
 
 (defun nnml-active-number (group &optional server)
@@ -778,6 +781,37 @@
       (setcdr active (1+ (cdr active))))
     (cdr active)))
 
+(defvar nnml-incremental-nov-buffer-alist nil)
+
+(defun nnml-save-incremental-nov ()
+  (message "nnml saving incremental nov...")
+  (save-excursion
+    (while nnml-incremental-nov-buffer-alist
+      (when (buffer-name (cdar nnml-incremental-nov-buffer-alist))
+	(set-buffer (cdar nnml-incremental-nov-buffer-alist))
+	(when (buffer-modified-p)
+	  (nnmail-write-region (point-min) (point-max)
+			       nnml-nov-buffer-file-name t 'nomesg))
+	(set-buffer-modified-p nil)
+	(kill-buffer (current-buffer)))
+      (setq nnml-incremental-nov-buffer-alist
+	    (cdr nnml-incremental-nov-buffer-alist))))
+  (message "nnml saving incremental nov...done"))
+
+(defun nnml-open-incremental-nov (group)
+  (or (cdr (assoc group nnml-incremental-nov-buffer-alist))
+      (let ((buffer (nnml-get-nov-buffer group t)))
+	(push (cons group buffer) nnml-incremental-nov-buffer-alist)
+	buffer)))
+
+(defun nnml-add-incremental-nov (group article headers)
+  "Add a nov line for the GROUP nov headers, incrementally."
+  (save-excursion
+    (set-buffer (nnml-open-incremental-nov group))
+    (goto-char (point-max))
+    (mail-header-set-number headers article)
+    (nnheader-insert-nov headers)))
+
 (defun nnml-add-nov (group article headers)
   "Add a nov line for the GROUP base."
   (save-excursion
@@ -804,16 +838,21 @@
 	(mail-header-set-number headers number)
 	headers))))
 
-(defun nnml-get-nov-buffer (group)
+(defun nnml-get-nov-buffer (group &optional incrementalp)
   (let* ((decoded (nnml-decoded-group-name group))
-	 (buffer (get-buffer-create (format " *nnml overview %s*" decoded)))
+	 (buffer (get-buffer-create (format " *nnml %soverview %s*"
+					    (if incrementalp
+						"incremental "
+					      "")
+					    decoded)))
 	 (file-name-coding-system nnmail-pathname-coding-system))
     (save-excursion
       (set-buffer buffer)
       (set (make-local-variable 'nnml-nov-buffer-file-name)
 	   (nnmail-group-pathname decoded nnml-directory nnml-nov-file-name))
       (erase-buffer)
-      (when (file-exists-p nnml-nov-buffer-file-name)
+      (when (and (not incrementalp)
+		 (file-exists-p nnml-nov-buffer-file-name))
 	(nnheader-insert-file-contents nnml-nov-buffer-file-name)))
     buffer))
 
@@ -824,6 +863,7 @@
 	buffer)))
 
 (defun nnml-save-nov ()
+  (message "nnml saving nov...")
   (save-excursion
     (while nnml-nov-buffer-alist
       (when (buffer-name (cdar nnml-nov-buffer-alist))
@@ -833,7 +873,8 @@
 			       nnml-nov-buffer-file-name nil 'nomesg))
 	(set-buffer-modified-p nil)
 	(kill-buffer (current-buffer)))
-      (setq nnml-nov-buffer-alist (cdr nnml-nov-buffer-alist)))))
+      (setq nnml-nov-buffer-alist (cdr nnml-nov-buffer-alist))))
+  (message "nnml saving nov...done"))
 
 ;;;###autoload
 (defun nnml-generate-nov-databases (&optional server)
--- a/lisp/gnus/nnvirtual.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/nnvirtual.el	Sun Sep 05 22:45:59 2010 +0000
@@ -300,10 +300,6 @@
   t)
 
 
-(deffoo nnvirtual-request-list (&optional server)
-  (nnheader-report 'nnvirtual "LIST is not implemented."))
-
-
 (deffoo nnvirtual-request-newgroups (date &optional server)
   (nnheader-report 'nnvirtual "NEWGROUPS is not supported."))
 
--- a/lisp/gnus/pop3.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/gnus/pop3.el	Sun Sep 05 22:45:59 2010 +0000
@@ -98,12 +98,6 @@
   :type 'boolean
   :group 'pop3)
 
-(defcustom pop3-display-message-size-flag t
-  "*If non-nil, display the size of the message that is being fetched."
-  :version "22.1" ;; Oort Gnus
-  :type 'boolean
-  :group 'pop3)
-
 (defvar pop3-timestamp nil
   "Timestamp returned when initially connected to the POP server.
 Used for APOP authentication.")
@@ -134,15 +128,90 @@
 		       (truncate pop3-read-timeout))
 		    1000))))))
 
-(defun pop3-movemail (&optional crashbox)
-  "Transfer contents of a maildrop to the specified CRASHBOX."
-  (or crashbox (setq crashbox (expand-file-name "~/.crashbox")))
+(defun pop3-streaming-movemail (file)
+  "Transfer contents of a maildrop to the specified FILE.
+Use streaming commands."
   (let* ((process (pop3-open-server pop3-mailhost pop3-port))
-	 (crashbuf (get-buffer-create " *pop3-retr*"))
-	 (n 1)
-	 message-count
-	 message-sizes
-	 (pop3-password pop3-password))
+	 message-count message-total-size)
+    (pop3-logon process)
+    (with-current-buffer (process-buffer process)
+      (let ((size (pop3-stat process)))
+	(setq message-count (car size)
+	      message-total-size (cadr size)))
+      (when (plusp message-count)
+	(pop3-send-streaming-command
+	 process "RETR" message-count message-total-size)
+	(pop3-write-to-file file)
+	(unless pop3-leave-mail-on-server
+	  (pop3-send-streaming-command
+	   process "DELE" message-count nil))))
+    (pop3-quit process)))
+
+(defun pop3-send-streaming-command (process command count total-size)
+  (erase-buffer)
+  (let ((i 1))
+    (while (>= count i)
+      (process-send-string process (format "%s %d\r\n" command i))
+      ;; Only do 100 messages at a time to avoid pipe stalls.
+      (when (zerop (% i 100))
+	(pop3-wait-for-messages process i total-size))
+      (incf i)))
+  (pop3-wait-for-messages process count total-size))
+
+(defun pop3-wait-for-messages (process count total-size)
+  (while (< (pop3-number-of-responses total-size) count)
+    (when total-size
+      (message "pop3 retrieved %dKB (%d%%)"
+	       (truncate (/ (buffer-size) 1000))
+	       (truncate (* (/ (* (buffer-size) 1.0)
+			       total-size) 100))))
+    (nnheader-accept-process-output process)))
+
+(defun pop3-write-to-file (file)
+  (let ((pop-buffer (current-buffer))
+	(start (point-min))
+	beg end
+	temp-buffer)
+    (with-temp-buffer
+      (setq temp-buffer (current-buffer))
+      (with-current-buffer pop-buffer
+	(goto-char (point-min))
+	(while (re-search-forward "^\\+OK" nil t)
+	  (forward-line 1)
+	  (setq beg (point))
+	  (when (re-search-forward "^\\.\r?\n" nil t)
+	    (setq start (point))
+	    (forward-line -1)
+	    (setq end (point)))
+	  (with-current-buffer temp-buffer
+	    (goto-char (point-max))
+	    (let ((hstart (point)))
+	      (insert-buffer-substring pop-buffer beg end)
+	      (pop3-clean-region hstart (point))
+	      (goto-char (point-max))
+	      (pop3-munge-message-separator hstart (point))
+	      (goto-char (point-max))))))
+      (let ((coding-system-for-write 'binary))
+	(goto-char (point-min))
+	;; Check whether something inserted a newline at the start and
+	;; delete it.
+	(when (eolp)
+	  (delete-char 1))
+	(write-region (point-min) (point-max) file nil 'nomesg)))))
+
+(defun pop3-number-of-responses (endp)
+  (let ((responses 0))
+    (save-excursion
+      (goto-char (point-min))
+      (while (or (and (re-search-forward "^\\+OK " nil t)
+		      (or (not endp)
+			  (re-search-forward "^\\.\r?\n" nil t)))
+		 (re-search-forward "^-ERR " nil t))
+	(incf responses)))
+    responses))
+
+(defun pop3-logon (process)
+  (let ((pop3-password pop3-password))
     ;; for debugging only
     (if pop3-debug (switch-to-buffer (process-buffer process)))
     ;; query for password
@@ -154,30 +223,33 @@
 	  ((equal 'pass pop3-authentication-scheme)
 	   (pop3-user process pop3-maildrop)
 	   (pop3-pass process))
-	  (t (error "Invalid POP3 authentication scheme")))
+	  (t (error "Invalid POP3 authentication scheme")))))
+
+(defun pop3-movemail (&optional crashbox)
+  "Transfer contents of a maildrop to the specified CRASHBOX."
+  (or crashbox (setq crashbox (expand-file-name "~/.crashbox")))
+  (let* ((process (pop3-open-server pop3-mailhost pop3-port))
+	 (crashbuf (get-buffer-create " *pop3-retr*"))
+	 (n 1)
+	 message-count
+	 message-sizes)
+    (pop3-logon process)
     (setq message-count (car (pop3-stat process)))
-    (when (and pop3-display-message-size-flag
-	       (> message-count 0))
+    (when (> message-count 0)
       (setq message-sizes (pop3-list process)))
     (unwind-protect
 	(while (<= n message-count)
-	  (if pop3-display-message-size-flag
-	      (message "Retrieving message %d of %d from %s... (%.1fk)"
-		       n message-count pop3-mailhost
-		       (/ (cdr (assoc n message-sizes))
-			  1024.0))
-	    (message "Retrieving message %d of %d from %s..."
-		     n message-count pop3-mailhost))
+	  (message "Retrieving message %d of %d from %s... (%.1fk)"
+		   n message-count pop3-mailhost
+		   (/ (cdr (assoc n message-sizes))
+		      1024.0))
 	  (pop3-retr process n crashbuf)
 	  (save-excursion
 	    (set-buffer crashbuf)
 	    (let ((coding-system-for-write 'binary))
 	      (write-region (point-min) (point-max) crashbox t 'nomesg))
 	    (set-buffer (process-buffer process))
-	    (while (> (buffer-size) 5000)
-	      (goto-char (point-min))
-	      (forward-line 50)
-	      (delete-region (point-min) (point))))
+	    (erase-buffer))
           (unless pop3-leave-mail-on-server
             (pop3-dele process n))
 	  (setq n (+ 1 n))
@@ -229,6 +301,13 @@
 		 (const :tag "SSL/TLS" ssl)
 		 (const starttls)))
 
+(eval-and-compile
+  (if (fboundp 'set-process-query-on-exit-flag)
+      (defalias 'pop3-set-process-query-on-exit-flag
+	'set-process-query-on-exit-flag)
+    (defalias 'pop3-set-process-query-on-exit-flag
+      'process-kill-without-query)))
+
 (defun pop3-open-server (mailhost port)
   "Open TCP connection to MAILHOST on PORT.
 Returns the process associated with the connection."
@@ -289,16 +368,11 @@
 	(setq pop3-timestamp
 	      (substring response (or (string-match "<" response) 0)
 			 (+ 1 (or (string-match ">" response) -1)))))
+      (pop3-set-process-query-on-exit-flag process nil)
       process)))
 
 ;; Support functions
 
-(defun pop3-process-filter (process output)
-  (save-excursion
-    (set-buffer (process-buffer process))
-    (goto-char (point-max))
-    (insert output)))
-
 (defun pop3-send-command (process command)
   (set-buffer (process-buffer process))
   (goto-char (point-max))
@@ -415,10 +489,7 @@
 		nil
 	      (goto-char (point-max))
 	      (insert "\n"))
-	    (narrow-to-region (point) (point-max))
-	    (let ((size (- (point-max) (point-min))))
-	      (goto-char (point-min))
-	      (widen)
+	    (let ((size (- (point-max) (point))))
 	      (forward-line -1)
 	      (insert (format "Content-Length: %s\n" size)))
 	    )))))
Binary file lisp/international/uni-bidi.el has changed
Binary file lisp/international/uni-category.el has changed
Binary file lisp/international/uni-combining.el has changed
Binary file lisp/international/uni-decimal.el has changed
Binary file lisp/international/uni-mirrored.el has changed
Binary file lisp/international/uni-name.el has changed
--- a/lisp/progmodes/compile.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/progmodes/compile.el	Sun Sep 05 22:45:59 2010 +0000
@@ -227,10 +227,6 @@
      "^[-[:alnum:]_/ ]+: \\(?:\\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*: \\)?\
 \\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2))
 
-    (ruby
-     "^[\t ]*\\(?:from \\)?\
-\\([^\(\n][^[:space:]\n]*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?.*$" 1 2)
-
     (java
      "^\\(?:[ \t]+at \\|==[0-9]+== +\\(?:at\\|b\\(y\\)\\)\\).+(\\([^()\n]+\\):\\([0-9]+\\))$" 2 3 nil (1))
 
@@ -241,6 +237,10 @@
      nil 1 nil 2 0
      (2 (compilation-face '(3))))
 
+    (gcc-include
+     "^\\(?:In file included \\|                 \\|\t\\)from \
+\\(.+\\):\\([0-9]+\\)\\(?:\\(:\\)\\|\\(,\\|$\\)\\)?" 1 2 nil (3 . 4))
+
     (gnu
      ;; The first line matches the program name for
 
@@ -264,7 +264,7 @@
      ;; can be composed of any non-newline char, but it also rules out some
      ;; valid but unlikely cases, such as a trailing space or a space
      ;; followed by a -.
-     "^\\(?:[[:alpha:]][-[:alnum:].]+: ?\\)?\
+     "^\\(?:[[:alpha:]][-[:alnum:].]+: ?\\|[ \t]+\\(?:in \\|from \\)\\)?\
 \\([0-9]*[^0-9\n]\\(?:[^\n ]\\| [^-/\n]\\)*?\\): ?\
 \\([0-9]+\\)\\(?:\\([.:]\\)\\([0-9]+\\)\\)?\
 \\(?:-\\([0-9]+\\)?\\(?:\\.\\([0-9]+\\)\\)?\\)?:\
@@ -273,12 +273,6 @@
 \[0-9]?\\(?:[^0-9\n]\\|$\\)\\|[0-9][0-9][0-9]\\)"
      1 (2 . 5) (4 . 6) (7 . 8))
 
-    ;; The `gnu' style above can incorrectly match gcc's "In file
-    ;; included from" message, so we process that first. -- cyd
-    (gcc-include
-     "^\\(?:In file included\\|                \\) from \
-\\(.+\\):\\([0-9]+\\)\\(?:\\(:\\)\\|\\(,\\)\\)?" 1 2 nil (3 . 4))
-
     (lcc
      "^\\(?:E\\|\\(W\\)\\), \\([^(\n]+\\)(\\([0-9]+\\),[ \t]*\\([0-9]+\\)"
      2 3 4 (1))
--- a/lisp/progmodes/octave-mod.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/progmodes/octave-mod.el	Sun Sep 05 22:45:59 2010 +0000
@@ -193,10 +193,19 @@
        ((eq (nth 3 state) ?\')
         ;; A '..' string.
         (save-excursion
-          (when (and (or (looking-at "\\('\\)")
-                         (re-search-forward "[^\\]\\(?:\\\\\\\\\\)*\\('\\)"
-                                            nil t))
-                     (not (eobp)))
+          (when (re-search-forward "\\(?:\\=\\|[^']\\)\\(?:''\\)*\\('\\)[^']"
+                                   nil t)
+            (goto-char (1- (point)))
+            ;; Remove any syntax-table property we may have applied to
+            ;; some of the (doubled) single quotes within the string.
+            ;; Since these are the only chars on which we place properties,
+            ;; we take a shortcut and just remove all properties.
+            (remove-text-properties (1+ (nth 8 state)) (match-beginning 1)
+                                    '(syntax-table nil))
+            (when (eq (char-before (match-beginning 1)) ?\\)
+              ;; Backslash cannot escape a single quote.
+              (put-text-property (1- (match-beginning 1)) (match-beginning 1)
+                                 'syntax-table (string-to-syntax ".")))
             (put-text-property (match-beginning 1) (match-end 1)
                                'syntax-table (string-to-syntax "\"'"))))))
 
@@ -342,29 +351,6 @@
   :type 'integer
   :group 'octave)
 
-(defvar octave-block-else-regexp
-  (concat "\\<\\("
-	  (mapconcat 'identity octave-else-keywords "\\|")
-	  "\\)\\>"))
-(defvar octave-block-end-regexp
-  (concat "\\<\\("
-	  (mapconcat 'identity octave-end-keywords "\\|")
-	  "\\)\\>"))
-(defvar octave-block-else-or-end-regexp
-  (concat octave-block-else-regexp "\\|" octave-block-end-regexp))
-(defvar octave-block-match-alist
-  '(("do" . ("until"))
-    ("for" . ("end" "endfor"))
-    ("function" . ("end" "endfunction"))
-    ("if" . ("else" "elseif" "end" "endif"))
-    ("switch" . ("case" "otherwise" "end" "endswitch"))
-    ("try" . ("catch" "end" "end_try_catch"))
-    ("unwind_protect" . ("unwind_protect_cleanup" "end" "end_unwind_protect"))
-    ("while" . ("end" "endwhile")))
-  "Alist with Octave's matching block keywords.
-Has Octave's begin keywords as keys and a list of the matching else or
-end keywords as associated values.")
-
 (defvar octave-block-comment-start
   (concat (make-string 2 octave-comment-char) " ")
   "String to insert to start a new Octave comment on an empty line.")
@@ -435,43 +421,49 @@
     ;; could be convenient to treat it as one.
     (assoc "...")))
 
+(defconst octave-smie-bnf-table
+  '((atom)
+    ;; We can't distinguish the first element in a sequence with
+    ;; precedence grammars, so we can't distinguish the condition
+    ;; if the `if' from the subsequent body, for example.
+    ;; This has to be done later in the indentation rules.
+    (exp (exp "\n" exp)
+         ;; We need to mention at least one of the operators in this part
+         ;; of the grammar: if the BNF and the operator table have
+         ;; no overlap, SMIE can't know how they relate.
+         (exp ";" exp)
+         ("try" exp "catch" exp "end_try_catch")
+         ("try" exp "catch" exp "end")
+         ("unwind_protect" exp
+          "unwind_protect_cleanup" exp "end_unwind_protect")
+         ("unwind_protect" exp "unwind_protect_cleanup" exp "end")
+         ("for" exp "endfor")
+         ("for" exp "end")
+         ("do" exp "until" atom)
+         ("while" exp "endwhile")
+         ("while" exp "end")
+         ("if" exp "endif")
+         ("if" exp "else" exp "endif")
+         ("if" exp "elseif" exp "else" exp "endif")
+         ("if" exp "elseif" exp "elseif" exp "else" exp "endif")
+         ("if" exp "elseif" exp "elseif" exp "else" exp "end")
+         ("switch" exp "case" exp "endswitch")
+         ("switch" exp "case" exp "otherwise" exp "endswitch")
+         ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch")
+         ("switch" exp "case" exp "case" exp "otherwise" exp "end")
+         ("function" exp "endfunction")
+         ("function" exp "end"))
+    ;; (fundesc (atom "=" atom))
+    ))
+
+(defconst octave-smie-closer-alist
+  (smie-bnf-closer-alist octave-smie-bnf-table))
+
 (defconst octave-smie-op-levels
   (smie-prec2-levels
    (smie-merge-prec2s
     (smie-bnf-precedence-table
-     '((atom)
-       ;; We can't distinguish the first element in a sequence with
-       ;; precedence grammars, so we can't distinguish the condition
-       ;; if the `if' from the subsequent body, for example.
-       ;; This has to be done later in the indentation rules.
-       (exp (exp "\n" exp)
-            ;; We need to mention at least one of the operators in this part
-            ;; of the grammar: if the BNF and the operator table have
-            ;; no overlap, SMIE can't know how they relate.
-            (exp ";" exp)
-            ("try" exp "catch" exp "end_try_catch")
-            ("try" exp "catch" exp "end")
-            ("unwind_protect" exp
-             "unwind_protect_cleanup" exp "end_unwind_protect")
-            ("unwind_protect" exp "unwind_protect_cleanup" exp "end")
-            ("for" exp "endfor")
-            ("for" exp "end")
-            ("do" exp "until" atom)
-            ("while" exp "endwhile")
-            ("while" exp "end")
-            ("if" exp "endif")
-            ("if" exp "else" exp "endif")
-            ("if" exp "elseif" exp "else" exp "endif")
-            ("if" exp "elseif" exp "elseif" exp "else" exp "endif")
-            ("if" exp "elseif" exp "elseif" exp "else" exp "end")
-            ("switch" exp "case" exp "endswitch")
-            ("switch" exp "case" exp "otherwise" exp "endswitch")
-            ("switch" exp "case" exp "case" exp "otherwise" exp "endswitch")
-            ("switch" exp "case" exp "case" exp "otherwise" exp "end")
-            ("function" exp "endfunction")
-            ("function" exp "end"))
-       ;; (fundesc (atom "=" atom))
-       )
+     octave-smie-bnf-table
      '((assoc "\n" ";")))
 
     (smie-precs-precedence-table
@@ -646,9 +638,28 @@
        'octave-smie-forward-token)
   (set (make-local-variable 'forward-sexp-function)
        'smie-forward-sexp-command)
-  (set (make-local-variable 'smie-closer-alist)
-       (mapcar (lambda (elem) (cons (car elem) (car (last elem))))
-               octave-block-match-alist))
+  (set (make-local-variable 'smie-closer-alist) octave-smie-closer-alist)
+  ;; Only needed for interactive calls to blink-matching-open.
+  (set (make-local-variable 'blink-matching-check-function)
+       #'smie-blink-matching-check)
+
+  (when octave-blink-matching-block
+    (add-hook 'post-self-insert-hook #'smie-blink-matching-open 'append 'local)
+    (set (make-local-variable 'smie-blink-matching-triggers)
+         (append smie-blink-matching-triggers '(\;)
+                 ;; Rather than wait for SPC or ; to blink, try to blink as
+                 ;; soon as we type the last char of a block ender.
+                 ;; But strip ?d from this list so that we don't blink twice
+                 ;; when the user writes "endif" (once at "end" and another
+                 ;; time at "endif").
+                 (delq ?d (delete-dups
+                           (mapcar (lambda (kw)
+                                     (aref (cdr kw) (1- (length (cdr kw)))))
+                                   smie-closer-alist))))))
+
+  ;; FIXME: maybe we should use (cons ?\; electric-indent-chars)
+  ;; since only ; is really octave-specific.
+  (set (make-local-variable 'electric-indent-chars) '(?\; ?\s ?\n))
 
   (set (make-local-variable 'comment-start) octave-comment-start)
   (set (make-local-variable 'comment-end) "")
@@ -846,54 +857,6 @@
     (backward-up-list 1))
   (mark-sexp))
 
-(defun octave-blink-matching-block-open ()
-  "Blink the matching Octave begin block keyword.
-If point is right after an Octave else or end type block keyword, move
-cursor momentarily to the corresponding begin keyword.
-Signal an error if the keywords are incompatible."
-  (interactive)
-  (let (bb-keyword bb-arg eb-keyword pos eol)
-    (if (and (octave-not-in-string-or-comment-p)
-	     (looking-at "\\>")
-	     (save-excursion
-	       (skip-syntax-backward "w")
-	       (octave-looking-at-kw octave-block-else-or-end-regexp)))
-	(save-excursion
-	  (cond
-	   ((match-end 1)
-	    (setq eb-keyword
-		  (buffer-substring-no-properties
-		   (match-beginning 1) (match-end 1)))
-	    (backward-up-list 1))
-	   ((match-end 2)
-	    (setq eb-keyword
-		  (buffer-substring-no-properties
-		   (match-beginning 2) (match-end 2)))
-	    (backward-sexp 1)))
-	  (setq pos (match-end 0)
-		bb-keyword
-		(buffer-substring-no-properties
-		 (match-beginning 0) pos)
-		pos (+ pos 1)
-		eol (line-end-position)
-		bb-arg
-		(save-excursion
-		  (save-restriction
-		    (goto-char pos)
-		    (while (and (skip-syntax-forward "^<" eol)
-				(octave-in-string-p)
-				(not (forward-char 1))))
-		    (skip-syntax-backward " ")
-		    (buffer-substring-no-properties pos (point)))))
-	  (if (member eb-keyword
-		      (cdr (assoc bb-keyword octave-block-match-alist)))
-	      (progn
-		(message "Matches `%s %s'" bb-keyword bb-arg)
-		(if (pos-visible-in-window-p)
-		    (sit-for blink-matching-delay)))
-	    (error "Block keywords `%s' and `%s' do not match"
-		   bb-keyword eb-keyword))))))
-
 (defun octave-beginning-of-defun (&optional arg)
   "Move backward to the beginning of an Octave function.
 With positive ARG, do it that many times.  Negative argument -N means
@@ -1082,9 +1045,6 @@
 If Abbrev mode is on, expand abbrevs first."
   ;; FIXME: None of this is Octave-specific.
   (interactive)
-  (if abbrev-mode (expand-abbrev))
-  (if octave-blink-matching-block
-      (octave-blink-matching-block-open))
   (reindent-then-newline-and-indent))
 
 (defun octave-electric-semi ()
@@ -1093,14 +1053,12 @@
 Reindent the line if `octave-auto-indent' is non-nil.
 Insert a newline if `octave-auto-newline' is non-nil."
   (interactive)
+  (setq last-command-event ?\;)
   (if (not (octave-not-in-string-or-comment-p))
-      (insert ";")
-    (if abbrev-mode (expand-abbrev))
-    (if octave-blink-matching-block
-	(octave-blink-matching-block-open))
+      (self-insert-command 1)
     (if octave-auto-indent
 	(indent-according-to-mode))
-    (insert ";")
+    (self-insert-command 1)
     (if octave-auto-newline
 	(newline-and-indent))))
 
@@ -1115,9 +1073,6 @@
       (progn
 	(indent-according-to-mode)
 	(self-insert-command 1))
-    (if abbrev-mode (expand-abbrev))
-    (if octave-blink-matching-block
-	(octave-blink-matching-block-open))
     (if (and octave-auto-indent
 	     (save-excursion
 	       (skip-syntax-backward " ")
--- a/lisp/simple.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/simple.el	Sun Sep 05 22:45:59 2010 +0000
@@ -457,38 +457,43 @@
 than the value of `fill-column' and ARG is nil."
   (interactive "*P")
   (barf-if-buffer-read-only)
-  (let ((was-page-start (and (bolp)
-			     (looking-at page-delimiter)))
-	(beforepos (point)))
-    ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
-    ;; Set last-command-event to tell self-insert what to insert.
-    (let ((last-command-event ?\n)
-	  ;; Don't auto-fill if we have a numeric argument.
-	  (auto-fill-function (if arg nil auto-fill-function))
-          (post-self-insert-hook post-self-insert-hook))
-      ;; Do the rest in post-self-insert-hook, because we want to do it
-      ;; *before* other functions on that hook.
-      (add-hook 'post-self-insert-hook
-                (lambda ()
-                  ;; Mark the newline(s) `hard'.
-                  (if use-hard-newlines
-                      (set-hard-newline-properties
-                       (- (point) (prefix-numeric-value arg)) (point)))
-                  ;; If the newline leaves the previous line blank, and we
-                  ;; have a left margin, delete that from the blank line.
-                  (save-excursion
-                    (goto-char beforepos)
-                    (beginning-of-line)
-                    (and (looking-at "[ \t]$")
-                         (> (current-left-margin) 0)
-                         (delete-region (point)
-                                        (line-end-position))))
-                  ;; Indent the line after the newline, except in one case:
-                  ;; when we added the newline at the beginning of a line which
-                  ;; starts a page.
-                  (or was-page-start
-                      (move-to-left-margin nil t))))
-      (self-insert-command (prefix-numeric-value arg))))
+  ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
+  ;; Set last-command-event to tell self-insert what to insert.
+  (let* ((was-page-start (and (bolp) (looking-at page-delimiter)))
+         (beforepos (point))
+         (last-command-event ?\n)
+         ;; Don't auto-fill if we have a numeric argument.
+         (auto-fill-function (if arg nil auto-fill-function))
+         (postproc
+          ;; Do the rest in post-self-insert-hook, because we want to do it
+          ;; *before* other functions on that hook.
+          (lambda ()
+            ;; Mark the newline(s) `hard'.
+            (if use-hard-newlines
+                (set-hard-newline-properties
+                 (- (point) (prefix-numeric-value arg)) (point)))
+            ;; If the newline leaves the previous line blank, and we
+            ;; have a left margin, delete that from the blank line.
+            (save-excursion
+              (goto-char beforepos)
+              (beginning-of-line)
+              (and (looking-at "[ \t]$")
+                   (> (current-left-margin) 0)
+                   (delete-region (point)
+                                  (line-end-position))))
+            ;; Indent the line after the newline, except in one case:
+            ;; when we added the newline at the beginning of a line which
+            ;; starts a page.
+            (or was-page-start
+                (move-to-left-margin nil t)))))
+    (unwind-protect
+        (progn
+          (add-hook 'post-self-insert-hook postproc)
+          (self-insert-command (prefix-numeric-value arg)))
+      ;; We first used let-binding to protect the hook, but that was naive
+      ;; since add-hook affects the symbol-default value of the variable,
+      ;; whereas the let-binding might only protect the buffer-local value.
+      (remove-hook 'post-self-insert-hook postproc)))
   nil)
 
 (defun set-hard-newline-properties (from to)
--- a/lisp/textmodes/ispell.el	Fri Sep 03 06:22:01 2010 +0000
+++ b/lisp/textmodes/ispell.el	Sun Sep 05 22:45:59 2010 +0000
@@ -221,10 +221,10 @@
 	(let (ver mver)
 	  (if (string-match "[0-9]+" version start-ver)
 	      (setq start-ver (match-end 0)
-		    ver (string-to-number (substring version (match-beginning 0) (match-end 0)))))
+		    ver (string-to-number (match-string 0 version))))
 	  (if (string-match "[0-9]+" minver start-mver)
 	      (setq start-mver (match-end 0)
-		    mver (string-to-number (substring minver (match-beginning 0) (match-end 0)))))
+		    mver (string-to-number (match-string 0 minver))))
 
 	  (if (or ver mver)
 	      (progn
@@ -310,7 +310,9 @@
 may produce undesired results."
   :type '(choice (const exclusive) (const :tag "off" nil) (const :tag "on" t))
   :group 'ispell)
-;;;###autoload(put 'ispell-check-comments 'safe-local-variable (lambda (a) (memq a '(nil t exclusive))))
+;;;###autoload
+(put 'ispell-check-comments 'safe-local-variable
+     (lambda (a) (memq a '(nil t exclusive))))
 
 (defcustom ispell-query-replace-choices nil
   "*Corrections made throughout region when non-nil.
@@ -514,7 +516,8 @@
   :type '(choice string
 		 (const :tag "default" nil))
   :group 'ispell)
-;;;###autoload(put 'ispell-local-dictionary 'safe-local-variable 'string-or-null-p)
+;;;###autoload
+(put 'ispell-local-dictionary 'safe-local-variable 'string-or-null-p)
 
 (make-variable-buffer-local 'ispell-local-dictionary)
 
@@ -738,8 +741,8 @@
 contain the same character set as casechars and otherchars in the
 LANGUAGE.aff file \(e.g., english.aff\).")
 
-(defvar ispell-really-aspell nil)   ; Non-nil if aspell extensions should be used
-(defvar ispell-really-hunspell nil) ; Non-nil if hunspell extensions should be used
+(defvar ispell-really-aspell nil)   ; Non-nil if we can use aspell extensions.
+(defvar ispell-really-hunspell nil) ; Non-nil if we can use hunspell extensions.
 (defvar ispell-encoding8-command nil
   "Command line option prefix to select UTF-8 if supported, nil otherwise.
 If UTF-8 if supported by spellchecker and is selectable from the command line
@@ -962,7 +965,8 @@
 	(setq found (nconc found (list dict)))))
     (setq ispell-aspell-dictionary-alist found)
     ;; Add a default entry
-    (let ((default-dict '(nil "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-B") nil utf-8)))
+    (let ((default-dict
+           '(nil "[[:alpha:]]" "[^[:alpha:]]" "[']" nil ("-B") nil utf-8)))
       (push default-dict ispell-aspell-dictionary-alist))))
 
 (defvar ispell-aspell-data-dir nil
@@ -1026,7 +1030,8 @@
 (defun ispell-aspell-add-aliases (alist)
   "Find aspell's dictionary aliases and add them to dictionary ALIST.
 Return the new dictionary alist."
-  (let ((aliases (file-expand-wildcards
+  (let ((aliases
+         (file-expand-wildcards
 		  (concat (or ispell-aspell-dict-dir
 			      (setq ispell-aspell-dict-dir
 				    (ispell-get-aspell-config-value "dict-dir")))
@@ -1168,7 +1173,8 @@
 	`(menu-item ,(purecopy "Complete Word") ispell-complete-word
 		    :help ,(purecopy "Complete word at cursor using dictionary")))
       (define-key ispell-menu-map [ispell-complete-word-interior-frag]
-	`(menu-item ,(purecopy "Complete Word Fragment") ispell-complete-word-interior-frag
+	`(menu-item ,(purecopy "Complete Word Fragment")
+                    ispell-complete-word-interior-frag
 		    :help ,(purecopy "Complete word fragment at cursor")))))
 
 ;;;###autoload
@@ -1185,7 +1191,8 @@
 	`(menu-item ,(purecopy "Spell-Check Word") ispell-word
 		    :help ,(purecopy "Spell-check word at cursor")))
       (define-key ispell-menu-map [ispell-comments-and-strings]
-	`(menu-item ,(purecopy "Spell-Check Comments") ispell-comments-and-strings
+	`(menu-item ,(purecopy "Spell-Check Comments")
+                    ispell-comments-and-strings
 		    :help ,(purecopy "Spell-check only comments and strings")))))
 
 ;;;###autoload
@@ -1334,9 +1341,6 @@
 (defvar ispell-process-directory nil
   "The directory where `ispell-process' was started.")
 
-(defvar ispell-process-buffer-name nil
-  "The buffer where `ispell-process' was started.")
-
 (defvar ispell-filter nil
   "Output filter from piped calls to Ispell.")
 
@@ -1400,7 +1404,8 @@
     (ispell-dictionary-keyword	   forward-line)
     (ispell-pdict-keyword	   forward-line)
     (ispell-parsing-keyword	   forward-line)
-    (,(purecopy "^---*BEGIN PGP [A-Z ]*--*") . ,(purecopy "^---*END PGP [A-Z ]*--*"))
+    (,(purecopy "^---*BEGIN PGP [A-Z ]*--*")
+     . ,(purecopy "^---*END PGP [A-Z ]*--*"))
     ;; assume multiline uuencoded file? "\nM.*$"?
     (,(purecopy "^begin [0-9][0-9][0-9] [^ \t]+$") . ,(purecopy "\nend\n"))
     (,(purecopy "^%!PS-Adobe-[123].0")	 . ,(purecopy "\n%%EOF\n"))
@@ -1880,9 +1885,10 @@
     ;; setup the *Choices* buffer with valid data.
     (with-current-buffer (get-buffer-create ispell-choices-buffer)
       (setq mode-line-format
-	    (concat "--  %b  --  word: " word
-		    "  --  dict: " (or ispell-current-dictionary "default")
-		    "  --  prog: " (file-name-nondirectory ispell-program-name)))
+	    (concat
+             "--  %b  --  word: " word
+             "  --  dict: " (or ispell-current-dictionary "default")
+             "  --  prog: " (file-name-nondirectory ispell-program-name)))
       ;; XEmacs: no need for horizontal scrollbar in choices window
       (with-no-warnings
        (and (fboundp 'set-specifier)
@@ -2280,8 +2286,9 @@
       (unless (file-readable-p lookup-dict)
 	(error "lookup-words error: Unreadable or missing plain word-list %s."
 	       lookup-dict))
-    (error (concat "lookup-words error: No plain word-list found at system default "
-		   "locations.  Customize `ispell-alternate-dictionary' to set yours.")))
+    (error (concat "lookup-words error: No plain word-list found at system"
+                   "default locations.  "
+                   "Customize `ispell-alternate-dictionary' to set yours.")))
 
   (let* ((process-connection-type ispell-use-ptys-p)
 	 (wild-p (string-match "\\*" word))
@@ -2332,16 +2339,16 @@
     results))
 
 
-;;; "ispell-filter" is a list of output lines from the generating function.
-;;;   Each full line (ending with \n) is a separate item on the list.
-;;; "output" can contain multiple lines, part of a line, or both.
-;;; "start" and "end" are used to keep bounds on lines when "output" contains
-;;;   multiple lines.
-;;; "ispell-filter-continue" is true when we have received only part of a
-;;;   line as output from a generating function ("output" did not end with \n)
-;;; THIS FUNCTION WILL FAIL IF THE PROCESS OUTPUT DOESN'T END WITH \n!
-;;;   This is the case when a process dies or fails. The default behavior
-;;;   in this case treats the next input received as fresh input.
+;; "ispell-filter" is a list of output lines from the generating function.
+;;   Each full line (ending with \n) is a separate item on the list.
+;; "output" can contain multiple lines, part of a line, or both.
+;; "start" and "end" are used to keep bounds on lines when "output" contains
+;;   multiple lines.
+;; "ispell-filter-continue" is true when we have received only part of a
+;;   line as output from a generating function ("output" did not end with \n)
+;; THIS FUNCTION WILL FAIL IF THE PROCESS OUTPUT DOESN'T END WITH \n!
+;;   This is the case when a process dies or fails. The default behavior
+;;   in this case treats the next input received as fresh input.
 
 (defun ispell-filter (process output)
   "Output filter function for ispell, grep, and look."
@@ -2573,37 +2580,34 @@
 (defun ispell-start-process ()
   "Start the ispell process, with support for no asynchronous processes.
 Keeps argument list for future ispell invocations for no async support."
-  (let ((default-directory default-directory)
-	args)
-    (unless (and (file-directory-p default-directory)
-		 (file-readable-p default-directory))
-      ;; Defend against bad `default-directory'.
-      (setq default-directory (expand-file-name "~/")))
-    ;; Local dictionary becomes the global dictionary in use.
-    (setq ispell-current-dictionary
-	  (or ispell-local-dictionary ispell-dictionary))
-    (setq ispell-current-personal-dictionary
-	  (or ispell-local-pdict ispell-personal-dictionary))
-    (setq args (ispell-get-ispell-args))
-    (if (and ispell-current-dictionary	; use specified dictionary
-	     (not (member "-d" args)))	; only define if not overridden
-	(setq args
-	      (append (list "-d" ispell-current-dictionary) args)))
-    (if ispell-current-personal-dictionary	; use specified pers dict
-	(setq args
-	      (append args
-		      (list "-p"
-			    (expand-file-name ispell-current-personal-dictionary)))))
-
-    ;; If we are using recent aspell or hunspell, make sure we use the right encoding
-    ;; for communication. ispell or older aspell/hunspell does not support this
-    (if ispell-encoding8-command
-	(setq args
-	      (append args
-		      (list
-		       (concat ispell-encoding8-command
-			       (symbol-name (ispell-get-coding-system)))))))
-    (setq args (append args ispell-extra-args))
+  ;; Local dictionary becomes the global dictionary in use.
+  (setq ispell-current-dictionary
+        (or ispell-local-dictionary ispell-dictionary))
+  (setq ispell-current-personal-dictionary
+        (or ispell-local-pdict ispell-personal-dictionary))
+  (let* ((default-directory
+           (if (and (file-directory-p default-directory)
+                    (file-readable-p default-directory))
+               default-directory
+             ;; Defend against bad `default-directory'.
+             (expand-file-name "~/")))
+         (args
+          (append
+           (if (and ispell-current-dictionary ; Use specified dictionary.
+                    (not (member "-d" args))) ; Only define if not overridden.
+               (list "-d" ispell-current-dictionary))
+           (ispell-get-ispell-args)
+           (if ispell-current-personal-dictionary ; Use specified pers dict.
+               (list "-p"
+                     (expand-file-name ispell-current-personal-dictionary)))
+           ;; If we are using recent aspell or hunspell, make sure we use the
+           ;; right encoding for communication. ispell or older aspell/hunspell
+           ;; does not support this.
+           (if ispell-encoding8-command
+               (list
+                (concat ispell-encoding8-command
+                        (symbol-name (ispell-get-coding-system)))))
+           ispell-extra-args)))
 
     ;; Initially we don't know any buffer's local words.
     (setq ispell-buffer-local-name nil)
@@ -2612,9 +2616,11 @@
 	(let ((process-connection-type ispell-use-ptys-p))
 	  (apply 'start-process
 		 "ispell" nil ispell-program-name
-		 "-a"			             ; accept single input lines
-		 (if ispell-really-hunspell "" "-m") ; make root/affix combos not in dict
-		 args))                              ; hunspell -m option means different
+		 "-a"                   ; Accept single input lines.
+                 ;; Make root/affix combos not in dict.
+                 ;; hunspell -m option means different.
+		 (if ispell-really-hunspell "" "-m")
+		 args))
       (setq ispell-cmd-args args
 	    ispell-output-buffer (generate-new-buffer " *ispell-output*")
 	    ispell-session-buffer (generate-new-buffer " *ispell-session*"))
@@ -2650,10 +2656,11 @@
     ;; Check if process needs restart
     (if (and ispell-process
 	     (eq (ispell-process-status) 'run)
-	     ;; Unless we are using an explicit personal dictionary,
-	     ;; ensure we're in the same default directory!
-	     ;; Restart check for personal dictionary is done in
-	     ;; `ispell-internal-change-dictionary', called from `ispell-buffer-local-dict'
+	     ;; Unless we are using an explicit personal dictionary, ensure
+	     ;; we're in the same default directory!  Restart check for
+	     ;; personal dictionary is done in
+	     ;; `ispell-internal-change-dictionary', called from
+	     ;; `ispell-buffer-local-dict'
 	     (or (or ispell-local-pdict ispell-personal-dictionary)
 		 (equal ispell-process-directory default-directory)))
 	(setq ispell-filter nil ispell-filter-continue nil)
@@ -2667,17 +2674,25 @@
 	    ispell-filter nil
 	    ispell-filter-continue nil
 	    ispell-process-directory default-directory)
-      ;; When spellchecking minibuffer contents, assign ispell process to parent
-      ;; buffer if known (not known for XEmacs).  Use (buffer-name) otherwise.
-      (setq ispell-process-buffer-name
+
+      ;; Kill ispell process when killing its associated buffer if using Ispell
+      ;; per-directory personal dictionaries.
+      (unless (equal ispell-process-directory (expand-file-name "~/"))
+        (with-current-buffer
 	    (if (and (window-minibuffer-p)
-		     (fboundp 'minibuffer-selected-window)) ;; Not XEmacs
+                     (fboundp 'minibuffer-selected-window)) ;; E.g. XEmacs.
+                ;; When spellchecking minibuffer contents, assign ispell
+                ;; process to parent buffer if known (not known for XEmacs).
+                ;; Use (buffer-name) otherwise.
 		(window-buffer (minibuffer-selected-window))
-	      (buffer-name)))
+              (current-buffer))
+          (add-hook 'kill-buffer-hook (lambda () (ispell-kill-ispell t))
+                    nil 'local)))
 
       (if ispell-async-processp
 	  (set-process-filter ispell-process 'ispell-filter))
-      ;; protect against bogus binding of `enable-multibyte-characters' in XEmacs
+      ;; protect against bogus binding of `enable-multibyte-characters' in
+      ;; XEmacs.
       (if (and (or (featurep 'xemacs)
 		   (and (boundp 'enable-multibyte-characters)
 			enable-multibyte-characters))
@@ -2735,19 +2750,10 @@
       (kill-buffer ispell-session-buffer)
       (setq ispell-output-buffer nil
 	    ispell-session-buffer nil))
-    (setq ispell-process-buffer-name nil)
     (setq ispell-process nil)
     (message "Ispell process killed")
     nil))
 
-;; Kill ispell process when killing its associated buffer if using Ispell
-;; per-directory personal dictionaries.
-(add-hook 'kill-buffer-hook
-	  '(lambda ()
-	     (if (and (not (equal ispell-process-directory (expand-file-name "~/")))
-		      (equal ispell-process-buffer-name (buffer-name)))
-		 (ispell-kill-ispell t))))
-
 ;;; ispell-change-dictionary is set in some people's hooks.  Maybe this should
 ;;;  call ispell-init-process rather than wait for a spell checking command?
 
@@ -2844,9 +2850,10 @@
 		  (set-marker skip-region-start (- (point) (length key)))
 		  (goto-char reg-start)))
 	    (let (message-log-max)
-	      (message "Continuing spelling check using %s with %s dictionary..."
-		       (file-name-nondirectory ispell-program-name)
-		       (or ispell-current-dictionary "default")))
+	      (message
+               "Continuing spelling check using %s with %s dictionary..."
+               (file-name-nondirectory ispell-program-name)
+               (or ispell-current-dictionary "default")))
 	    (set-marker rstart reg-start)
 	    (set-marker ispell-region-end reg-end)
 	    (while (and (not ispell-quit)
@@ -3111,9 +3118,9 @@
 	  (sit-for 2)))))
 
 
-;;; Grab the next line of data.
-;;; Returns a string with the line data
 (defun ispell-get-line (start end in-comment)
+  "Grab the next line of data.
+Returns a string with the line data."
   (let ((ispell-casechars (ispell-get-casechars))
 	string)
     (cond				; LOOK AT THIS LINE AND SKIP OR PROCESS
@@ -3140,7 +3147,8 @@
 				       (point) (+ (point) len))
 				      coding)))))
 
-;;; Avoid error messages when compiling for these dynamic variables.
+;; Avoid error messages when compiling for these dynamic variables.
+;; FIXME: dynamically scoped vars should have an "ispell-" prefix.
 (defvar start)
 (defvar end)
 
@@ -3275,10 +3283,12 @@
 	      ;;			   (length (car poss)))))
 	      ))
 	    (if (not ispell-quit)
+                ;; FIXME: remove redundancy with identical code above.
 		(let (message-log-max)
-		  (message "Continuing spelling check using %s with %s dictionary..."
-			   (file-name-nondirectory ispell-program-name)
-			   (or ispell-current-dictionary "default"))))
+		  (message
+                   "Continuing spelling check using %s with %s dictionary..."
+                   (file-name-nondirectory ispell-program-name)
+                   (or ispell-current-dictionary "default"))))
 	    (sit-for 0)
 	    (setq start (marker-position line-start)
 		  end (marker-position line-end))
@@ -3351,7 +3361,7 @@
 
 
 ;;; Interactive word completion.
-;;; Forces "previous-word" processing.  Do we want to make this selectable?
+;; Forces "previous-word" processing.  Do we want to make this selectable?
 
 ;;;###autoload
 (defun ispell-complete-word (&optional interior-frag)
--- a/src/ChangeLog	Fri Sep 03 06:22:01 2010 +0000
+++ b/src/ChangeLog	Sun Sep 05 22:45:59 2010 +0000
@@ -1,3 +1,37 @@
+2010-09-05  Juanma Barranquero  <lekktu@gmail.com>
+
+	* biditype.h: Regenerate.
+
+2010-09-04  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* nsimage.m (ns_load_image): Check argument types.
+
+	* image.c: Remove all uses of gcpro.
+	(xpm_load): Check all lisp types.
+	(pbm_load): Likewise.
+	(png_load): Likewise.
+	(jpeg_load): Likewise.
+	(tiff_load): Likewise.
+	(gif_load): Likewise.
+	(imagemagick_load_image): Likewise.
+	(imagemagick_load): Likewise.
+	(svg_load): Likewise.
+	(gs_load): Likewise.
+
+2010-09-04  Eli Zaretskii  <eliz@gnu.org>
+
+	* w32uniscribe.c (uniscribe_shape): Update commentary.  Don't
+	try to reorder grapheme clusters, since LGSTRING should always
+	hold them in the logical order.
+	(uniscribe_encode_char, uniscribe_shape): Force ScriptShape to
+	return glyph codes in the logical order.
+
+2010-09-04  Andreas Schwab  <schwab@linux-m68k.org>
+
+	* image.c (imagemagick_image_p): Replace bcopy by memcpy.
+	(imagemagick_load_image): Fix type mismatch.
+	(Fimagemagick_types): Likewise.  Doc fix.
+
 2010-09-02  Jan Djärv  <jan.h.d@swipnet.se>
 
 	* xterm.h (struct dpyinfo): Remove cut_buffers_initialized.
--- a/src/biditype.h	Fri Sep 03 06:22:01 2010 +0000
+++ b/src/biditype.h	Sun Sep 05 22:45:59 2010 +0000
@@ -83,7 +83,8 @@
 	{ 0x0671, 0x06D5, STRONG_AL },
 	{ 0x06D6, 0x06DC, WEAK_NSM },
 	{ 0x06DD, 0x06DD, WEAK_AN },
-	{ 0x06DE, 0x06E4, WEAK_NSM },
+	{ 0x06DE, 0x06DE, NEUTRAL_ON },
+	{ 0x06DF, 0x06E4, WEAK_NSM },
 	{ 0x06E5, 0x06E6, STRONG_AL },
 	{ 0x06E7, 0x06E8, WEAK_NSM },
 	{ 0x06E9, 0x06E9, NEUTRAL_ON },
@@ -271,7 +272,7 @@
 	{ 0x2080, 0x2089, WEAK_EN },
 	{ 0x208A, 0x208B, WEAK_ES },
 	{ 0x208C, 0x208E, NEUTRAL_ON },
-	{ 0x20A0, 0x20B8, WEAK_ET },
+	{ 0x20A0, 0x20B9, WEAK_ET },
 	{ 0x20D0, 0x20F0, WEAK_NSM },
 	{ 0x2100, 0x2101, NEUTRAL_ON },
 	{ 0x2103, 0x2106, NEUTRAL_ON },
--- a/src/image.c	Fri Sep 03 06:22:01 2010 +0000
+++ b/src/image.c	Sun Sep 05 22:45:59 2010 +0000
@@ -1735,7 +1735,6 @@
   struct image_cache *c;
   struct image *img;
   unsigned hash;
-  struct gcpro gcpro1;
   EMACS_TIME now;
 
   /* F must be a window-system frame, and SPEC must be a valid image
@@ -1745,8 +1744,6 @@
 
   c = FRAME_IMAGE_CACHE (f);
 
-  GCPRO1 (spec);
-
   /* Look up SPEC in the hash table of the image cache.  */
   hash = sxhash (spec, 0);
   img = search_image_cache (f, spec, hash);
@@ -1838,8 +1835,6 @@
   EMACS_GET_TIME (now);
   img->timestamp = EMACS_SECS (now);
 
-  UNGCPRO;
-
   /* Value is the image id.  */
   return img->id;
 }
@@ -2179,16 +2174,13 @@
 x_find_image_file (Lisp_Object file)
 {
   Lisp_Object file_found, search_path;
-  struct gcpro gcpro1, gcpro2;
   int fd;
 
-  file_found = Qnil;
   /* TODO I think this should use something like image-load-path
      instead.  Unfortunately, that can contain non-string elements.  */
   search_path = Fcons (Fexpand_file_name (build_string ("images"),
 					  Vdata_directory),
 		       Vx_bitmap_file_path);
-  GCPRO2 (file_found, search_path);
 
   /* Try to find FILE in data-directory/images, then x-bitmap-file-path.  */
   fd = openp (search_path, file, Qnil, &file_found, Qnil);
@@ -2201,7 +2193,6 @@
       close (fd);
     }
 
-  UNGCPRO;
   return file_found;
 }
 
@@ -2875,14 +2866,11 @@
       Lisp_Object file;
       unsigned char *contents;
       int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", file_name, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -2890,12 +2878,10 @@
       if (contents == NULL)
 	{
 	  image_error ("Error loading XBM image `%s'", img->spec, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
       success_p = xbm_load_image (f, img, contents, contents + size);
-      UNGCPRO;
     }
   else
     {
@@ -3456,12 +3442,31 @@
 	   CONSP (tail);
 	   ++i, tail = XCDR (tail))
 	{
-	  Lisp_Object name = XCAR (XCAR (tail));
-	  Lisp_Object color = XCDR (XCAR (tail));
-	  xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
-	  strcpy (xpm_syms[i].name, SDATA (name));
-	  xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
-	  strcpy (xpm_syms[i].value, SDATA (color));
+	  Lisp_Object name;
+	  Lisp_Object color;
+
+	  if (!CONSP (XCAR (tail)))
+	    {
+	      xpm_syms[i].name = "";
+	      xpm_syms[i].value = "";
+	      continue;
+	    }
+	  name = XCAR (XCAR (tail));
+	  color = XCDR (XCAR (tail));
+	  if (STRINGP (name))
+	    {
+	      xpm_syms[i].name = (char *) alloca (SCHARS (name) + 1);
+	      strcpy (xpm_syms[i].name, SDATA (name));
+	    }
+	  else
+	    xpm_syms[i].name = "";
+	  if (STRINGP (color))
+	    {
+	      xpm_syms[i].value = (char *) alloca (SCHARS (color) + 1);
+	      strcpy (xpm_syms[i].value, SDATA (color));
+	    }
+	  else
+	    xpm_syms[i].value = "";
 	}
     }
 
@@ -3487,6 +3492,9 @@
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
+#ifdef ALLOC_XPM_COLORS
+	  xpm_free_color_cache ();
+#endif
 	  return 0;
 	}
 
@@ -3505,6 +3513,14 @@
   else
     {
       Lisp_Object buffer = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (buffer))
+	{
+	  image_error ("Invalid image data `%s'", buffer, Qnil);
+#ifdef ALLOC_XPM_COLORS
+	  xpm_free_color_cache ();
+#endif
+	  return 0;
+	}
 #ifdef HAVE_NTGUI
       /* XpmCreatePixmapFromBuffer is not available in the Windows port
 	 of libxpm.  But XpmCreateImageFromBuffer almost does what we want.  */
@@ -4071,14 +4087,11 @@
       Lisp_Object file;
       unsigned char *contents;
       int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", file_name, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -4086,19 +4099,22 @@
       if (contents == NULL)
 	{
 	  image_error ("Error loading XPM image `%s'", img->spec, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
       success_p = xpm_load_image (f, img, contents, contents + size);
       xfree (contents);
-      UNGCPRO;
     }
   else
     {
       Lisp_Object data;
 
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+	{
+	  image_error ("Invalid image data `%s'", data, Qnil);
+	  return 0;
+	}
       success_p = xpm_load_image (f, img, SDATA (data),
 				  SDATA (data) + SBYTES (data));
     }
@@ -5090,14 +5106,11 @@
   XImagePtr ximg;
   Lisp_Object file, specified_file;
   enum {PBM_MONO, PBM_GRAY, PBM_COLOR} type;
-  struct gcpro gcpro1;
   unsigned char *contents = NULL;
   unsigned char *end, *p;
   int size;
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (STRINGP (specified_file))
     {
@@ -5105,7 +5118,6 @@
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -5113,7 +5125,6 @@
       if (contents == NULL)
 	{
 	  image_error ("Error reading `%s'", file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -5124,6 +5135,11 @@
     {
       Lisp_Object data;
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+	{
+	  image_error ("Invalid image data `%s'", data, Qnil);
+	  return 0;
+	}
       p = SDATA (data);
       end = p + SBYTES (data);
     }
@@ -5134,7 +5150,6 @@
       image_error ("Not a PBM image: `%s'", img->spec, Qnil);
     error:
       xfree (contents);
-      UNGCPRO;
       return 0;
     }
 
@@ -5336,7 +5351,6 @@
      img->width = width;
      img->height = height; */
 
-  UNGCPRO;
   xfree (contents);
   return 1;
 }
@@ -5576,7 +5590,6 @@
   Lisp_Object specified_data;
   int x, y, i;
   XImagePtr ximg, mask_img = NULL;
-  struct gcpro gcpro1;
   png_struct *png_ptr = NULL;
   png_info *info_ptr = NULL, *end_info = NULL;
   FILE *volatile fp = NULL;
@@ -5593,8 +5606,6 @@
   /* Find out what file to load.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (NILP (specified_data))
     {
@@ -5602,7 +5613,6 @@
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -5611,7 +5621,6 @@
       if (!fp)
 	{
 	  image_error ("Cannot open image file `%s'", file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -5620,13 +5629,18 @@
 	  || fn_png_sig_cmp (sig, 0, sizeof sig))
 	{
 	  image_error ("Not a PNG file: `%s'", file, Qnil);
-	  UNGCPRO;
 	  fclose (fp);
 	  return 0;
 	}
     }
   else
     {
+      if (!STRINGP (specified_data))
+	{
+	  image_error ("Invalid image data `%s'", specified_data, Qnil);
+	  return 0;
+	}
+
       /* Read from memory.  */
       tbr.bytes = SDATA (specified_data);
       tbr.len = SBYTES (specified_data);
@@ -5637,7 +5651,6 @@
 	  || fn_png_sig_cmp (tbr.bytes, 0, sizeof sig))
 	{
 	  image_error ("Not a PNG image: `%s'", img->spec, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -5653,7 +5666,6 @@
   if (!png_ptr)
     {
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
@@ -5663,7 +5675,6 @@
     {
       fn_png_destroy_read_struct (&png_ptr, NULL, NULL);
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
@@ -5673,7 +5684,6 @@
     {
       fn_png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
@@ -5687,7 +5697,6 @@
       xfree (pixels);
       xfree (rows);
       if (fp) fclose (fp);
-      UNGCPRO;
       return 0;
     }
 
@@ -5912,7 +5921,6 @@
       x_destroy_x_image (mask_img);
     }
 
-  UNGCPRO;
   return 1;
 }
 
@@ -6313,13 +6321,10 @@
   int rc;
   unsigned long *colors;
   int width, height;
-  struct gcpro gcpro1;
 
   /* Open the JPEG file.  */
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (NILP (specified_data))
     {
@@ -6327,7 +6332,6 @@
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -6335,10 +6339,14 @@
       if (fp == NULL)
 	{
 	  image_error ("Cannot open `%s'", file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
     }
+  else if (!STRINGP (specified_data))
+    {
+      image_error ("Invalid image data `%s'", specified_data, Qnil);
+      return 0;
+    }
 
   /* Customize libjpeg's error handling to call my_error_exit when an
      error is detected.  This function will perform a longjmp.
@@ -6367,8 +6375,6 @@
 
       /* Free pixmap and colors.  */
       x_clear_image (f, img);
-
-      UNGCPRO;
       return 0;
     }
 
@@ -6466,7 +6472,6 @@
   /* Put the image into the pixmap.  */
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
-  UNGCPRO;
   return 1;
 }
 
@@ -6741,14 +6746,11 @@
   uint32 *buf;
   int rc, rc2;
   XImagePtr ximg;
-  struct gcpro gcpro1;
   tiff_memory_source memsrc;
   Lisp_Object image;
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   fn_TIFFSetErrorHandler (tiff_error_handler);
   fn_TIFFSetWarningHandler (tiff_warning_handler);
@@ -6760,7 +6762,6 @@
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -6770,12 +6771,17 @@
       if (tiff == NULL)
 	{
 	  image_error ("Cannot open `%s'", file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
     }
   else
     {
+      if (!STRINGP (specified_data))
+	{
+	  image_error ("Invalid image data `%s'", specified_data, Qnil);
+	  return 0;
+	}
+
       /* Memory source! */
       memsrc.bytes = SDATA (specified_data);
       memsrc.len = SBYTES (specified_data);
@@ -6794,7 +6800,6 @@
       if (!tiff)
 	{
 	  image_error ("Cannot open memory source for `%s'", img->spec, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
     }
@@ -6808,7 +6813,6 @@
 	  image_error ("Invalid image number `%s' in image `%s'",
 		       image, img->spec);
 	  fn_TIFFClose (tiff);
-	  UNGCPRO;
 	  return 0;
 	}
     }
@@ -6822,7 +6826,6 @@
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_TIFFClose (tiff);
-      UNGCPRO;
       return 0;
     }
 
@@ -6844,7 +6847,6 @@
     {
       image_error ("Error reading TIFF image `%s'", img->spec, Qnil);
       xfree (buf);
-      UNGCPRO;
       return 0;
     }
 
@@ -6852,7 +6854,6 @@
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
     {
       xfree (buf);
-      UNGCPRO;
       return 0;
     }
 
@@ -6893,7 +6894,6 @@
   x_destroy_x_image (ximg);
   xfree (buf);
 
-  UNGCPRO;
   return 1;
 }
 
@@ -7099,7 +7099,6 @@
   ColorMapObject *gif_color_map;
   unsigned long pixel_colors[256];
   GifFileType *gif;
-  struct gcpro gcpro1;
   Lisp_Object image;
   int ino, image_height, image_width;
   gif_memory_source memsrc;
@@ -7107,8 +7106,6 @@
 
   specified_file = image_spec_value (img->spec, QCfile, NULL);
   specified_data = image_spec_value (img->spec, QCdata, NULL);
-  file = Qnil;
-  GCPRO1 (file);
 
   if (NILP (specified_data))
     {
@@ -7116,7 +7113,6 @@
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", specified_file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -7126,12 +7122,17 @@
       if (gif == NULL)
 	{
 	  image_error ("Cannot open `%s'", file, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
     }
   else
     {
+      if (!STRINGP (specified_data))
+	{
+	  image_error ("Invalid image data `%s'", specified_data, Qnil);
+	  return 0;
+	}
+
       /* Read from memory! */
       current_gif_memory_src = &memsrc;
       memsrc.bytes = SDATA (specified_data);
@@ -7143,7 +7144,6 @@
       if (!gif)
 	{
 	  image_error ("Cannot open memory source `%s'", img->spec, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
     }
@@ -7153,7 +7153,6 @@
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7163,7 +7162,6 @@
     {
       image_error ("Error reading `%s'", img->spec, Qnil);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7174,7 +7172,6 @@
       image_error ("Invalid image number `%s' in image `%s'",
 		   image, img->spec);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7196,7 +7193,6 @@
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7204,7 +7200,6 @@
   if (!x_create_x_image_and_pixmap (f, width, height, 0, &ximg, &img->pixmap))
     {
       fn_DGifCloseFile (gif);
-      UNGCPRO;
       return 0;
     }
 
@@ -7323,7 +7318,6 @@
   x_put_x_image (f, ximg, img->pixmap, width, height);
   x_destroy_x_image (ximg);
 
-  UNGCPRO;
   return 1;
 }
 
@@ -7389,9 +7383,9 @@
     {":heuristic-mask",	IMAGE_DONT_CHECK_VALUE_TYPE,		0},
     {":mask",		IMAGE_DONT_CHECK_VALUE_TYPE,		0},
     {":background",	IMAGE_STRING_OR_NIL_VALUE,		0},
-    {":height",		IMAGE_INTEGER_VALUE,			0},    
-    {":width",		IMAGE_INTEGER_VALUE,			0},    
-    {":rotation",	IMAGE_NUMBER_VALUE,     		0},    
+    {":height",		IMAGE_INTEGER_VALUE,			0},
+    {":width",		IMAGE_INTEGER_VALUE,			0},
+    {":rotation",	IMAGE_NUMBER_VALUE,     		0},
     {":crop",		IMAGE_DONT_CHECK_VALUE_TYPE,		0}
   };
 /* Free X resources of imagemagick image IMG which is used on frame F.  */
@@ -7413,7 +7407,7 @@
 imagemagick_image_p (Lisp_Object object)
 {
   struct image_keyword fmt[IMAGEMAGICK_LAST];
-  bcopy (imagemagick_format, fmt, sizeof fmt);
+  memcpy (fmt, imagemagick_format, sizeof fmt);
 
   if (!parse_image_spec (object, fmt, IMAGEMAGICK_LAST, Qimagemagick))
     return 0;
@@ -7440,7 +7434,7 @@
 imagemagick_load_image (/* Pointer to emacs frame structure.  */
                         struct frame *f,
                         /* Pointer to emacs image structure.  */
-                        struct image *img, 
+                        struct image *img,
                         /* String containing the IMAGEMAGICK data to
                            be parsed.  */
                         unsigned char *contents,
@@ -7450,8 +7444,8 @@
                            contents/size.  */
                         unsigned char *filename)
 {
-  size_t width;
-  size_t height;
+  unsigned long width;
+  unsigned long height;
 
   MagickBooleanType
     status;
@@ -7463,52 +7457,52 @@
   int y;
 
   MagickWand  *image_wand;
-  MagickWand  *ping_wand;  
+  MagickWand  *ping_wand;
   PixelIterator *iterator;
   PixelWand  **pixels;
   MagickPixelPacket  pixel;
   Lisp_Object image;
-  Lisp_Object value;  
+  Lisp_Object value;
   Lisp_Object crop, geometry;
   long ino;
   int desired_width, desired_height;
   double rotation;
   int imagemagick_rendermethod;
-  int pixelwidth; 
+  int pixelwidth;
   ImageInfo  *image_info;
   ExceptionInfo *exception;
   Image * im_image;
 
-  
+
   /* Handle image index for image types who can contain more than one
      image.  Interface :index is same as for GIF.  First we "ping" the
      image to see how many sub-images it contains. Pinging is faster
      than loading the image to find out things about it.  */
   image = image_spec_value (img->spec, QCindex, NULL);
   ino = INTEGERP (image) ? XFASTINT (image) : 0;
-  ping_wand=NewMagickWand();
-  MagickSetResolution(ping_wand, 2, 2);
+  ping_wand = NewMagickWand ();
+  MagickSetResolution (ping_wand, 2, 2);
   if (filename != NULL)
     {
-      status = MagickPingImage(ping_wand, filename);
+      status = MagickPingImage (ping_wand, filename);
     }
   else
     {
-      status = MagickPingImageBlob(ping_wand, contents, size);
-    }
-  
-  if (ino >= MagickGetNumberImages(ping_wand)) 
-    { 
-      image_error ("Invalid image number `%s' in image `%s'", 
-         	   image, img->spec); 
-      UNGCPRO; 
-      return 0; 
-    } 
+      status = MagickPingImageBlob (ping_wand, contents, size);
+    }
+
+  if (ino >= MagickGetNumberImages (ping_wand))
+    {
+      image_error ("Invalid image number `%s' in image `%s'",
+		   image, img->spec);
+      DestroyMagickWand (ping_wand);
+      return 0;
+    }
 
   if (MagickGetNumberImages(ping_wand) > 1)
     img->data.lisp_val =
       Fcons (Qcount,
-             Fcons (make_number (MagickGetNumberImages(ping_wand)),
+             Fcons (make_number (MagickGetNumberImages (ping_wand)),
                     img->data.lisp_val));
 
   DestroyMagickWand (ping_wand);
@@ -7517,21 +7511,21 @@
 
   if (filename != NULL)
     {
-      image_info=CloneImageInfo((ImageInfo *) NULL);
-      (void) strcpy(image_info->filename, filename);
-      image_info -> number_scenes = 1;
-      image_info -> scene = ino;
-      exception=AcquireExceptionInfo();
-
-      im_image = ReadImage (image_info, exception); 
-      CatchException(exception);
-
-      image_wand = NewMagickWandFromImage(im_image);
+      image_info = CloneImageInfo ((ImageInfo *) NULL);
+      (void) strcpy (image_info->filename, filename);
+      image_info->number_scenes = 1;
+      image_info->scene = ino;
+      exception = AcquireExceptionInfo ();
+
+      im_image = ReadImage (image_info, exception);
+      CatchException (exception);
+
+      image_wand = NewMagickWandFromImage (im_image);
     }
   else
     {
-      image_wand = NewMagickWand();  
-      status = MagickReadImageBlob(image_wand, contents, size);
+      image_wand = NewMagickWand ();
+      status = MagickReadImageBlob (image_wand, contents, size);
     }
   image_error ("im read failed", Qnil, Qnil);
   if (status == MagickFalse) goto imagemagick_error;
@@ -7552,44 +7546,56 @@
   if(desired_width != -1 && desired_height == -1)
     {
       /* w known, calculate h.  */
-      desired_height = ( (double)desired_width / width  ) * height;
+      desired_height = (double) desired_width / width * height;
     }
   if(desired_width == -1 && desired_height != -1)
     {
       /* h known, calculate w.  */
-      desired_width = ( (double)desired_height / height  ) * width;
-    }  
+      desired_width = (double) desired_height / height * width;
+    }
   if(desired_width != -1 && desired_height != -1)
     {
-      status = MagickScaleImage(image_wand, desired_width, desired_height);
-      if (status == MagickFalse) {
-        image_error ("Imagemagick scale failed", Qnil, Qnil);
-        goto imagemagick_error;
-      }
+      status = MagickScaleImage (image_wand, desired_width, desired_height);
+      if (status == MagickFalse)
+	{
+	  image_error ("Imagemagick scale failed", Qnil, Qnil);
+	  goto imagemagick_error;
+	}
     }
 
 
   /* crop behaves similar to image slicing in Emacs but is more memory
-     efficient */
-  crop     = image_spec_value (img->spec, QCcrop, NULL);
-  
-  if(CONSP (crop))
-    {
-      /* 
-         after some testing, it seems MagickCropImage is the fastest
-         crop function in ImageMagick. This crop function seems to do
+     efficient.  */
+  crop = image_spec_value (img->spec, QCcrop, NULL);
+
+  if (CONSP (crop) && INTEGERP (XCAR (crop)))
+    {
+      /* After some testing, it seems MagickCropImage is the fastest
+         crop function in ImageMagick.  This crop function seems to do
          less copying than the alternatives, but it still reads the
          entire image into memory before croping, which is aparently
-         difficult to avoid when using imagemagick. */
-      
-      int w,h,x,y;
-      w=XFASTINT(XCAR(crop));
-      h=XFASTINT(XCAR(XCDR(crop)));
-      x=XFASTINT(XCAR(XCDR(XCDR(crop))));
-      y=XFASTINT(XCAR(XCDR(XCDR(XCDR(crop)))));
-      MagickCropImage(image_wand, w,h, x,y);
-    }
-  
+         difficult to avoid when using imagemagick.  */
+
+      int w, h, x, y;
+      w = XFASTINT (XCAR (crop));
+      crop = XCDR (crop);
+      if (CONSP (crop) && INTEGERP (XCAR (crop)))
+	{
+	  h = XFASTINT (XCAR (crop));
+	  crop = XCDR (crop);
+	  if (CONSP (crop) && INTEGERP (XCAR (crop)))
+	    {
+	      x = XFASTINT (XCAR (crop));
+	      crop = XCDR (crop);
+	      if (CONSP (crop) && INTEGERP (XCAR (crop)))
+		{
+		  y = XFASTINT (XCAR (crop));
+		  MagickCropImage (image_wand, w, h, x, y);
+		}
+	    }
+	}
+    }
+
   /* Furthermore :rotation. we need background color and angle for
      rotation.  */
   /*
@@ -7599,11 +7605,11 @@
   value = image_spec_value (img->spec, QCrotation, NULL);
   if (FLOATP (value))
     {
-      PixelWand* background = NewPixelWand();
+      PixelWand* background = NewPixelWand ();
       PixelSetColor (background, "#ffffff");/*TODO remove hardcode*/
-        
+
       rotation = extract_float (value);
-        
+
       status = MagickRotateImage (image_wand, background, rotation);
       DestroyPixelWand (background);
       if (status == MagickFalse)
@@ -7612,23 +7618,23 @@
           goto imagemagick_error;
         }
     }
-  
+
   /* Finaly we are done manipulating the image, figure out resulting
      width, height, and then transfer ownerwship to Emacs.  */
   height = MagickGetImageHeight (image_wand);
   width = MagickGetImageWidth (image_wand);
   if (status == MagickFalse)
     {
-      image_error ("Imagemagick image get size failed", Qnil, Qnil);  
+      image_error ("Imagemagick image get size failed", Qnil, Qnil);
       goto imagemagick_error;
     }
-    
+
   if (! check_image_size (f, width, height))
     {
       image_error ("Invalid image size (see `max-image-size')", Qnil, Qnil);
       goto imagemagick_error;
     }
-  
+
   /* We can now get a valid pixel buffer from the imagemagick file, if all
      went ok.  */
 
@@ -7644,24 +7650,24 @@
           image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
           goto imagemagick_error;
         }
-    
+
       /* Copy imagegmagick image to x with primitive yet robust pixel
          pusher loop.  This has been tested a lot with many different
          images.  */
-  
+
       /* Copy pixels from the imagemagick image structure to the x image map. */
       iterator = NewPixelIterator (image_wand);
-      if ((iterator == (PixelIterator *) NULL))
+      if (iterator == (PixelIterator *) NULL)
         {
           image_error ("Imagemagick pixel iterator creation failed",
                        Qnil, Qnil);
           goto imagemagick_error;
         }
 
-      for (y = 0; y < (long) MagickGetImageHeight(image_wand); y++)
+      for (y = 0; y < (long) MagickGetImageHeight (image_wand); y++)
         {
           pixels = PixelGetNextIteratorRow (iterator, &width);
-          if ((pixels == (PixelWand **) NULL))
+          if (pixels == (PixelWand **) NULL)
             break;
           for (x = 0; x < (long) width; x++)
             {
@@ -7685,12 +7691,13 @@
       char* exportdepth = imagedepth <= 8 ? "I" : "BGRP";/*"RGBP";*/
       /* Try to create a x pixmap to hold the imagemagick pixmap.  */
       if (!x_create_x_image_and_pixmap (f, width, height, imagedepth,
-                                        &ximg, &img->pixmap)){
-        image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
-        goto imagemagick_error;
-      }
-
-    
+                                        &ximg, &img->pixmap))
+	{
+	  image_error("Imagemagick X bitmap allocation failure", Qnil, Qnil);
+	  goto imagemagick_error;
+	}
+
+
       /* Oddly, the below code doesnt seem to work:*/
       /* switch(ximg->bitmap_unit){ */
       /* case 8: */
@@ -7711,20 +7718,20 @@
         seems about 3 times as fast as pixel pushing(not carefully measured)
       */
       pixelwidth = CharPixel;/*??? TODO figure out*/
-#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS    
-      MagickExportImagePixels(image_wand,
-                              0, 0,
-                              width, height,
-                              exportdepth,
-                              pixelwidth, 
-                              /*&(img->pixmap));*/
-                              ximg->data);
+#ifdef HAVE_MAGICKEXPORTIMAGEPIXELS
+      MagickExportImagePixels (image_wand,
+			       0, 0,
+			       width, height,
+			       exportdepth,
+			       pixelwidth,
+			       /*&(img->pixmap));*/
+			       ximg->data);
 #else
-      image_error("You dont have MagickExportImagePixels, upgrade ImageMagick!",
-                  Qnil, Qnil);
-#endif    
-    }
-  
+      image_error ("You dont have MagickExportImagePixels, upgrade ImageMagick!",
+		   Qnil, Qnil);
+#endif
+    }
+
 
 #ifdef COLOR_TABLE_SUPPORT
   /* Remember colors allocated for this image.  */
@@ -7770,20 +7777,14 @@
   if (STRINGP (file_name))
     {
       Lisp_Object file;
-      unsigned char *contents;
-      int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", file_name, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
-      success_p = imagemagick_load_image (f, img, 0, 0, SDATA(file_name));
-      UNGCPRO;
+      success_p = imagemagick_load_image (f, img, 0, 0, SDATA (file));
     }
   /* Else its not a file, its a lisp object.  Load the image from a
      lisp object rather than a file.  */
@@ -7792,6 +7793,11 @@
       Lisp_Object data;
 
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+	{
+	  image_error ("Invalid image data `%s'", data, Qnil);
+	  return 0;
+	}
       success_p = imagemagick_load_image (f, img, SDATA (data),
                                           SBYTES (data), NULL);
     }
@@ -7823,16 +7829,16 @@
 
 
 
-DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0, 
+DEFUN ("imagemagick-types", Fimagemagick_types, Simagemagick_types, 0, 0, 0,
        doc: /* Return image file types supported by ImageMagick.
-               Since ImageMagick recognizes a lot of file-types that clash with Emacs,
-               such as .c, we want to be able to alter the list at the lisp level.  */)
+Since ImageMagick recognizes a lot of file-types that clash with Emacs,
+such as .c, we want to be able to alter the list at the lisp level.  */)
   (void)
 {
   Lisp_Object typelist = Qnil;
-  size_t numf;
+  unsigned long numf;
   ExceptionInfo ex;
-  char** imtypes = GetMagickList ("*", &numf, &ex);
+  char **imtypes = GetMagickList ("*", &numf, &ex);
   int i;
   Lisp_Object Qimagemagicktype;
   for (i = 0; i < numf; i++)
@@ -7842,7 +7848,7 @@
     }
   return typelist;
 }
-  
+
 #endif	/* defined (HAVE_IMAGEMAGICK) */
 
 
@@ -8038,14 +8044,11 @@
       Lisp_Object file;
       unsigned char *contents;
       int size;
-      struct gcpro gcpro1;
 
       file = x_find_image_file (file_name);
-      GCPRO1 (file);
       if (!STRINGP (file))
 	{
 	  image_error ("Cannot find image file `%s'", file_name, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
 
@@ -8054,13 +8057,11 @@
       if (contents == NULL)
 	{
 	  image_error ("Error loading SVG image `%s'", img->spec, Qnil);
-	  UNGCPRO;
 	  return 0;
 	}
       /* If the file was slurped into memory properly, parse it.  */
       success_p = svg_load_image (f, img, contents, size);
       xfree (contents);
-      UNGCPRO;
     }
   /* Else its not a file, its a lisp object.  Load the image from a
      lisp object rather than a file.  */
@@ -8069,6 +8070,11 @@
       Lisp_Object data;
 
       data = image_spec_value (img->spec, QCdata, NULL);
+      if (!STRINGP (data))
+	{
+	  image_error ("Invalid image data `%s'", data, Qnil);
+	  return 0;
+	}
       success_p = svg_load_image (f, img, SDATA (data), SBYTES (data));
     }
 
@@ -8368,7 +8374,6 @@
 {
   char buffer[100];
   Lisp_Object window_and_pixmap_id = Qnil, loader, pt_height, pt_width;
-  struct gcpro gcpro1, gcpro2;
   Lisp_Object frame;
   double in_width, in_height;
   Lisp_Object pixel_colors = Qnil;
@@ -8378,10 +8383,10 @@
      = 1/72 in, xdpi and ydpi are stored in the frame's X display
      info.  */
   pt_width = image_spec_value (img->spec, QCpt_width, NULL);
-  in_width = XFASTINT (pt_width) / 72.0;
+  in_width = INTEGERP (pt_width) ? XFASTINT (pt_width) / 72.0 : 0;
   img->width = in_width * FRAME_X_DISPLAY_INFO (f)->resx;
   pt_height = image_spec_value (img->spec, QCpt_height, NULL);
-  in_height = XFASTINT (pt_height) / 72.0;
+  in_height = INTEGERP (pt_height) ? XFASTINT (pt_height) / 72.0 : 0;
   img->height = in_height * FRAME_X_DISPLAY_INFO (f)->resy;
 
   if (!check_image_size (f, img->width, img->height))
@@ -8410,8 +8415,6 @@
      if successful.  We do not record_unwind_protect here because
      other places in redisplay like calling window scroll functions
      don't either.  Let the Lisp loader use `unwind-protect' instead.  */
-  GCPRO2 (window_and_pixmap_id, pixel_colors);
-
   sprintf (buffer, "%lu %lu",
 	   (unsigned long) FRAME_X_WINDOW (f),
 	   (unsigned long) img->pixmap);
@@ -8432,7 +8435,6 @@
 			      make_number (img->height),
 			      window_and_pixmap_id,
 			      pixel_colors);
-  UNGCPRO;
   return PROCESSP (img->data.lisp_val);
 }
 
@@ -8622,12 +8624,13 @@
 #endif
 
 #if defined (HAVE_IMAGEMAGICK)
-  if (EQ (type, Qimagemagick)){
-    /* MagickWandGenesis() initalizes the imagemagick library.  */
-    MagickWandGenesis(); 
-    return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
-                                libraries);
-  }
+  if (EQ (type, Qimagemagick))
+    {
+      /* MagickWandGenesis() initalizes the imagemagick library.  */
+      MagickWandGenesis ();
+      return CHECK_LIB_AVAILABLE (&imagemagick_type, init_imagemagick_functions,
+				  libraries);
+    }
 #endif
 
 #ifdef HAVE_GHOSTSCRIPT
@@ -8786,7 +8789,7 @@
   staticpro (&Qimagemagick);
   ADD_IMAGE_TYPE (Qimagemagick);
 #endif
-  
+
 #if defined (HAVE_RSVG)
   Qsvg = intern_c_string ("svg");
   staticpro (&Qsvg);
@@ -8803,9 +8806,9 @@
 #endif /* HAVE_RSVG  */
 
   defsubr (&Sinit_image_library);
-#ifdef HAVE_IMAGEMAGICK  
+#ifdef HAVE_IMAGEMAGICK
   defsubr (&Simagemagick_types);
-#endif  
+#endif
   defsubr (&Sclear_image_cache);
   defsubr (&Simage_flush);
   defsubr (&Simage_size);
@@ -8836,10 +8839,10 @@
 
 The function `clear-image-cache' disregards this variable.  */);
   Vimage_cache_eviction_delay = make_number (300);
-#ifdef HAVE_IMAGEMAGICK  
+#ifdef HAVE_IMAGEMAGICK
   DEFVAR_LISP ("imagemagick-render-type", &Vimagemagick_render_type,
                doc: /* Choose between ImageMagick render methods.  */);
-#endif    
+#endif
 
 }
 
--- a/src/nsimage.m	Fri Sep 03 06:22:01 2010 +0000
+++ b/src/nsimage.m	Sun Sep 05 22:45:59 2010 +0000
@@ -83,19 +83,21 @@
 ns_load_image (struct frame *f, struct image *img,
                Lisp_Object spec_file, Lisp_Object spec_data)
 {
-  EmacsImage *eImg;
+  EmacsImage *eImg = nil;
   NSSize size;
 
   NSTRACE (ns_load_image);
 
-  if (NILP (spec_data))
+  if (STRINGP (spec_file))
     {
       eImg = [EmacsImage allocInitFromFile: spec_file];
     }
-  else
+  else if (STRINGP (spec_data))
     {
-      NSData *data = [NSData dataWithBytes: SDATA (spec_data)
-                                    length: SBYTES (spec_data)];
+      NSData *data;
+
+      data = [NSData dataWithBytes: SDATA (spec_data)
+			    length: SBYTES (spec_data)];
       eImg = [[EmacsImage alloc] initWithData: data];
       [eImg setPixmapData];
     }
--- a/src/w32uniscribe.c	Fri Sep 03 06:22:01 2010 +0000
+++ b/src/w32uniscribe.c	Sun Sep 05 22:45:59 2010 +0000
@@ -180,17 +180,18 @@
 
 /* Uniscribe implementation of shape for font backend.
 
-   Shape text in LGSTRING.  See the docstring of `font-make-gstring'
-   for the format of LGSTRING.  If the (N+1)th element of LGSTRING
-   is nil, input of shaping is from the 1st to (N)th elements.  In
-   each input glyph, FROM, TO, CHAR, and CODE are already set.
+   Shape text in LGSTRING.  See the docstring of
+   `composition-get-gstring' for the format of LGSTRING.  If the
+   (N+1)th element of LGSTRING is nil, input of shaping is from the
+   1st to (N)th elements.  In each input glyph, FROM, TO, CHAR, and
+   CODE are already set.
 
    This function updates all fields of the input glyphs.  If the
    output glyphs (M) are more than the input glyphs (N), (N+1)th
    through (M)th elements of LGSTRING are updated possibly by making
    a new glyph object and storing it in LGSTRING.  If (M) is greater
-   than the length of LGSTRING, nil should be return.  In that case,
-   this function is called again with the larger LGSTRING.  */
+   than the length of LGSTRING, nil should be returned.  In that case,
+   this function is called again with a larger LGSTRING.  */
 static Lisp_Object
 uniscribe_shape (Lisp_Object lgstring)
 {
@@ -217,6 +218,9 @@
   max_glyphs = nchars = LGSTRING_GLYPH_LEN (lgstring);
   done_glyphs = 0;
   chars = (wchar_t *) alloca (nchars * sizeof (wchar_t));
+  /* FIXME: This loop assumes that characters in the input LGSTRING
+     are all inside the BMP.  Need to encode characters beyond the BMP
+     as UTF-16.  */
   for (i = 0; i < nchars; i++)
     {
       /* lgstring can be bigger than the number of characters in it, in
@@ -248,9 +252,6 @@
       return Qnil;
     }
 
-  /* TODO: When we get BIDI support, we need to call ScriptLayout here.
-     Requires that we know the surrounding context.  */
-
   glyphs = alloca (max_glyphs * sizeof (WORD));
   clusters = alloca (nchars * sizeof (WORD));
   attributes = alloca (max_glyphs * sizeof (SCRIPT_VISATTR));
@@ -259,8 +260,12 @@
 
   for (i = 0; i < nitems; i++)
     {
-      int nglyphs, nchars_in_run, rtl = items[i].a.fRTL ? -1 : 1;
+      int nglyphs, nchars_in_run;
       nchars_in_run = items[i+1].iCharPos - items[i].iCharPos;
+      /* Force ScriptShape to generate glyphs in the same order as
+	 they are in the input LGSTRING, which is in the logical
+	 order.  */
+      items[i].a.fLogicalOrder = 1;
 
       /* Context may be NULL here, in which case the cache should be
          used without needing to select the font.  */
@@ -321,7 +326,7 @@
 	    {
 	      int j, nclusters, from, to;
 
-	      from = rtl > 0 ? 0 : nchars_in_run - 1;
+	      from = 0;
 	      to = from;
 
 	      for (j = 0; j < nglyphs; j++)
@@ -342,22 +347,19 @@
 		  gl = glyphs[j];
 		  LGLYPH_SET_CODE (lglyph, gl);
 
-		  /* Detect clusters, for linking codes back to characters.  */
+		  /* Detect clusters, for linking codes back to
+		     characters.  */
 		  if (attributes[j].fClusterStart)
 		    {
-		      while (from >= 0 && from < nchars_in_run
-			     && clusters[from] < j)
-			from += rtl;
-		      if (from < 0)
-			from = to = 0;
-		      else if (from >= nchars_in_run)
+		      while (from < nchars_in_run && clusters[from] < j)
+			from++;
+		      if (from >= nchars_in_run)
 			from = to = nchars_in_run - 1;
 		      else
 			{
 			  int k;
-			  to = rtl > 0 ? nchars_in_run - 1 : 0;
-			  for (k = from + rtl; k >= 0 && k < nchars_in_run;
-			       k += rtl)
+			  to = nchars_in_run - 1;
+			  for (k = from + 1; k < nchars_in_run; k++)
 			    {
 			      if (clusters[k] > j)
 				{
@@ -486,6 +488,10 @@
           SCRIPT_VISATTR attrs[2];
           int nglyphs;
 
+	  /* Force ScriptShape to generate glyphs in the logical
+	     order.  */
+	  items[0].a.fLogicalOrder = 1;
+
           result = ScriptShape (context, &(uniscribe_font->cache),
                                 ch, len, 2, &(items[0].a),
                                 glyphs, clusters, attrs, &nglyphs);