diff --git a/README b/README
index 1030ca9366320621cccb09107519fc5f8e5b5dc5..fa4418986a933685d48ac9a9c1c2a43f29c01549 100644
--- a/README
+++ b/README
@@ -1,9 +1,33 @@
-$Id: README,v 1.19 2002/04/30 17:22:51 dan_b Exp $         -*- Text -*-
+$Id: README,v 1.20 2002/06/08 01:54:16 dan_b Exp $         -*- Text -*-
 
 
 asdf: another system definition facility          
 ========================================
 
+* Getting the latest version
+
+0) Decide which version you want.  HEAD is the newest version and
+usually OK, whereas STABLE is for cautious people (e.g. who already
+have systems using asdf that they don't want broken), a slightly older
+version about which none of the HEAD users have complained.
+
+1) Check it out from sourceforge cCLan CVS:
+
+1a) cvs -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan login
+     (no password: just press Enter)
+ 
+1a.1) cvs -z3 -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan
+         co -r STABLE asdf
+
+or for the bleeding edge, instead
+
+1a.2) cvs -z3 -d:pserver:anonymous@cvs.cclan.sourceforge.net:/cvsroot/cclan
+          co -A asdf
+
+
+For more CVS information, look at http://sourceforge.net/cvs/?group_id=28536
+
+
 * Getting started
 
 - The single file asdf.lisp is all you need to use asdf normally.  For
@@ -45,7 +69,15 @@ a custom core, or something.
 - cclan.asd and the source files listed therein contain useful extensions 
   for maintainers of systems in the cCLan.  If this isn't you, you
   don't need them - although you may want to look at them anyway
- 
+
+- For systems that do complicated things (e.g. compiling C files to
+  load as foreign code), the packages in vn-cclan may provide some
+  guidance.  db-sockets, for example, is known to do outlandish things
+  with preprocessors
+
+   http://ww.telent.net/cliki/vn-cclan 
+
+
 
 * Concepts
 
@@ -186,10 +218,7 @@ required-components := component-name
                      | (required-components required-components)
 
 component-name := string
-                | (version string object)
-
-The last case in required-components is a shorthand for the 'and'
-form, as and is usually the common case
+                | (:version string minimum-version-object)
 
 [ This is on a par with what ACL defsystem does.  mk-defsystem is less
 general: it has an implied dependency
@@ -476,9 +505,9 @@ component-type := :module | :file | :system | other-component-type
 
 dependency := (dependent-op {requirement}+)
 requirement := (required-op {required-component}+)
-             | (test-feature feature-name)
+             | (feature feature-name)
 dependent-op := operation-name
-required-op := operation-name | test-feature
+required-op := operation-name | feature
 
 For example
 
diff --git a/asdf.lisp b/asdf.lisp
index d57c6919379951a90d4635e3d5918eccfd2d0369..ee9ceccfc888f58d15d7221f35b00ae9e723efdb 100644
--- a/asdf.lisp
+++ b/asdf.lisp
@@ -159,6 +159,9 @@ and NIL NAME and TYPE components"
        (component-pathname it)
        *default-pathname-defaults*))
 
