anchor.diff:  Variants and configurations are sometimes used interchangeably in the documentation, DSL or API for historical reasons.
   
   All components provide _variants_ and those variants may be backed by a consumable configuration.
  -Not all configurations are variants. 
  -====
  +Not all configurations are variants because they may be used for declaring or resolving dependencies.
  +====
  +
  +[[sec:abm_configuration_attributes]]
  +== Variant attributes
  +
  +<<variant_attributes.adoc#variant_attributes,Attributes>> are type-safe key-value pairs that are defined by the consumer (for a resolvable configuration) and the producer (for each variant).
  +
  +The consumer can define any number of attributes.
  +Each attribute helps narrow the possible variants that can be selected.
  +Attribute values do not need to be exact matches. 
  +
  +The variant can also define any number of attributes.
  +The attributes should describe how the variant is intended to be used.
  +For example, Gradle uses an attribute named `org.gradle.usage` to describe with how a component is used by the consumer (for compilation, for runtime execution, etc). 
  +It is not unusual for a variant to have more attributes than the consumer needs to provide to select it.
   
   [[sec:variant-aware-matching]]
  -== Variant aware matching
  +== Variant attribute matching
   
   [NOTE]
   .About producer variants
   ====
   The variant _name_ is mostly for debugging purposes and error messages.
   The name does not participate variant matching--only its attributes do.
  +====
   
   There are no restrictions on the number of variants a component can define.
  -Usually, a component would have at least an implementation variant, but it could also expose test fixtures, documentation or source code.
  -A component may also expose _different variants_ for different consumers for the same usage. For example, when compiling against a component, it could have different headers for Linux vs Windows vs macOS.
  +Usually, a component has at least an implementation variant, but it could also expose test fixtures, documentation or source code.
  +A component may also expose _different variants_ for different consumers for the same usage. For example, when compiling, a component could have different headers for Linux vs Windows vs macOS.
  +
  +Gradle performs _variant aware selection_ by matching the attributes requested by the consumer against attributes defined by the producer.
  +
  +[NOTE]
  +====
  +There are two exceptions to this rule that bypass variant aware resolution:
  +- when a producer has no variants, a default artifact is chosen.
  +- when a consumer _explicitly selects a configuration by name_, the artifacts of the configuration are chosen.
   ====
   
   == A simple example
  
positive.code: Let's consider an example where a consumer is trying to use a library for compilation. 
  
  First, the consumer needs to explain how it's going to use the result of dependency resolution. This is done by setting _attributes_ on the resolvable configuration of the consumer.
  
  An attribute consists of a strongly-typed name-value pair. 
  The consumer can define any arbitrary number of attributes.
  Each attribute helps narrow the possible variants that can be selected.
  For example, Gradle uses an attribute named `org.gradle.usage` to deal with how a component is used by the consumer (for compilation, for runtime execution, etc).
  
  The consumer wants to resolve a variant that matches:
  - `org.gradle.usage=JAVA_API`
  
negative.code: - `org.gradle.jvm.version` that describes the _minimal version_ of Java this variant targets
  - `org.gradle.jvm.environment` that describes the type of JVM this variant targets
  
  Let's consider an example where the consumer wants to run tests with a library on Java 8 and the producer supports two different Java versions (Java 8 and Java 11).
  
  First, the consumer needs to explain which version of the Java it needs.
  
  The consumer wants to resolve a variant that:
  - can be used at runtime (has `org.gradle.usage=JAVA_RUNTIME`)
  - can be run on _at least_ Java 8 (`org.gradle.jvm.version=8`)
  
  Second, the producer needs to expose the different variants of the component.
  
  Like in the simple example, there is both a API (compilation) and runtime variant. These exist for both the Java 8 and Java 11 version of the component.
  - its API for Java 8 consumers (named `apiJava8Elements`) with attribute `org.gradle.usage=JAVA_API` and `org.gradle.jvm.version=8`
  - its runtime for Java 8 consumers (named `runtime8Elements`) with attribute `org.gradle.usage=JAVA_RUNTIME` and `org.gradle.jvm.version=8`
  - its API for Java 11 consumers (named `apiJava11Elements`) with attribute `org.gradle.usage=JAVA_API` and `org.gradle.jvm.version=11`
  - its runtime for Java 11 consumers (named `runtime11Elements`) with attribute `org.gradle.usage=JAVA_RUNTIME` and `org.gradle.jvm.version=11`
  
  Finally, Gradle selects the best matching variant by looking at all of the attributes:
  - the consumer wants a variant with compatible attributes to `org.gradle.usage=JAVA_RUNTIME` and `org.gradle.jvm.version=8`
  - the variants `runtime8Elements` and `runtime11Elements` have `org.gradle.usage=JAVA_RUNTIME`
  - the variants `apiJava8Elements` and `apiJava11Elements` are incompatible
  - the variant `runtime8Elements` is compatible because it can run on Java 8
  - the variant `runtime11Elements` is incompatible because it cannot run on Java 8
  
  Gradle provides the artifacts and dependencies from the `runtime8Elements` variant to the consumer.
  
  [NOTE]
  .Compatibility of variants
  ====
  What if the consumer sets `org.gradle.jvm.version` to 7?
  
  Dependency resolution would _fail_ with an error message explaining that there's no suitable variant.
  Gradle recognizes that the consumer wants a Java 7 compatible library and the _minimal_ version of Java available on the producer is 8.
  
  If the consumer requested `org.gradle.jvm.version=15`, then Gradle knows either the Java 8 or Java 11 variants could work. Gradle select the highest compatible Java version (11).
  ====
  
  [[sec:variant-select-errors]]
  == Variant selection errors
  
  When selecting the most compatible variant of a component, resolution may fail:
  * when more than one variant from the producer matches the consumer attributes (ambiguity error)
  * when no variants from the producer match the consumer attributes (incompatibility error)
  
  [[sub:variant-ambiguity]]
  === Dealing with ambiguity errors
  
  An ambiguous variant selection looks like the following:
  
  [listing]
  ----
  