anchor.diff:  
   The Gradle dependency cache consists of two storage types located under `GRADLE_USER_HOME/caches`:
   
  -* A file-based store of downloaded artifacts, including binaries like jars as well as raw downloaded meta-data like POM files and Ivy files. The storage path for a downloaded artifact includes the SHA1 checksum, meaning that 2 artifacts with the same name but different content can easily be cached.
  -* A binary store of resolved module meta-data, including the results of resolving dynamic versions, module descriptors, and artifacts.
  +* A file-based store of downloaded artifacts, including binaries like jars as well as raw downloaded meta-data like POM files and Ivy files.
  +The storage path for a downloaded artifact includes the SHA1 checksum, meaning that 2 artifacts with the same name but different content can easily be cached.
  +* A binary store of resolved module metadata, including the results of resolving dynamic versions, module descriptors, and artifacts.
   
   The Gradle cache does not allow the local cache to hide problems and create other mysterious and difficult to debug behavior.
   Gradle enables reliable and reproducible enterprise builds with a focus on bandwidth and storage efficiency.
  
positive.code: === Cache Locking
  
  The Gradle dependency cache uses file-based locking to ensure that it can safely be used by multiple Gradle processes concurrently.
  The lock is held whenever the binary meta-data store is being read or written, but is released for slow operations such as downloading remote artifacts.
  
  [[sub:cache_cleanup]]
  ==== Cache Cleanup
  
