diff --git a/.gitignore b/.gitignore
index 4a7c338733b8606c319aff7a3eea1e2ac2511141..15bf22137f44bbabbd51b4830d21042139ff7096 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1,9 @@
 # really this is private to my build process
-make/
-common-lisp.net
-.vcs
-init-lisp.lisp
-website/changelog.xml
 push
 resbcl
 reccl
+reecl
+regcl
 
 # Temporary files from documentation build
 doc/asdf/
@@ -26,17 +23,18 @@ doc/asdf.tp
 doc/asdf.vr
 doc/asdf.vrs
 
-# We build these at various stages in the make process
+# We build these at various stages in the build and test process
 LICENSE
-website/output/
 tmp/
-lift-local.config
 *.dribble
 *.fasl
 *.dfsl
 *.cfsl
 *.fas
 *.lib
-*.o
+*.[oahcisS]
 *.*fsl
 *.bak
+*.data
+test/try-reloading-dependency.asd
+test/fileMissing.lisp
diff --git a/GNUmakefile b/GNUmakefile
index ad952fd3640fe18a4db9b2cca9cf7287547c48d7..b2186b2ef63d900537e5999255692e4f2b89cf71 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -7,11 +7,12 @@ clnet_home      := "/project/asdf/public_html/"
 
 sourceDirectory := $(shell pwd)
 
-lisps = allegro allegromodern ccl clisp sbcl
+lisps ?= allegro ccl clisp ecl sbcl
+## not tested by me: abcl allegromodern cmucl lisworks
+## FAIL: gclcvs
+## maybe supported by asdf, not supported yet by our tests: cormancl mcl scl
 
-ifndef lisp
-lisp := sbcl
-endif
+lisp ?= sbcl
 
 # website, tag, install
 
@@ -26,11 +27,12 @@ archive: FORCE
 	bin/build-tarball.sh
 
 archive-copy: archive
+	git checkout release
 	bin/rsync-cp.sh tmp/asdf*.tar.gz $(webhome_private)/archives
 	bin/link-tarball.sh $(clnet_home) $(user)
 	bin/rsync-cp.sh tmp/asdf.lisp $(webhome_private)
-	git push cl.net
-	git push --tags cl.net
+	git push cl.net release
+	git push --tags cl.net release
 
 website:
 	make -C doc website
@@ -54,13 +56,11 @@ clean: FORCE
 	make -C doc clean
 
 test: FORCE
-	@cd test; make clean;./run-tests.sh $(lisp) $(test-regex)
+	@cd test; make clean;./run-tests.sh ${lisp} ${test-glob}
 
 test-all: FORCE
-	@for lisp in $(lisps); do \
-		make test lisp=$$lisp; \
+	@for lisp in ${lisps} ; do \
+		make test lisp=$$lisp || exit 1 ; \
 	done
-	sbcl --userinit /dev/null --sysinit /dev/null --load bin/make-helper.lisp \
-		--eval "(write-test-web-pages)" --eval "(quit)"
 
 FORCE:
diff --git a/README b/README
index 95229e32e6e9befb8ffe10352cbd4a6ea42fadbb..eb604a420c68aeab8a87aeb64f30c3e93a2da01c 100644
--- a/README
+++ b/README
@@ -1,20 +1,20 @@
 ASDF: another system definition facility
 ========================================
 
-If you want to use ASDF to load systems, see the getting
-started guide at:
+If you want to use ASDF, read our manual:
 
-    http://common-lisp.net/project/asdf/getting-started.html
+    http://common-lisp.net/project/asdf/asdf.html
 
-If you want to define your own systems, see the manual at:
+The first few sections, Loading ASDF, Configuring ASDF and Using ASDF,
+will get you started as a simple user.
 
-    http://common-lisp.net/project/asdf/manual.html
+If you want to define your own systems, further read the section
+Defining systems with defsystem.
 
 More information and additional links can be found on ASDF's
 home page at:
 
-    http://common-lisp.net/project/asdf
+    http://common-lisp.net/project/asdf/
 
 
-
-last updated Saturday; July 18, 2009, 10:20 AM EDT
+last updated Wednesday; May 5, 2010
diff --git a/asdf-ecl.lisp b/asdf-ecl.lisp
index acec80f7c51aae828945193b6c88776d16896aae..3cf857511e3210095596693555822c63df15b55c 100644
--- a/asdf-ecl.lisp
+++ b/asdf-ecl.lisp
@@ -5,14 +5,14 @@
 ;;;   License as published by the Free Software Foundation; either
 ;;;   version 2 of the License, or (at your option) any later version.
 ;;;
-;;;   See file '../../Copyright' for full details.
+;;;   See file 'ecl/Copyright' for full details.
 ;;;
 ;;; ECL SPECIFIC OPERATIONS FOR ASDF
 ;;;
 #+xcvb (module (:depends-on ("asdf")))
 
 (in-package :asdf)
-(require 'cmp)
+(require :cmp)
 
 ;;;
 ;;; COMPILE-OP / LOAD-OP
@@ -52,12 +52,12 @@
    (prologue-code :accessor monolithic-op-prologue-code)
    (epilogue-code :accessor monolithic-op-epilogue-code)))
 
-(defclass monolithic-fasl-op (fasl-op monolithic-bundle-op) ())
+(defclass monolithic-fasl-op (monolithic-bundle-op fasl-op) ())
 
