diff --git a/asdf.asd b/asdf.asd
index ae49f410c59e715c940a353e55722c149d002ee8..69f00cc8137defa838b4c05261fe887a8bc1e94b 100644
--- a/asdf.asd
+++ b/asdf.asd
@@ -75,7 +75,7 @@
   :licence "MIT"
   :description "Another System Definition Facility"
   :long-description "ASDF builds Common Lisp software organized into defined systems."
-  :version "3.1.0.46" ;; to be automatically updated by make bump-version
+  :version "3.1.0.49" ;; to be automatically updated by make bump-version
   :depends-on ()
   #+asdf3 :encoding #+asdf3 :utf-8
   :class #.(if (find-class 'package-system nil) 'package-system 'system)
diff --git a/debian/changelog b/debian/changelog
index 9bb34879e907979879465be55816ecb8a7e5c3f8..aae214753d4923068a4e0e712dd5785464533b6a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -4,13 +4,15 @@ cl-asdf (2:3.1.1-1) unstable; urgency=low
   * asdf-package-system combines the one-file, one-package, one-system paradigm
     of quick-build and faslpath with the portability and robustness of ASDF 3.
   * Portability: much improved support for the latest GCL 2.8.
-  * Robustness: Fixes and tweaks for ABCL, CLISP, ECL, SBCL/Windows, XCL.
+  * Robustness: Fixes for ABCL, CLISP, ECL, LispWorks, SBCL/Windows, XCL.
     Test improvements. Added missing dependencies in asdf.asd(!).
     Fixes to version-satisfies (thanks to stassats) and to the file-stamp cache.
+    Fixes regression from 3.0.2.12 whereby ASDF failed to avoid downgrading.
+    Some cleanups in the operation class definitions.
   * run-program tweaked again on Windows;
     punting on trying to ensure no final space is ever echo'ed by CMD.EXE " ".
   * provide both "asdf" and "ASDF" to play nicer with various Lisps.
-  * Upgrading from a sufficiently forward-compatible version (currently: 2.27)
+  * Upgrading from a sufficiently forward-compatible version (currently: 2.33)
     will be less disruptive of ASDF uses and enhancements in the current image:
     previously loaded systems will not be cleared anymore,
     variables defined with defparameter* will not be reset.
@@ -20,7 +22,7 @@ cl-asdf (2:3.1.1-1) unstable; urgency=low
   * ASDF3.1 feature pushed, to signal the slew of significant improvements
     since initial ASDF 3.0 pre-release (i.e. version 2.27).
 
- -- Francois-Rene Rideau <fare@tunes.org>  Tue, 03 Jan 2014 15:10:56 -0500
+ -- Francois-Rene Rideau <fare@tunes.org>  Tue, 14 Jan 2014 00:28:00 -0500
 
 cl-asdf (2:3.0.3-1) unstable; urgency=low
 
diff --git a/find-system.lisp b/find-system.lisp
index 9606712c6976ac2d7920dc5294cba32da895daa6..84d53d27536e84fcbfa6a7233c78387b5d19f65f 100644
--- a/find-system.lisp
+++ b/find-system.lisp
@@ -309,14 +309,17 @@ Going forward, we recommend new users should be using the source-registry.
                (version (and (probe-file* version-pathname :truename nil)
                              (read-file-form version-pathname)))
                (old-version (asdf-version)))