negative.code: This chapter covers the way dependency resolution works _inside_ Gradle.
  After covering how you can declare <<declaring_repositories.adoc#,repositories>> and <<declaring_dependencies.adoc#,dependencies>>, it makes sense to explain how these declarations come together during dependency resolution.
  
  Dependency resolution is a process that consists of two phases, which are repeated until the dependency graph is complete:
  
  * When a new dependency is added to the graph, perform conflict resolution to determine which version should be added to the graph.
  * When a specific dependency, that is a module with a version, is identified as part of the graph, retrieve its metadata so that its dependencies can be added in turn.
  
  The following section will describe what Gradle identifies as conflict and how it can resolve them automatically.
  After that, the retrieval of metadata will be covered, explaining how Gradle can <<#sec:how-gradle-downloads-deps,follow dependency links>>.
  
  [[sec:conflict-resolution]]
  == How Gradle handles conflicts?
  
  When doing dependency resolution, Gradle handles two types of conflicts:
  
  Version conflicts::
  That is when two or more dependencies require a given dependency but with different versions.
  
  Implementation conflicts::
  That is when the dependency graph contains module that provide the same implementation, or capability in Gradle terminology.
  
  The following sections will explain in detail how Gradle attempts to resolve these conflicts.
  
  The dependency resolution process is highly customizable to meet enterprise requirements.
  For more information, see the chapter on <<controlling_transitive_dependencies.adoc#,Controlling transitive dependencies>>.
  
  [[sec:version-conflict]]
  == Version conflict resolution
  
  A version conflict occurs when two components:
  
  * Depend on the same module, let's say `com.google.guava:guava`
  * But on different versions, let's say `20.0` and `25.1-android`
  ** Our project itself depends on `com.google.guava:guava:20.0`
  ** Our project also depends on `com.google.inject:guice:4.2.2` which itself depends on `com.google.guava:guava:25.1-android`
  
  [[sub:resolution-strategy]]
  === Resolution strategy
  
  Given the conflict above, there exist multiple ways to handle it, either by selecting a version or failing the resolution.
  Different tools that handle dependency management have different ways of handling these type of conflicts.
  
  [NOTE]
  ====
  https://maven.apache.org/[Apache Maven] uses a nearest first strategy.
  
  Maven will take the _shortest_ path to a dependency and use that version.
  In case there are multiple paths of the same length, the first one wins.
  
  This means that in the example above, the version of `guava` will be `20.0` because the direct dependency is _closer_ than the `guice` dependency.
  
  The main drawback of this method is that it is ordering dependent.
  Keeping order in a very large graph can be a challenge.
  For example, what if the new version of a dependency ends up having its own dependency declarations in a different order than the previous version?
  
  With Maven, this could have unwanted impact on resolved versions.
  ====
  
  [NOTE]
  ====
  https://ant.apache.org/ivy/[Apache Ivy] is a very flexible dependency management tooling.
  It offers the possibility to customize dependency resolution, including conflict resolution.
  
  This flexibility comes with the price of making it hard to reason about.
  ====
  
  Gradle will consider _all_ requested versions, wherever they appear in the dependency graph.
  Out of these versions, it will select the _highest_ one.
  
  As you have seen, Gradle supports a concept of <<rich_versions.adoc#,rich version declaration>>, so what is the highest version depends on the way versions were declared:
  
  * If no ranges are involved, then the highest version that is not rejected will be selected.
  ** If a strictly is lower than that version, selection will fail.
  * If ranges are involved:
  ** If there is a non range version that falls within the specified ranges or is higher than their upper bound, it will be selected.
  ** If there are only ranges, the highest _existing_ version of the range with the highest upper bound will be selected.
  ** If a strictly is lower than that version, selection will fail.
  
  Note that in the case where ranges come into play, Gradle requires metadata to determine which versions do exist for the considered range.
  This causes an intermediate lookup for metadata, as described in <<#sec:how-gradle-downloads-deps>>.
  
  [[sec:implementation-conflict]]
  == Implementation conflict resolution
  
  Gradle uses variants and capabilities to identify what a module _provides_.
  
  This is a unique feature that deserves its <<variant_model.adoc#,own chapter>> to understand what it means and enables.
  
  A conflict occurs the moment two modules either:
  
  * Attempt to select incompatible variants,
  * Declare the same capability
  
  Learn more about handling these type of conflicts in <<controlling_transitive_dependencies.adoc#selecting-between-candidates,Selecting between candidates>>.
  
  [[sec:how-gradle-downloads-deps]]
  == How Gradle retrieves dependency metadata?
  
  Gradle requires metadata about the modules included in your dependency graph.
  That information is required for two main points:
  
  * Determine the existing versions of a module when the declared version is dynamic.
  * Determine the dependencies of the module for a given version.
  
  === Discovering versions
  
  Faced with a dynamic version, Gradle needs to identify the concrete matching versions:
  
  * Each repository is inspected, Gradle does not stop on the first one returning some metadata.
  When multiple are defined, they are inspected _in the order they were added_.
  * For Maven repositories, Gradle will use the `maven-metadata.xml` which provides information about the available versions.
  * For Ivy repositories, Gradle will resort to directory listing.
  
  This process results in a list of candidate versions that are then matched to the dynamic version expressed.
  At this point, <<#sub:resolution-strategy,version conflict resolution>> is resumed.
  
  Note that Gradle caches the version information, more information can be found in the section <<declaring_dependency_versions.adoc#sec:controlling-dynamic-version-caching,Controlling dynamic version caching>>.
  
  === Obtaining module metadata
  
  Given a required dependency, with a version, Gradle attempts to resolve the dependency by searching for the module the dependency points at.
  
  * Each repository is inspected in order.
  ** Depending on the type of repository, Gradle looks for metadata files describing the module (`.module`, `.pom` or `ivy.xml` file) or directly for artifact files.
  ** Modules that have a module metadata file (`.module`, `.pom` or `ivy.xml` file) are preferred over modules that have an artifact file only.
  ** Once a repository returns a _metadata_ result, following repositories are ignored.
  * Metadata for the dependency is retrieved and parsed, if found
  ** If the module metadata is a POM file that has a parent POM declared, Gradle will recursively attempt to resolve each of the parent modules for the POM.
  * All of the artifacts for the module are then requested from the _same repository_ that was chosen in the process above.
  * All of that data, including the repository source and potential misses are then stored in the <<#sec:dependency_cache>>.
  
  [NOTE]
  ====
  The last point above is what can make the integration with <<declaring_repositories.adoc#sec:case-for-maven-local,Maven Local>> problematic.
  As it is a cache for Maven, it will sometimes miss some artifacts of a given module.
  If Gradle is sourcing such a module from Maven Local, it will consider the missing artifacts to be missing altogether.
  ====
  
  === Repository blacklisting
  
  When Gradle fails to retrieve information from a repository, it will blacklist it for the duration of the build and fail all dependency resolution.
  
  That last point is important for reproducibility.
  If the build was allowed to continue, ignoring the faulty repository, subsequent builds could have a different result once the repository is back online.
  
  [[sub:http-retries]]
  ==== HTTP Retries
  
  Gradle will make several attempts to connect to a given repository before blacklisting it.
  If connection fails, Gradle will retry on certain errors which have a chance of being transient, increasing the amount of time waiting between each retry.
  
  Blacklisting happens when the repository cannot be contacted, either because of a permanent error or because the maximum retries was reached.
  
  [[sec:dependency_cache]]
  == The Dependency Cache
  