-(defclass monolithic-lib-op (lib-op monolithic-bundle-op)
+(defclass monolithic-lib-op (monolithic-bundle-op lib-op)
   ((type :initform :lib)))
 
-(defclass monolithic-dll-op (dll-op monolithic-bundle-op)
+(defclass monolithic-dll-op (monolithic-bundle-op dll-op)
   ((type :initform :dll)))
 
 (defclass program-op (monolithic-bundle-op)
@@ -66,6 +66,7 @@
 (defmethod initialize-instance :after ((instance bundle-op) &rest initargs
                                        &key (name-suffix nil name-suffix-p)
                                        &allow-other-keys)
+  (declare (ignorable initargs name-suffix))
   (unless name-suffix-p
     (setf (slot-value instance 'name-suffix)
           (if (bundle-op-monolithic-p instance) "-mono" "")))
@@ -84,6 +85,7 @@
 (defvar *force-load-p* nil)
 
 (defmethod operation-done-p :around ((operation load-op) c)
+  (declare (ignorable operation c))
   (if *force-load-p* nil (call-next-method)))
 
 (defun gather-components (op-type system &key filter-system filter-type include-self)
@@ -122,6 +124,7 @@
 ;;; Gather the static libraries of all components.
 ;;;
 (defmethod bundle-sub-operations ((o monolithic-bundle-op) c)
+  (declare (ignorable o))
   (gather-components 'lib-op c :filter-type 'system :include-self t))
 ;;;
 ;;; STATIC LIBRARIES
@@ -141,6 +144,7 @@
 ;;; with the static library of this module.
 ;;;
 (defmethod bundle-sub-operations ((o dll-op) c)
+  (declare (ignorable o))
   (list (cons (make-instance 'lib-op) c)))
 ;;;
 ;;; FASL FILES
@@ -148,6 +152,7 @@
 ;;; Gather the statically linked library of this component.
 ;;;
 (defmethod bundle-sub-operations ((o fasl-op) c)
+  (declare (ignorable o))
   (list (cons (make-instance 'lib-op) c)))
 
 (defmethod component-depends-on ((o bundle-op) (c system))
@@ -157,9 +162,11 @@
                    (component-name dep))))
 
 (defmethod component-depends-on ((o lib-op) (c system))
+  (declare (ignorable o))
   (list (list 'compile-op (component-name c))))
 
 (defmethod component-depends-on ((o bundle-op) c)
+  (declare (ignorable o c))
   nil)
 
 (defmethod input-files ((o bundle-op) (c system))
@@ -173,17 +180,21 @@
                             (component-relative-pathname c)))))
 
 (defmethod output-files ((o fasl-op) (c system))
+  (declare (ignorable o c))
   (loop for file in (call-next-method)
      collect (make-pathname :type "fasb" :defaults file)))
 
 (defmethod perform ((o bundle-op) (c t))
+  (declare (ignorable o c))
   t)
 
 (defmethod operation-done-p ((o bundle-op) (c source-file))
+  (declare (ignorable o c))
   t)
 
 (defmethod perform ((o bundle-op) (c system))
-  (let* ((object-files (remove "fas" (input-files o c) :key #'pathname-type :test #'string=))
+  (let* ((object-files (remove "fas" (input-files o c)
+                               :key #'pathname-type :test #'string=))
          (output (output-files o c)))
     (ensure-directories-exist (first output))
     (apply #'c::builder (bundle-op-type o) (first output) :lisp-files object-files
@@ -197,6 +208,8 @@
 
 (defun select-operation (monolithic type)
   (ecase type
+    ((:binary)
+     (if monolithic 'monolithic-binary-op 'binary-op))
     ((:dll :shared-library)
      (if monolithic 'monolithic-dll-op 'dll-op))
     ((:lib :static-library)
@@ -206,37 +219,31 @@
     ((:program)
      'program-op)))
 
-
 (defun make-build (system &rest args &key (monolithic nil) (type :fasl)
                    (move-here nil move-here-p)
                    &allow-other-keys)
   (let* ((operation-name (select-operation monolithic type))
+         (move-here-path (if (and move-here
+                                  (typep move-here '(or pathname string)))
+                             (pathname move-here)
+                             (merge-pathnames "./asdf-output/")))
          (operation (apply #'operate operation-name
                            system
                            (remove-keys '(monolithic type move-here) args)))
          (system (find-system system))
          (files (and system (output-files operation system))))
-    (print files)
-    (print move-here)
-    (if (or move-here
-            (and (null move-here-p)
-                 (member operation-name '(:program))))
-        (loop for path in files
-           for filename = (namestring (truename path))
-           for new-path = (make-pathname :name (pathname-name path)
-                                         :type (pathname-type path)
-                                         :defaults *default-pathname-defaults*)
-           for new-filename = (namestring new-path)
-           for command =
-             #+windows
-             (format nil "move ~S ~S" filename new-filename)
-             #-windows
-             (format nil "mv ~S ~S" filename new-filename)
-           do (unless (equalp new-filename filename)
-                (when (plusp (si::system (print command)))
-                  (error "Unable to move file~&  ~S~&to new location~&  ~S"
-                         path new-path)))
-           collect new-path)
+    (if (or move-here (and (null move-here-p)
+                           (member operation-name '(:program :binary))))
+        (loop with dest-path = (truename (ensure-directories-exist move-here-path))
+           for f in files
+           for new-f = (make-pathname :name (pathname-name f)
+                                      :type (pathname-type f)
+                                      :defaults dest-path)
+           do (progn
+                (when (probe-file new-f)
+                  (delete-file new-f))
+                (rename-file f new-f))
+           collect new-f)
         files)))
 
 ;;;
@@ -251,16 +258,19 @@
   (every #'(lambda (c) (typep c 'compiled-file)) (module-components c)))
 
 (defmethod component-depends-on ((o load-fasl-op) (c system))
+  (declare (ignorable o))
   (unless (trivial-system-p c)
     (subst 'load-fasl-op 'load-op
            (subst 'fasl-op 'compile-op
                   (component-depends-on (make-instance 'load-op) c)))))
 
 (defmethod input-files ((o load-fasl-op) (c system))
+  (declare (ignore o))
   (unless (trivial-system-p c)
     (output-files (make-instance 'fasl-op) c)))
 
 (defmethod perform ((o load-fasl-op) (c t))
+  (declare (ignore o c))
   nil)
 
 (defmethod perform ((o load-fasl-op) (c system))
@@ -287,14 +297,19 @@
     :type "fas")))
 
 (defmethod output-files (o (c compiled-file))
+  (declare (ignore o c))
   nil)
 (defmethod input-files (o (c compiled-file))
+  (declare (ignore o c))
   nil)
 (defmethod perform ((o load-op) (c compiled-file))
+  (declare (ignore o))
   (load (component-pathname c)))
 (defmethod perform ((o load-fasl-op) (c compiled-file))
+  (declare (ignore o))
   (load (component-pathname c)))
 (defmethod perform (o (c compiled-file))
+  (declare (ignore o c))
   nil)
 
 ;;;
@@ -304,6 +319,7 @@
   ((static-library :accessor prebuilt-system-static-library :initarg :lib)))
 
 (defmethod output-files ((o lib-op) (c prebuilt-system))
+  (declare (ignore o))
   (values (list (compile-file-pathname (prebuilt-system-static-library c)
                                        :type :lib))
           t ; Advertise that we do not want this path renamed
@@ -313,22 +329,89 @@
   (car (output-files o c)))
 
 (defmethod component-depends-on ((o lib-op) (c prebuilt-system))
+  (declare (ignorable o c))
   nil)
 
 (defmethod bundle-sub-operations ((o lib-op) (c prebuilt-system))
+  (declare (ignorable o c))
   nil)
 
 (defmethod bundle-sub-operations ((o monolithic-lib-op) (c prebuilt-system))
+  (declare (ignorable o))
   (error "Prebuilt system ~S shipped with ECL can not be used in a monolithic library operation." c))
 
 (defmethod bundle-sub-operations ((o monolithic-bundle-op) (c prebuilt-system))
+  (declare (ignorable o c))
   nil)
 
+;;;
+;;; PREBUILT SYSTEM CREATOR
+;;;
+
+(defclass binary-op (bundle-op)
+  ())
+
+(defclass monolithic-binary-op (binary-op monolithic-bundle-op)
+  ())
+
+(defun binary-op-dependencies (o s)
+  (let (lib-op fasl-op)
+    (if (bundle-op-monolithic-p o)
+        (setf lib-op 'monolithic-lib-op
+              fasl-op 'monolithic-fasl-op)
+        (setf lib-op 'lib-op
+              fasl-op 'fasl-op))
+    (list (list (make-instance lib-op :args (bundle-op-build-args o))
+                s)
+          (list (make-instance fasl-op :args (bundle-op-build-args o))
+                s))))
+
+(defmethod component-depends-on ((o binary-op) (s system))
+  (loop for dep in (binary-op-dependencies o s)
+     append (apply #'component-depends-on dep)))
+
+(defmethod input-files ((o binary-op) (s system))
+  (loop for dep in (binary-op-dependencies o s)
+     append (apply #'input-files dep)))
+
+(defmethod output-files ((o binary-op) (s system))
+  (list* (merge-pathnames* (make-pathname :name (component-name s)
+                                          :type "asd")
+                           (component-relative-pathname s))
+         (loop for dep in (binary-op-dependencies o s)
+            append (apply #'output-files dep))))
+
+(defmethod perform ((o binary-op) (s system))
+  (let* ((dependencies (binary-op-dependencies o s))
+         (library (first (apply #'output-files (first dependencies))))
+         (fasl (first (apply #'output-files (second dependencies))))
+         (filename (first (output-files o s)))
+         (name (component-name s))
+         (name-keyword (intern (string name) (find-package :keyword))))
+    (loop for dep in dependencies
+       do (apply #'perform dep))
+    (with-open-file (s filename :direction :output :if-exists :supersede
+                       :if-does-not-exist :create)
+      (format s ";;; Prebuilt ASDF definition for system ~A" name)
+      (format s ";;; Built for ~A ~A on a ~A/~A ~A"
+              (lisp-implementation-type)
+              (lisp-implementation-version)
+              (software-type)
+              (machine-type)
+              (software-version))
+      (let ((*package* (find-package :keyword)))
+        (pprint `(defsystem ,name-keyword
+                     :class asdf::prebuilt-system
+                     :components ((:compiled-file ,(pathname-name fasl)))
+                     :lib ,(make-pathname :name (pathname-name library)
+                                          :type (pathname-type library)))
+                s)))))
+
 ;;;
 ;;; Final integration steps
 ;;;
 
-(export '(make-build load-fasl-op))
+(export '(make-build load-fasl-op prebuilt-system))
 (push '("fasb" . si::load-binary) si::*load-hooks*)
 
 (require 'cmp)
diff --git a/asdf-install.lisp b/asdf-install.lisp
deleted file mode 100644
index 9813f29c893837576abdbb574e8b843b34f83288..0000000000000000000000000000000000000000
--- a/asdf-install.lisp
+++ /dev/null
@@ -1,299 +0,0 @@
-#|| sh asdf-install.lisp will compile this file to an exe called asdf-install
-sbcl <<EOF
-(require 'sb-executable)
-(compile-file "asdf-install.lisp")
-(sb-executable:make-executable "asdf-install" *)
-EOF
-exit 0
-||#
-
-;;; Install an ASDF system or anything else that looks convincingly
-;;; like one, including updating symlink for all the toplevel .asd files it
-;;; contains
-
-;;; If the file $HOME/.asdf-install exists, it is loaded.  This can be
-;;; used to override the default values of exported special variables
-;;; (see the defpackage form for details) - however, most of them are
-;;; sensible and/or taken from the environment anyway
-
-#||
-TODO:
-a) gpg signature checking would be better if it actually checked against
-a list of "trusted to write Lisp" keys, instead of just "trusted to be
-who they say they are"
-
-d) in sbcl 0.8.1 we'll have a run-program that knows about $PATH and so
-won't need to hardcode gpgpgpgp and tar locations.
-
-e) nice to have: resume half-done downloads instead of starting from scratch
-every time.  but right now we're dealing in fairly small packages, this is not
-an immediate concern
-
-||#
-(in-package :cl-user)
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  (require 'asdf)
-  (require 'sb-posix)
-  (require 'sb-executable)
-  (require 'sb-bsd-sockets))
-
-(defpackage :asdf-install
-  (:use "CL" "SB-EXT"  "SB-BSD-SOCKETS")
-  (:export #:*proxy* #:*cclan-mirror* #:*sbcl-home*
-           #:*verify-gpg-signatures* #:*locations*))
-
-(defpackage :asdf-install-customize
-  (:use "CL" "SB-EXT"  "SB-BSD-SOCKETS" "ASDF-INSTALL"))
-
-(in-package :asdf-install)
-
-(defvar *proxy* (posix-getenv "http_proxy"))
-(defvar *cclan-mirror*
-  (or (posix-getenv "CCLAN_MIRROR")
-      "http://ftp.linux.org.uk/pub/lisp/cclan/"))
-
-(defun directorify (name)
-  ;; input name may or may not have a training #\/, but we know we
-  ;; want a directory
-  (let ((path (pathname name)))
-    (if (pathname-name path)
-        (merge-pathnames
-         (make-pathname :directory `(:relative ,(pathname-name path))
-                        :name "")
-         path)
-        path)))
-
-(defvar *sbcl-home* (directorify (posix-getenv "SBCL_HOME")))
-(defvar *dot-sbcl*
-  (merge-pathnames (make-pathname :directory '(:relative ".sbcl"))
-                   (user-homedir-pathname)))
-
-(defvar *verify-gpg-signatures* t)
-
-(defvar *locations*
-  `((,(merge-pathnames "site/" *sbcl-home*)
-     ,(merge-pathnames "site-systems/" *sbcl-home*)
-     "System-wide install")
-    (,(merge-pathnames "site/" *dot-sbcl*)
-     ,(merge-pathnames "systems/" *dot-sbcl*)
-     "Personal installation")))
-
-(let* ((*package* (find-package :asdf-install-customize))
-       (file (probe-file (merge-pathnames
-                          (make-pathname :name ".asdf-install")
-                          (user-homedir-pathname)))))
-  (when file (load file)))
-
-(define-condition download-error (error)
-  ((url :initarg :url :reader download-url)
-   (response :initarg :response :reader download-response))
-  (:report (lambda (c s)
-             (format s "Server responded ~A for GET ~A"
-                     (download-response c) (download-url c)))))
-
-(define-condition signature-error (error)
-  ((cause :initarg :cause :reader signature-error-cause))
-  (:report (lambda (c s)
-             (format s "Cannot verify package signature:  ~A"
-                     (signature-error-cause c)))))
-
-(defun url-host (url)
-  (assert (string-equal url "http://" :end1 7))
-  (let* ((port-start (position #\: url :start 7))
-         (host-end (min (or (position #\/ url :start 7) (length url))
-                        (or port-start (length url)))))
-    (subseq url 7 host-end)))
-
-(defun url-port (url)
-  (assert (string-equal url "http://" :end1 7))
-  (let ((port-start (position #\: url :start 7)))
-    (if port-start (parse-integer url :start port-start :junk-allowed t) 80)))
-
-(defun url-connection (url)
-  (let ((s (make-instance 'inet-socket :type :stream :protocol :tcp))
-        (host (url-host url))
-        (port (url-port url)))
-    (socket-connect
-     s (car (host-ent-addresses (get-host-by-name (url-host (or *proxy* url)))))
-     (url-port (or  *proxy* url)))
-    (let ((stream (socket-make-stream s :input t :output t :buffering :full)))
-      ;; we are exceedingly unportable about proper line-endings here.
-      ;; Anyone wishing to run this under non-SBCL should take especial care
-      (format stream "GET ~A HTTP/1.0~%Host: ~A~%Cookie: CCLAN-SITE=~A~%~%"
-              url host *cclan-mirror*)
-      (force-output stream)
-      (list
-       (let* ((l (read-line stream))
-              (space (position #\Space l)))
-         (parse-integer l :start (1+ space) :junk-allowed t))
-       (loop for line = (read-line stream nil nil)
-             until (or (null line) (eql (elt line 0) (code-char 13)))
-             collect
-             (let ((colon (position #\: line)))
-               (cons (intern (string-upcase (subseq line 0 colon)) :keyword)
-                     (string-trim (list #\Space (code-char 13))
-                                  (subseq line (1+ colon))))))
-       stream))))
-
-(defun download (package-name-or-url file-name)
-  (let ((url
-         (if (= (mismatch package-name-or-url "http://") 7)
-             package-name-or-url
-             (format nil "http://www.cliki.net/~A?download"
-                     package-name-or-url))))
-    (destructuring-bind (response headers stream)
-        (block got
-          (loop
-           (destructuring-bind (response headers stream) (url-connection url)
-             (unless (member response '(301 302))
-               (return-from got (list response headers stream)))
-             (close stream)
-             (setf url (cdr (assoc :location headers))))))
-      (if (>= response 400)
-        (error 'download-error :url url :response response))
-      (let ((length (parse-integer
-                     (or (cdr (assoc :content-length headers)) "")
-                     :junk-allowed t)))
-        (format t "Downloading ~A bytes from ~A ..."
-                (if length length "some unknown number of") url)
-        (force-output)
-        (with-open-file (o file-name :direction :output)
-          (if length
-              (let ((buf (make-array length
-                                     :element-type
-                                     (stream-element-type stream)  )))
-                (read-sequence buf stream)
-                (write-sequence buf o))
-              (sb-executable:copy-stream stream o))))
-      (close stream)
-      (terpri)
-      ;; seems to have worked.  let's try for a detached gpg signature too
-      (when *verify-gpg-signatures*
-        (verify-gpg-signature url file-name)))))
-
-(defun verify-gpg-signature (url file-name)
-  (destructuring-bind (response headers stream)
-      (url-connection (concatenate 'string url ".asc"))
-    (declare (ignore headers))
-    (unwind-protect
-         (if (= response 200)
-             ;; sadly, we can't pass the stream directly to run-program,
-             ;; because (at least in sbcl 0.8) that ignores existing buffered
-             ;; data and only reads new fresh data direct from the file
-             ;; descriptor
-             (let ((data (make-string (parse-integer
-                                       (cdr (assoc :content-length headers))
-                                       :junk-allowed t))))
-               (read-sequence data stream)
-               (let ((ret
-                      (process-exit-code
-                       (sb-ext:run-program "/usr/bin/gpg"
-                                           (list "--verify" "-"
-                                                 (namestring file-name))
-                                           :output t
-                                           :input (make-string-input-stream data)
-                                           :wait t))))
-                 (unless (zerop ret)
-                   (error 'signature-error
-                          :cause (make-condition
-                                  'simple-error
-                                  :format-control "GPG returned exit status ~A"
-                                  :format-arguments (list ret))))))
-             (error 'signature-error
-                    :cause
-                    (make-condition
-                     'download-error :url  (concatenate 'string url ".asc")
-                     :response response)))
-      (close stream))))
-
-
-
-
-(defun where ()
-  (format t "Install where?~%")
-  (loop for (source system name) in *locations*
-        for i from 1
-        do (format t "~A) ~A: ~%   System in ~A~%   Files in ~A ~%"
-                   i name system source))
-  (format t " --> ") (force-output)
-  (let ((response (read)))
-    (when (> response 0)
-      (elt *locations* (1- response)))))
-
-(defun install (source system packagename)
-  "Returns a list of asdf system names for installed asdf systems"
-  (ensure-directories-exist source )
-    (ensure-directories-exist system )
-  (let* ((tar
-          (with-output-to-string (o)
-            (or
-             (sb-ext:run-program "/bin/tar"
-                                 (list "-C" (namestring source)
-                                       "-xzvf" (namestring packagename))
-                                 :output o
-                                 :wait t)
-             (error "can't untar"))))
-         (dummy (princ tar))
-         (pos-slash (position #\/ tar))
-         (*default-pathname-defaults*
-          (merge-pathnames
-           (make-pathname :directory
-                          `(:relative ,(subseq tar 0 pos-slash)))
-           source)))
-    (loop for asd in (directory
-                      (make-pathname :name :wild :type "asd"))
-          do (let ((target (merge-pathnames
-                            (make-pathname :name (pathname-name asd)
-                                           :type (pathname-type asd))
-                            system)))
-               (when (probe-file target)
-                 (sb-posix:unlink target))
-               (sb-posix:symlink asd target))
-          collect (pathname-name asd))))
-
-(defvar *temporary-files*)
-(defun temp-file-name (p)
-  (let* ((pos-slash (position #\/ p :from-end t))
-         (pos-dot (position #\. p :start (or pos-slash 0))))
-    (merge-pathnames
-     (make-pathname
-      :name (subseq p (if pos-slash (1+ pos-slash) 0) pos-dot)
-      :type "asdf-install-tmp"))))
-
-
-
-(defun run (&optional (packages (cdr *posix-argv*)))
-  (destructuring-bind (source system name) (where)
-    (labels ((one-iter (packages)
-               (dolist (asd
-                         (loop for p in packages
-                               unless (probe-file p)
-                               do (let ((tmp (temp-file-name p)))
-                                    (pushnew tmp *temporary-files*)
-                                    (download p tmp)
-                                    (setf p tmp))
-                               end
-                               do (format t "Installing ~A in ~A,~A~%" p source system)
-                               append (install source system p)))
-                 (handler-case
-                     (asdf:operate 'asdf:load-op asd)
-                   (asdf:missing-dependency (c)
-                     (format t "Downloading package ~A, required by ~A~%"
-                             (asdf::missing-requires c)
-                             (asdf:component-name (asdf::missing-required-by c)))
-                     (one-iter (list
-                                (symbol-name (asdf::missing-requires c)))))))))
-      (one-iter packages))))
-
-(handler-case
-    (let ((*temporary-files* nil))
-      (unwind-protect
-           (run)
-        (dolist (l *temporary-files*)
-          (when (probe-file l) (delete-file l)))))
-  (error (c)
-    (princ "Install failed due to error:") (terpri)
-    (princ c) (terpri)
-    (quit :unix-status 1)))
-
-;(quit)
\ No newline at end of file
diff --git a/asdf.asd b/asdf.asd
index 57f5cdf13638c446cd1aa5845b6fcc90251bf452..0645d3a891df2ea37d44ec9f633d7e2ceb1c73f1 100644
--- a/asdf.asd
+++ b/asdf.asd
@@ -3,7 +3,7 @@
 ;;;                                                                  ;;;
 ;;; Free Software available under an MIT-style license.              ;;;
 ;;;                                                                  ;;;
-;;; Copyright (c) 2001-2009 Daniel Barlow and contributors           ;;;
+;;; Copyright (c) 2001-2010 Daniel Barlow and contributors           ;;;
 ;;;                                                                  ;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 
diff --git a/asdf.lisp b/asdf.lisp
index 16a55dbd2a24b557c19be69e70d84bb0f8809356..4c92cb1b6a3d6d76add65b5afa4e1f5016e91faf 100644
--- a/asdf.lisp
+++ b/asdf.lisp
@@ -47,238 +47,288 @@
 
 #+xcvb (module ())
 
-(cl:in-package :cl-user)
+(cl:in-package :cl)
+(defpackage :asdf-bootstrap (:use :cl))
+(in-package :asdf-bootstrap)
 
-(declaim (optimize (speed 2) (debug 2) (safety 3)))
-
-#+ecl (require :cmp)
+;; Implementation-dependent tweaks
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  ;; (declaim (optimize (speed 2) (debug 2) (safety 3)) ; NO: rely on the implementation defaults.
+  #+allegro
+  (setf excl::*autoload-package-name-alist*
+        (remove "asdf" excl::*autoload-package-name-alist*
+                :test 'equalp :key 'car))
+  #+ecl (require :cmp)
+  #+gcl
+  (eval-when (:compile-toplevel :load-toplevel)
+    (defpackage :asdf-utilities (:use :cl))
+    (defpackage :asdf (:use :cl :asdf-utilities))))
 
 ;;;; Create packages in a way that is compatible with hot-upgrade.
 ;;;; See https://bugs.launchpad.net/asdf/+bug/485687
 ;;;; See more at the end of the file.
 
 (eval-when (:load-toplevel :compile-toplevel :execute)
-  #+allegro
-  (setf excl::*autoload-package-name-alist*
-        (remove "asdf" excl::*autoload-package-name-alist* :test 'equalp :key 'car))
-  (let* ((asdf-version
-          ;; the 1+ hair is to ensure that we don't do an inadvertent find and replace
-          (subseq "VERSION:1.704" (1+ (length "VERSION"))))
+  (let* ((asdf-version ;; the 1+ helps the version bumping script discriminate
+          (subseq "VERSION:2.004" (1+ (length "VERSION")))) ; NB: same as 2.111.
          (existing-asdf (find-package :asdf))
-         (versym '#:*asdf-version*)
-         (existing-version (and existing-asdf
-                                (symbol-value
-                                 (find-symbol (string versym) existing-asdf))))
-         (redefined-functions
-          '(#:perform #:explain #:output-files #:operation-done-p
-            #:perform-with-restarts #:component-relative-pathname
-            #:system-source-file)))
-    (unless (equal asdf-version existing-version)
+         (vername '#:*asdf-version*)
+         (versym (and existing-asdf
+                      (find-symbol (string vername) existing-asdf)))
+         (existing-version (and versym (boundp versym) (symbol-value versym)))
+         (already-there (equal asdf-version existing-version)))
+    (unless (and existing-asdf already-there)
+      #-gcl
       (when existing-asdf
-        (format *error-output*
+        (format *trace-output*
                 "~&Upgrading ASDF package ~@[from version ~A ~]to version ~A~%"
                 existing-version asdf-version))
-      (labels ((rename-away (package)
-                 (loop :with name = (package-name package)
-                   :for i :from 1 :for new = (format nil "~A.~D" name i)
-                   :unless (find-package new) :do
-                   (rename-package-name package name new)))
-               (rename-package-name (package old new)
-                 (let* ((old-names (cons (package-name package) (package-nicknames package)))
-                        (new-names (subst new old old-names :test 'equal))
-                        (new-name (car new-names))
-                        (new-nicknames (cdr new-names)))
-                   (rename-package package new-name new-nicknames)))
-               (ensure-exists (name nicknames use)
-                 (let* ((previous
-                         (remove-duplicates
-                          (remove-if
-                           #'null
-                           (mapcar #'find-package (cons name nicknames)))
-                          :from-end t)))
-                   (cond
-                     (previous
-                      (map () #'rename-away (cdr previous)) ;; packages with conflicting (nick)names
-                      (let ((p (car previous))) ;; previous package with same name
-                        (rename-package p name nicknames)
-                        (ensure-use p use)
-                        p))
-                     (t
-                      (make-package name :nicknames nicknames :use use)))))
-               (find-sym (symbol package)
-                 (find-symbol (string symbol) package))
-               (remove-symbol (symbol package)
-                 (let ((sym (find-sym symbol package)))
-                   (when sym
-                     (unexport sym package)
-                     (unintern sym package))))
-               (ensure-unintern (package symbols)
-                 (dolist (sym symbols) (remove-symbol sym package)))
-               (ensure-shadow (package symbols)
-                 (shadow symbols package))
-               (ensure-use (package use)
-                 (dolist (used (reverse use))
-                   (do-external-symbols (sym used)
-                     (unless (eq sym (find-sym sym package))
-                       (remove-symbol sym package)))
-                   (use-package used package)))
-               (ensure-fmakunbound (package symbols)
-                 (loop :for name :in symbols
-                   :for sym = (find-sym name package)
-                   :when sym :do (fmakunbound sym)))
-               (ensure-export (package export)
-                 (let ((syms (loop :for x :in export :collect
-                               (intern (string x) package))))
-                   (do-external-symbols (sym package)
-                     (unless (member sym syms)
-                       (remove-symbol sym package)))
-                   (dolist (sym syms)
-                     (export sym package))))
-               (ensure-package (name &key nicknames use unintern fmakunbound shadow export)
-                 (let ((p (ensure-exists name nicknames use)))
-                   (ensure-unintern p unintern)
-                   (ensure-shadow p shadow)
-                   (ensure-export p export)
-                   (ensure-fmakunbound p fmakunbound)
-                   p)))
-        (ensure-package
-         ':asdf-utilities
-         :nicknames '(#:asdf-extensions)
-         :use '(#:common-lisp)
-         :unintern '(#:split #:make-collector)
-         :export
-         '(#:absolute-pathname-p
-           #:aif
-           #:appendf
-           #:asdf-message
-           #:coerce-name
-           #:directory-pathname-p
-           #:ends-with
-           #:ensure-directory-pathname
-           #:getenv
-           #:get-uid
-           #:length=n-p
-           #:merge-pathnames*
-           #:pathname-directory-pathname
-           #:pathname-sans-name+type ;; deprecated. Use pathname-directory-pathname
-           #:read-file-forms
-           #:remove-keys
-           #:remove-keyword
-           #:resolve-symlinks
-           #:split-string
-           #:component-name-to-pathname-components
-           #:split-name-type
-           #:system-registered-p
-           #:truenamize
-           #:while-collecting))
-        (ensure-package
-         ':asdf
-         :use '(:common-lisp :asdf-utilities)
-         :unintern `(#-ecl ,@redefined-functions
-                           #:*asdf-revision* #:around #:asdf-method-combination
-                           #:split #:make-collector)
-         :fmakunbound `(#+ecl ,@redefined-functions
-                              #:system-source-file
-                              #:component-relative-pathname #:system-relative-pathname
-                              #:process-source-registry
-                              #:inherit-source-registry #:process-source-registry-directive)
-         :export
-         '(#:defsystem #:oos #:operate #:find-system #:run-shell-command
-           #:system-definition-pathname #:find-component ; miscellaneous
-           #:compile-system #:load-system #:test-system
-           #:compile-op #:load-op #:load-source-op
-           #:test-op
-           #:operation               ; operations
-           #:feature                 ; sort-of operation
-           #:version                 ; metaphorically sort-of an operation
-           #:version-satisfies
-
-           #:input-files #:output-files #:perform ; operation methods
-           #:operation-done-p #:explain
-
-           #:component #:source-file
-           #:c-source-file #:cl-source-file #:java-source-file
-           #:static-file
-           #:doc-file
-           #:html-file
-           #:text-file
-           #:source-file-type
-           #:module                     ; components
-           #:system
-           #:unix-dso
-
-           #:module-components          ; component accessors
-           #:module-components-by-name  ; component accessors
-           #:component-pathname
-           #:component-relative-pathname
-           #:component-name
-           #:component-version
-           #:component-parent
-           #:component-property
-           #:component-system
-
-           #:component-depends-on
-
-           #:system-description
-           #:system-long-description
-           #:system-author
-           #:system-maintainer
-           #:system-license
-           #:system-licence
-           #:system-source-file
-           #:system-source-directory
-           #:system-relative-pathname
-           #:map-systems
-
-           #:operation-on-warnings
-           #:operation-on-failure
-                                        ;#:*component-parent-pathname*
-           #:*system-definition-search-functions*
-           #:*central-registry*         ; variables
-           #:*compile-file-warnings-behaviour*
-           #:*compile-file-failure-behaviour*
-           #:*resolve-symlinks*
-           #:*asdf-verbose*
-
-           #:asdf-version
-
-           #:operation-error #:compile-failed #:compile-warned #:compile-error
-           #:error-name
-           #:error-pathname
-           #:load-system-definition-error
-           #:error-component #:error-operation
-           #:system-definition-error
-           #:missing-component
-           #:missing-component-of-version
-           #:missing-dependency
-           #:missing-dependency-of-version
-           #:circular-dependency        ; errors
-           #:duplicate-names
-
-           #:try-recompiling
-           #:retry
-           #:accept                     ; restarts
-           #:coerce-entry-to-directory
-           #:remove-entry-from-registry
-
-           #:initialize-output-translations
-           #:disable-output-translations
-           #:clear-output-translations
-           #:ensure-output-translations
-           #:apply-output-translations
-           #:compile-file-pathname*
-           #:enable-asdf-binary-locations-compatibility
-
-           #:*default-source-registries*
-           #:initialize-source-registry
-           #:compute-source-registry
-           #:clear-source-registry
-           #:ensure-source-registry
-           #:process-source-registry))
-        (eval `(defparameter ,(intern (string versym) (find-package :asdf))
-                 ,asdf-version))))))
-
-(in-package #:asdf)
+      (labels
+          ((rename-away (package)
+             (loop :with name = (package-name package)
+               :for i :from 1 :for new = (format nil "~A.~D" name i)
+               :unless (find-package new) :do
+               (rename-package-name package name new)))
+           (rename-package-name (package old new)
+             (let* ((old-names (cons (package-name package)
+                                     (package-nicknames package)))
+                    (new-names (subst new old old-names :test 'equal))
+                    (new-name (car new-names))
+                    (new-nicknames (cdr new-names)))
+               (rename-package package new-name new-nicknames)))
+           (ensure-exists (name nicknames use)
+             (let* ((previous
+                     (remove-duplicates
+                      (remove-if
+                       #'null
+                       (mapcar #'find-package (cons name nicknames)))
+                      :from-end t)))
+               (cond
+                 (previous
+                  ;; do away with packages with conflicting (nick)names
+                  (map () #'rename-away (cdr previous))
+                  ;; reuse previous package with same name
+                  (let ((p (car previous)))
+                    (rename-package p name nicknames)
+                    (ensure-use p use)
+                    p))
+                 (t
+                  (make-package name :nicknames nicknames :use use)))))
+           (find-sym (symbol package)
+             (find-symbol (string symbol) package))
+           (intern* (symbol package)
+             (intern (string symbol) package))
+           (remove-symbol (symbol package)
+             (let ((sym (find-sym symbol package)))
+               (when sym
+                 (unexport sym package)
+                 (unintern sym package))))
+           (ensure-unintern (package symbols)
+             (dolist (sym symbols) (remove-symbol sym package)))
+           (ensure-shadow (package symbols)
+             (shadow symbols package))
+           (ensure-use (package use)
+             (dolist (used (reverse use))
+               (do-external-symbols (sym used)
+                 (unless (eq sym (find-sym sym package))
+                   (remove-symbol sym package)))
+               (use-package used package)))
+           (ensure-fmakunbound (package symbols)
+             (loop :for name :in symbols
+               :for sym = (find-sym name package)
+               :when sym :do (fmakunbound sym)))
+           (ensure-export (package export)
+             (let ((syms (loop :for x :in export :collect
+                           (intern* x package))))
+               (do-external-symbols (sym package)
+                 (unless (member sym syms)
+                   (remove-symbol sym package)))
+               (dolist (sym syms)
+                 (export sym package))))
+           (ensure-package (name &key nicknames use unintern fmakunbound shadow export)
+             (let ((p (ensure-exists name nicknames use)))
+               (ensure-unintern p unintern)
+               (ensure-shadow p shadow)
+               (ensure-export p export)
+               (ensure-fmakunbound p fmakunbound)
+               p)))
+        (macrolet
+            ((pkgdcl (name &key nicknames use export
+                           redefined-functions unintern fmakunbound shadow)
+                 `(ensure-package
+                   ',name :nicknames ',nicknames :use ',use :export ',export
+                   :shadow ',shadow
+                   :unintern ',(append #-(or gcl ecl) redefined-functions unintern)
+                   :fmakunbound ',(append fmakunbound))))
+          (pkgdcl
+           :asdf-utilities
+           :nicknames (#:asdf-extensions)
+           :use (#:common-lisp)
+           :unintern (#:split #:make-collector)
+           :export
+           (#:absolute-pathname-p
+            #:aif
+            #:appendf
+            #:asdf-message
+            #:coerce-name
+            #:directory-pathname-p
+            #:ends-with
+            #:ensure-directory-pathname
+            #:getenv
+            #:get-uid
+            #:length=n-p
+            #:merge-pathnames*
+            #:pathname-directory-pathname
+            #:read-file-forms
+            #:remove-keys
+            #:remove-keyword
+            #:resolve-symlinks
+            #:split-string
+            #:component-name-to-pathname-components
+            #:split-name-type
+            #:system-registered-p
+            #:truenamize
+            #:while-collecting))
+          (pkgdcl
+           :asdf
+           :use (:common-lisp :asdf-utilities)
+           :redefined-functions
+           (#:perform #:explain #:output-files #:operation-done-p
+            #:perform-with-restarts #:component-relative-pathname
+            #:system-source-file #:operate #:find-component)
+           :unintern
+           (#:*asdf-revision* #:around #:asdf-method-combination
+            #:split #:make-collector)
+           :fmakunbound
+           (#:system-source-file
+            #:component-relative-pathname #:system-relative-pathname
+            #:process-source-registry
+            #:inherit-source-registry #:process-source-registry-directive)
+           :export
+           (#:defsystem #:oos #:operate #:find-system #:run-shell-command
+            #:system-definition-pathname #:find-component ; miscellaneous
+            #:compile-system #:load-system #:test-system
+            #:compile-op #:load-op #:load-source-op
+            #:test-op
+            #:operation               ; operations
+            #:feature                 ; sort-of operation
+            #:version                 ; metaphorically sort-of an operation
+            #:version-satisfies
+
+            #:input-files #:output-files #:perform ; operation methods
+            #:operation-done-p #:explain
+
+            #:component #:source-file
+            #:c-source-file #:cl-source-file #:java-source-file
+            #:static-file
+            #:doc-file
+            #:html-file
+            #:text-file
+            #:source-file-type
+            #:module                     ; components
+            #:system
+            #:unix-dso
+
+            #:module-components          ; component accessors
+            #:module-components-by-name  ; component accessors
+            #:component-pathname
+            #:component-relative-pathname
+            #:component-name
+            #:component-version
+            #:component-parent
+            #:component-property
+            #:component-system
+
+            #:component-depends-on
+
+            #:system-description
+            #:system-long-description
+            #:system-author
+            #:system-maintainer
+            #:system-license
+            #:system-licence
+            #:system-source-file
+            #:system-source-directory
+            #:system-relative-pathname
+            #:map-systems
+
+            #:operation-on-warnings
+            #:operation-on-failure
+            ;;#:*component-parent-pathname*
+            #:*system-definition-search-functions*
+            #:*central-registry*         ; variables
+            #:*compile-file-warnings-behaviour*
+            #:*compile-file-failure-behaviour*
+            #:*resolve-symlinks*
+            #:*asdf-verbose*
+
+            #:asdf-version
+
+            #:operation-error #:compile-failed #:compile-warned #:compile-error
+            #:error-name
+            #:error-pathname
+            #:load-system-definition-error
+            #:error-component #:error-operation
+            #:system-definition-error
+            #:missing-component
+            #:missing-component-of-version
+            #:missing-dependency
+            #:missing-dependency-of-version
+            #:circular-dependency        ; errors
+            #:duplicate-names
+
+            #:try-recompiling
+            #:retry
+            #:accept                     ; restarts
+            #:coerce-entry-to-directory
+            #:remove-entry-from-registry
+
+            #:initialize-output-translations
+            #:disable-output-translations
+            #:clear-output-translations
+            #:ensure-output-translations
+            #:apply-output-translations
+            #:compile-file*
+            #:compile-file-pathname*
+            #:enable-asdf-binary-locations-compatibility
+
+            #:*default-source-registries*
+            #:initialize-source-registry
+            #:compute-source-registry
+            #:clear-source-registry
+            #:ensure-source-registry
+            #:process-source-registry)))
+        (let* ((version (intern* vername :asdf))
+               (upvar (intern* '#:*upgraded-p* :asdf))
+               (upval0 (and (boundp upvar) (symbol-value upvar)))
+               (upval1 (if existing-version (cons existing-version upval0) upval0)))
+          (eval `(progn
+                   (defparameter ,version ,asdf-version)
+                   (defparameter ,upvar ',upval1))))))))
+
+(in-package :asdf)
+
+;; More cleanups in case of hot-upgrade. See https://bugs.launchpad.net/asdf/+bug/485687
+#+gcl
+(eval-when (:compile-toplevel :load-toplevel)
+  (defvar *asdf-version* nil)
+  (defvar *upgraded-p* nil))
+(when *upgraded-p*
+   #+ecl
+   (when (find-class 'compile-op nil)
+     (defmethod update-instance-for-redefined-class :after
+         ((c compile-op) added deleted plist &key)
+       (declare (ignore added deleted))
+       (let ((system-p (getf plist 'system-p)))
+         (when system-p (setf (getf (slot-value c 'flags) :system-p) system-p)))))
+   (when (find-class 'module nil)
+     (eval
+      '(defmethod update-instance-for-redefined-class :after
+           ((m module) added deleted plist &key)
+         (declare (ignorable deleted plist))
+         (format *trace-output* "Updating ~A~%" m)
+         (when (member 'components-by-name added)
+           (compute-module-components-by-name m))))))
 
 ;;;; -------------------------------------------------------------------------
 ;;;; User-visible parameters
@@ -286,7 +336,7 @@
 (defun asdf-version ()
   "Exported interface to the version of ASDF currently installed. A string.
 You can compare this string with e.g.:
-(ASDF:VERSION-SATISFIES (ASDF:ASDF-VERSION) \"1.704\")."
+(ASDF:VERSION-SATISFIES (ASDF:ASDF-VERSION) \"2.000\")."
   *asdf-version*)
 
 (defvar *resolve-symlinks* t
@@ -294,9 +344,15 @@ You can compare this string with e.g.:
 
 Defaults to `t`.")
 
-(defvar *compile-file-warnings-behaviour* :warn)
+(defvar *compile-file-warnings-behaviour* :warn
+  "How should ASDF react if it encounters a warning when compiling a
+file?  Valid values are :error, :warn, and :ignore.")
 
-(defvar *compile-file-failure-behaviour* #+sbcl :error #-sbcl :warn)
+(defvar *compile-file-failure-behaviour* #+sbcl :error #-sbcl :warn
+        "How should ASDF react if it encounters a failure \(per the
+ANSI spec of COMPILE-FILE\) when compiling a file?  Valid values are
+:error, :warn, and :ignore.  Note that ASDF ALWAYS raises an error
+if it fails to create an output file when compiling.")
 
 (defvar *verbose-out* nil)
 
@@ -313,38 +369,22 @@ Defaults to `t`.")
   (when (boundp 'excl:*warn-on-nested-reader-conditionals*)
     (setf excl:*warn-on-nested-reader-conditionals* nil)))
 
-;;;; -------------------------------------------------------------------------
-;;;; Cleanups before hot-upgrade.
-;;;; Things to do in case we're upgrading from a previous version of ASDF.
-;;;; See https://bugs.launchpad.net/asdf/+bug/485687
-;;;; * define methods on UPDATE-INSTANCE-FOR-REDEFINED-CLASS
-;;;;   for each of the classes we define that has changed incompatibly.
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  (when (find-class 'module nil)
-    (eval ;; without this protection, Lispworks issues a warning. Sigh.
-     '(defmethod update-instance-for-redefined-class :after
-       ((m module) added deleted plist &key)
-       (when (member 'components-by-name added)
-         (compute-module-components-by-name m)))))
-  #+ecl
-  (when (find-class 'compile-op nil)
-    (defmethod update-instance-for-redefined-class :after
-        ((c compile-op) added deleted plist &key)
-      (format *trace-output* "~&UI4RC:a ~S~%" (list c added deleted plist))
-      (let ((system-p (getf plist 'system-p)))
-        (when system-p (setf (getf (slot-value c 'flags) :system-p) system-p))))))
-
 ;;;; -------------------------------------------------------------------------
 ;;;; ASDF Interface, in terms of generic functions.
-
-(defgeneric perform-with-restarts (operation component))
-(defgeneric perform (operation component))
-(defgeneric operation-done-p (operation component))
-(defgeneric explain (operation component))
-(defgeneric output-files (operation component))
-(defgeneric input-files (operation component))
-
-(defgeneric system-source-file (system)
+(defmacro defgeneric* (name formals &rest options)
+  `(progn
+     #+(or gcl ecl) (fmakunbound ',name)
+     (defgeneric ,name ,formals ,@options)))
+
+(defgeneric* perform-with-restarts (operation component))
+(defgeneric* perform (operation component))
+(defgeneric* operation-done-p (operation component))
+(defgeneric* explain (operation component))
+(defgeneric* output-files (operation component))
+(defgeneric* input-files (operation component))
+(defgeneric component-operation-time (operation component))
+
+(defgeneric* system-source-file (system)
   (:documentation "Return the source file in which system is defined."))
 
 (defgeneric component-system (component)
@@ -366,10 +406,9 @@ another pathname in a degenerate way."))
 
 (defgeneric version-satisfies (component version))
 
-(defgeneric find-component (module name &optional version)
-  (:documentation "Finds the component with name NAME present in the
-MODULE module; if MODULE is nil, then the component is assumed to be a
-system."))
+(defgeneric* find-component (base path)
+  (:documentation "Finds the component with PATH starting from BASE module;
+if BASE is nil, then the component is assumed to be a system."))
 
 (defgeneric source-file-type (component system))
 
@@ -426,17 +465,27 @@ discarded instead of recorded."))
 
 (defgeneric traverse (operation component)
   (:documentation
-"Generate and return a plan for performing `operation` on `component`.
+"Generate and return a plan for performing OPERATION on COMPONENT.
 
-The plan returned is a list of dotted-pairs. Each pair is the `cons`
-of ASDF operation object and a `component` object. The pairs will be
-processed in order by `operate`."))
+The plan returned is a list of dotted-pairs. Each pair is the CONS
+of ASDF operation object and a COMPONENT object. The pairs will be
+processed in order by OPERATE."))
 
 
 ;;;; -------------------------------------------------------------------------
 ;;;; General Purpose Utilities
 
 (defmacro while-collecting ((&rest collectors) &body body)
+  "COLLECTORS should be a list of names for collections.  A collector
+defines a function that, when applied to an argument inside BODY, will
+add its argument to the corresponding collection.  Returns multiple values,
+a list for each collection, in order.
+   E.g.,
+\(while-collecting \(foo bar\)
+           \(dolist \(x '\(\(a 1\) \(b 2\) \(c 3\)\)\)
+             \(foo \(first x\)\)
+             \(bar \(second x\)\)\)\)
+Returns two values: \(A B C\) and \(1 2 3\)."
   (let ((vars (mapcar #'(lambda (x) (gensym (symbol-name x))) collectors))
         (initial-values (mapcar (constantly nil) collectors)))
     `(let ,(mapcar #'list vars initial-values)
@@ -447,21 +496,11 @@ processed in order by `operate`."))
 (defmacro aif (test then &optional else)
   `(let ((it ,test)) (if it ,then ,else)))
 
-(defun pathname-sans-name+type (pathname)
-  "Returns a new pathname with same HOST, DEVICE, DIRECTORY as PATHNAME,
-and NIL NAME and TYPE components.
-Issue: doesn't override the VERSION component.
-
-Deprecated. Use PATHNAME-DIRECTORY-PATHNAME instead."
-  (make-pathname :name nil :type nil :defaults pathname))
-
 (defun pathname-directory-pathname (pathname)
   "Returns a new pathname with same HOST, DEVICE, DIRECTORY as PATHNAME,
 and NIL NAME, TYPE and VERSION components"
-  (make-pathname :name nil :type nil :version nil :defaults pathname))
-
-(defun current-directory ()
-  (truenamize (pathname-directory-pathname *default-pathname-defaults*)))
+  (when pathname
+    (make-pathname :name nil :type nil :version nil :defaults pathname)))
 
 (defun merge-pathnames* (specified &optional (defaults *default-pathname-defaults*))
   "MERGE-PATHNAMES* is like MERGE-PATHNAMES except that if the SPECIFIED pathname
@@ -472,7 +511,7 @@ Also, if either argument is NIL, then the other argument is returned unmodified.
   (let* ((specified (pathname specified))
          (defaults (pathname defaults))
          (directory (pathname-directory specified))
-         (directory (if (stringp directory) `(:absolute ,directory) directory))
+         #-sbcl (directory (if (stringp directory) `(:absolute ,directory) directory))
          (name (or (pathname-name specified) (pathname-name defaults)))
          (type (or (pathname-type specified) (pathname-type defaults)))
          (version (or (pathname-version specified) (pathname-version defaults))))
@@ -481,7 +520,7 @@ Also, if either argument is NIL, then the other argument is returned unmodified.
              (unspecific-handler (p)
                (if (typep p 'logical-pathname) #'ununspecific #'identity)))
       (multiple-value-bind (host device directory unspecific-handler)
-          (ecase (first directory)
+          (#-gcl ecase #+gcl case (first directory)
             ((nil)
              (values (pathname-host defaults)
                      (pathname-device defaults)
@@ -495,7 +534,16 @@ Also, if either argument is NIL, then the other argument is returned unmodified.
             ((:relative)
              (values (pathname-host defaults)
                      (pathname-device defaults)
-                     (append (pathname-directory defaults) (cdr directory))
+                     (if (pathname-directory defaults)
+                         (append (pathname-directory defaults) (cdr directory))
+                         directory)
+                     (unspecific-handler defaults)))
+            #+gcl
+            (t
+             (assert (stringp (first directory)))
+             (values (pathname-host defaults)
+                     (pathname-device defaults)
+                     (append (pathname-directory defaults) directory)
                      (unspecific-handler defaults))))
         (make-pathname :host host :device device :directory directory
                        :name (funcall unspecific-handler name)
@@ -508,13 +556,19 @@ Also, if either argument is NIL, then the other argument is returned unmodified.
 (define-modify-macro orf (&rest args)
   or "or a flag")
 
+(defun first-char (s)
+  (and (stringp s) (plusp (length s)) (char s 0)))
+
+(defun last-char (s)
+  (and (stringp s) (plusp (length s)) (char s (1- (length s)))))
+
 (defun asdf-message (format-string &rest format-args)
   (declare (dynamic-extent format-args))
   (apply #'format *verbose-out* format-string format-args))
 
 (defun split-string (string &key max (separator '(#\Space #\Tab)))
-  "Split STRING in components separater by any of the characters in the sequence SEPARATOR,
-return a list.
+  "Split STRING into a list of components separated by
+any of the characters in the sequence SEPARATOR.
 If MAX is specified, then no more than max(1,MAX) components will be returned,
 starting the separation from the end, e.g. when called with arguments
  \"a.b.c.d.e\" :max 3 :separator \".\" it will return (\"a.b.c\" \"d\" \"e\")."
@@ -537,7 +591,7 @@ starting the separation from the end, e.g. when called with arguments
          ;; Giving :unspecific as argument to make-pathname is not portable.
          ;; See CLHS make-pathname and 19.2.2.2.3.
          ;; We only use it on implementations that support it.
-         (or #+(or sbcl ccl ecl lispworks) :unspecific)))
+         (or #+(or ccl ecl gcl lispworks sbcl) :unspecific)))
     (destructuring-bind (name &optional (type unspecific))
         (split-string filename :max 2 :separator ".")
       (if (equal name "")
@@ -565,13 +619,14 @@ pathnames."
          (last-comp (car (last components))))
     (multiple-value-bind (relative components)
         (if (equal (first components) "")
-            (if (and (plusp (length s)) (eql (char s 0) #\/))
+            (if (equal (first-char s) #\/)
                 (values :absolute (cdr components))
                 (values :relative nil))
           (values :relative components))
+      (setf components (remove "" components :test #'equal))
       (cond
         ((equal last-comp "")
-         (values relative (butlast components) nil))
+         (values relative components nil)) ; "" already removed
         (force-directory
          (values relative components nil))
         (t
@@ -588,17 +643,13 @@ pathnames."
     :unless (eq k key)
     :append (list k v)))
 
-(defun resolve-symlinks (path)
-  #-allegro (truenamize path)
-  #+allegro (excl:pathname-resolve-symbolic-links path))
-
 (defun getenv (x)
   #+abcl
   (ext:getenv x)
   #+sbcl
   (sb-ext:posix-getenv x)
   #+clozure
-  (ccl::getenv x)
+  (ccl:getenv x)
   #+clisp
   (ext:getenv x)
   #+cmu
@@ -613,13 +664,13 @@ pathnames."
   (si:getenv x))
 
 (defun directory-pathname-p (pathname)
-  "Does `pathname` represent a directory?
+  "Does PATHNAME represent a directory?
 
 A directory-pathname is a pathname _without_ a filename. The three
-ways that the filename components can be missing are for it to be `nil`,
-`:unspecific` or the empty string.
+ways that the filename components can be missing are for it to be NIL,
+:UNSPECIFIC or the empty string.
 
-Note that this does _not_ check to see that `pathname` points to an
+Note that this does _not_ check to see that PATHNAME points to an
 actually-existing directory."
   (flet ((check-one (x)
            (member x '(nil :unspecific "") :test 'equal)))
@@ -676,14 +727,18 @@ actually-existing directory."
 #+clisp (defun get-uid () (posix:uid))
 #+sbcl (defun get-uid () (sb-unix:unix-getuid))
 #+cmu (defun get-uid () (unix:unix-getuid))
-#+ecl (ffi:clines "#include <sys/types.h>" "#include <unistd.h>")
-#+ecl (defun get-uid () (ffi:c-inline () () :int "getuid()" :one-liner t))
+#+ecl #.(cl:and (cl:< ext:+ecl-version-number+ 100601)
+         '(ffi:clines "#include <sys/types.h>" "#include <unistd.h>"))
+#+ecl (defun get-uid ()
+        #.(cl:if (cl:< ext:+ecl-version-number+ 100601)
+            '(ffi:c-inline () () :int "getuid()" :one-liner t)
+            '(ext::getuid)))
 #+allegro (defun get-uid () (excl.osi:getuid))
 #-(or cmu sbcl clisp allegro ecl)
 (defun get-uid ()
   (let ((uid-string
          (with-output-to-string (*verbose-out*)
-           (asdf:run-shell-command "id -ur"))))
+           (run-shell-command "id -ur"))))
     (with-input-from-string (stream uid-string)
       (read-line stream)
       (handler-case (parse-integer (read-line stream))
@@ -703,38 +758,68 @@ actually-existing directory."
            (directory (pathname-directory p)))
       (when (typep p 'logical-pathname) (return p))
       (ignore-errors (return (truename p)))
-      (when (stringp directory)
-         (return p))
-      (when (not (eq :absolute (car directory)))
-        (return p))
+      #-sbcl (when (stringp directory) (return p))
+      (when (not (eq :absolute (car directory))) (return p))
       (let ((sofar (ignore-errors (truename (pathname-root p)))))
         (unless sofar (return p))
-        (loop :for component :in (cdr directory)
-          :for rest :on (cdr directory)
-          :for more = (ignore-errors
-                        (truename
-                         (merge-pathnames*
-                          (make-pathname :directory `(:relative ,component))
-                          sofar))) :do
-          (if more
-              (setf sofar more)
-              (return
-                (merge-pathnames*
-                 (make-pathname :host nil :device nil
-                                :directory `(:relative ,@rest)
-                                :defaults p)
-                 sofar)))
-          :finally
-          (return
-            (merge-pathnames*
-             (make-pathname :host nil :device nil
-                            :directory nil
-                            :defaults p)
-             sofar)))))))
+        (flet ((solution (directories)
+                 (merge-pathnames*
+                  (make-pathname :host nil :device nil
+                                 :directory `(:relative ,@directories)
+                                 :name (pathname-name p)
+                                 :type (pathname-type p)
+                                 :version (pathname-version p))
+                  sofar)))
+          (loop :for component :in (cdr directory)
+            :for rest :on (cdr directory)
+            :for more = (ignore-errors
+                          (truename
+                           (merge-pathnames*
+                            (make-pathname :directory `(:relative ,component))
+                            sofar))) :do
+            (if more
+                (setf sofar more)
+                (return (solution rest)))
+            :finally
+            (return (solution nil))))))))
+
+(defun resolve-symlinks (path)
+  #-allegro (truenamize path)
+  #+allegro (excl:pathname-resolve-symbolic-links path))
+
+(defun default-directory ()
+  (truenamize (pathname-directory-pathname *default-pathname-defaults*)))
 
 (defun lispize-pathname (input-file)
   (make-pathname :type "lisp" :defaults input-file))
 
+(defparameter *wild-path*
+  (make-pathname :directory '(:relative :wild-inferiors)
+                 :name :wild :type :wild :version :wild))
+
+(defun wilden (path)
+  (merge-pathnames* *wild-path* path))
+
+(defun directorize-pathname-host-device (pathname)
+  (let* ((root (pathname-root pathname))
+         (wild-root (wilden root))
+         (absolute-pathname (merge-pathnames* pathname root))
+         (foo (make-pathname :directory '(:absolute "FOO") :defaults root))
+         (separator (last-char (namestring foo)))
+         (root-namestring (namestring root))
+         (root-string
+          (substitute-if #\/
+                         (lambda (x) (or (eql x #\:)
+                                         (eql x separator)))
+                         root-namestring)))
+    (multiple-value-bind (relative path filename)
+        (component-name-to-pathname-components root-string t)
+      (declare (ignore relative filename))
+      (let ((new-base
+             (make-pathname :defaults root
+                            :directory `(:absolute ,@path))))
+        (translate-pathname absolute-pathname wild-root (wilden new-base))))))
+
 ;;;; -------------------------------------------------------------------------
 ;;;; Classes, Conditions
 
@@ -747,6 +832,15 @@ actually-existing directory."
   ;; order to fix all conditions that build on it.  -- rgr, 28-Jul-02.]
   #+cmu (:report print-object))
 
+(declaim (ftype (function (t) t)
+                format-arguments format-control
+                error-name error-pathname error-condition
+                duplicate-names-name
+                error-component error-operation
+                module-components module-components-by-name)
+         (ftype (function (t t) t) (setf module-components-by-name)))
+
+
 (define-condition formatted-system-definition-error (system-definition-error)
   ((format-control :initarg :format-control :reader format-control)
    (format-arguments :initarg :format-arguments :reader format-arguments))
@@ -821,6 +915,16 @@ actually-existing directory."
    (properties :accessor component-properties :initarg :properties
                :initform nil)))
 
+(defun component-find-path (component)
+  (reverse
+   (loop :for c = component :then (component-parent c)
+     :while c :collect (component-name c))))
+
+(defmethod print-object ((c component) stream)
+  (print-unreadable-object (c stream :type t :identity nil)
+    (format stream "~@<~{~S~^ ~}~@:>" (component-find-path c))))
+
+
 ;;;; methods: conditions
 
 (defmethod print-object ((c missing-dependency) s)
@@ -853,16 +957,11 @@ actually-existing directory."
        (component-system it)
        component))
 
-(defmethod print-object ((c component) stream)
-  (print-unreadable-object (c stream :type t :identity t)
-    (ignore-errors
-      (prin1 (component-name c) stream))))
-
 (defvar *default-component-class* 'cl-source-file)
 
 (defun compute-module-components-by-name (module)
-  (let ((hash (module-components-by-name module)))
-    (clrhash hash)
+  (let ((hash (make-hash-table :test 'equal)))
+    (setf (module-components-by-name module) hash)
     (loop :for c :in (module-components module)
       :for name = (component-name c)
       :for previous = (gethash name (module-components-by-name module))
@@ -878,7 +977,6 @@ actually-existing directory."
     :initarg :components
     :accessor module-components)
    (components-by-name
-    :initform (make-hash-table :test 'equal)
     :accessor module-components-by-name)
    ;; What to do if we can't satisfy a dependency of one of this module's
    ;; components.  This allows a limited form of conditional processing.
@@ -906,7 +1004,7 @@ actually-existing directory."
       (let ((pathname
              (merge-pathnames*
              (component-relative-pathname component)
-             (component-parent-pathname component))))
+             (pathname-directory-pathname (component-parent-pathname component)))))
         (unless (or (null pathname) (absolute-pathname-p pathname))
           (error "Invalid relative pathname ~S for component ~S" pathname component))
         (setf (slot-value component 'absolute-pathname) pathname)
@@ -979,10 +1077,21 @@ of which is a system object.")
 (defun system-registered-p (name)
   (gethash (coerce-name name) *defined-systems*))
 
+(defun clear-system (name)
+  "Clear the entry for a system in the database of systems previously loaded.
+Note that this does NOT in any way cause the code of the system to be unloaded."
+  ;; There is no "unload" operation in Common Lisp, and a general such operation
+  ;; cannot be portably written, considering how much CL relies on side-effects
+  ;; of global data structures.
+  ;; Note that this does a setf gethash instead of a remhash
+  ;; this way there remains a hint in the *defined-systems* table
+  ;; that the system was loaded at some point.
+  (setf (gethash (coerce-name name) *defined-systems*) nil))
+
 (defun map-systems (fn)
-  "Apply `fn` to each defined system.
+  "Apply FN to each defined system.
 
-`fn` should be a function of one argument. It will be
+FN should be a function of one argument. It will be
 called with an object of type asdf:system."
   (maphash (lambda (_ datum)
              (declare (ignore _))
@@ -995,7 +1104,7 @@ called with an object of type asdf:system."
 ;;; convention that functions in this list are prefixed SYSDEF-
 
 (defparameter *system-definition-search-functions*
-  '(sysdef-central-registry-search sysdef-source-registry-search))
+  '(sysdef-central-registry-search sysdef-source-registry-search sysdef-find-asdf))
 
 (defun system-definition-pathname (system)
   (let ((system-name (coerce-name system)))
@@ -1021,6 +1130,27 @@ This is for backward compatibilily.
 Going forward, we recommend new users should be using the source-registry.
 ")
 
+(defun probe-asd (name defaults)
+  (block nil
+    (when (directory-pathname-p defaults)
+      (let ((file
+             (make-pathname
+              :defaults defaults :version :newest :case :local
+              :name name
+              :type "asd")))
+        (when (probe-file file)
+          (return file)))
+      #+(and (or win32 windows mswindows mingw32) (not cygwin) (not clisp))
+      (let ((shortcut
+             (make-pathname
+              :defaults defaults :version :newest :case :local
+              :name (concatenate 'string name ".asd")
+              :type "lnk")))
+        (when (probe-file shortcut)
+          (let ((target (parse-windows-shortcut shortcut)))
+            (when target
+              (return (pathname target)))))))))
+
 (defun sysdef-central-registry-search (system)
   (let ((name (coerce-name system))
         (to-remove nil)
@@ -1039,8 +1169,8 @@ Going forward, we recommend new users should be using the source-registry.
                             (let* ((*print-circle* nil)
                                    (message
                                     (format nil
-                                            "~@<While searching for system `~a`: `~a` evaluated ~
-to `~a` which is not a directory.~@:>"
+                                            "~@<While searching for system ~S: ~S evaluated ~
+to ~S which is not a directory.~@:>"
                                             system dir defaults)))
                               (error message))
                           (remove-entry-from-registry ()
@@ -1066,18 +1196,21 @@ to `~a` which is not a directory.~@:>"
 (defun make-temporary-package ()
   (flet ((try (counter)
            (ignore-errors
-             (make-package (format nil "~a~D" 'asdf counter)
+             (make-package (format nil "~A~D" :asdf counter)
                            :use '(:cl :asdf)))))
     (do* ((counter 0 (+ counter 1))
           (package (try counter) (try counter)))
          (package package))))
 
 (defun safe-file-write-date (pathname)
-           ;; if FILE-WRITE-DATE returns NIL, it's possible that the
-           ;; user or some other agent has deleted an input file.  If
-           ;; that's the case, well, that's not good, but as long as
-           ;; the operation is otherwise considered to be done we
-           ;; could continue and survive.
+  ;; If FILE-WRITE-DATE returns NIL, it's possible that
+  ;; the user or some other agent has deleted an input file.
+  ;; Also, generated files will not exist at the time planning is done
+  ;; and calls operation-done-p which calls safe-file-write-date.
+  ;; So it is very possible that we can't get a valid file-write-date,
+  ;; and we can survive and we will continue the planning
+  ;; as if the file were very old.
+  ;; (or should we treat the case in a different, special way?)
   (or (and pathname (probe-file pathname) (file-write-date pathname))
       (progn
         (when pathname
@@ -1086,55 +1219,80 @@ to `~a` which is not a directory.~@:>"
         0)))
 
 (defun find-system (name &optional (error-p t))
-  (let* ((name (coerce-name name))
-         (in-memory (system-registered-p name))
-         (on-disk (system-definition-pathname name)))
-    (when (and on-disk
-               (or (not in-memory)
-                   (< (car in-memory) (safe-file-write-date on-disk))))
-      (let ((package (make-temporary-package)))
-        (unwind-protect
-             (handler-bind
-                 ((error (lambda (condition)
-                           (error 'load-system-definition-error
-                                  :name name :pathname on-disk
-                                  :condition condition))))
-               (let ((*package* package))
-                 (asdf-message
-                  "~&~@<; ~@;loading system definition from ~A into ~A~@:>~%"
-                  ;; FIXME: This wants to be (ENOUGH-NAMESTRING
-                  ;; ON-DISK), but CMUCL barfs on that.
-                  on-disk
-                  *package*)
-                 (load on-disk)))
-          (delete-package package))))
-    (let ((in-memory (system-registered-p name)))
-      (if in-memory
-          (progn (when on-disk (setf (car in-memory)
-                                     (safe-file-write-date on-disk)))
-                 (cdr in-memory))
-          (when error-p (error 'missing-component :requires name))))))
+  (catch 'find-system
+    (let* ((name (coerce-name name))
+           (in-memory (system-registered-p name))
+           (on-disk (system-definition-pathname name)))
+      (when (and on-disk
+                 (or (not in-memory)
+                     (< (car in-memory) (safe-file-write-date on-disk))))
+        (let ((package (make-temporary-package)))
+          (unwind-protect
+               (handler-bind
+                   ((error (lambda (condition)
+                             (error 'load-system-definition-error
+                                    :name name :pathname on-disk
+                                    :condition condition))))
+                 (let ((*package* package))
+                   (asdf-message
+                    "~&~@<; ~@;loading system definition from ~A into ~A~@:>~%"
+                    on-disk *package*)
+                   (load on-disk)))
+            (delete-package package))))
+      (let ((in-memory (system-registered-p name)))
+        (if in-memory
+            (progn (when on-disk (setf (car in-memory)
+                                       (safe-file-write-date on-disk)))
+                   (cdr in-memory))
+            (when error-p (error 'missing-component :requires name)))))))
 
 (defun register-system (name system)
   (asdf-message "~&~@<; ~@;registering ~A as ~A~@:>~%" system name)
   (setf (gethash (coerce-name name) *defined-systems*)
         (cons (get-universal-time) system)))
 
+(defun sysdef-find-asdf (system)
+  (let ((name (coerce-name system)))
+    (when (equal name "asdf")
+      (let* ((registered (cdr (gethash name *defined-systems*)))
+             (asdf (or registered
+                       (make-instance
+                        'system :name "asdf"
+                        :source-file (or *compile-file-truename* *load-truename*)))))
+        (unless registered
+          (register-system "asdf" asdf))
+        (throw 'find-system asdf)))))
+
 
 ;;;; -------------------------------------------------------------------------
 ;;;; Finding components
 
-(defmethod find-component ((module module) name &optional version)
-  (if (slot-boundp module 'components)
-      (let ((m (gethash name (module-components-by-name module))))
-        (if (and m (version-satisfies m version)) m))))
+(defmethod find-component ((base string) path)
+  (let ((s (find-system base nil)))
+    (and s (find-component s path))))
 
+(defmethod find-component ((base symbol) path)
+  (cond
+    (base (find-component (coerce-name base) path))
+    (path (find-component path nil))
+    (t    nil)))
+
+(defmethod find-component ((base cons) path)
+  (find-component (car base) (cons (cdr base) path)))
+
+(defmethod find-component ((module module) (name string))
+  (unless (slot-boundp module 'components-by-name) ;; SBCL may miss the u-i-f-r-c method!!!
+    (compute-module-components-by-name module))
+  (values (gethash name (module-components-by-name module))))
+
+(defmethod find-component ((component component) (name symbol))
+  (if name
+      (find-component component (coerce-name name))
+      component))
+
+(defmethod find-component ((module module) (name cons))
+  (find-component (find-component module (car name)) (cdr name)))
 
-;;; a component with no parent is a system
-(defmethod find-component ((module (eql nil)) name &optional version)
-  (declare (ignorable module))
-  (let ((m (find-system name nil)))
-    (if (and m (version-satisfies m version)) m)))
 
 ;;; component subclasses
 
@@ -1152,8 +1310,11 @@ to `~a` which is not a directory.~@:>"
 (defclass html-file (doc-file)
   ((type :initform "html")))
 
-(defmethod source-file-type ((component module) (s module)) :directory)
+(defmethod source-file-type ((component module) (s module))
+  (declare (ignorable component s))
+  :directory)
 (defmethod source-file-type ((component source-file) (s module))
+  (declare (ignorable s))
   (source-file-explicit-type component))
 
 (defun merge-component-name-type (name &key type defaults)
@@ -1313,12 +1474,17 @@ class specifier, not an operation."
         ;; original source file, then
         (list (component-pathname c)))))
 
-(defmethod input-files ((operation operation) (c module)) nil)
+(defmethod input-files ((operation operation) (c module))
+  (declare (ignorable operation c))
+  nil)
+
+(defmethod component-operation-time (o c)
+  (gethash (type-of o) (component-operation-times c)))
 
 (defmethod operation-done-p ((o operation) (c component))
   (let ((out-files (output-files o c))
         (in-files (input-files o c))
-        (op-time (gethash (type-of o) (component-operation-times c))))
+        (op-time (component-operation-time o c)))
     (flet ((earliest-out ()
              (reduce #'min (mapcar #'safe-file-write-date out-files)))
            (latest-in ()
@@ -1382,12 +1548,8 @@ recursive calls to traverse.")
 (defun %do-one-dep (operation c collect required-op required-c required-v)
   ;; collects a partial plan that results from performing required-op
   ;; on required-c, possibly with a required-vERSION
-  (let* ((dep-c (or (find-component
-                     (component-parent c)
-                     ;; XXX tacky.  really we should build the
-                     ;; in-order-to slot with canonicalized
-                     ;; names instead of coercing this late
-                     (coerce-name required-c) required-v)
+  (let* ((dep-c (or (let ((d (find-component (component-parent c) required-c)))
+                      (and d (version-satisfies d required-v) d))
                     (if required-v
                         (error 'missing-dependency-of-version
                                :required-by c
@@ -1551,9 +1713,26 @@ recursive calls to traverse.")
       (visit-component operation c flag)
       flag))
 
+(defun flatten-tree (l)
+  ;; You collected things into a list.
+  ;; Most elements are just things to collect again.
+  ;; A (simple-vector 1) indicate that you should recurse into its contents.
+  ;; This way, in two passes (rather than N being the depth of the tree),
+  ;; you can collect things with marginally constant-time append,
+  ;; achieving linear time collection instead of quadratic time.
+  (while-collecting (c)
+    (labels ((r (x)
+               (if (typep x '(simple-vector 1))
+                   (r* (svref x 0))
+                   (c x)))
+             (r* (l)
+               (dolist (x l) (r x))))
+      (r* l))))
+
 (defmethod traverse ((operation operation) (c component))
-  ;; cerror'ing a feature that seems to have NEVER EVER worked,
-  ;; ever since danb created it in his 2003-03-16 commit e0d02781
+  ;; cerror'ing a feature that seems to have NEVER EVER worked
+  ;; ever since danb created it in his 2003-03-16 commit e0d02781.
+  ;; It was both fixed and disabled in the 1.700 rewrite.
   (when (consp (operation-forced operation))
     (cerror "Continue nonetheless."
             "Congratulations, you're the first ever user of the :force (list of system names) feature! Please contact the asdf-devel mailing-list to collect a cookie.")
@@ -1563,16 +1742,6 @@ recursive calls to traverse.")
    (while-collecting (collect)
      (do-traverse operation c #'collect))))
 
-(defun flatten-tree (l)
-  (while-collecting (c)
-    (labels ((r (x)
-               (if (vectorp x)
-                   (r* (svref x 0))
-                   (c x)))
-             (r* (l)
-               (dolist (x l) (r x))))
-      (r* l))))
-
 (defmethod perform ((operation operation) (c source-file))
   (sysdef-error
    "~@<required method PERFORM not implemented ~
@@ -1580,6 +1749,7 @@ recursive calls to traverse.")
    (class-of operation) (class-of c)))
 
 (defmethod perform ((operation operation) (c module))
+  (declare (ignorable operation c))
   nil)
 
 (defmethod explain ((operation operation) (component component))
@@ -1604,22 +1774,29 @@ recursive calls to traverse.")
 (defmethod perform :after ((o compile-op) (c cl-source-file))
   ;; Note how we use OUTPUT-FILES to find the binary locations
   ;; This allows the user to override the names.
-  (let* ((input (output-files o c))
-         (output (compile-file-pathname (lispize-pathname (first input)) :type :fasl)))
-    (c:build-fasl output :lisp-files (remove "fas" input :key #'pathname-type :test #'string=))))
+  (let* ((files (output-files o c))
+         (object (first files))
+         (fasl (second files)))
+    (c:build-fasl fasl :lisp-files (list object))))
 
 (defmethod perform :after ((operation operation) (c component))
   (setf (gethash (type-of operation) (component-operation-times c))
         (get-universal-time)))
 
+(declaim (ftype (function ((or pathname string) &rest t &key &allow-other-keys)
+                          (values t t t))
+                compile-file*))
+
 ;;; perform is required to check output-files to find out where to put
 ;;; its answers, in case it has been overridden for site policy
 (defmethod perform ((operation compile-op) (c cl-source-file))
   #-:broken-fasl-loader
   (let ((source-file (component-pathname c))
-        (output-file (car (output-files operation c))))
+        (output-file (car (output-files operation c)))
+        (*compile-file-warnings-behaviour* (operation-on-warnings operation))
+        (*compile-file-failure-behaviour* (operation-on-failure operation)))
     (multiple-value-bind (output warnings-p failure-p)
-        (apply #'compile-file source-file :output-file output-file
+        (apply #'compile-file* source-file :output-file output-file
                (compile-op-flags operation))
       (when warnings-p
         (case (operation-on-warnings operation)
@@ -1639,20 +1816,23 @@ recursive calls to traverse.")
         (error 'compile-error :component c :operation operation)))))
 
 (defmethod output-files ((operation compile-op) (c cl-source-file))
+  (declare (ignorable operation))
   (let ((p (lispize-pathname (component-pathname c))))
     #-:broken-fasl-loader
-    (list #-ecl (compile-file-pathname p)
-          #+ecl (compile-file-pathname p :type :object)
+    (list (compile-file-pathname p #+ecl :type #+ecl :object)
           #+ecl (compile-file-pathname p :type :fasl))
     #+:broken-fasl-loader (list p)))
 
 (defmethod perform ((operation compile-op) (c static-file))
+  (declare (ignorable operation c))
   nil)
 
 (defmethod output-files ((operation compile-op) (c static-file))
+  (declare (ignorable operation c))
   nil)
 
-(defmethod input-files ((op compile-op) (c static-file))
+(defmethod input-files ((operation compile-op) (c static-file))
+  (declare (ignorable operation c))
   nil)
 
 
@@ -1674,35 +1854,60 @@ recursive calls to traverse.")
   (perform operation component))
 
 (defmethod perform-with-restarts ((o load-op) (c cl-source-file))
-  (let ((state :initial))
-    (loop :until (or (eq state :success)
-                     (eq state :failure)) :do
-         (case state
-           (:recompiled
-            (setf state :failure)
-            (call-next-method)
-            (setf state :success))
-           (:failed-load
-            (setf state :recompiled)
-            (perform (make-instance 'compile-op) c))
-           (t
-            (with-simple-restart
-                (try-recompiling "Recompile ~a and try loading it again"
-                                  (component-name c))
-              (setf state :failed-load)
-              (call-next-method)
-              (setf state :success)))))))
+  (declare (ignorable o))
+  (loop :with state = :initial
+    :until (or (eq state :success)
+               (eq state :failure)) :do
+    (case state
+      (:recompiled
+       (setf state :failure)
+       (call-next-method)
+       (setf state :success))
+      (:failed-load
+       (setf state :recompiled)
+       (perform (make-instance 'compile-op) c))
+      (t
+       (with-simple-restart
+           (try-recompiling "Recompile ~a and try loading it again"
+                            (component-name c))
+         (setf state :failed-load)
+         (call-next-method)
+         (setf state :success))))))
+
+(defmethod perform-with-restarts ((o compile-op) (c cl-source-file))
+  (loop :with state = :initial
+    :until (or (eq state :success)
+               (eq state :failure)) :do
+    (case state
+      (:recompiled
+       (setf state :failure)
+       (call-next-method)
+       (setf state :success))
+      (:failed-compile
+       (setf state :recompiled)
+       (perform-with-restarts o c))
+      (t
+       (with-simple-restart
+           (try-recompiling "Try recompiling ~a"
+                            (component-name c))
+         (setf state :failed-compile)
+         (call-next-method)
+         (setf state :success))))))
 
 (defmethod perform ((operation load-op) (c static-file))
+  (declare (ignorable operation c))
   nil)
 
 (defmethod operation-done-p ((operation load-op) (c static-file))
+  (declare (ignorable operation c))
   t)
 
-(defmethod output-files ((o operation) (c component))
+(defmethod output-files ((operation operation) (c component))
+  (declare (ignorable operation c))
   nil)
 
 (defmethod component-depends-on ((operation load-op) (c component))
+  (declare (ignorable operation))
   (cons (list 'compile-op (component-name c))
         (call-next-method)))
 
@@ -1712,19 +1917,23 @@ recursive calls to traverse.")
 (defclass load-source-op (basic-load-op) ())
 
 (defmethod perform ((o load-source-op) (c cl-source-file))
+  (declare (ignorable o))
   (let ((source (component-pathname c)))
     (setf (component-property c 'last-loaded-as-source)
           (and (load source)
                (get-universal-time)))))
 
 (defmethod perform ((operation load-source-op) (c static-file))
+  (declare (ignorable operation c))
   nil)
 
 (defmethod output-files ((operation load-source-op) (c component))
+  (declare (ignorable operation c))
   nil)
 
 ;;; FIXME: we simply copy load-op's dependencies.  this is Just Not Right.
 (defmethod component-depends-on ((o load-source-op) (c component))
+  (declare (ignorable o))
   (let ((what-would-load-op-do (cdr (assoc 'load-op
                                            (component-in-order-to c)))))
     (mapcar (lambda (dep)
@@ -1734,6 +1943,7 @@ recursive calls to traverse.")
             what-would-load-op-do)))
 
 (defmethod operation-done-p ((o load-source-op) (c source-file))
+  (declare (ignorable o))
   (if (or (not (component-property c 'last-loaded-as-source))
           (> (safe-file-write-date (component-pathname c))
              (component-property c 'last-loaded-as-source)))
@@ -1746,22 +1956,27 @@ recursive calls to traverse.")
 (defclass test-op (operation) ())
 
 (defmethod perform ((operation test-op) (c component))
+  (declare (ignorable operation c))
   nil)
 
 (defmethod operation-done-p ((operation test-op) (c system))
   "Testing a system is _never_ done."
+  (declare (ignorable operation c))
   nil)
 
 (defmethod component-depends-on :around ((o test-op) (c system))
+  (declare (ignorable o))
   (cons `(load-op ,(component-name c)) (call-next-method)))
 
 
 ;;;; -------------------------------------------------------------------------
 ;;;; Invoking Operations
 
-(defun operate (operation-class system &rest args
-                &key ((:verbose *asdf-verbose*) *asdf-verbose*) version force
-                &allow-other-keys)
+(defgeneric* operate (operation-class system &key &allow-other-keys))
+
+(defmethod operate (operation-class system &rest args
+                    &key ((:verbose *asdf-verbose*) *asdf-verbose*) version force
+                    &allow-other-keys)
   (declare (ignore force))
   (let* ((*package* *package*)
          (*readtable* *readtable*)
@@ -1777,8 +1992,9 @@ recursive calls to traverse.")
         (loop :for (op . component) :in steps :do
           (loop
             (restart-case
-                (progn (perform-with-restarts op component)
-                       (return))
+                (progn
+                  (perform-with-restarts op component)
+                  (return))
               (retry ()
                 :report
                 (lambda (s)
@@ -1804,15 +2020,15 @@ recursive calls to traverse.")
 (let ((operate-docstring
   "Operate does three things:
 
-1. It creates an instance of `operation-class` using any keyword parameters
+1. It creates an instance of OPERATION-CLASS using any keyword parameters
 as initargs.
-2. It finds the  asdf-system specified by `system` (possibly loading
+2. It finds the  asdf-system specified by SYSTEM (possibly loading
 it from disk).
-3. It then calls `traverse` with the operation and system as arguments
+3. It then calls TRAVERSE with the operation and system as arguments
 
-The traverse operation is wrapped in `with-compilation-unit` and error
-handling code. If a `version` argument is supplied, then operate also
-ensures that the system found satisfies it using the `version-satisfies`
+The traverse operation is wrapped in WITH-COMPILATION-UNIT and error
+handling code. If a VERSION argument is supplied, then operate also
+ensures that the system found satisfies it using the VERSION-SATISFIES
 method.
 
 Note that dependencies may cause the operation to invoke other
@@ -1850,38 +2066,35 @@ details."
 ;;;; -------------------------------------------------------------------------
 ;;;; Defsystem
 
+(defun load-pathname ()
+  (let ((pn (or *load-pathname* *compile-file-pathname*)))
+    (if *resolve-symlinks*
+        (and pn (resolve-symlinks pn))
+        pn)))
+
 (defun determine-system-pathname (pathname pathname-supplied-p)
-  ;; called from the defsystem macro.
-  ;; the pathname of a system is either
+  ;; The defsystem macro calls us to determine
+  ;; the pathname of a system as follows:
   ;; 1. the one supplied,
-  ;; 2. derived from the *load-truename* (see below), or
-  ;; 3. taken from *default-pathname-defaults*
-  ;;
-  ;; if using *load-truename*, then we also deal with whether or not
-  ;; to resolve symbolic links. If not resolving symlinks, then we use
-  ;; *load-pathname* instead of *load-truename* since in some
-  ;; implementations, the latter has *already resolved it.
-  (let ((file-pathname
-         (when (or *load-pathname* *compile-file-pathname*)
-           (pathname-directory-pathname
-            (if *resolve-symlinks*
-                (resolve-symlinks (or *load-truename* *compile-file-truename*))
-                *load-pathname*)))))
-    (or (and pathname-supplied-p (merge-pathnames* pathname file-pathname))
+  ;; 2. derived from *load-pathname* via load-pathname
+  ;; 3. taken from the *default-pathname-defaults* via default-directory
+  (let* ((file-pathname (load-pathname))
+         (directory-pathname (and file-pathname (pathname-directory-pathname file-pathname))))
+    (or (and pathname-supplied-p (merge-pathnames* pathname directory-pathname))
         file-pathname
-        (current-directory))))
+        (default-directory))))
 
 (defmacro defsystem (name &body options)
   (destructuring-bind (&key (pathname nil pathname-arg-p) (class 'system)
-                            system-dependencies &allow-other-keys)
+                            defsystem-depends-on &allow-other-keys)
       options
-    (let ((component-options (remove-keys '(:system-dependencies :class) options)))
+    (let ((component-options (remove-keys '(:defsystem-depends-on :class) options)))
       `(progn
          ;; system must be registered before we parse the body, otherwise
          ;; we recur when trying to find an existing system of the same name
          ;; to reuse options (e.g. pathname) from
-         ,@(loop for system in system-dependencies
-              collect `(asdf:load-system ,system))
+         ,@(loop :for system :in defsystem-depends-on
+             :collect `(load-system ,system))
          (let ((s (system-registered-p ',name)))
            (cond ((and s (eq (type-of (cdr s)) ',class))
                   (setf (car s) (get-universal-time)))
@@ -1890,34 +2103,27 @@ details."
                  (t
                   (register-system (quote ,name)
                                    (make-instance ',class :name ',name))))
-           (%set-system-source-file *load-truename*
+           (%set-system-source-file (load-pathname)
                                     (cdr (system-registered-p ',name))))
          (parse-component-form
-          nil (apply
-               #'list
+          nil (list*
                :module (coerce-name ',name)
                :pathname
                ,(determine-system-pathname pathname pathname-arg-p)
                ',component-options))))))
 
-
 (defun class-for-type (parent type)
-  (let* ((extra-symbols (list (find-symbol (symbol-name type) *package*)
-                              (find-symbol (symbol-name type)
-                                           (load-time-value
-                                            (package-name :asdf)))))
-         (class (dolist (symbol (if (keywordp type)
-                                    extra-symbols
-                                    (cons type extra-symbols)))
-                  (when (and symbol
-                             (find-class symbol nil)
-                             (subtypep symbol 'component))
-                    (return (find-class symbol))))))
-    (or class
-        (and (eq type :file)
-             (or (module-default-component-class parent)
-                 (find-class 'cl-source-file)))
-        (sysdef-error "~@<don't recognize component type ~A~@:>" type))))
+  (or (loop :for symbol :in (list
+                             (unless (keywordp type) type)
+                             (find-symbol (symbol-name type) *package*)
+                             (find-symbol (symbol-name type) :asdf))
+        :for class = (and symbol (find-class symbol nil))
+        :when (and class (subtypep class 'component))
+        :return class)
+      (and (eq type :file)
+           (or (module-default-component-class parent)
+               (find-class *default-component-class*)))
+      (sysdef-error "~@<don't recognize component type ~A~@:>" type)))
 
 (defun maybe-add-tree (tree op1 op2 c)
   "Add the node C at /OP1/OP2 in TREE, unless it's there already.
@@ -1949,7 +2155,7 @@ Returns the new tree (which probably shares structure with the old one)"
 
 (defun sysdef-error-component (msg type name value)
   (sysdef-error (concatenate 'string msg
-                             "~&The value specified for ~(~A~) ~A is ~W")
+                             "~&The value specified for ~(~A~) ~A is ~S")
                 type name value))
 
 (defun check-component-input (type name weakly-depends-on
@@ -2080,25 +2286,14 @@ Returns the new tree (which probably shares structure with the old one)"
 ;;;; years so everyone has time to migrate away from it. -- fare 2009-12-01
 
 (defun run-shell-command (control-string &rest args)
-  "Interpolate `args` into `control-string` as if by `format`, and
+  "Interpolate ARGS into CONTROL-STRING as if by FORMAT, and
 synchronously execute the result using a Bourne-compatible shell, with
-output to `*verbose-out*`.  Returns the shell's exit code."
+output to *VERBOSE-OUT*.  Returns the shell's exit code."
   (let ((command (apply #'format nil control-string args)))
     (asdf-message "; $ ~A~%" command)
-    #+sbcl
-    (sb-ext:process-exit-code
-     (apply #'sb-ext:run-program
-            #+win32 "sh" #-win32 "/bin/sh"
-            (list  "-c" command)
-            :input nil :output *verbose-out*
-            #+win32 '(:search t) #-win32 nil))
 
-    #+(or cmu scl)
-    (ext:process-exit-code
-     (ext:run-program
-      "/bin/sh"
-      (list  "-c" command)
-      :input nil :output *verbose-out*))
+    #+abcl
+    (ext:run-shell-command command :output *verbose-out*)
 
     #+allegro
     ;; will this fail if command has embedded quotes - it seems to work
@@ -2112,18 +2307,10 @@ output to `*verbose-out*`.  Returns the shell's exit code."
       (format *verbose-out* "~{~&; ~a~%~}~%" stdout)
       exit-code)
 
-    #+lispworks
-    (system:call-system-showing-output
-     command
-     :shell-type "/bin/sh"
-     :show-cmd nil
-     :prefix ""
-     :output-stream *verbose-out*)
-
     #+clisp                     ;XXX not exactly *verbose-out*, I know
     (ext:run-shell-command  command :output :terminal :wait t)
 
-    #+openmcl
+    #+clozure
     (nth-value 1
                (ccl:external-process-status
                 (ccl:run-program "/bin/sh" (list "-c" command)
@@ -2133,12 +2320,34 @@ output to `*verbose-out*`.  Returns the shell's exit code."
     #+ecl ;; courtesy of Juan Jose Garcia Ripoll
     (si:system command)
 
-    #+abcl
-    (ext:run-shell-command command :output *verbose-out*)
+    #+gcl
+    (lisp:system command)
+
+    #+lispworks
+    (system:call-system-showing-output
+     command
+     :shell-type "/bin/sh"
+     :show-cmd nil
+     :prefix ""
+     :output-stream *verbose-out*)
+
+    #+sbcl
+    (sb-ext:process-exit-code
+     (apply #'sb-ext:run-program
+            #+win32 "sh" #-win32 "/bin/sh"
+            (list  "-c" command)
+            :input nil :output *verbose-out*
+            #+win32 '(:search t) #-win32 nil))
+
+    #+(or cmu scl)
+    (ext:process-exit-code
+     (ext:run-program
+      "/bin/sh"
+      (list  "-c" command)
+      :input nil :output *verbose-out*))
 
-    #-(or openmcl clisp lispworks allegro scl cmu sbcl ecl abcl)
-    (error "RUN-SHELL-COMMAND not implemented for this Lisp")
-    ))
+    #-(or abcl allegro clisp clozure cmu ecl gcl lispworks sbcl scl)
+    (error "RUN-SHELL-COMMAND not implemented for this Lisp")))
 
 ;;;; ---------------------------------------------------------------------------
 ;;;; system-relative-pathname
@@ -2157,9 +2366,13 @@ located."
                  :defaults (system-source-file system-designator)))
 
 (defun relativize-directory (directory)
-  (if (eq (car directory) :absolute)
-      (cons :relative (cdr directory))
-      directory))
+  (cond
+    ((stringp directory)
+     (list :relative directory))
+    ((eq (car directory) :absolute)
+     (cons :relative (cdr directory)))
+    (t
+     directory)))
 
 (defun relativize-pathname-directory (pathspec)
   (let ((p (pathname pathspec)))
@@ -2186,27 +2399,21 @@ located."
 (defparameter *os-features*
   '((:windows :mswindows :win32 :mingw32)
     (:solaris :sunos)
+    :linux ;; for GCL at least, must appear before :bsd.
     :macosx :darwin :apple
     :freebsd :netbsd :openbsd :bsd
-    :linux :unix))
+    :unix))
 
 (defparameter *architecture-features*
   '((:x86-64 :amd64 :x86_64 :x8664-target)
     (:x86 :i686 :i586 :pentium3 :i486 :i386 :pc386 :iapx386 :x8632-target :pentium4)
-    :hppa64 :hppa :ppc64 (:ppc32 :ppc :powerpc) :sparc64 :sparc))
+    :hppa64 :hppa :ppc64 (:ppc32 :ppc :powerpc) :sparc64 :sparc
+    :java-1.4 :java-1.5 :java-1.6 :java-1.7))
+
 
 (defun lisp-version-string ()
   (let ((s (lisp-implementation-version)))
     (declare (ignorable s))
-    #+(or scl sbcl ecl armedbear cormanlisp mcl) s
-    #+cmu (substitute #\- #\/ s)
-    #+clozure (format nil "~d.~d~@[-~d~]"
-                      ccl::*openmcl-major-version*
-                      ccl::*openmcl-minor-version*
-                      #+ppc64-target 64
-                      #-ppc64-target nil)
-    #+lispworks (format nil "~A~@[~A~]" s
-                        (when (member :lispworks-64bit *features*) "-64bit"))
     #+allegro (format nil
                       "~A~A~A~A"
                       excl::*common-lisp-version-number*
@@ -2219,8 +2426,25 @@ located."
                        (:-ics "8")
                        (:+ics ""))
                       (if (member :64bit *features*) "-64bit" ""))
-    #+(or clisp gcl) (subseq s 0 (position #\space s))
-    #+digitool (subseq s 8)))
+    #+armedbear (format nil "~a-fasl~a" s system::*fasl-version*)
+    #+clisp (subseq s 0 (position #\space s))
+    #+clozure (format nil "~d.~d-fasl~d"
+                      ccl::*openmcl-major-version*
+                      ccl::*openmcl-minor-version*
+                      (logand ccl::fasl-version #xFF))
+    #+cmu (substitute #\- #\/ s)
+    #+digitool (subseq s 8)
+    #+ecl (format nil "~A~@[-~A~]" s
+                  (let ((vcs-id (ext:lisp-implementation-vcs-id)))
+                    (when (>= (length vcs-id) 8)
+                      (subseq vcs-id 0 8))))
+    #+gcl (subseq s (1+ (position #\space s)))
+    #+lispworks (format nil "~A~@[~A~]" s
+                        (when (member :lispworks-64bit *features*) "-64bit"))
+    ;; #+sbcl (format nil "~a-fasl~d" s sb-fasl:+fasl-file-version+) ; f-f-v redundant w/ version
+    #+(or cormanlisp mcl sbcl scl) s
+    #-(or allegro armedbear clisp clozure cmu cormanlisp digitool
+          ecl gcl lispworks mcl sbcl scl) s))
 
 (defun first-feature (features)
   (labels
@@ -2291,9 +2515,7 @@ located."
        #+(and (or win32 windows mswindows mingw32) (not cygwin))
         ,@`(#+lispworks ,(try (sys:get-folder-path :common-appdata) "common-lisp/config/")
             ;;; read-windows-registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\AppData
-           #+(not cygwin)
-           ,(try (or (getenv "USERPROFILE") (user-homedir))
-                 "Application Data/common-lisp/config/"))
+           ,(try (getenv "APPDATA") "common-lisp/config/"))
        ,(try (user-homedir) ".config/common-lisp/")))))
 (defun system-configuration-directories ()
   (remove-if
@@ -2304,10 +2526,11 @@ located."
       `(,@`(#+lispworks ,(try (sys:get-folder-path :local-appdata) "common-lisp/config/")
            ;;; read-windows-registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Common AppData
         ,(try (getenv "ALLUSERSPROFILE") "Application Data/common-lisp/config/"))))
-    (list #p"/etc/"))))
+    (list #p"/etc/common-lisp/"))))
 (defun in-first-directory (dirs x)
   (loop :for dir :in dirs
-    :thereis (and dir (ignore-errors (truename (merge-pathnames* x (ensure-directory-pathname dir)))))))
+    :thereis (and dir (ignore-errors
+                        (truename (merge-pathnames* x (ensure-directory-pathname dir)))))))
 (defun in-user-configuration-directory (x)
   (in-first-directory (user-configuration-directories) x))
 (defun in-system-configuration-directory (x)
@@ -2339,10 +2562,15 @@ located."
       (error "One and only one form allowed for ~A. Got: ~S~%" description forms))
     (funcall validator (car forms))))
 
+(defun hidden-file-p (pathname)
+  (equal (first-char (pathname-name pathname)) #\.))
+
 (defun validate-configuration-directory (directory tag validator)
   (let ((files (sort (ignore-errors
-                       (directory (make-pathname :name :wild :type :wild :defaults directory)
-                                  #+sbcl :resolve-symlinks #+sbcl nil))
+                       (remove-if
+                        'hidden-file-p
+                        (directory (make-pathname :name :wild :type "conf" :defaults directory)
+                                   #+sbcl :resolve-symlinks #+sbcl nil)))
                      #'string< :key #'namestring)))
     `(,tag
       ,@(loop :for file :in files :append
@@ -2364,27 +2592,16 @@ Each mapping is a pair of a source pathname and destination pathname,
 and the order is by decreasing length of namestring of the source pathname.")
 
 (defvar *user-cache*
-  (or
-   (let ((h (getenv "XDG_CACHE_HOME")))
-     (and h `(,h "common-lisp" :implementation)))
-   #+(and windows lispworks)
-   (let ((h (sys:get-folder-path :common-appdata))) ;; no :common-caches in Windows???
-     (and h `(,h "common-lisp" "cache")))
-   #+(and (or win32 windows mswindows mingw32) (not cygwin))
-   ;;; read-windows-registry HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders\Cache
-   (let ((h (or (getenv "USERPROFILE") (user-homedir))))
-     (and h `(,h "Local Settings" "Temporary Internet Files" "common-lisp")))
-   '(:home ".cache" "common-lisp" :implementation)))
+  (flet ((try (x &rest sub) (and x `(,x ,@sub))))
+    (or
+     (try (getenv "XDG_CACHE_HOME") "common-lisp" :implementation)
+     #+(and (or win32 windows mswindows mingw32) (not cygwin))
+     (try (getenv "APPDATA") "common-lisp" "cache" :implementation)
+     '(:home ".cache" "common-lisp" :implementation))))
 (defvar *system-cache*
-  (or
-   #+(and windows lispworks)
-   (let ((h (sys:get-folder-path :common-appdata))) ;; no :common-caches in Windows???
-     (and h `(,h "common-lisp" "cache")))
-   #+(and (or win32 windows mswindows mingw32) (not cygwin))
-   (let ((h (or (getenv "USERPROFILE") (user-homedir))))
-     (and h `(,h "Local Settings" "Temporary Internet Files" "common-lisp")))
-   #+(or unix cygwin)
-   '("/var/cache/common-lisp" :uid :implementation)))
+  ;; No good default, plus there's a security problem
+  ;; with other users messing with such directories.
+  *user-cache*)
 
 (defun output-translations ()
   (car *output-translations*))
@@ -2410,16 +2627,38 @@ with a different configuration, so the configuration would be re-read then."
   (setf *output-translations* '())
   (values))
 
-(defparameter *wild-path*
-  (make-pathname :directory '(:relative :wild-inferiors)
-                 :name :wild :type :wild :version :wild))
-
 (defparameter *wild-asd*
   (make-pathname :directory '(:relative :wild-inferiors)
                  :name :wild :type "asd" :version :newest))
 
-(defun wilden (path)
-  (merge-pathnames* *wild-path* path))
+
+(declaim (ftype (function (t &optional boolean) (or null pathname))
+                resolve-location))
+
+(defun resolve-relative-location-component (super x &optional wildenp)
+  (let* ((r (etypecase x
+              (pathname x)
+              (string x)
+              (cons
+               (let ((car (resolve-relative-location-component super (car x) nil)))
+                 (if (null (cdr x))
+                     car
+                     (let ((cdr (resolve-relative-location-component
+                                 (merge-pathnames* car super) (cdr x) wildenp)))
+                       (merge-pathnames* cdr car)))))
+              ((eql :default-directory)
+               (relativize-pathname-directory (default-directory)))
+              ((eql :implementation) (implementation-identifier))
+              ((eql :implementation-type) (string-downcase (implementation-type)))
+              #-(and (or win32 windows mswindows mingw32) (not cygwin))
+              ((eql :uid) (princ-to-string (get-uid)))))
+         (d (if (pathnamep x) r (ensure-directory-pathname r)))
+         (s (if (and wildenp (not (pathnamep x)))
+                (wilden d)
+                d)))
+    (when (and (absolute-pathname-p s) (not (pathname-match-p s (wilden super))))
+      (error "pathname ~S is not relative to ~S" s super))
+    (merge-pathnames* s super)))
 
 (defun resolve-absolute-location-component (x wildenp)
   (let* ((r
@@ -2441,7 +2680,7 @@ with a different configuration, so the configuration would be re-read then."
             ((eql :home) (user-homedir))
             ((eql :user-cache) (resolve-location *user-cache* nil))
             ((eql :system-cache) (resolve-location *system-cache* nil))
-            ((eql :current-directory) (current-directory))))
+            ((eql :default-directory) (default-directory))))
          (s (if (and wildenp (not (pathnamep x)))
                 (wilden r)
                 r)))
@@ -2449,30 +2688,6 @@ with a different configuration, so the configuration would be re-read then."
       (error "Not an absolute pathname ~S" s))
     s))
 
-(defun resolve-relative-location-component (super x &optional wildenp)
-  (let* ((r (etypecase x
-              (pathname x)
-              (string x)
-              (cons
-               (let ((car (resolve-relative-location-component super (car x) nil)))
-                 (if (null (cdr x))
-                     car
-                     (let ((cdr (resolve-relative-location-component
-                                 (merge-pathnames* car super) (cdr x) wildenp)))
-                       (merge-pathnames* cdr car)))))
-              ((eql :current-directory)
-               (relativize-pathname-directory (current-directory)))
-              ((eql :implementation) (implementation-identifier))
-              ((eql :implementation-type) (string-downcase (implementation-type)))
-              ((eql :uid) (princ-to-string (get-uid)))))
-         (d (if (pathnamep x) r (ensure-directory-pathname r)))
-         (s (if (and wildenp (not (pathnamep x)))
-                (wilden d)
-                d)))
-    (when (and (absolute-pathname-p s) (not (pathname-match-p s (wilden super))))
-      (error "pathname ~S is not relative to ~S" s super))
-    (merge-pathnames* s super)))
-
 (defun resolve-location (x &optional wildenp)
   (if (atom x)
       (resolve-absolute-location-component x wildenp)
@@ -2578,12 +2793,13 @@ with a different configuration, so the configuration would be re-read then."
     ;; Some implementations have precompiled ASDF systems,
     ;; so we must disable translations for implementation paths.
     #+sbcl (,(getenv "SBCL_HOME") ())
-    #+ecl (,(translate-logical-pathname "SYS:**;*.*") ()) ; only needed if LPNs are resolved manually.
-    #+clozure (,(wilden (ccl::ccl-directory)) ()) ; not needed: no precompiled ASDF system
-    #+abcl (#p"jar:file:/**/*.jar!/**/*.*" (:function translate-jar-pathname))
-    #+abcl (#p"/:jar:file/**/*.*" (:user-cache #p"**/*.*"))
+    #+ecl (,(translate-logical-pathname "SYS:**;*.*") ()) ; not needed: no precompiled ASDF system
+    #+clozure (,(wilden (truename #p"ccl:")) ()) ; not needed: no precompiled ASDF system
     ;; All-import, here is where we want user stuff to be:
     :inherit-configuration
+    ;; These are for convenience, and can be overridden by the user:
+    #+abcl (#p"/___jar___file___root___/**/*.*" (:user-cache #p"**/*.*"))
+    #+abcl (#p"jar:file:/**/*.jar!/**/*.*" (:function translate-jar-pathname))
     ;; If we want to enable the user cache by default, here would be the place:
     :enable-user-cache))
 
@@ -2602,6 +2818,11 @@ with a different configuration, so the configuration would be re-read then."
   (getenv "ASDF_OUTPUT_TRANSLATIONS"))
 
 (defgeneric process-output-translations (spec &key inherit collect))
+(declaim (ftype (function (t &key (:collect (or symbol function))) t)
+                inherit-output-translations))
+(declaim (ftype (function (t &key (:collect (or symbol function)) (:inherit list)) t)
+                process-output-translations-directive))
+
 (defmethod process-output-translations ((x symbol) &key
                                         (inherit *default-output-translations*)
                                         collect)
@@ -2729,29 +2950,6 @@ effectively disabling the output translation facility."
           (translate-pathname p absolute-source destination)))
        :finally (return p)))))
 
-(defun last-char (s)
-  (and (stringp s) (plusp (length s)) (char s (1- (length s)))))
-
-(defun directorize-pathname-host-device (pathname)
-  (let* ((root (pathname-root pathname))
-         (wild-root (wilden root))
-         (absolute-pathname (merge-pathnames* pathname root))
-         (foo (make-pathname :directory '(:absolute "FOO") :defaults root))
-         (separator (last-char (namestring foo)))
-         (root-namestring (namestring root))
-         (root-string
-          (substitute-if #\/
-                         (lambda (x) (or (eql x #\:)
-                                         (eql x separator)))
-                         root-namestring)))
-    (multiple-value-bind (relative path filename)
-        (component-name-to-pathname-components root-string t)
-      (declare (ignore relative filename))
-      (let ((new-base
-             (make-pathname :defaults root
-                            :directory `(:absolute ,@path))))
-        (translate-pathname absolute-pathname wild-root (wilden new-base))))))
-
 (defmethod output-files :around (operation component)
   "Translate output files, unless asked not to"
   (declare (ignorable operation component))
@@ -2762,24 +2960,59 @@ effectively disabling the output translation facility."
          (mapcar #'apply-output-translations files)))
    t))
 
-(defun compile-file-pathname* (input-file &rest keys)
-  (apply-output-translations
-   (apply #'compile-file-pathname
-          (truenamize (lispize-pathname input-file))
-          keys)))
+(defun compile-file-pathname* (input-file &rest keys &key output-file &allow-other-keys)
+  (or output-file
+      (apply-output-translations
+       (apply 'compile-file-pathname
+              (truenamize (lispize-pathname input-file))
+              keys))))
+
+(defun tmpize-pathname (x)
+  (make-pathname
+   :name (format nil "ASDF-TMP-~A" (pathname-name x))
+   :defaults x))
+
+(defun delete-file-if-exists (x)
+  (when (and x (probe-file x))
+    (delete-file x)))
+
+(defun compile-file* (input-file &rest keys &key &allow-other-keys)
+  (let* ((output-file (apply 'compile-file-pathname* input-file keys))
+         (tmp-file (tmpize-pathname output-file))
+         (status :error))
+    (multiple-value-bind (output-truename warnings-p failure-p)
+        (apply 'compile-file input-file :output-file tmp-file keys)
+      (cond
+        (failure-p
+         (setf status *compile-file-failure-behaviour*))
+        (warnings-p
+         (setf status *compile-file-warnings-behaviour*))
+        (t
+         (setf status :success)))
+      (ecase status
+        ((:success :warn :ignore)
+         (delete-file-if-exists output-file)
+         (when output-truename
+           (rename-file output-truename output-file)
+           (setf output-truename output-file)))
+        (:error
+         (delete-file-if-exists output-truename)
+         (setf output-truename nil)))
+      (values output-truename warnings-p failure-p))))
 
 #+abcl
 (defun translate-jar-pathname (source wildcard)
   (declare (ignore wildcard))
-  (let ((root (apply-output-translations
-               (concatenate 'string
-                            "/:jar:file/"
-                            (namestring (first (pathname-device
-                                                source))))))
-        (entry (make-pathname :directory (pathname-directory source)
-                              :name (pathname-name source)
-                              :type (pathname-type source))))
-    (concatenate 'string (namestring root) (namestring entry))))
+  (let* ((p (pathname (first (pathname-device source))))
+         (root (format nil "/___jar___file___root___/~@[~A/~]"
+                       (and (find :windows *features*)
+                            (pathname-device p)))))
+    (apply-output-translations
+     (merge-pathnames*
+      (relativize-pathname-directory source)
+      (merge-pathnames*
+       (relativize-pathname-directory (ensure-directory-pathname p))
+       root)))))
 
 ;;;; -----------------------------------------------------------------
 ;;;; Compatibility mode for ASDF-Binary-Locations
@@ -2893,11 +3126,13 @@ effectively disabling the output translation facility."
 ;;;; See the Manual and https://bugs.launchpad.net/asdf/+bug/485918
 
 ;; Using ack 1.2 exclusions
-(defvar *default-exclusions*
+(defvar *default-source-registry-exclusions*
   '(".bzr" ".cdv" "~.dep" "~.dot" "~.nib" "~.plst"
     ".git" ".hg" ".pc" ".svn" "CVS" "RCS" "SCCS" "_darcs"
     "_sgbak" "autom4te.cache" "cover_db" "_build"))
 
+(defvar *source-registry-exclusions* *default-source-registry-exclusions*)
+
 (defvar *source-registry* ()
   "Either NIL (for uninitialized), or a list of one element,
 said element itself being a list of directory pathnames where to look for .asd files")
@@ -2919,34 +3154,6 @@ with a different configuration, so the configuration would be re-read then."
   (setf *source-registry* '())
   (values))
 
-(defun probe-asd (name defaults)
-  (block nil
-    (when (directory-pathname-p defaults)
-      (let ((file
-             (make-pathname
-              :defaults defaults :version :newest :case :local
-              :name name
-              :type "asd")))
-        (when (probe-file file)
-          (return file)))
-      #+(and (or win32 windows mswindows mingw32) (not cygwin) (not clisp))
-      (let ((shortcut
-             (make-pathname
-              :defaults defaults :version :newest :case :local
-              :name (concatenate 'string name ".asd")
-              :type "lnk")))
-        (when (probe-file shortcut)
-          (let ((target (parse-windows-shortcut shortcut)))
-            (when target
-              (return (pathname target)))))))))
-
-(defun sysdef-source-registry-search (system)
-  (ensure-source-registry)
-  (loop :with name = (coerce-name system)
-    :for defaults :in (source-registry)
-    :for file = (probe-asd name defaults)
-    :when file :return file))
-
 (defun validate-source-registry-directive (directive)
   (unless
       (or (member directive '(:default-registry (:default-registry)) :test 'equal)
@@ -2955,7 +3162,7 @@ with a different configuration, so the configuration would be re-read then."
               ((:include :directory :tree)
                (and (length=n-p rest 1)
                     (typep (car rest) '(or pathname string null))))
-              ((:exclude)
+              ((:exclude :also-exclude)
                (every #'stringp rest))
               (null rest))))
     (error "Invalid directive ~S~%" directive))
@@ -3010,10 +3217,15 @@ with a different configuration, so the configuration would be re-read then."
 (defun register-asd-directory (directory &key recurse exclude collect)
   (if (not recurse)
       (funcall collect directory)
-      (let* ((files (ignore-errors
-                      (directory (merge-pathnames* *wild-asd* directory)
-                                 #+sbcl #+sbcl :resolve-symlinks nil
-                                 #+clisp #+clisp :circle t)))
+      (let* ((files
+              (handler-case
+                  (directory (merge-pathnames* *wild-asd* directory)
+                             #+sbcl #+sbcl :resolve-symlinks nil
+                             #+clisp #+clisp :circle t)
+                (error (c)
+                  (warn "Error while scanning system definitions under directory ~S:~%~A"
+                        directory c)
+                  nil)))
              (dirs (remove-duplicates (mapcar #'pathname-directory-pathname files)
                                       :test #'equal :from-end t)))
         (loop
@@ -3036,7 +3248,8 @@ with a different configuration, so the configuration would be re-read then."
 (defun wrapping-source-registry ()
   `(:source-registry
     #+sbcl (:tree ,(getenv "SBCL_HOME"))
-   :inherit-configuration))
+    :inherit-configuration
+    #+cmu (:tree #p"modules:")))
 (defun default-source-registry ()
   (flet ((try (x sub) (try-directory-subpath x sub :type :directory)))
     `(:source-registry
@@ -3051,10 +3264,7 @@ with a different configuration, so the configuration would be re-read then."
            (or (getenv "XDG_DATA_DIRS") "/usr/local/share:/usr/share"))
           (dirs (cons datahome (split-string datadirs :separator ":"))))
          #+(and (or win32 windows mswindows mingw32) (not cygwin))
-         ((datahome
-           #+lispworks (sys:get-folder-path :common-appdata)
-           #-lispworks (try (or (getenv "USERPROFILE") (user-homedir))
-                            "Application Data"))
+         ((datahome (getenv "APPDATA"))
           (datadir
            #+lispworks (sys:get-folder-path :local-appdata)
            #-lispworks (try (getenv "ALLUSERSPROFILE")
@@ -3078,6 +3288,11 @@ with a different configuration, so the configuration would be re-read then."
   (getenv "CL_SOURCE_REGISTRY"))
 
 (defgeneric process-source-registry (spec &key inherit register))
+(declaim (ftype (function (t &key (:register (or symbol function))) t)
+                inherit-source-registry))
+(declaim (ftype (function (t &key (:register (or symbol function)) (:inherit list)) t)
+                process-source-registry-directive))
+
 (defmethod process-source-registry ((x symbol) &key inherit register)
   (process-source-registry (funcall x) :inherit inherit :register register))
 (defmethod process-source-registry ((pathname pathname) &key inherit register)
@@ -3097,7 +3312,7 @@ with a different configuration, so the configuration would be re-read then."
   (declare (ignorable x))
   (inherit-source-registry inherit :register register))
 (defmethod process-source-registry ((form cons) &key inherit register)
-  (let ((*default-exclusions* *default-exclusions*))
+  (let ((*source-registry-exclusions* *default-source-registry-exclusions*))
     (dolist (directive (cdr (validate-source-registry-form form)))
       (process-source-registry-directive directive :inherit inherit :register register))))
 
@@ -3118,15 +3333,18 @@ with a different configuration, so the configuration would be re-read then."
       ((:tree)
        (destructuring-bind (pathname) rest
          (when pathname
-           (funcall register (ensure-directory-pathname pathname) :recurse t :exclude *default-exclusions*))))
+           (funcall register (ensure-directory-pathname pathname) :recurse t :exclude *source-registry-exclusions*))))
       ((:exclude)
-       (setf *default-exclusions* rest))
+       (setf *source-registry-exclusions* rest))
+      ((:also-exclude)
+       (appendf *source-registry-exclusions* rest))
       ((:default-registry)
        (inherit-source-registry '(default-source-registry) :register register))
       ((:inherit-configuration)
        (inherit-source-registry inherit :register register))
       ((:ignore-inherited-configuration)
-       nil))))
+       nil)))
+  nil)
 
 (defun flatten-source-registry (&optional parameter)
   (remove-duplicates
@@ -3152,36 +3370,49 @@ with a different configuration, so the configuration would be re-read then."
 (defun initialize-source-registry (&optional parameter)
   (setf (source-registry) (compute-source-registry parameter)))
 
-;; checks an initial variable to see whether the state is initialized
+;; Checks an initial variable to see whether the state is initialized
 ;; or cleared. In the former case, return current configuration; in
 ;; the latter, initialize.  ASDF will call this function at the start
-;; of (asdf:find-system).
-(defun ensure-source-registry ()
+;; of (asdf:find-system) to make sure the source registry is initialized.
+;; However, it will do so *without* a parameter, at which point it
+;; will be too late to provide a parameter to this function, though
+;; you may override the configuration explicitly by calling
+;; initialize-source-registry directly with your parameter.
+(defun ensure-source-registry (&optional parameter)
   (if (source-registry-initialized-p)
       (source-registry)
-      (initialize-source-registry)))
+      (initialize-source-registry parameter)))
+
+(defun sysdef-source-registry-search (system)
+  (ensure-source-registry)
+  (loop :with name = (coerce-name system)
+    :for defaults :in (source-registry)
+    :for file = (probe-asd name defaults)
+    :when file :return file))
 
 ;;;; -----------------------------------------------------------------
-;;;; SBCL and ClozureCL hook into REQUIRE
+;;;; Hook into REQUIRE for ABCL, ClozureCL, CMUCL, ECL and SBCL
 ;;;;
-#+(or sbcl clozure abcl)
+#+(or abcl clozure cmu ecl sbcl)
 (progn
   (defun module-provide-asdf (name)
     (handler-bind
         ((style-warning #'muffle-warning)
          (missing-component (constantly nil))
          (error (lambda (e)
-                  (format *error-output* "ASDF could not load ~A because ~A.~%"
+                  (format *error-output* "ASDF could not load ~(~A~) because ~A.~%"
                           name e))))
       (let* ((*verbose-out* (make-broadcast-stream))
-             (system (asdf:find-system name nil)))
+             (system (find-system (string-downcase name) nil)))
         (when system
-          (asdf:operate 'asdf:load-op name)
+          (load-system system)
           t))))
   (pushnew 'module-provide-asdf
-           #+sbcl sb-ext:*module-provider-functions*
-           #+clozure ccl::*module-provider-functions*
-           #+abcl sys::*module-provider-functions*))
+           #+abcl sys::*module-provider-functions*
+           #+clozure ccl:*module-provider-functions*
+           #+cmu ext:*module-provider-functions*
+           #+ecl si:*module-provider-functions*
+           #+sbcl sb-ext:*module-provider-functions*))
 
 ;;;; -------------------------------------------------------------------------
 ;;;; Cleanups after hot-upgrade.
@@ -3203,7 +3434,7 @@ with a different configuration, so the configuration would be re-read then."
 ;;;; -----------------------------------------------------------------
 ;;;; Done!
 (when *load-verbose*
-  (asdf-message ";; ASDF, version ~a" (asdf-version)))
+  (asdf-message ";; ASDF, version ~a~%" (asdf-version)))
 
 #+allegro
 (eval-when (:compile-toplevel :execute)
@@ -3211,7 +3442,6 @@ with a different configuration, so the configuration would be re-read then."
     (setf excl:*warn-on-nested-reader-conditionals* *acl-warn-save*)))
 
 (pushnew :asdf *features*)
-;; this is a release candidate for ASDF 2.0
 (pushnew :asdf2 *features*)
 
 (provide :asdf)
diff --git a/cclan-package.lisp b/cclan-package.lisp
deleted file mode 100644
index a00d604025f7e97c92dd807dc1ec11ad6e264e0b..0000000000000000000000000000000000000000
--- a/cclan-package.lisp
+++ /dev/null
@@ -1,5 +0,0 @@
-(in-package :cl-user)
-
-(defpackage :cclan (:use #:cl #:asdf)
-            (:export #:all-components #:write-package))
-
diff --git a/cclan.asd b/cclan.asd
deleted file mode 100644
index 7f0c3b0fbaa888288f84805673e3432e9da97d06..0000000000000000000000000000000000000000
--- a/cclan.asd
+++ /dev/null
@@ -1,8 +0,0 @@
-;;; -*- Lisp -*-
-(defpackage :cclan-system (:use #:cl #:asdf))
-(in-package :cclan-system)
-
-(defsystem cclan
-    :version "0.1"
-    :components ((:file "cclan-package")
-                 (:file "cclan" :depends-on ("cclan-package"))))
diff --git a/cclan.lisp b/cclan.lisp
deleted file mode 100644
index 9b31fb45c6ce680a4dd46904a1fe47cb6b77d394..0000000000000000000000000000000000000000
--- a/cclan.lisp
+++ /dev/null
@@ -1,99 +0,0 @@
-(in-package :cclan)
-
-;;;; This file contains functions, classes etc that are not part of
-;;;; asdf itself, but extend it in various ways useful for maintainers
-;;;; of new-style cCLan packages
-
-;;;; The public interface consists of the functions whose symbols are
-;;;; exported from the package
-
-;;;; This file does not contain references to asdf internals - or
-;;;; shouldn't, anyway.  Send bug reports
-
-
-(defun mapappend (function list)
-  (let ((f (coerce function 'function)))
-    (loop for i in list append (funcall f i))))
-
-(defgeneric all-components (component))
-(defmethod all-components ((source-file source-file))
-  (list source-file))
-
-(defmethod all-components ((module module))
-  (cons module (mapappend #'all-components (module-components module))))
-
-(defmethod all-components ((module symbol))
-  (all-components (find-system module)))
-
-(defun cvs-tag-name (system)
-  (let* ((system (find-system system))
-         (version (component-version system)))
-    (format nil "release_~A"  (substitute #\_ #\. version))))
-
-(defun cvs-tag (system)
-  (let* ((system (find-system system))
-         (directory (component-pathname system)))
-    (run-shell-command "cd ~A && cvs tag -F ~A"
-                       (namestring directory)  (cvs-tag-name system))))
-
-
-(defun write-readme-file (stream suggested-registry system-name)
-  "Write a README.install file detailing a possible sequence of commands to use the newly-untarred system."
-  (format stream "~
-1.  Make a symlink in ~W[*] pointing to the .asd file
-2.  Start your asdf-enabled lisp
-2a. Ensure that ~W[*] is in asdf:*central-registry*
-3.  At the lisp prompt, type '(asdf:operate 'asdf:load-op ~W)'. This
-    will compile and load the system into your running lisp.
-
-[*] This path (~W) is only a suggestion; the important
-thing is that asdf know where to find the .asd file.  asdf uses the
-contents of the variable ASDF:*CENTRAL-REGISTRY* to find its system
-definitions.
-
-These instructions were automatically generated by cCLan software. Use
-at your own peril.~%" suggested-registry suggested-registry system-name suggested-registry))
-
-(defun write-package (system)
-  (let* ((parent-dir
-          (parse-namestring
-           (format nil "/tmp/~A.~A/"
-                   #+sbcl (sb-unix:unix-getpid)
-                   #-sbcl (random 1000000)
-                   (get-internal-run-time))))
-         (system (find-system system))
-         (sub-dir-name
-          (format nil "~A_~A"
-                  (component-name system) (component-version system)))
-         (cvsroot-file
-          (merge-pathnames "CVS/Root" (component-pathname system)))
-         (old-pwd *default-pathname-defaults*)
-         (*default-pathname-defaults* parent-dir))
-    (ensure-directories-exist parent-dir)
-    (cvs-tag system)
-    (and
-     (zerop (asdf:run-shell-command
-             "cd ~A && cvs -d `cat ~A` checkout -d ~A -r ~A -kv ~A"
-             (namestring parent-dir)
-             (namestring cvsroot-file)
-             sub-dir-name
-             (cvs-tag-name system)
-             (component-name system)))
-     (with-open-file (o (format nil "~A/INSTALL.asdf" sub-dir-name)
-                        :direction :output)
-       (write-readme-file o "$HOME/lisp/systems/" (component-name system))
-       t)
-     (zerop (asdf:run-shell-command "cd ~A && tar cf ~A~A.tar ~A"
-                                    (namestring parent-dir)
-                                    (namestring old-pwd) sub-dir-name
-                                    sub-dir-name))
-     (zerop (asdf:run-shell-command
-             "gzip -f9  ~A~A.tar"
-             (namestring old-pwd) sub-dir-name))
-     (format t "Now run~%  gpg -b -a  ~A~A.tar.gz~%in a shell with a tty"
-             (namestring old-pwd) sub-dir-name))))
-
-(defun class-name-of (x)
-  (class-name (class-of x)))
-
-
diff --git a/doc/asdf.texinfo b/doc/asdf.texinfo
index 7d7689ae5b72651a7cf046dbde274f4002b3282c..d33c21c43de9f4d1b1d69324dab01c2d111833bb 100644
--- a/doc/asdf.texinfo
+++ b/doc/asdf.texinfo
@@ -65,7 +65,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
 
 @titlepage
-@title asdf: another system definition facility
+@title ASDF: Another System Definition Facility
 
 @c The following two commands start the copyright page.
 @page
@@ -170,12 +170,10 @@ to learn how to define a system of your own.
 the ASDF internals and how to extend ASDF.
 
 @emph{Nota Bene}:
-We are preparing for a release of ASDF 2,
-which will have version 2.000 and later.
-Current releases, in the 1.700 series and beyond,
-should be considered as release candidates.
-We're still working on polishing the code and documentation.
-@ref{FAQ,,``What has changed between ASDF 1 and ASDF 2?''}.
+We have released ASDF 2.000 on May 31st 2010.
+It hopefully will have been it included
+in all CL maintained implementations shortly afterwards.
+@xref{FAQ,,``What has changed between ASDF 1 and ASDF 2?''}.
 
 
 @node Loading ASDF, Configuring ASDF, Introduction, Top
@@ -241,7 +239,7 @@ If it returns the keyword @code{:OLD},
 then you're using an old version of ASDF (from before 1.635).
 If it returns @code{NIL} then ASDF is not installed.
 
-If you are running a version older than 1.703,
+If you are running a version older than 2.000,
 we recommend that you load a newer ASDF using the method below.
 
 
@@ -340,27 +338,28 @@ If you're using some tool to install software,
 the authors of that tool should already have configured ASDF.
 
 The simplest way to add a path to your search path,
-say @file{/foo/bar/baz/quux/}
+say @file{/home/luser/.asd-link-farm/}
 is to create the directory
 @file{~/.config/common-lisp/source-registry.conf.d/}
-and there create a file with any name of your choice,
-for instance @file{42-bazquux.conf}
+and there create a file with any name of your choice but the type @file{conf},
+for instance @file{42-asd-link-farm.conf}
 containing the line:
 
-@kbd{(:directory "/foo/bar/baz/quux/")}
+@kbd{(:directory "/home/luser/.asd-link-farm/")}
 
-If you want all the subdirectories under @file{/foo/bar/baz/}
+If you want all the subdirectories under @file{/home/luser/lisp/}
 to be recursively scanned for @file{.asd} files, instead use:
 
-@kbd{(:tree "/foo/bar/baz/quux/")}
+@kbd{(:tree "/home/luser/lisp/")}
 
 Note that your Operating System distribution or your system administrator
 may already have configured system-managed libraries for you.
 
-Also note that when choosing a filename, the convention is to use
-the @file{.conf} extension
-(and a non-empty extension is required for CLISP compatibility),
-and it is customary to start the filename with two digits
+The required @file{.conf} extension allows you to have disabled files
+or editor backups (ending in @file{~}), and works portably
+(for instance, it is a pain to allow both empty and non-empty extension on CLISP).
+Excluded are files the name of which start with a @file{.} character.
+It is customary to start the filename with two digits
 that specify the order in which the directories will be scanned.
 
 ASDF will automatically read your configuration
@@ -485,7 +484,7 @@ say from @file{/foo/bar/baz/quux/}
 to @file{/where/i/want/my/fasls/}
 is to create the directory
 @file{~/.config/common-lisp/asdf-output-translations.conf.d/}
-and there create a file with any name of your choice,
+and there create a file with any name of your choice and the type @file{conf},
 for instance @file{42-bazquux.conf}
 containing the line:
 
@@ -510,11 +509,11 @@ In absence of any configuration, the default is to redirect everything
 under an implementation-dependent subdirectory of @file{~/.cache/common-lisp/}.
 @xref{Controlling where ASDF searches for systems}, for full details.
 
-
-Also note that when choosing a filename, the convention is to use
-the @file{.conf} extension
-(and a non-empty extension is required for CLISP compatibility),
-and it is customary to start the filename with two digits
+The required @file{.conf} extension allows you to have disabled files
+or editor backups (ending in @file{~}), and works portably
+(for instance, it is a pain to allow both empty and non-empty extension on CLISP).
+Excluded are files the name of which start with a @file{.} character.
+It is customary to start the filename with two digits
 that specify the order in which the directories will be scanned.
 
 ASDF will automatically read your configuration
@@ -535,7 +534,7 @@ other ASDF add-ons offered the same functionality,
 each in subtly different and incompatible ways:
 ASDF-Binary-Locations, cl-launch, common-lisp-controller.
 ASDF-Binary-Locations is now not needed anymore and should not be used.
-cl-launch 3.0 and common-lisp-controller 7.1 have been updated
+cl-launch 3.000 and common-lisp-controller 7.2 have been updated
 to just delegate this functionality to ASDF.
 
 @node Using ASDF, Defining systems with defsystem, Configuring ASDF, Top
@@ -552,7 +551,7 @@ by evaluating the following Lisp form:
 (asdf:load-system :@var{foo})
 @end example
 
-On some implementations (namely, SBCL and Clozure CL),
+On some implementations (namely ABCL, Clozure CL, CMUCL, ECL and SBCL),
 ASDF hooks into the @code{CL:REQUIRE} facility
 and you can just use:
 
@@ -813,6 +812,7 @@ the current package @code{my-system-asd} can be specified as
 @code{:my-component-type}, or @code{my-component-type}.
 
 @subsection Pathname specifiers
+@cindex pathname specifiers
 
 A pathname specifier (@code{pathname-specifier})
 may be a pathname, a string or a symbol.
@@ -845,6 +845,14 @@ will be interpreted as the pathname @file{#p"foo/bar"},
 and a string @code{"foo/bar.quux"}
 will be interpreted as the pathname @file{#p"foo/bar.quux"}.
 
+ASDF does not interpret the string @code{".."} to designate the parent
+directory.  This string will be passed through to the underlying
+operating system for interpretation.  We @emph{believe} that this will
+work on all platforms where ASDF is deployed, but do not guarantee this
+behavior.  A pathname object with a relative directory component of
+@code{:up} or @code{:back} is the only guaranteed way to specify a
+parent directory.
+
 If a symbol is given, it will be translated into a string,
 and downcased in the process.
 The downcasing of symbols is unconventional,
@@ -856,23 +864,26 @@ so this makes more sense than attempting to use @code{:case :common}
 as argument to @code{make-pathname},
 which is reported not to work on some implementations.
 
-Pathnames objects may be given to override the path for a component.
+Pathname objects may be given to override the path for a component.
 Such objects are typically specified using reader macros such as @code{#p}
 or @code{#.(make-pathname ...)}.
-Note however, that @code{#p...} is a short for @code{#.(parse-namestring ...)}
-and that the behavior @code{parse-namestring} is completely non-portable,
-unless you are using Common Lisp @code{logical-pathname}s.
-(@xref{The defsystem grammar,,Warning about logical pathnames}, below.)
+Note however, that @code{#p...} is a shorthand for @code{#.(parse-namestring ...)}
+and that the behavior of @code{parse-namestring} is completely non-portable,
+unless you are using Common Lisp @code{logical-pathname}s
+(@pxref{The defsystem grammar,,Warning about logical pathnames}, below).
 Pathnames made with @code{#.(make-pathname ...)}
 can usually be done more easily with the string syntax above.
 The only case that you really need a pathname object is to override
 the component-type default file type for a given component.
-Therefore, it is a rare case that pathname objects should be used at all.
+Therefore, pathname objects should only rarely be used.
 Unhappily, ASDF 1 didn't properly support
 parsing component names as strings specifying paths with directories,
 and the cumbersome @code{#.(make-pathname ...)} syntax had to be used.
-Note that when specifying pathname objects, no magic interpretation of the pathname
-is made depending on the component type.
+
+Note that when specifying pathname objects, 
+ASDF does not do any special interpretation of the pathname
+influenced by the component type, unlike the procedure for
+pathname-specifying strings.
 On the one hand, you have to be careful to provide a pathname that correctly
 fulfills whatever constraints are required from that component type
 (e.g. naming a directory or a file with appropriate type);
@@ -881,6 +892,11 @@ be forced upon you if you were specifying a string.
 
 
 @subsection Warning about logical pathnames
+@cindex logical pathnames 
+
+We recommend that you not use logical pathnames
+in your asdf system definitions at this point,
+but logical pathnames @emph{are} supported.
 
 To use logical pathnames,
 you will have to provide a pathname object as a @code{:pathname} specifier
@@ -888,24 +904,29 @@ to components that use it, using such syntax as
 @code{#p"LOGICAL-HOST:absolute;path;to;component.lisp"}.
 
 You only have to specify such logical pathname for your system or
-some top-level component, as sub-components using the usual string syntax
-for names will be properly merged with the pathname of their parent.
+some top-level component.  Sub-components' relative pathnames, specified
+using the string syntax
+for names, will be properly merged with the pathnames of their parents.
 The specification of a logical pathname host however is @emph{not}
 otherwise directly supported in the ASDF syntax
 for pathname specifiers as strings.
 
-Logical pathnames are not specifically recommended to newcomers,
-but are otherwise supported.
-Moreover, the @code{asdf-output-translation} layer will
-avoid trying to resolve and translate logical-pathnames,
-so you can define yourself what translations you want to use
+The @code{asdf-output-translation} layer will
+avoid trying to resolve and translate logical-pathnames.
+The advantage of this is that you can define yourself what translations you want to use
 with the logical pathname facility.
+The disadvantage is that if you do not define such translations, any
+system that uses logical pathnames will be have differently under
+asdf-output-translations than other systems you use.
 
-The user of logical pathnames will have to configure logical pathnames himself,
-before they may be used, and ASDF provides no specific support for that.
+If you wish to use logical pathnames you will have to configure the
+translations yourself before they may be used.
+ASDF currently provides no specific support
+for defining logical pathname translations.
 
 
 @subsection Serial dependencies
+@cindex serial dependencies
 
 If the @code{:serial t} option is specified for a module,
 ASDF will add dependencies for each each child component,
@@ -913,8 +934,8 @@ on all the children textually preceding it.
 This is done as if by @code{:depends-on}.
 
 @lisp
-:components ((:file "a") (:file "b") (:file "c"))
 :serial t
+:components ((:file "a") (:file "b") (:file "c"))
 @end lisp
 
 is equivalent to
@@ -1319,11 +1340,11 @@ Don't hold your breath.
 @code{defsystem} grammar subsection,
 which doesn't provide any obvious way to specify required features.
 Furthermore, in 2009, discussions on the
-@uref{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
+@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
 suggested that the specification of required features may be broken,
 and that no one may have been using them for a while.
 Please contact the
-@uref{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
+@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
 if you are interested in getting this features feature fixed.}
 
 Traditionally defsystem users have used reader conditionals
@@ -1674,7 +1695,7 @@ where data files are located,
 where output file caches are located.
 Mentions of XDG variables refer to that document.
 
-@uref{http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html}
+@url{http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html}
 
 This specification allows the user to specify some environment variables
 to customize how applications behave to his preferences.
@@ -1713,23 +1734,26 @@ CONFIGURATION := (:source-registry DIRECTIVE ...)
 
 ;; A directive is one of the following:
 DIRECTIVE :=
+    ;; INHERITANCE DIRECTIVE:
+    ;; Your configuration expression MUST contain
+    ;; exactly one of either of these:
+    :inherit-configuration | ; splices inherited configuration (often specified last)
+    :ignore-inherited-configuration | ; drop inherited configuration (specified anywhere)
+
     ;; add a single directory to be scanned (no recursion)
     (:directory DIRECTORY-PATHNAME-DESIGNATOR) |
 
     ;; add a directory hierarchy, recursing but excluding specified patterns
     (:tree DIRECTORY-PATHNAME-DESIGNATOR) |
 
-    ;; override the default defaults for exclusion patterns
+    ;; override the defaults for exclusion patterns
     (:exclude PATTERN ...) |
+    ;; augment the defaults for exclusion patterns
+    (:also-exclude PATTERN ...) |
 
     ;; splice the parsed contents of another config file
     (:include REGULAR-FILE-PATHNAME-DESIGNATOR) |
 
-    ;; Your configuration expression MUST contain
-    ;; exactly one of either of these:
-    :inherit-configuration | ; splices contents of inherited configuration
-    :ignore-inherited-configuration | ; drop contents of inherited configuration
-
     ;; This directive specifies that some default must be spliced.
     :default-registry
 
@@ -1738,6 +1762,15 @@ PATTERN := a string without wildcards, that will be matched exactly
         of a path. e.g. @code{"_darcs"} will match @file{#p"/foo/bar/_darcs/src/bar.asd"}
 @end example
 
+For instance, as a simple case, my @file{~/.config/common-lisp/source-registry.conf},
+which is the default place ASDF looks for this configuration,
+once contained:
+@example
+(:source-registry
+  (:tree "/home/fare/cl/")
+  :inherit-configuration)
+@end example
+
 
 @section Configuration Directories
 
@@ -1746,7 +1779,7 @@ a list of directives without any enclosing @code{(:source-registry ...)} form.
 The files will be sorted by namestring as if by @code{string<} and
 the lists of directives of these files with be concatenated in order.
 An implicit @code{:inherit-configuration} will be included
-at the end of the list.
+at the @emph{end} of the list.
 
 This allows for packaging software that has file granularity
 (e.g. Debian's @code{dpkg} or some future version of @code{clbuild})
@@ -1766,6 +1799,15 @@ or namestring in an @code{:include} directive, e.g.:
 	(:include "/foo/bar/")
 @end example
 
+Hence, to achieve the same effect as
+my example @file{~/.config/common-lisp/source-registry.conf} above,
+I could simply create a file
+@file{~/.config/common-lisp/source-registry.conf.d/33-home-fare-cl.conf}
+alone in its directory with the following contents:
+@example
+(:tree "/home/fare/cl/")
+@end example
+
 
 @section Shell-friendly syntax for configuration
 
@@ -1808,9 +1850,14 @@ ASDF currently returns the first system found,
 XCVB currently raised an error.
 If none is found, the search continues.
 
-Exclude statements specify patterns of subdirectories the systems of which
-to ignore. Typically you don't want to use copies of files kept by such
+Exclude statements specify patterns of subdirectories
+the systems from which to ignore.
+Typically you don't want to use copies of files kept by such
 version control systems as Darcs.
+Exclude statements are not propagated to further included or inherited
+configuration files or expressions;
+instead the defaults are reset around every configuration statement
+to the default defaults from @code{asdf::*default-source-registry-exclusions*}.
 
 Include statements cause the search to recurse with the path specifications
 from the file specified.
@@ -2057,7 +2104,7 @@ for configuration by the end-user
 in an easy way with configuration files.
 Recent versions of same packages use
 the new @code{asdf-output-translations} API as defined below:
-@code{common-lisp-controller} (7.1) and @code{cl-launch} (3.00);
+@code{common-lisp-controller} (7.2) and @code{cl-launch} (3.000).
 @code{ASDF-Binary-Locations} is fully superseded and not to be used anymore.
 
 This incompatibility shouldn't inconvenience many people.
@@ -2110,13 +2157,14 @@ CONFIGURATION := (:output-translations DIRECTIVE ...)
 
 ;; A directive is one of the following:
 DIRECTIVE :=
-    ;; include a configuration file or directory
-    (:include PATHNAME-DESIGNATOR) |
-
+    ;; INHERITANCE DIRECTIVE:
     ;; Your configuration expression MUST contain
     ;; exactly one of either of these:
-    :inherit-configuration | ; splices contents of inherited configuration
-    :ignore-inherited-configuration | ; drop contents of inherited configuration
+    :inherit-configuration | ; splices inherited configuration (often specified last)
+    :ignore-inherited-configuration | ; drop inherited configuration (specified anywhere)
+
+    ;; include a configuration file or directory
+    (:include PATHNAME-DESIGNATOR) |
 
     ;; enable global cache in ~/.common-lisp/cache/sbcl-1.0.35-x86-64/ or something.
     :enable-user-cache |
@@ -2232,7 +2280,7 @@ a list of directives without any enclosing
 The files will be sorted by namestring as if by @code{string<} and
 the lists of directives of these files with be concatenated in order.
 An implicit @code{:inherit-configuration} will be included
-at the end of the list.
+at the @emph{end} of the list.
 
 This allows for packaging software that has file granularity
 (e.g. Debian's @command{dpkg} or some future version of @command{clbuild})
@@ -2446,13 +2494,45 @@ as pathname specifiers for components.
 
 @defun system-source-directory system-designator
 
-ASDF does not provide a turnkey solution for locating data (or other
-miscellaneous) files that are distributed together with the source code
-of a system.  Programmers can use @code{system-source-directory} to find
-such files.  Returns a pathname object.  The @var{system-designator} may
-be a string, symbol, or ASDF system object.
+ASDF does not provide a turnkey solution for locating
+data (or other miscellaneous) files
+that are distributed together with the source code of a system.
+Programmers can use @code{system-source-directory} to find such files.
+Returns a pathname object.
+The @var{system-designator} may be a string, symbol, or ASDF system object.
 @end defun
 
+@defun clear-system system-designator
+
+It is sometimes useful to force recompilation of a previously loaded system.
+In these cases, it may be useful to @code{(asdf:clear-system :foo)}
+to remove the system from the table of currently loaded systems;
+the next time the system @code{foo} or one that depends on it is re-loaded,
+@code{foo} will then be loaded again.
+Alternatively, you could touch @code{foo.asd} or
+remove the corresponding fasls from the output file cache.
+(It was once conceived that one should provide
+a list of systems the recompilation of which to force
+as the @code{:force} keyword argument to @code{load-system};
+but this has never worked, and though the feature was fixed in ASDF 2.000,
+it remains @code{cerror}'ed out as nobody ever used it.)
+
+Note that this does not and cannot by itself undo the previous loading
+of the system. Common Lisp has no provision for such an operation,
+and its reliance on irreversible side-effects to global datastructures
+makes such a thing impossible in the general case.
+If the software being re-loaded is not conceived with hot upgrade in mind,
+this re-loading may cause many errors, warnings or subtle silent problems,
+as packages, generic function signatures, structures, types, macros, constants, etc.
+are being redefined incompatibly.
+It is up to the user to make sure that reloading is possible and has the desired effect.
+In some cases, extreme measures such as recursively deleting packages,
+unregistering symbols, defining methods on @code{update-instance-for-redefined-class}
+and much more are necessary for reloading to happen smoothly.
+ASDF itself goes through notable pains to make such a hot upgrade possible
+with respect to its own code, and what it does is ridiculously complex;
+look at the beginning of @file{asdf.lisp} to see what it does.
+@end defun
 
 @node Getting the latest version, FAQ, Miscellaneous additional functionality, Top
 @comment  node-name,  next,  previous,  up
@@ -2466,7 +2546,7 @@ a slightly older version about which none of the HEAD users have complained.
 There is also a STABLE version, which is earlier than release.
 
 You may get the ASDF source repository using git:
-@kbd{git clone http://common-lisp.net/project/asdf/asdf.git}
+@kbd{git clone git://common-lisp.net/projects/asdf/asdf.git}
 
 You will find the above referenced tags in this repository.
 You can also browse the repository on
@@ -2475,7 +2555,7 @@ You can also browse the repository on
 Discussion of ASDF development is conducted on the
 mailing list
 @kbd{asdf-devel@@common-lisp.net}.
-@uref{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel}
+@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel}
 
 
 @node FAQ, TODO list, Getting the latest version, Top
@@ -2487,41 +2567,38 @@ mailing list
 ASDF bugs are tracked on launchpad: @url{https://launchpad.net/asdf}.
 
 If you're unsure about whether something is a bug, of for general discussion,
-use the @uref{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
+use the @url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list}
 
 
 @section ``What has changed between ASDF 1 and ASDF 2?''
 
 @subsection What are ASDF 1 and ASDF 2?
 
-We are preparing for a release of ASDF 2,
-which will have version 2.000 and later.
-While the code and documentation are essentially complete
-we are still working on polishing them before release.
+On May 31st 2010, we have released ASDF 2.
+ASDF 2 refers to release 2.000 and later.
+(Releases between 1.656 and 1.728 were development releases for ASDF 2.)
+ASDF 1 to any release earlier than 1.369 or so.
+If your ASDF doesn't sport a version, it's an old ASDF 1.
 
-Releases in the 1.700 series and beyond
-should be considered as release candidates.
-For all practical purposes,
-ASDF 2 refers to releases later than 1.656,
-and ASDF 1 to any release earlier than 1.369 or so.
-If your ASDF doesn't have a version, it's old.
-
-ASDF 2 release candidates and beyond will have
+ASDF 2 and its release candidates push
 @code{:asdf2} onto @code{*features*} so that if you are writing
 ASDF-dependent code you may check for this feature
 to see if the new API is present.
 @emph{All} versions of ASDF should have the @code{:asdf} feature.
 
 If you are experiencing problems or limitations of any sort with ASDF 1,
-we recommend that you should upgrade to ASDF 2 or its latest release candidate.
+we recommend that you should upgrade to ASDF 2,
+or whatever is the latest release.
 
 
 @subsection ASDF can portably name files in subdirectories
 
 Common Lisp namestrings are not portable,
 except maybe for logical pathnamestrings,
-that themselves require a lot of setup that is itself ultimately non-portable.
-The only portable ways to refer to pathnames inside systems and components
+that themselves have various limitations and require a lot of setup
+that is itself ultimately non-portable.
+
+In ASDF 1, the only portable ways to refer to pathnames inside systems and components
 were very awkward, using @code{#.(make-pathname ...)} and
 @code{#.(merge-pathnames ...)}.
 Even the above were themselves were inadequate in the general case
@@ -2535,8 +2612,15 @@ Naming files within a system definition becomes easy and portable again.
 @code{asdf-utilities:merge-pathnames*},
 @code{asdf::merge-component-name-type}.
 
+On the other hand, there are places where systems used to accept namestrings
+where you must now use an explicit pathname object:
+@code{(defsystem ... :pathname "LOGICAL-HOST:PATH;TO;SYSTEM;" ...)}
+must now be written with the @code{#p} syntax:
+@code{(defsystem ... :pathname #p"LOGICAL-HOST:PATH;TO;SYSTEM;" ...)}
+
 @xref{The defsystem grammar,,Pathname specifiers}.
 
+
 @subsection Output translations
 
 A popular feature added to ASDF was output pathname translation:
@@ -2574,13 +2658,24 @@ ASDF 2 provides a well-documented way to configure ASDF,
 with sensible defaults, adequate configuration languages,
 and a coherent set of configuration files and hooks.
 
+We believe it's a vast improvement because it decouples
+application distribution from library distribution.
+The application writer can avoid thinking where the libraries are,
+and the library distributor (dpkg, clbuild, advanced user, etc.)
+can configure them once and for every application.
+Yet settings can be easily overridden where needed,
+so whoever needs control has exactly as much as required.
+
 At the same time, ASDF 2 remains compatible
 with the old magic you may have in your build scripts
+(using @code{*central-registry*} and
+@code{*system-definition-search-functions*})
 to tailor the ASDF configuration to your build automation needs,
 and also allows for new magic, simpler and more powerful magic.
 
 @xref{Controlling where ASDF searches for systems}.
 
+
 @subsection Usual operations are made easier to the user
 
 In ASDF 1, you had to use the awkward syntax
@@ -2595,9 +2690,10 @@ similarly for @code{compile-system}, @code{test-system}.
 
 @subsection Many bugs have been fixed
 
-These issues and many others have been fixed,
-including the following:
+The following issues and many others have been fixed:
 
+@itemize
+@item
 The infamous TRAVERSE function has been revamped significantly,
 with many bugs squashed.
 In particular, dependencies were not correctly propagated
@@ -2605,17 +2701,33 @@ across submodules within a system but now are.
 The :version and :feature features and
 the :force (system1 .. systemN) feature have been fixed.
 
+@item
+Performance has been notably improved for large systems
+(say with thousands of components) by using
+hash-tables instead of linear search,
+and linear-time list accumulation
+instead of quadratic-time recursive appends.
+
+@item
 Many features used to not be portable,
 especially where pathnames were involved.
+Windows support was notably quirky because of such non-portability.
 
-The internal test suite used to massively fail
-on many implementations.
+@item
+The internal test suite used to massively fail on many implementations.
+While still incomplete, it now fully passes
+on all implementations supported by the test suite,
+except for GCL (due to GCL bugs).
 
-Support was broken for some implementations (notably ABCL).
+@item
+Support was lacking for some implementations.
+ABCL and GCL were notably wholly broken.
+ECL extensions were not integrated in the ASDF release.
 
+@item
 The documentation was grossly out of date.
 
-ECL extensions were not integrated in the ASDF release.
+@end itemize
 
 
 @subsection ASDF itself is versioned
@@ -2630,9 +2742,10 @@ or take great pains to have the correct version of ASDF installed.
 With ASDF 2, we provide a new stable set of working features
 that everyone can rely on from now on.
 Use @code{#+asdf2} to detect presence of ASDF 2,
-@code{(asdf:version-satisfies (asdf:asdf-version) "1.703")}
+@code{(asdf:version-satisfies (asdf:asdf-version) "2.000")}
 to check the availability of a version no earlier than required.
 
+
 @subsection ASDF can be upgraded
 
 When an old version of ASDF was loaded,
@@ -2674,6 +2787,74 @@ This means that release cycles will be causally decoupled,
 the practical consequence of which will mean faster convergence
 towards the latest version for everyone.
 
+
+@subsection Pitfalls of ASDF 2
+
+The main pitfalls in upgrading to ASDF 2 seem to be related
+to the output translation mechanism.
+
+@itemize
+
+@item
+Output translations is enabled by default. This may surprise some users,
+most of them in pleasant way (we hope), a few of them in an unpleasant way.
+It is trivial to disable output translations.
+@xref{FAQ,,``How can I wholly disable the compiler output cache?''}.
+
+@item
+Some systems in the large have been known not to play well with output translations.
+They were relatively easy to fix.
+Once again, it is also easy to disable output translations,
+or to override its configuration.
+
+@item
+The new ASDF output translations are incompatible with ASDF-Binary-Locations.
+They replace A-B-L, and there is compatibility mode to emulate
+your previous A-B-L configuration.
+See @code{asdf:enable-asdf-binary-locations-compatibility} in
+@pxref{Controlling where ASDF saves compiled files,,Backward Compatibility}.
+But thou shall not load ABL on top of ASDF 2.
+
+@item
+ASDF pathname designators are now specified in places where they were unspecified,
+and a few small adjustments have to be made to some non-portable defsystems.
+Notably, in the @code{:pathname} argument to a @code{defsystem} and its components,
+a logical pathname (or implementation-dependent hierarchical pathname)
+must now be specified with @code{#p} syntax
+where the namestring might have previously sufficed;
+moreover when evaluation is desired @code{#.} must be used,
+where it wasn't necessary in the toplevel @code{:pathname} argument.
+
+@end itemize
+
+Other issues include the following:
+
+@itemize
+
+@item
+There is a slight performance bug, notably on SBCL,
+when initially searching for @file{asd} files,
+the implicit @code{(directory "/configured/path/**/*.asd")}
+for every configured path @code{(:tree "/configured/path/")}
+in your @code{source-registry} configuration can cause a slight pause.
+Try to @code{(time (asdf:initialize-source-registry))}
+to see how bad it is or isn't on your system.
+If you insist on not having this pause,
+you can avoid the pause by overriding the default source-registry configuration
+and not use any deep @code{:tree} entry but only @code{:directory} entries
+or shallow @code{:tree} entries.
+Or you can fix your implementation to not be quite that slow
+when recursing through directories.
+
+@item
+On Windows, only LispWorks supports proper default configuration pathnames
+based on the Windows registry.
+Other implementations make do.
+Windows support is largely untested, so please help report and fix bugs.
+
+@end itemize
+
+
 @section Issues with installing the proper version of ASDF
 
 @subsection ``My Common Lisp implementation comes with an outdated version of ASDF. What to do?''
@@ -2697,25 +2878,59 @@ We trust you to thoroughly test it with your implementation before you release i
 If there are any issues with the current release,
 it's a bug that you should report upstream and that we will fix ASAP.
 
-As to how to include ASDF, we recommend that
-if you do have a few magic systems in your implementation path,
-that are specially treated in @code{wrapping-source-registry},
-like SBCL does.
-In this case, we explicitly ask you to @emph{NOT} distribute
-@file{asdf.asd} together with your implementation's ASDF,
-least you separate it from the other systems in this path,
-or otherwise rename the system and its @file{asd} file
-to e.g. @code{asdf-sbcl} and @file{asdf-sbcl.asd}.
+As to how to include ASDF, we recommend the following:
 
+@itemize
+@item
+If ASDF isn't installed yet, then @code{(require :asdf)}
+should load the version of ASDF that is bundled with your system.
+You may have it load some other version configured by the user,
+if you allow such configuration.
+
+@item
+If your system provides a mechanism to hook into @code{CL:REQUIRE},
+then it would be nice to add ASDF to this hook the same way that
+ABCL, CCL, CMUCL, ECL and SBCL do it.
+
+@item
+You may, like SBCL, have ASDF be implicitly used to require systems
+that are bundled with your Lisp distribution.
+If you do have a few magic systems that come with your implementation
+in a precompiled way such that one should only use the binary version
+that goes with your distribution, like SBCL does,
+then you should add them in the beginning of @code{wrapping-source-registry}.
+
+@item
+If you have magic systems as above, like SBCL does,
+then we explicitly ask you to @emph{NOT} distribute
+@file{asdf.asd} as part of those magic systems.
+You should still include the file @file{asdf.lisp} in your source distribution
+and precompile it in your binary distribution,
+but @file{asdf.asd} if included at all,
+should be secluded from the magic systems,
+in a separate file hierarchy,
+or you may otherwise rename the system and its file to e.g.
+@code{asdf-ecl} and @file{asdf-ecl.asd}, or
+@code{sb-asdf} and @file{sb-asdf.asd}.
+Indeed, if you made @file{asdf.asd} a magic system,
+then users would no longer be able to upgrade ASDF using ASDF itself
+to some version of their preference that
+they maintain independently from your Lisp distribution.
+
+@item
 If you do not have any such magic systems, or have other non-magic systems
 that you want to bundle with your implementation,
 then you may add them to the @code{default-source-registry},
 and you are welcome to include @file{asdf.asd} amongst them.
 
-Please send upstream any patches you make to ASDF itself,
+@item
+Please send us upstream any patches you make to ASDF itself,
 so we can merge them back in for the benefit of your users
 when they upgrade to the upstream version.
 
+@end itemize
+
+
 
 @section Issues with configuring ASDF
 
@@ -2779,9 +2994,9 @@ ASDF provides a predefined test operation, @code{test-op}.
 The test operation, however, is largely left to the system definer to specify.
 @code{test-op} has been
 a topic of considerable discussion on the
-@uref{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list},
+@url{http://common-lisp.net/cgi-bin/mailman/listinfo/asdf-devel,asdf-devel mailing list},
 and on the
-@uref{https://launchpad.net/asdf,launchpad bug-tracker}.
+@url{https://launchpad.net/asdf,launchpad bug-tracker}.
 
 Here are some guidelines:
 
@@ -2966,12 +3181,8 @@ What would be a nice interface for this functionality?
 
 @section Missing bits in implementation
 
-** all of the above
-
 ** reuse the same scratch package whenever a system is reloaded from disk
 
-** rules for system pathname defaulting are not yet implemented properly
-
 ** proclamations probably aren't
 
 ** when a system is reloaded with fewer components than it previously had, odd things happen
@@ -2980,16 +3191,6 @@ We should do something inventive when processing a @code{defsystem} form,
 like take the list of kids and @code{setf} the slot to @code{nil},
 then transfer children from old to new list as they're found.
 
-**  traverse may become a normal function
-
-If you're defining methods on @code{traverse}, speak up.
-
-
-** a lot of load-op methods can be rewritten to use input-files
-
-so should be.
-
-
 ** (stuff that might happen later)
 
 *** Propagation of the @code{:force} option.
diff --git a/doc/index.html b/doc/index.html
index a4de63ca636f00c8fee9a3a97fcb9ebe68adfeb3..e09661160610e0468186bcfbc8f2f9bbd11669c6 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -26,12 +26,18 @@
       </ul>
     </div>
     <div class="contents">
+        <a id="ASDF 2"></a>
+        <h3>ASDF 2</h3>
+        <p>We recently released ASDF 2 (on May 31st 2010).
+          It will hopefully be bundled will all official releases
+          of Common Lisp implementations made after that date.
+        </p>
         <a id="what_it_is"></a>
         <h3>What it is</h3>
         <p>ASDF is a tool for describing how source files are organized:
           what depends on which and when.
         </p>
-        <p>It is roughly what Common-Lisp hackers use to build software
+        <p>It is roughly what Common Lisp hackers use to build software
           where C hackers would use say GNU Make.
         </p>
         <p>ASDF stands for <em>A</em>nother <em>S</em>ystem <em>D</em>efinition <em>F</em>acility,
@@ -47,7 +53,7 @@
           <li><a href="http://common-lisp.net/gitweb?p=projects/asdf/asdf.git;a=blob;f=asdf.texinfo">as texinfo source</a></li>
         </ul>
 
-        <a href="downloads"></a>
+        <a id="downloads"></a>
         <h3>Getting it</h3>
         <p>Though they may lag behind the version here, ASDF comes bundled with most Lisps.
           To get the greatest and latest, you can:
@@ -64,7 +70,9 @@
           </li>
           <li>pull the latest from our git repository
             (<a href="http://common-lisp.net/gitweb?p=projects/asdf/asdf.git">browse</a>)
-            <pre>git clone http://common-lisp.net/project/asdf/asdf.git</pre>
+            <pre>git clone git://common-lisp.net/projects/asdf/asdf.git</pre>
+            (Note that our "master" branch is for current development;
+            get our "release" branch for the latest stable release.)
         </li></ul>
 
         <a id="bugs">
@@ -90,19 +98,20 @@
         <a id="news"></a>
         <h3>What is happening</h3>
         <dl>
-          <dt>December 2009 to April 2010</dt>
+          <dt>December 2009 to June 2010</dt>
           <dd>Fran&ccedil;ois-Ren&eacute; Rideau is de facto maintainer,
-            with notable contributions from Robert P. Goldman.
-            Push towards an ASDF 2 release
+            with notable contributions from Robert P. Goldman,
+            Juanjo Garcia-Ripoll and James Anderson.
+            ASDF 2 released
             with many clean-ups, better configurability
             and updated documentation.
           </dd>
           <dt>May 2006 to November 2009</dt>
           <dd>Gary King is de facto maintainer,
             with notable contributions from
-            Robert P. Goldman, Nikodemus Siivola, Christophe Rhodes, D Herring.
+            Robert P. Goldman, Nikodemus Siivola, Christophe Rhodes, Daniel Herring.
             Many small features and bug fixes,
-            trying to make the project more usable,
+            making the project more maintanable,
             moving to using git and common-lisp.net.
           </dd>
           <dt>May 2004 to April 2006</dt>
@@ -124,7 +133,7 @@
         <a class="nav" href="http://common-lisp.net/" title="Common-Lisp.net"> <img src="http://common-lisp.net/project/cl-containers/shared/buttons/lisp-lizard.png" width="80" height="15" title="Common-Lisp.net" alt="Common-Lisp.net button" /></a>
         <p><span class="copyright"Copyright &copy; 2001-2010 Daniel Barlow and contributors</span></p>
         <p>ASDF has an <a href="http://www.opensource.org/licenses/mit-license.php">MIT style</a> license</p>
-        <div id="timestamp">Last updated 2010-04-08</div>
+        <div id="timestamp">Last updated 2010-06-02</div>
     </div>
   </body>
 </html>
diff --git a/test/asdf-pathname-test.script b/test/asdf-pathname-test.script
index 460ce9327c4e5c79374e4607df4ed535a2851f99..123f36cfb56c5b8700a435601a22a7a6f92637a0 100644
--- a/test/asdf-pathname-test.script
+++ b/test/asdf-pathname-test.script
@@ -185,11 +185,11 @@
                       (handler-bind
                         ((error (lambda (c)
                                   (incf system-failures)
-                                  (format *error-output* "~&error! ~a~%sysdef:~% ~W~%" c system-definition)
+                                  (format *error-output* "~&error! ~a~%sysdef:~% ~S~%" c system-definition)
                                   #+sbcl (sb-debug:backtrace 69)
                                   #+clozure (ccl:print-call-history :count 69 :start-frame-number 1)
                                   #+clisp (system::print-backtrace)
-                                  (format result-stream "~&~%***~%error: ~a~%~:w"
+                                  (format result-stream "~&~%***~%error: ~a~%~s"
                                           c system-definition)
                                   (return-from :test-system))))
                         (unless (and (or (typep system-pathname 'logical-pathname)
@@ -241,9 +241,9 @@
                                              :missing)))
                             test-files))
 
-            (format result-stream "~&~%~% translations: ~a: ~:w" "ASDFTEST" (logical-pathname-translations "ASDFTEST"))
+            (format result-stream "~&~%~% translations: ~a: ~s" "ASDFTEST" (logical-pathname-translations "ASDFTEST"))
 
-            (format result-stream "~&~%~% variations:~% systems: ~:w~% modules: ~:w~% files: ~:w"
+            (format result-stream "~&~%~% variations:~% systems: ~s~% modules: ~s~% files: ~s"
                     systems modules files)
 
             (let ((homogeneous-failures 0) (*print-length* nil))
diff --git a/test/compile-asdf.lisp b/test/compile-asdf.lisp
index 3285c7c2ebb74a63817fb81604c078a9735285df..f379dece5c8beafe9670fef320dbf6a53eb8869f 100644
--- a/test/compile-asdf.lisp
+++ b/test/compile-asdf.lisp
@@ -18,18 +18,14 @@
                          #'(lambda (w)
                              (princ w *error-output*)
                              (muffle-warning w))))
-           (compile-file *asdf-lisp* :output-file tmp))
+           (compile-file *asdf-lisp* :output-file tmp :print t :verbose t))
        (declare (ignore result))
        (cond
-         #-ecl
          (warnings-p
           (leave-lisp "Testsuite failed: ASDF compiled with warnings" 1))
          (errors-p
           (leave-lisp "Testsuite failed: ASDF compiled with ERRORS" 2))
          (t
-          #+ecl
-          (when warnings-p
-            (format t "~&ASDF compiled with warnings. Please fix ECL.~%"))
           (when (probe-file *asdf-fasl*)
             (delete-file *asdf-fasl*))
           (rename-file tmp *asdf-fasl*)
diff --git a/test/run-tests.sh b/test/run-tests.sh
index da2ba6821e18db1695cc061a7574e33c7459b958..abd8752108c49c0fdc55e0b82f9187befddfdaa2 100755
--- a/test/run-tests.sh
+++ b/test/run-tests.sh
@@ -86,6 +86,7 @@ do_tests() {
     echo "  $test_pass passing and $test_fail failing" >&2
     if [ $test_fail -eq 0 ] ; then
 	echo "all tests apparently successful" >&2
+        echo success > ../tmp/results/status
     else
 	echo "failing test(s): $failed_list" >&2
     fi
@@ -190,8 +191,11 @@ if [ -z "$command" ] ; then
 else
     create_config
     mkdir -p ../tmp/results
+    echo failure > ../tmp/results/status
     thedate=`date "+%Y-%m-%d"`
     do_tests "$command" "$eval" 2>&1 | \
 	tee "../tmp/results/${lisp}.text" "../tmp/results/${lisp}-${thedate}.save"
+    read a < ../tmp/results/status
     clean_up
+    [ success = "$a" ] ## exit code
 fi
diff --git a/test/script-support.lisp b/test/script-support.lisp
index edecd3be3bb1b6b452a8e3b6f8a214dff744a906..fd9066fc65bf404fb2ce6f72aa73c5be46b98939 100644
--- a/test/script-support.lisp
+++ b/test/script-support.lisp
@@ -43,6 +43,7 @@
 ;;; code adapted from cl-launch (any errors in transcription are mine!)
 ;; http://www.cliki.net/cl-launch
 (defun leave-lisp (message return)
+  (fresh-line *error-output*)
   (when message
     (format *error-output* message)
     (terpri *error-output*))
diff --git a/test/test-compile-file-failure.asd b/test/test-compile-file-failure.asd
new file mode 100644
index 0000000000000000000000000000000000000000..3899a407ec12687aca22fa69cb62c0d87b9315ce
--- /dev/null
+++ b/test/test-compile-file-failure.asd
@@ -0,0 +1,2 @@
+(defsystem test-compile-file-failure
+  :components ((:file "test-compile-file-failure")))
diff --git a/test/test-compile-file-failure.lisp b/test/test-compile-file-failure.lisp
new file mode 100644
index 0000000000000000000000000000000000000000..ed9b02eebdde1f89277a292a4b49d50a06960253
--- /dev/null
+++ b/test/test-compile-file-failure.lisp
@@ -0,0 +1,4 @@
+(eval-when (:compile-toplevel :load-toplevel :execute)
+  ;; CLISP 2.48 has a bug that makes this test fail. Work around:
+  #+clisp (when (eq asdf:*compile-file-failure-behaviour* :error) (error 'asdf:compile-error))
+  (warn "Warning."))
diff --git a/test/test-compile-file-failure.script b/test/test-compile-file-failure.script
new file mode 100644
index 0000000000000000000000000000000000000000..7e470c67a972d564921e8b0f6f82006a08440b01
--- /dev/null
+++ b/test/test-compile-file-failure.script
@@ -0,0 +1,17 @@
+;;; -*- Lisp -*-
+
+(load "script-support")
+(load-asdf)
+
+(quit-on-error
+ (setf asdf:*central-registry* '(*default-pathname-defaults*))
+ (assert (handler-case
+             (let ((asdf:*compile-file-failure-behaviour* :warn))
+               (asdf:load-system 'test-compile-file-failure :force t)
+               t)
+           (asdf:compile-error () nil)))
+ (assert (handler-case
+             (let ((asdf:*compile-file-failure-behaviour* :error))
+               (asdf:load-system 'test-compile-file-failure :force t)
+               nil)
+           (asdf:compile-error () t))))
diff --git a/test/test-module-excessive-depend.asd b/test/test-module-excessive-depend.asd
index a8d8495c22e28be6ba9ec7272fc4db4715a10166..249a9bdfc99ac00090c48602633357ec021a7b72 100644
--- a/test/test-module-excessive-depend.asd
+++ b/test/test-module-excessive-depend.asd
@@ -29,7 +29,7 @@
         (call-next-method)))
 
 (defmethod find-component :around ((m (eql (find-quux)))
-                                   (c string) &optional version)
+                                   (c string))
   "FIND-COMPONENT on a component is a no-op --- it's already found."
   (declare (ignore version))
   (if (string-equal c "file3-only")
diff --git a/test/test-redundant-recompile.asd b/test/test-redundant-recompile.asd
new file mode 100644
index 0000000000000000000000000000000000000000..a69d558cadaa9de26d65a967aa1f3e9c10dcd673
--- /dev/null
+++ b/test/test-redundant-recompile.asd
@@ -0,0 +1,16 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test-redundant-recompile
+  :components ((:file "file2" :in-order-to ((compile-op (load-op "file1"))
+                                            (load-op (load-op "file1"))))
+               (:file "file1")))
+
+#|
+;;;This test system definition attempts to replicate the excess dependencies
+;;;that seem to give rise to launchpad bug 590517
+;;;(https://bugs.launchpad.net/asdf/+bug/590517)
+
+1) from clean, check that all fasl files build and that some function
+   defined in the second file is present
+
+2) load again.  Check to make sure that nothing is recompiled.
+|#
diff --git a/test/test-redundant-recompile.script b/test/test-redundant-recompile.script
new file mode 100644
index 0000000000000000000000000000000000000000..9f16fcba8f258a7e3bd324bd385de6ee3aa25a09
--- /dev/null
+++ b/test/test-redundant-recompile.script
@@ -0,0 +1,28 @@
+;;; -*- Lisp -*-
+(load "script-support")
+(load-asdf)
+
+(quit-on-error
+ (setf asdf:*central-registry* '(*default-pathname-defaults*))
+ (asdf:operate 'asdf:load-op 'test-redundant-recompile)
+ ;; test that it compiled
+ (let* ((file1 (asdf:compile-file-pathname* "file1"))
+        (file2 (asdf:compile-file-pathname* "file2"))
+        (file1-date (file-write-date file1))
+        (file2-date (file-write-date file2)))
+
+   (format t "~&test-redundant-recompile 1: ~S ~S~%" file1 file1-date)
+   (format t "~&test-redundant-recompile 2: ~S ~S~%" file2 file2-date)
+   (assert file1-date)
+   (assert file2-date)
+
+   ;; and loaded
+   (assert (symbol-value (find-symbol (symbol-name :*file1*) :test-package)))
+
+   ;; now rerun the load-op and check that no files are recompiled
+
+   ;;(trace asdf::operation-done-p asdf::traverse)
+   (asdf:operate 'asdf:load-op 'test-redundant-recompile)
+   (assert (= file1-date (file-write-date file1)))
+   (assert (= file2-date (file-write-date file2)))))
+
diff --git a/test/test-samedir-modules.asd b/test/test-samedir-modules.asd
new file mode 100644
index 0000000000000000000000000000000000000000..ae7f049b00fcb140578ea19b5dac66d66a76e5c8
--- /dev/null
+++ b/test/test-samedir-modules.asd
@@ -0,0 +1,13 @@
+;;; -*- Lisp -*-
+(asdf:defsystem test-samedir-modules
+  :components ((:module "here"
+                        :components
+                        (
+                         (:file "file2" :in-order-to ((compile-op (load-op "file1"))))
+                         (:file "file1"))
+                        :pathname "")))
+
+#|
+from clean, check that all fasl files build and that some function
+   defined in the second file is present
+|#
diff --git a/test/test-samedir-modules.script b/test/test-samedir-modules.script
new file mode 100644
index 0000000000000000000000000000000000000000..bd6ce84ee0fc855846194dedfe6e748498703891
--- /dev/null
+++ b/test/test-samedir-modules.script
@@ -0,0 +1,19 @@
+;;; -*- Lisp -*-
+(load "script-support")
+(load-asdf)
+
+(quit-on-error
+ (setf asdf:*central-registry* '(*default-pathname-defaults*))
+ (asdf:operate 'asdf:load-op 'test-samedir-modules)
+ ;; test that it compiled
+ (let* ((file1 (asdf:compile-file-pathname* "file1"))
+        (file2 (asdf:compile-file-pathname* "file2"))
+        (file1-date (file-write-date file1)))
+
+   (format t "~&test samedir modules 1: ~S ~S~%" file1 file1-date)
+   (assert file1-date)
+   (assert (file-write-date file2))
+
+   ;; and loaded
+   (assert (symbol-value (find-symbol (symbol-name :*file1*) :test-package)))))
+
diff --git a/test/test-sysdef-asdf.script b/test/test-sysdef-asdf.script
new file mode 100644
index 0000000000000000000000000000000000000000..53560b4e143d3a349cf6b8f603edaa678068115d
--- /dev/null
+++ b/test/test-sysdef-asdf.script
@@ -0,0 +1,9 @@
+;;; -*- Lisp -*-
+(load "script-support")
+(load-asdf)
+
+(quit-on-error
+ (asdf:initialize-source-registry '(:source-registry :ignore-inherited-configuration))
+ (asdf:load-system :asdf)
+ (asdf:initialize-source-registry `(:source-registry (:directory ,*asdf-directory*) :ignore-inherited-configuration))
+ (asdf:load-system :asdf))
diff --git a/test/test-utilities.script b/test/test-utilities.script
index 5be682f6f909f50b37ceecde874ad2a1212197b1..45084d609d632480d1371d5239670f9e9239aed6 100644
--- a/test/test-utilities.script
+++ b/test/test-utilities.script
@@ -39,8 +39,7 @@
 (assert
  (asdf::version-satisfies (asdf:asdf-version) (asdf:asdf-version)))
 (assert
- (asdf::version-satisfies (asdf:asdf-version) "1.608"))
+ (asdf::version-satisfies (asdf:asdf-version) "2.000"))
 (assert
  (not (asdf::version-satisfies (asdf:asdf-version) "666")))
-
 )
diff --git a/test/test1.script b/test/test1.script
index fe6955f8148277e42558cf4ad641cddfe5606bb0..bc23f8b46743344b1c3d456f0480f701cd3e73cc 100644
--- a/test/test1.script
+++ b/test/test1.script
@@ -4,7 +4,6 @@
 
 (quit-on-error
  (setf asdf:*central-registry* '(*default-pathname-defaults*))
- ;;(trace ASDF::MERGE-COMPONENT-RELATIVE-PATHNAME ASDF::COMPONENT-RELATIVE-PATHNAME)
  (asdf:operate 'asdf:load-op 'test1)
  ;; test that it compiled
  (let* ((file1 (asdf:compile-file-pathname* "file1"))
@@ -18,11 +17,8 @@
    ;; and loaded
    (assert (symbol-value (find-symbol (symbol-name :*file1*) :test-package)))
 
-   ;; now remove one output file and check that the other is _not_
-   ;; recompiled
-   (sleep 1) ; mtime has 1-second granularity, so pause here for fast machines
+   ;; now remove one output file and check that the other is _not_ recompiled
 
-   (trace asdf::operation-done-p asdf::traverse)
    (asdf::run-shell-command "rm -f ~A" (namestring file2))
    (asdf:operate 'asdf:load-op 'test1)
    (assert (= file1-date (file-write-date file1)))
@@ -34,6 +30,7 @@
    ;; unix cwd.  this is not a problem for run-tests.sh, but can be in general
 
    (let ((before (file-write-date file2)))
+     ;; filesystem mtime has 1 second granularity. Make sure even fast machines see a difference.
      (sleep 1)
      (asdf::run-shell-command "touch file1.lisp")
      (asdf:operate 'asdf:load-op 'test1)
diff --git a/test/try-recompiling-1.lisp b/test/try-recompiling-1.lisp
index 8f754c0253a1555a3a5af963cb191b1e9539cb72..395c719da2530b524c7216a05fdc8b493b85f612 100644
--- a/test/try-recompiling-1.lisp
+++ b/test/try-recompiling-1.lisp
@@ -1,5 +1,7 @@
 (in-package #:common-lisp-user)
 
+#+clisp (eval-when (:compile-toplevel) (fmakunbound 'try-recompiling-1))
+
 (defun try-recompiling-1 ()
   (assert *caught-error*))
 
diff --git a/test/try-reloading-dependency.asd b/test/try-reloading-dependency.asd
deleted file mode 100644
index e5534d8b4c59173b3afcc2dcb2cc21b98c416f7f..0000000000000000000000000000000000000000
--- a/test/try-reloading-dependency.asd
+++ /dev/null
@@ -1,5 +0,0 @@
-;;; -*- Lisp -*-
-(asdf:defsystem try-reloading-dependency
-    :components ((:file "file3")))
-
-
diff --git a/wild-modules.lisp b/wild-modules.lisp
index 2649d7eff479ef7bda03f404338afe7eeea30d8a..7a8267d071c6781b9b0405ba37e5555f1b424bf4 100644
--- a/wild-modules.lisp
+++ b/wild-modules.lisp
@@ -33,6 +33,6 @@ use a wild pathname instead." module)))
                     files)))))
 
 ;; Don't export wild-module or else will get a full warning
-;; when (require 'asdf) if asdf is already loaded
+;; when (require :asdf) if asdf is already loaded
 
 ;;(export '(wild-module))