-          (or (version<= old-version version)
-              (ensure-gethash
-               (list pathname old-version) *old-asdf-systems*
-                 #'(lambda ()
-                     (let ((old-pathname
-                             (if-let (pair (system-registered-p "asdf"))
-                               (system-source-file (cdr pair)))))
-                       (warn "~@<~
+          (cond
+            ((version< old-version version) t) ;; newer version: good!
+            ((equal old-version version) nil) ;; same version: don't load, but don't warn
+            (t ;; old version: bad
+             (ensure-gethash
+              (list (namestring pathname) version) *old-asdf-systems*
+              #'(lambda ()
+                 (let ((old-pathname
+                         (if-let (pair (system-registered-p "asdf"))
+                           (system-source-file (cdr pair)))))
+                   (warn "~@<~
         You are using ASDF version ~A ~:[(probably from (require \"asdf\") ~
         or loaded by quicklisp)~;from ~:*~S~] and have an older version of ASDF ~
         ~:[(and older than 2.27 at that)~;~:*~A~] registered at ~S. ~
@@ -338,8 +341,8 @@ Going forward, we recommend new users should be using the source-registry.
         then you might indeed want to either install and register a more recent version, ~
         or use :ignore-inherited-configuration to avoid registering the old one. ~
         Please consult ASDF documentation and/or experts.~@:>~%"
-                             old-version old-pathname version pathname)
-                       t)))))))
+                         old-version old-pathname version pathname))))
+             nil))))) ;; only issue the warning the first time, but always return nil
 
   (defun locate-system (name)
     "Given a system NAME designator, try to locate where to load the system from.
diff --git a/header.lisp b/header.lisp
index b285e7fed598574f64ce53a51f1479fabb787b9b..bc402189d76dcbd5dba84fb6bf9ae183e667bc25 100644
--- a/header.lisp
+++ b/header.lisp
@@ -1,5 +1,5 @@
 ;;; -*- mode: Common-Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp -*-
-;;; This is ASDF 3.1.0.46: Another System Definition Facility.
+;;; This is ASDF 3.1.0.49: Another System Definition Facility.
 ;;;
 ;;; Feedback, bug reports, and patches are all welcome:
 ;;; please mail to <asdf-devel@common-lisp.net>.
@@ -19,7 +19,7 @@
 ;;;  http://www.opensource.org/licenses/mit-license.html on or about
 ;;;  Monday; July 13, 2009)
 ;;;
