diff --git a/asdf.asd b/asdf.asd
index c4bc1e46477b9905d86f05e65341ea1016febd2f..36cf9591cc73779db1abf4f023713722d7f94200 100644
--- a/asdf.asd
+++ b/asdf.asd
@@ -14,7 +14,7 @@
   :licence "MIT"
   :description "Another System Definition Facility"
   :long-description "ASDF builds Common Lisp software organized into defined systems."
-  :version "2.26.26" ;; to be automatically updated by bin/bump-revision
+  :version "2.26.27" ;; to be automatically updated by bin/bump-revision
   :depends-on ()
   :components
   ((:file "asdf")))
diff --git a/asdf.lisp b/asdf.lisp
index 0b94273b8d9ffe49dee3e042258e77edaf2bdb2f..c866c158c0b163042c6f6e4a24616cdf5a567933 100644
--- a/asdf.lisp
+++ b/asdf.lisp
@@ -1,5 +1,5 @@
 ;; -*- mode: Common-Lisp; Base: 10 ; Syntax: ANSI-Common-Lisp ; coding: utf-8 -*-
-;;; This is ASDF 2.26.26: Another System Definition Facility.
+;;; This is ASDF 2.26.27: Another System Definition Facility.
 ;;;
 ;;; Feedback, bug reports, and patches are all welcome:
 ;;; please mail to <asdf-devel@common-lisp.net>.
@@ -118,7 +118,7 @@
          ;; "2.345.6" would be a development version in the official upstream
          ;; "2.345.0.7" would be your seventh local modification of official release 2.345
          ;; "2.345.6.7" would be your seventh local modification of development version 2.345.6
-         (asdf-version "2.26.26")
+         (asdf-version "2.26.27")
          (existing-asdf (find-class 'component nil))
          (existing-version *asdf-version*)
          (already-there (equal asdf-version existing-version)))
@@ -1991,6 +1991,8 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
   (declare (ignorable base))
   actual)
 
+(defgeneric* resolve-dependency-combination (component combinator arguments))
+
 (defun* resolve-dependency-name (component name &optional version)
   (loop
     (restart-case
@@ -2018,21 +2020,21 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
                    (equal (missing-requires c) name))))))))
 
 (defun* resolve-dependency-spec (component dep-spec)
-  (cond
-    ((atom dep-spec)
-     (resolve-dependency-name component dep-spec))
-    ;; Structured dependencies --- this parses keywords.
-    ;; The keywords could conceivably be broken out and cleanly (extensibly)
-    ;; processed by EQL methods. But for now, here's what we've got.
-    ((eq :version (first dep-spec))
-     ;; https://bugs.launchpad.net/asdf/+bug/527788
-     (resolve-dependency-name component (second dep-spec) (third dep-spec)))
-    ((eq :feature (first dep-spec))
-     (when (featurep (second dep-spec))
-       (resolve-dependency-spec component (third dep-spec))))
-    (t
-     (error (compatfmt "~@<Bad dependency ~s.  Dependencies must be (:version <name> <version>), (:feature <feature> <name>), or <name>.~@:>") dep-spec))))
+  (if (atom dep-spec)
+      (resolve-dependency-name component dep-spec)
+      (resolve-dependency-combination component (car dep-spec) (cdr dep-spec))))
 
+(defmethod resolve-dependency-combination (component combinator arguments)
+  (error (compatfmt "~@<Bad dependency ~S for ~S~@:>")
+         (cons combinator arguments) component))
+
+(defmethod resolve-dependency-combination (component (combinator (eql :feature)) arguments)
+  (when (featurep (first arguments))
+    (resolve-dependency-spec component (second arguments))))
+
+(defmethod resolve-dependency-combination (component (combinator (eql :version)) arguments)
+  ;; https://bugs.launchpad.net/asdf/+bug/527788
+  (resolve-dependency-name component (first arguments) (second arguments)))
 
 ;;; component subclasses
 
