package org.gradle.api.internal.artifacts.ivyservice;

import org.apache.ivy.core.cache.CacheMetadataOptions;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.plugins.resolver.ChainResolver;
import org.apache.ivy.plugins.resolver.DependencyResolver;

import java.text.ParseException;
import java.util.List;

public class CacheFirstChainResolver extends ChainResolver {

    public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
            throws ParseException {

        // First attempt to locate the module in a resolver cache
        for (DependencyResolver resolver : getResolvers()) {
            ResolvedModuleRevision cachedModule = findModuleInCache(resolver, dd, data);
            if (cachedModule != null) {
                return cachedModule;
            }
        }

        // Otherwise delegate to the regular chain (each resolver will re-check cache)
        return super.getDependency(dd, data);
    }

    private ResolvedModuleRevision findModuleInCache(DependencyResolver resolver, DependencyDescriptor dd, ResolveData resolveData) {
        // TODO construct cache options relevant for resolver and resolveData (use details from AbstractResolver if appropriate)
        return resolver.getRepositoryCacheManager().findModuleInCache(dd, dd.getDependencyRevisionId(), new CacheMetadataOptions(), resolver.getName());
    }

    @Override
    public List<DependencyResolver> getResolvers() {
        return super.getResolvers();
    }
}

@@ -273,24 +273,81 @@
 leRevision;%0A
+import org.apache.ivy.plugins.resolver.AbstractResolver;%0A
 import org.a
@@ -447,16 +447,88 @@
 solver;%0A
+import org.gradle.api.GradleException;%0A%0Aimport java.lang.reflect.Method;
 %0Aimport 
@@ -1371,128 +1371,91 @@
     
-// TODO construct
+CacheMetadataOptions
  cache
- o
+O
 ptions 
-relevant for resolver and resolveData (use details from AbstractResolver if appropriate)
+= getCacheMetadataOptions(resolver, resolveData);
 %0A   
@@ -1555,16 +1555,659 @@
 onId(), 
+cacheOptions, resolver.getName());%0A    %7D%0A    %0A    private CacheMetadataOptions getCacheMetadataOptions(DependencyResolver resolver, ResolveData resolveData) %7B%0A        if (resolver instanceof AbstractResolver) %7B%0A            try %7B%0A                Method method = AbstractResolver.class.getDeclaredMethod(%22getCacheOptions%22, ResolveData.class);%0A                method.setAccessible(true);%0A                return (CacheMetadataOptions) method.invoke(resolver, resolveData);%0A            %7D catch (Exception e) %7B%0A                throw new GradleException(%22Could not get cache options from AbstractResolver%22, e);%0A            %7D%0A        %7D%0A        return 
 new Cach
@@ -2227,29 +2227,8 @@
 ons(
-), resolver.getName()
 );%0A 

Use appropriate cache options when asking resolver for cached meta-data