-;;; Copyright (c) 2001-2012 Daniel Barlow and contributors
+;;; Copyright (c) 2001-2014 Daniel Barlow and contributors
 ;;;
 ;;; Permission is hereby granted, free of charge, to any person obtaining
 ;;; a copy of this software and associated documentation files (the
@@ -53,7 +53,7 @@
 (eval-when (:load-toplevel :compile-toplevel :execute)
   (setf ext:*gc-verbose* nil))
 
-#+(or abcl clozure cmu ecl xcl) ;; punt on hard package upgrade on those implementations
+;; Punt on hard package upgrade: from ASDF1 always, and even from ASDF2 on most implementations.
 (eval-when (:load-toplevel :compile-toplevel :execute)
   (unless (member :asdf3 *features*)
     (let* ((existing-version
@@ -70,7 +70,8 @@
            (existing-version-number (and existing-version (read-from-string existing-major-minor)))
            (away (format nil "~A-~A" :asdf existing-version)))
       (when (and existing-version
-                 (< existing-version-number 2.27))
+                 (< existing-version-number
+		    (or #+(or allegro clisp lispworks sbcl) 2.0 2.27)))
         (rename-package :asdf away)
         (when *load-verbose*
           (format t "~&; Renamed old ~A package away to ~A~%" :asdf away))))))
diff --git a/test/always-error.lisp b/test/always-error.lisp
new file mode 100644
index 0000000000000000000000000000000000000000..8c7d93688cede07a9c9948e6e2f3e39b0f4511c0
--- /dev/null
+++ b/test/always-error.lisp
@@ -0,0 +1,6 @@
+(in-package :asdf-test)
+
+(defparameter *always-error-was-read-p* t)
+
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  (error "ALWAYS ERROR"))
diff --git a/test/test-sysdef-asdf.script b/test/test-sysdef-asdf.script
index e3943185e328f7d60036552a85677675dc798b57..ca64760d6353442b9c9ca9fa696543bfc7c27204 100644
--- a/test/test-sysdef-asdf.script
+++ b/test/test-sysdef-asdf.script
@@ -1,23 +1,54 @@
 ;;; -*- Lisp -*-
 
-;; Empty configuration: no asdf.asd
+(format! t "~%Using ASDF ~A~%" (asdf-version))
+(assert (version< "3.0" (asdf-version))) ;; check that we have a recent enough ASDF
+
+(DBG "Try load ASDF with an empty configuration")
 (initialize-source-registry
  '(:source-registry :ignore-inherited-configuration))
 (load-system :asdf)
-;; We didn't find it and got the fallback
+;; We haven't found it, and got the fallback
 (assert-equal nil (system-source-file (find-system :asdf)))
 
-;; Proper configuration: asdf.asd from the source above
+;; Bogus sysdef finding function, for the sake of testing no-load-old-version.
+(defun sysdef-bogus-test-search (system)
+  (declare (ignore system))
+  (subpathname *test-directory* "always-error.lisp"))
+
+(let ((*system-definition-search-functions* '(sysdef-bogus-test-search))
+      (state "Didn't catch warning"))
+  (DBG "Bogus attempt at loading an old ASDF: should issue a warning and ignore")
+  (handler-bind
+      ((simple-warning
+         #'(lambda (c)
+             (when (search "ASDF will ignore this configured system rather than downgrade itself."
+                           (simple-condition-format-control c))
+               (setf state "Caught warning")))))
+      (upgrade-asdf))
+  (assert-equal state "Caught warning")
+  (DBG "2nd bogus attempt at loading same old ASDF: should ignore without a warning")
+  (handler-bind
+      ((simple-warning
+         #'(lambda (c)
+             (error "Should not have issued warning, but did issue:~%  ~A" c))))
+    (upgrade-asdf)))
+
+(DBG "Load ASDF with proper configuration: should find asdf.asd from the source above")
 (initialize-source-registry
  `(:source-registry
    (:directory ,*asdf-directory*)
    (:directory ,*uiop-directory*)
    :ignore-inherited-configuration))
 (load-system :asdf)
-;; This time we found it
+;; This time we found it, but it was skipped because the version was the same
+(assert-equal nil (system-source-file (find-system :asdf)))
+;; But if we cheat on our version, that should work
+(setf asdf::*asdf-version* "3.0")
+(load-system :asdf)
 (assert-pathname-equal (subpathname *asdf-directory* "asdf.asd")
                        (system-source-file (find-system :asdf)))
 
+(DBG "Checking that Makefile and asdf.asd are in synch")
 (defun system-lisp-files (system)
   (loop :for f :in (required-components system :keep-component 'cl-source-file)
         :collect (namestring (enough-pathname (component-pathname f) *asdf-directory*))))
diff --git a/test/test-utilities.script b/test/test-utilities.script
index b2a5eb576b81c224b1ba7112d758f2a3be425c0e..3daaaf26031ba299457e3d7aebc9764fd8f30fd3 100644
--- a/test/test-utilities.script
+++ b/test/test-utilities.script
@@ -274,3 +274,16 @@
           p)))
   (assert-equal (read-file-lines pn) '("Hello, World"))
   (delete-file pn))
+
+(DBG :ensure-gethash)
+(let ((h (make-hash-table :test 'equal)))
+  (assert-equal (multiple-value-list (gethash 1 h 2)) '(2 nil))
+  (assert-equal (multiple-value-list (ensure-gethash 1 h 2)) '(2 nil))
+  (assert-equal (multiple-value-list (gethash 1 h 2)) '(2 t))
+  (assert-equal (multiple-value-list (ensure-gethash 1 h 3)) '(2 t))
+  (assert-equal (multiple-value-list (ensure-gethash 1 h '(error "foo"))) '(2 t))
+  (signals parse-error (ensure-gethash 2 h '(error parse-error)))
+  (assert-equal (multiple-value-list (gethash 3 h nil)) '(nil nil))
+  (assert-equal (multiple-value-list (ensure-gethash 3 h nil)) '(nil nil))
+  (assert-equal (multiple-value-list (gethash 3 h 4)) '(nil t))
+  (assert-equal (multiple-value-list (ensure-gethash 3 h 5)) '(nil t)))
diff --git a/uiop/image.lisp b/uiop/image.lisp
index e965c886cffe8d186050a53d80c233fad690d670..bc9e42519da382bfe0378e681b617869b949a298 100644
--- a/uiop/image.lisp
+++ b/uiop/image.lisp
@@ -291,6 +291,7 @@ by setting appropriate variables, running various hooks, and calling any specifi
                                 (postlude *image-postlude*)
                                 (dump-hook *image-dump-hook*)
                                 #+clozure prepend-symbols #+clozure (purify t)
+                                #+sbcl compression
                                 #+(and sbcl windows) application-type)
     "Dump an image of the current Lisp environment at pathname FILENAME, with various options"
     ;; Note: at least SBCL saves only global values of variables in the heap image,
@@ -353,10 +354,13 @@ by setting appropriate variables, running various hooks, and calling any specifi
       (setf sb-ext::*gc-run-time* 0)
       (apply 'sb-ext:save-lisp-and-die filename
              :executable t ;--- always include the runtime that goes with the core
-             (when executable (list :toplevel #'restore-image :save-runtime-options t)) ;--- only save runtime-options for standalone executables
-             #+(and sbcl windows) ;; passing :application-type :gui will disable the console window.
-             ;; the default is :console - only works with SBCL 1.1.15 or later.
-             (when application-type (list :application-type application-type))))
+             (append
+              (when compression (list :compression compression))
+              ;;--- only save runtime-options for standalone executables
+              (when executable (list :toplevel #'restore-image :save-runtime-options t))
+              #+(and sbcl windows) ;; passing :application-type :gui will disable the console window.
+              ;; the default is :console - only works with SBCL 1.1.15 or later.
+              (when application-type (list :application-type application-type)))))
     #-(or allegro clisp clozure cmu gcl lispworks sbcl scl)
     (error "Can't ~S ~S: UIOP doesn't support image dumping with ~A.~%"
            'dump-image filename (nth-value 1 (implementation-type))))
diff --git a/uiop/utility.lisp b/uiop/utility.lisp
index bd645498928660da2f07d86cad7778838e7ff24c..48dd4759a139a799e184ed813bf6f69ba50634b0 100644
--- a/uiop/utility.lisp
+++ b/uiop/utility.lisp
@@ -438,13 +438,16 @@ When CALL-NOW-P is true, also call the function immediately."
 ;;; Hash-tables
 (with-upgradability ()
   (defun ensure-gethash (key table default)
-    "Lookup the TABLE for a KEY as by gethash, but if not present,
+    "Lookup the TABLE for a KEY as by GETHASH, but if not present,
 call the (possibly constant) function designated by DEFAULT as per CALL-FUNCTION,
-set the corresponding entry to the result in the table, and return that result."
+set the corresponding entry to the result in the table.
+Return two values: the entry after its optional computation, and whether it was found"
     (multiple-value-bind (value foundp) (gethash key table)
-      (if foundp
-          value
-          (setf (gethash key table) (values (call-function default))))))
+      (values
+       (if foundp
+           value
+           (setf (gethash key table) (call-function default)))
+       foundp)))
 
   (defun list-to-hash-set (list &aux (h (make-hash-table :test 'equal)))
     "Convert a LIST into hash-table that has the same elements when viewed as a set,
diff --git a/upgrade.lisp b/upgrade.lisp
index b113ba35948575805bd693d553f88f61d056c4d2..b7d1073a47d2780c143c699c0bbf41275a1f7cd3 100644
--- a/upgrade.lisp
+++ b/upgrade.lisp
@@ -64,7 +64,7 @@ You can compare this string with e.g.: (ASDF:VERSION-SATISFIES (ASDF:ASDF-VERSIO
          ;; "3.4.5.67" would be a development version in the official branch, on top of 3.4.5.
          ;; "3.4.5.0.8" would be your eighth local modification of official release 3.4.5
          ;; "3.4.5.67.8" would be your eighth local modification of development version 3.4.5.67
-         (asdf-version "3.1.0.46")
+         (asdf-version "3.1.0.49")
          (existing-version (asdf-version)))
     (setf *asdf-version* asdf-version)
     (when (and existing-version (not (equal asdf-version existing-version)))
diff --git a/version.lisp-expr b/version.lisp-expr
index f5aa3834203ab42608621325f0de5687f207abb4..4cde0f6ce5db9b0e3f5d712d815a00001d3a5018 100644
--- a/version.lisp-expr
+++ b/version.lisp-expr
@@ -1,2 +1,2 @@
-"3.1.0.46"
+"3.1.0.49"