anchor.diff:  <script src="/[contextPath]/assets/js/application.js"></script>
   ----
   
  -==== 4.2.2. `classpath` locator
  -
  -<h3 class="section-title" id="clu">Usage</h3>
  -<p>
  -   The <i>classpath locator</i> should be used whenever you need to load an asset stored in the classpath.
  -</p>
  -<p>
  -   <table class="table table-striped table-hover">
  -      <tbody>
  -         <tr>
  -            <td>Location key</td>
  -            <td><code>classpath</code></td>
  -         </tr>
  -         <tr>
  -            <td>Corresponding value</td>
  -            <td>Absolute name of the asset (no leading "/", as it internally uses <code>ClassLoader.getResourceAsStream()</code>)</td>
  -         </tr>
  -         <tr>
  -            <td>Caching forced</td>
  -            <td>yes</td>
  -         </tr>
  -         <tr>
  -            <td>Class(es)</td>
  -            <td>{% javadoc ddl dandelion-core ClasspathLocator %}</td>
  -         </tr>
  -      </tbody>
  -   </table>
  -</p>   
  -
  -<h3 class="section-title" id="cle">Example</h3>
  -<p>
  -   Assuming the following project structure:
  -<pre class="prettyprint">
  +==== 5.2.2. `classpath` locator
  +
  +The `classpath` should be used whenever you need to load an asset stored in the classpath.
  +
  +|===
  +| *Location key* | `classpath`
  +
  +| *Corresponding value* | Absolute name of the asset (no leading "/", as it internally uses `ClassLoader.getResourceAsStream()`)
  +
  +| *Caching forced* | Yes
  +|===
  +
  +[discrete]
  +==== Example
  +
  +Assuming the following project structure:
  +
  +.Example with a Maven project
  +[source, xml]
  +----
   your-project
   |__ src
      |__ main
         |__ resources
            |__ js
               |__ application.js
  -</pre>   
  -</p>
  -<p>
  +----
  +
   The asset declaration should look like:
  -<pre class="prettyprint">
  -{
  -   "bundle" : "my-bundle",
  -   "assets": [{
  -      "name": "my-application",
  -      "version": "1.0.0",
  -      "type": "js",
  -      "locations": {
  -          "classpath": "js/application.js"
  -      }
  -   }]
  -}
  -</pre>
  -</p>
  -<p>
  -   Client-side, Dandelion will generate the following link:
  -<pre class="prettyprint">
  -&lt;script src="/[contextPath]/dandelion-assets/[cacheKey]/application.js">&lt;/script>
  -</pre>
  -</p>
  -
  -==== 4.2.3. `cdn` locator
  -
  -<h3 class="section-title" id="cdnlu">Usage</h3>
  -<p>
  -   The <i>CDN locator</i> should be used whenever you need to load an asset hosted by a
  -   <a href="http://en.wikipedia.org/wiki/Content_delivery_network">Content Delivery Network</a>.
  -</p>
  -<p>
  -   <table class="table table-striped table-hover">
  -      <tbody>
  -         <tr>
  -            <td>Location key</td>
  -            <td><code>cdn</code></td>
  -         </tr>
  -         <tr>
  -            <td>Corresponding value</td>
  -            <td>URL of the asset (protocal-relative URLs such as <i>//domain/foo.js</i> are supported)</td>
  -         </tr>
  -         <tr>
  -            <td>Caching forced</td>
  -            <td>no</td>
  -         </tr>
  -         <tr>
  -            <td>Class(es)</td>
  -            <td>{% javadoc ddl dandelion-core CdnLocator %}</td>
  -         </tr>
  -      </tbody>
  -   </table>
  -</p>
  -
  -<h3 class="section-title" id="cdnle">Example</h3>
  -<p>
  -<pre class="prettyprint">
  -{
  -   "bundle" : "jquery",
  -   "assets": [{
  -      "name": "jquery",
  -      "version": "1.11.0",
  -      "type": "js",
  -      "locations": {
  -         "cdn": "//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.js"
  -      }
  -   }]
  -}
  -</pre>
  -</p>
  -<p>
  -   Client-side, Dandelion will generate the following link:
  -<pre class="prettyprint">
  -&lt;script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.js">&lt;/script>
  -</pre>
  -</p>
  -
  -==== 4.2.4. `jar` locator
  -
  -<h3 class="section-title" id="jlu">Usage</h3>
  -<p>
  -   The <i>JAR locator</i> should be used whenever you need to load an asset stored inside a JAR,
  -   under the
  -   <code>META-INF/resources</code>
  -   folder.
  -</p>
  -<p>
  -   <table class="table table-striped table-hover">
  -      <tbody>
  -         <tr>
  -            <td>Location key</td>
  -            <td><code>jar</code></td>
  -         </tr>
  -         <tr>
  -            <td>Corresponding value</td>
  -            <td>Relative path to the <code>META-INF/resources</code> folder.</td>
  -         </tr>
  -         <tr>
  -            <td>Caching forced</td>
  -            <td>
  -               <p>No if the Servlet 3.x API is being used, yes otherwise.
  -            </td>
  -         </tr>
  -         <tr>
  -            <td>Class(es)</td>
  -            <td>{% javadoc ddl dandelion-core JarLocator %}, {% javadoc ddl dandelion-core JarServlet2Locator %}</td>
  -         </tr>
  -      </tbody>
  -   </table>
  -</p>
  -
  -<h3 class="section-title" id="jls2s3">Servlet 2.x vs Servlet 3.x</h3>
  -<p>
  -   Dandelion automatically detects whether the running server is using the Servlet 3.x API (<a
  -      href="https://jcp.org/en/jsr/detail?id=315">JSR 315</a>) or lower.
  -</p>
  -<p>
  -   If so, it takes profit of the feature that consists of serving from the application web context
  -   root all resources placed under the
  -   <code>META-INF/resources</code>
  -   directory of any JAR placed in
  -   <code>WEB-INF/lib</code>
  -   . In such a case, the asset is not cached but directly served from the JAR instead.
  -</p>
  -<p>
  -   On the contrary, if the Servlet 2.x API is being used, Dandelion will apply the strategy
  -   <a href="/dandelion/features/asset-locators/introducing-asset-locators.html#ac">described in
  -      the introduction</a>.
  -</p>
  -
  -<h3 class="section-title" id="jle">Example</h3>
  -<p>
  -   <a href="/datatables">Dandelion-Datatables</a> internally uses this locator to serve almost all
  -   DataTables-related assets.
  -</p>
  -<p>
  -   For example, the <i>datatables-core</i> project contains the following tree structure:
  -<pre class="prettyprint">
  +
  +.dandelion/bundle.json
  +[source, json]
  +----
  +{
  +  "assets": [
  +    {
  +      "locations": {
  +        "classpath": "js/application.js"
  +      }
  +    }
  +  ]
  +}
  +----
  +
  +Client-side, Dandelion will generate the following link:
  +
  +[source, html]
  +----
  +<script src="/[contextPath]/dandelion-assets/[cacheKey]/application.js"></script>
  +----
  +
  +==== 5.2.3. `remote` locator
  +
  +The `remote` locator should be used whenever you need to load an asset hosted externally, e.g. on a http://en.wikipedia.org/wiki/Content_delivery_network[Content Delivery Network].
  +
  +|===
  +| *Location key* | `remote`
  +
  +| *Corresponding value* | URL of the asset (protocal-relative URLs such as _//domain/foo.js_ are supported)
  +
  +| *Caching forced* | No
  +|===
  +
  +[discrete]
  +==== Example
  +
  +Assuming the following asset declaration:
  +
  +.dandelion/bundle.json
  +[source, json]
  +----
  +{
  +  "assets": [
  +    {
  +      "locations": {
  +        "remote": "//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.js"
  +      }
  +    }
  +  ]
  +}
  +----
  +
  +Client-side, Dandelion will generate the following link:
  +
  +[source, html]
  +----
  +<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.11.0/jquery.js"></script>
  +----
  +
  +==== 5.2.4. `jar` locator
  +
  +The `jar` locator should be used whenever you need to load an asset stored inside a JAR, under the `META-INF/resources` folder. 
  +
  +|===
  +| *Location key* | `jar`
  +
  +| *Corresponding value* | Relative path to the `META-INF/resources` folder
  +
  +| *Caching forced* | No. Dandelion takes profit of the Servlet 3.x feature that consists of serving from the application web context root all assets placed under the `META-INF/resources` directory of any JAR placed in `WEB-INF/lib`. In such a case, the asset is not cached but directly served from the JAR instead.
  +|===
  +
  +[discrete]
  +==== Example
  +
  +Dandelion-Datatables internally uses this locator to serve almost all DataTables-related assets.
  +
  +For example, the _datatables-core_ project contains the following tree structure:
  +
  +.datatables-core project
  +[source, xml]
  +----
   datatables-core
   |__ src
      |__ main
  
positive.code:                   |__ datatables
                       |__ ajax
                          |__ reload.js
  </pre>   
  </p>
  <p>
     According to the above structure, the corresponding bundle should look like:
  <pre class="prettyprint">
  {
     "bundle" : "ddl-dt-ajax-reload",
     "dependencies": [ "datatables" ],
     "assets": [{
        "name": "reload",
        "version": "1.0.0",
        "type": "js",
        "locations": {
           "jar": "dandelion/datatables/ajax/reload.js"
        }
     }]
  }
  </pre>
  </p>
  <p>
     Now client-side, if the application is running inside a Servlet 3.x-compatible container, the link will look like:
  <pre class="prettyprint">
  &lt;script src="/[contextPath]/dandelion/datatables/ajax/reload.js">&lt;/script>
  </pre>
  </p>
  <p>
     Whereas with a Servlet 2.x-compatible container, the link will look like:
  <pre class="prettyprint">
  &lt;script src="/[contextPath]/dandelion-assets/[cacheKey]/reload.js">&lt;/script>
  </pre>
  </p>
  
  ==== 4.2.5. `webjar` locator
  
  <h3 class="section-title" id="wjli">Installation</h3>
  <p>
     This locator is bundled in the <i>dandelion-webjars</i> extra since it brings a new dependency to the
     <a href="https://github.com/webjars/webjars-locator">webjars-locator</a> project. This project is internally used
     by the <i>webjar locator</i> to locate assets inside <a href="http://www.webjars.org/">WebJars</a>.
  </p>
  <p>
     {% assign artifact = 'dandelion-webjars' %} 
     {% include build-tools.html %}
  </p>
  
  <h3 class="section-title" id="wjlu">Usage</h3>
  <p>
     The <i>webjar locator</i> should be used whenever you need to load an asset stored inside a
     <a href="http://www.webjars.org/">WebJar</a>.
  </p>
  <p>
     <table class="table table-striped table-hover">
        <tbody>
           <tr>
              <td>Location key</td>
              <td><code>webjars</code></td>
           </tr>
           <tr>
              <td>Corresponding value</td>
              <td>Name of the asset (path excluded but extension included)</td>
           </tr>
           <tr>
              <td>Caching forced</td>
              <td>
                 <p>No if the Servlet 3.x API is being used, yes otherwise.
              </td>
           </tr>
           <tr>
              <td>Class(es)</td>
              <td>{% javadoc ddl dandelion-extras/dandelion-webjars WebjarLocator %}, {% javadoc ddl dandelion-extras/dandelion-webjars WebjarServlet2Locator %}</td>
           </tr>
        </tbody>
     </table>
  </p>   
  
  <h3 class="section-title" id="jls2s3">Servlet 2.x vs Servlet 3.x</h3>
  <p>
     Dandelion automatically detects whether the running server is using the Servlet 3.x API (<a
        href="https://jcp.org/en/jsr/detail?id=315">JSR 315</a>) or lower.
  </p>
  <p>
     If so, it takes profit of the feature that consists of serving from the application web context
     root all resources placed under the
     <code>META-INF/resources</code>
     directory of any JAR placed in
     <code>WEB-INF/lib</code>
     . In such a case, the asset is not cached but directly served from the JAR instead.
  </p>
  <p>
     On the contrary, if the Servlet 2.x API is being used, Dandelion will apply the strategy
     <a href="/dandelion/features/asset-locators/introducing-asset-locators.html#ac">described in
        the introduction</a>.
  </p>
  
  <h3 class="section-title" id="wjle">Example</h3>
  <p>
     Assuming that the <strong>bootstrap-2.3.0.jar</strong> is present in your classpath, the bundle
     definition should look like:
  <pre class="prettyprint">
  {
     "bundle" : "my-bundle",
     "assets": [{
        "name": "bootstrap",
        "version": "2.3.0",
        "type": "css",
        "locations": {
           "webjars": "bootstrap.css"
        }
     }]
  }
  </pre>
  </p>
  <p>
     Now client-side, if the application is running inside a Servlet 3.x-compatible container, the link will look like:
  <pre class="prettyprint">
  &lt;link rel="stylesheet" href="/[contextPath]/webjars/bootstrap/2.3.0/css/bootstrap.css" />
  </pre>
  </p>
  <p>
     Whereas with a Servlet 2.x-compatible container, the link will look like:
  <pre class="prettyprint">
  &lt;link rel="stylesheet" href="/[contextPath]/dandelion-assets/[cacheKey]/bootstrap.css"/>
  </pre>
  </p>
  
  ==== 4.2.6. `delegate` locator
  
  <h3 class="section-title" id="dlu">Usage</h3>
  <p>
     The <i>delegate locator</i> should be used for generated assets, i.e. assets whose content is
     dynamically generated.
  </p>
  <p>
     <table class="table table-striped table-hover">
        <tbody>
           <tr>
              <td>Location key</td>
              <td><code>delegate</code></td>
           </tr>
           <tr>
              <td>Corresponding value</td>
              <td>Name given to the asset</td>
           </tr>
           <tr>
              <td>Caching forced</td>
              <td>yes</td>
           </tr>
           <tr>
              <td>Class(es)</td>
              <td>{% javadoc ddl dandelion-core DelegateLocator %}</td>
           </tr>
        </tbody>
     </table>
  </p>
  
  <p>
     This locator is a bit particular since it reads the content of the asset from a special parameter
     stored inside the {% javadoc ddl dandelion-core AssetRequestContext %}.
  </p>
  <p>
     This parameter:
  </p>
  <ul>
     <li>must be stored under the key <code>DelegateLocator.DELEGATED_CONTENT_PARAM</code></li>
     <li>must be a class that implements {% javadoc ddl dandelion-core DelegatedContent %} and where the
        <code>getContent()</code> method must return the asset content to be injected</li>
  </ul>
  
  <h3 class="section-title" id="dle">Example</h3>
  <p>
     <a href="/datatables">Dandelion-Datatables</a> internally uses this locator to delegate the
     content generation to {% javadoc ddl dandelion-core JavascriptGenerator %}.
  </p>
  <p>
     Below is the main Dandelion-Datatables bundle:
  <pre class="prettyprint">
  {
     "bundle": "ddl-dt",
     "dependencies": [ "datatables" ], 
     "assets": [{
        "name": "dandelion-datatables", 
        "version": "0.10.0",
        "type": "js", 
        "locations": {
           "delegate": "dandelion-datatables.js"
        }
     }]
  }
  </pre>
  </p>
  <p>
     In the above bundle, an asset called <strong>dandelion-datatables</strong> has a delegated
     content. It basically means that a delegate object must return the content to be injected into
     this asset.
  </p>
  <p>
     This can be done thanks to the {% javadoc ddl dandelion-core AssetRequestContext %}:
  <pre class="prettyprint">
  AssetRequestContext
     .get(request)
     .addBundles("ddl-dt", "datatables")
     .addParameter("dandelion-datatables", DelegateLocator.DELEGATED_CONTENT_PARAM, DatatablesConfigurator.getJavascriptGenerator(), false);
  </pre>
     where:
  </p>
  <ul>
     <li>
        <code>get(request)</code> returns the asset context of the current request, which is the main
        user-side entry point for manipulating the assets graph associated to the current <code>HttpServletRequest</code>.
     </li>
     <li>
        <code>addBundles("ddl-dt", "datatables")</code> just adds the given bundle to the {% javadoc ddl dandelion-core AssetRequestContext %}.
     </li>
     <li>
        <p>
           <code>addParameter(...)</code>
           fills the request context with a particular entry: the Dandelion-Datatables Javascript
           generator, which generates the DataTables configuration.
        </p> 
        <p>
           Note that this entry uses
           <code>DelegateLocator.DELEGATED_CONTENT_PARAM</code>
           as key since the <i>delegate locator</i> will attempt to find an entry in the
           parameters map with this key.
        </p>
        <p>
           Also note that the given JavaScriptGenerator (lien javadoc) implements the {% javadoc ddl dandelion-core DelegatedContent %} interface.
  <pre class="prettyprint">
  public class SomeJavascriptGenerator extends DelegatedContent {
     ...
  }
  </pre>
        </p>
     </li>
  </ul>
  <p>
     Finally, client-side, Dandelion will generate the following link:
  <pre class="prettyprint">
  &lt;script src="/[contextPath]/dandelion-assets/[cacheKey]/dandelion-datatables-0.10.0.js">&lt;/script>
  </pre>
  </p>
  
  === 4.3. Plugging-in your own asset locator
  
  TIP: Pending
  
  <p>
     You may wish to use a custom <a
        href="introducing-asset-locator.html">locator</a>. Let's see here how to
     proceed.
  </p>
  
  <h3 class="section-title" id="slw">SPI for locators</h3>
  <p>
     In order to plug-in your own locator, just follow these steps:
  </p>
  <ol>
     <li>Create a class:
        <ul>
           <li>that extends AbstractAssetLocator (lien)</li>
           <li>that implement either the {% javadoc ddl dandelion-core Servlet2Compatible %} interface, or {% javadoc ddl dandelion-core Servlet3Compatible %}, or both</li>
        </ul> 
  <pre class="prettyprint">
  package com.foo.asset.locator.impl;
  
  public class MyLocator extends AbstractAssetLocator implements Servlet2Compatible {
  
     @Override
     public String getLocationKey() {
  
negative.code:    }
  
     @Override
     protected String doGetContent(String location, Map<String, Object> parameters, HttpServletRequest request) {
        return "the content of the asset";
     }
  }
  ----
  
  . In the `META-INF/services` folder, create a text file (UTF-8 encoded) using the following convention:
  
  +
  .Example with a Maven project
  [source, xml]
  ----
  project-root
  |__ src
     |__ main
        |__ resources
           |__ META-INF
              |__ services
                 |__ com.github.dandelion.core.asset.locator.spi.AssetLocator
  ----
   
  +
  Inside this file, just add the fully qualified name of your own implementation. For example:
  
   com.foo.asset.locator.impl.MyLocator
  
  And that's all! Dandelion, thanks to the SPI mechanism, will automatically pick up your implementation on the next restart.
  