+(defgeneric component-relative-pathname (component)
+  (:documentation "Extracts the relative pathname applicable for a particular component."))
+   
 (defmethod component-relative-pathname ((component module))
   (or (slot-value component 'relative-pathname)
       (make-pathname
@@ -169,9 +172,13 @@ and NIL NAME and TYPE components"
   (let ((*default-pathname-defaults* (component-parent-pathname component)))
     (merge-pathnames (component-relative-pathname component))))
 
+(defgeneric component-property (component property))
+
 (defmethod component-property ((c component) property)
   (cdr (assoc property (slot-value c 'properties))))
 
+(defgeneric (setf component-property) (new-value component property))
+
 (defmethod (setf component-property) (new-value (c component) property)
   (let ((a (assoc property (slot-value c 'properties))))
     (if a
@@ -204,6 +211,8 @@ and NIL NAME and TYPE components"
 	(unless end (return list))
 	(setf start (1+ end)))))))
 
+(defgeneric version-satisfies (component version))
+
 (defmethod version-satisfies ((c component) version)
   (unless (and version (slot-boundp c 'version))
     (return-from version-satisfies t))
@@ -365,17 +374,24 @@ system."))
   (let ((args (operation-original-initargs o)))
     (apply #'make-instance type :parent o :original-initargs args args)))
 
+(defgeneric visit-component (operation component))
 
 (defmethod visit-component ((o operation) (c component))
   (pushnew (node-for o c)
 	   (operation-visited-nodes (operation-ancestor o))
 	   :test 'equal))
 
+(defgeneric component-visited-p (operation component))
+  
 (defmethod component-visited-p ((o operation) (c component))
   (member (node-for o c)
 	  (operation-visited-nodes (operation-ancestor o))
 	  :test 'equal))
 
+(defgeneric (setf visiting-component) (new-value operation component))
+
+(defmethod (setf visiting-component) (new-value operation component))
+
 (defmethod (setf visiting-component) (new-value (o operation) (c component))
   (let ((node (node-for o c))
 	(a (operation-ancestor o)))
@@ -384,6 +400,8 @@ system."))
 	(setf (operation-visiting-nodes a)
 	      (remove node  (operation-visiting-nodes a) :test 'equal)))))
 
+(defgeneric component-visiting-p (operation component))
+
 (defmethod component-visiting-p ((o operation) (c component))
   (let ((node (cons o c)))
     (member node (operation-visiting-nodes (operation-ancestor o))
@@ -436,38 +454,22 @@ system."))
 			      (error 'missing-dependency :required-by c
 				     :version required-v
 				     :requires required-c))))
-	       (traverse op dep-c function)))
-	   (do-every-dep (op deps)
-	     (dolist (d deps)
-	       (do-dep op  d)))
-	   (do-first-dep (op deps)
-	     (block found
-	       (dolist (d deps)
-		 (handler-case
-		     (do-dep op d)
-		   (missing-dependency (c)
-		     (declare (ignore c))
-		     (return-from found nil)))
-		 (error 'missing-dependency
-			:version nil :required-by c :requires deps))))
+	       (traverse op dep-c function)))	   	   
 	   (do-dep (op dep)
-	     (when (eq op 'feature)
-	       (return-from do-dep
-		 (or (member (car dep) *features*)
-		     (error 'missing-dependency :required-by c
-			    :requires (car dep) :version nil))))
-	     (cond 
-	       ((consp dep)
-		(case (car dep)
-		  (and (do-every-dep op (cdr dep)))
-		  (or (do-first-dep op (cdr dep)))
-		  (version
-		   (destructuring-bind (ignore name version-object) dep
-		     (declare (ignore ignore))
-		     (do-one-dep op name version-object)))
-		  ;; if we had a list with unrecognised car, assume 'and'
-		  (t (do-every-dep op dep))))
-	       (t (do-one-dep op dep nil)))))
+	     (cond ((eq op 'feature)
+		    (or (member (car dep) *features*)
+			(error 'missing-dependency :required-by c
+			       :requires (car dep) :version nil)))
+		   (t (dolist (d dep)
+			(cond ((consp d)
+			       (assert (string-equal
+					(symbol-name (first d))
+					"VERSION"))
+			       (do-one-dep op (second d) (third d)))
+			      (t
+			       (do-one-dep op d nil))))))))    
+    (when (component-visited-p operation c)
+      (return-from traverse nil)) ;; been here before
     ;; dependencies
     (if (component-visiting-p operation c)
 	(error 'circular-dependency :components (list c)))
@@ -492,17 +494,16 @@ system."))
 		   (not at-least-one))
 	  (error error))))
     ;; now the thing itself
-    (unless (component-visited-p operation c)
-      (if (or (operation-forced-p operation)
-	      (not (operation-done-p operation c)))
-	  (loop
-	   (restart-case 
-	       (progn (funcall function operation c)
-		      (return))
-	     (retry-component ())
-	     (skip-component () (return)))))
-      (setf (visiting-component operation c) nil)	      
-      (visit-component operation c))))
+    (if (or (operation-forced-p operation)
+	    (not (operation-done-p operation c)))
+	(loop
+	 (restart-case 
+	     (progn (funcall function operation c)
+		    (return))
+	   (retry-component ())
+	   (skip-component () (return)))))
+    (setf (visiting-component operation c) nil)	      
+    (visit-component operation c)))
 
 (defmethod perform ((operation operation) (c source-file))
   (sysdef-error