@@ -2117,7 +2119,8 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
 
 (defmethod component-self-dependencies ((o operation) (c component))
   (remove-if-not
-   #'(lambda (x) (find c (cdr x) :key #'(lambda (dep) (resolve-dependency-spec c dep))))
+   #'(lambda (x) (unless (eq (car x) 'feature) ;; avoid the "FEATURE" feature
+                   (find c (cdr x) :key #'(lambda (dep) (resolve-dependency-spec c dep)))))
    (component-depends-on o c)))
 
 (defmethod output-files ((o operation) (c component))
@@ -2201,10 +2204,12 @@ PREVIOUS-TIME when not null is the time at which the PREVIOUS system was loaded.
 
 (defun* visit-dependencies (operation component fun &aux stamp)
   (loop :for (dep-o-spec . dep-c-specs) :in (component-depends-on operation component)
-        :for dep-o = (find-operation operation dep-o-spec) :do
-          (loop :for dep-c-spec :in dep-c-specs
-                :for dep-c = (resolve-dependency-spec component dep-c-spec) :do
-                  (latest-stamp-f stamp (funcall fun dep-o dep-c))))
+        :for () = (format t "~&VD ~S ~S ~S~&" dep-o-spec dep-c-specs (eq dep-o-spec 'feature))
+        :unless (eq dep-o-spec 'feature) ;; avoid the "FEATURE" misfeature
+          :do (loop :with dep-o = (find-operation operation dep-o-spec)
+                    :for dep-c-spec :in dep-c-specs
+                    :for dep-c = (resolve-dependency-spec component dep-c-spec) :do
+                      (latest-stamp-f stamp (funcall fun dep-o dep-c))))
   stamp)
 
 (defvar *visit-count* 0) ; counter that allows to sort nodes from operation-visited-nodes
@@ -2872,6 +2877,24 @@ Returns the new tree (which probably shares structure with the old one)"
   (%remove-component-inline-methods component)
   (%define-component-inline-methods component rest))
 
+;; Resolve away the dubious and deprecated option :IF-COMPONENT-DEP-FAILS
+;; and its companion ASDF:FEATURE pseudo-dependency.
+(defvar *if-component-dep-fails-component* nil)
+(defun resolve-if-component-dep-fails (if-component-dep-fails component)
+  (asdf-message "The system definition for ~S uses deprecated ~
+                 ASDF option :IF-COMPONENT-DEP-DAILS. ~
+                 Starting with ASDF 2.27, please use :IF-FEATURE instead"
+                (coerce-name (component-system component)))
+  ;; This only supports the pattern of use of the "feature" seen in the wild
+  (check-type component parent-component)
+  (check-type if-component-dep-fails (member :fail :ignore :try-next))
+  (unless (eq if-component-dep-fails :fail)
+    (loop :with o = (make-instance 'compile-op)
+      :for c :in (component-children component) :do
+        (loop :for (feature? feature) :in (component-depends-on o c)
+              :when (eq feature? 'feature) :do
+                (setf (component-if-feature c) feature)))))
+
 (defun* parse-component-form (parent options)
   (destructuring-bind
         (type name &rest rest &key
@@ -2880,7 +2903,7 @@ Returns the new tree (which probably shares structure with the old one)"
               components pathname
               perform explain output-files operation-done-p
               weakly-depends-on depends-on serial in-order-to
-              do-first
+              do-first if-component-dep-fails
               (version nil versionp)
               ;; list ends
               &allow-other-keys) options
@@ -2896,12 +2919,12 @@ Returns the new tree (which probably shares structure with the old one)"
       (unless (parse-version version nil)
         (warn (compatfmt "~@<Invalid version ~S for component ~S~@[ of ~S~]~@:>")
               version name parent)))
-    (when do-first (error "do-first is not supported anymore by ASDF"))
+    (when do-first (error "DO-FIRST is not supported anymore since ASDF 2.27"))
     (let* ((args `(:name ,(coerce-name name)
                    :pathname ,pathname
                    ,@(when parent `(:parent ,parent))
                    ,@(remove-keys
-                      '(components pathname
+                      '(components pathname if-component-dep-fails
                         perform explain output-files operation-done-p
                         weakly-depends-on depends-on serial in-order-to)
                       rest)))
@@ -2927,6 +2950,7 @@ Returns the new tree (which probably shares structure with the old one)"
       (setf (component-sibling-dependencies ret) depends-on) ;; Used by POIU. ASDF3: rename to component-depends-on
       (setf (component-in-order-to ret) in-order-to)
       (%refresh-component-inline-methods ret rest)
+      (when if-component-dep-fails (resolve-if-component-dep-fails if-component-dep-fails ret))
       ret)))
 
 (defun* reset-system (system &rest keys &key &allow-other-keys)
diff --git a/doc/asdf.texinfo b/doc/asdf.texinfo
index 581a628da7e5a00f412a3810225e30cfc53edea1..ee7cf85e87c118e75eb094b69302a377d024b94c 100644
--- a/doc/asdf.texinfo
+++ b/doc/asdf.texinfo
@@ -1028,12 +1028,22 @@ system definition.
 @subsection Weakly depends on 
 @cindex :weakly-depends-on
 
-The @code{:weakly-depends-on} option to @code{defsystem} allows the
-programmer to specify another ASDF-defined system or set of systems that
-ASDF should @emph{try} to load, but need not load in order to be
-successful.  Typically this is used if there are a number of systems
-that, if present, could provide additional functionality, but which are
-not necessary for basic function.
+We do @emph{NOT} recommend you use this feature.
+If you are tempted to write a system @var{foo}
+that weakly-depends-on a system @var{bar},
+we recommend that you should instead
+write system @var{foo} in a parametric way,
+and offer some special variable and/or some hook to specialize its behavior;
+then you should write a system @var{foo+bar}
+that does the hooking of things together.
+
+The (deprecated) @code{:weakly-depends-on} option to @code{defsystem}
+allows the programmer to specify another ASDF-defined system or set of systems
+that ASDF should @emph{try} to load,
+but need not load in order to be successful.
+Typically this is used if there are a number of systems
+that, if present, could provide additional functionality,
+but which are not necessary for basic function.
 
 Currently, although it is specified to be an option only to @code{defsystem},
 this option is accepted at any component, but it probably