/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 */
package org.apache.ivy.core.resolve;

import org.apache.ivy.Ivy;
import org.apache.ivy.TestHelper;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.cache.DefaultRepositoryCacheManager;
import org.apache.ivy.core.deliver.DeliverOptions;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExtendsDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ArtifactRevisionId;
import org.apache.ivy.core.module.id.ModuleId;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.ConfigurationResolveReport;
import org.apache.ivy.core.report.DownloadStatus;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.plugins.circular.CircularDependencyException;
import org.apache.ivy.plugins.circular.ErrorCircularDependencyStrategy;
import org.apache.ivy.plugins.circular.IgnoreCircularDependencyStrategy;
import org.apache.ivy.plugins.circular.WarnCircularDependencyStrategy;
import org.apache.ivy.plugins.conflict.StrictConflictException;
import org.apache.ivy.plugins.matcher.ExactPatternMatcher;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorParser;
import org.apache.ivy.plugins.repository.AbstractRepository;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.resolver.BasicResolver;
import org.apache.ivy.plugins.resolver.DependencyResolver;
import org.apache.ivy.plugins.resolver.DualResolver;
import org.apache.ivy.plugins.resolver.FileSystemResolver;
import org.apache.ivy.util.CacheCleaner;
import org.apache.ivy.util.FileUtil;
import org.apache.ivy.util.MockMessageLogger;
import org.apache.ivy.util.XMLHelper;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import static org.apache.ivy.util.StringUtils.joinArray;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 *
 */
public class ResolveTest {
    private Ivy ivy;

    private File cache;

    private File deliverDir;

    private File workDir;

    @Rule
    public ExpectedException expExc = ExpectedException.none();

    @Before
    public void setUp() throws Exception {
        cache = new File("build/cache");
        System.setProperty("ivy.cache.dir", cache.getAbsolutePath());
        createCache();

        deliverDir = new File("build/test/deliver");
        deliverDir.mkdirs();

        workDir = new File("build/test/work");
        workDir.mkdirs();

        ivy = Ivy.newInstance();
        ivy.configure(new File("test/repositories/ivysettings.xml"));
    }

    private void createCache() {
        cache.mkdirs();
    }

    @After
    public void tearDown() {
        CacheCleaner.deleteDir(cache);
        FileUtil.forceDelete(deliverDir);
        FileUtil.forceDelete(workDir);
    }

    @Test
    public void testResolveWithRetainingArtifactName() throws Exception {
        ((DefaultRepositoryCacheManager) ivy.getSettings().getDefaultRepositoryCacheManager())
                .setArtifactPattern(ivy.substitute("[module]/[originalname].[ext]"));
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod15.2/ivy-1.1.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);

        ArtifactDownloadReport[] dReports = report.getConfigurationReport("default")
                .getDownloadReports(ModuleRevisionId.newInstance("org15", "mod15.1", "1.1"));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct", 1, dReports.length);

        Artifact artifact = dReports[0].getArtifact();
        assertNotNull(artifact);

        String cachePath = getArchivePathInCache(artifact);
        assertTrue("artifact name has not been retained: " + cachePath,
            cachePath.endsWith("library.jar"));

        dReports = report.getConfigurationReport("default").getDownloadReports(
            ModuleRevisionId.newInstance("org14", "mod14.1", "1.1"));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct", 1, dReports.length);

        artifact = dReports[0].getArtifact();
        assertNotNull(artifact);

        cachePath = getArchivePathInCache(artifact);
        assertTrue("artifact name has not been retained: " + cachePath,
            cachePath.endsWith("mod14.1-1.1.jar"));
    }

    @Test
    public void testResolveWithRetainingArtifactNameAndExtraAttributes() throws Exception {
        ((DefaultRepositoryCacheManager) ivy.getSettings().getDefaultRepositoryCacheManager())
                .setArtifactPattern(ivy.substitute("[module]/[originalname].[ext]"));
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod15.4/ivy-1.1.xml"),
            getResolveOptions(new String[] {"default"}).setValidate(false));
        assertNotNull(report);

        Map<String, String> extra = new HashMap<>();
        extra.put("extra", "foo");
        ArtifactDownloadReport[] dReports = report.getConfigurationReport("default")
                .getDownloadReports(ModuleRevisionId.newInstance("org15", "mod15.3", "1.1", extra));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct", 1, dReports.length);

        Artifact artifact = dReports[0].getArtifact();
        assertNotNull(artifact);

        String cachePath = getArchivePathInCache(artifact);
        assertTrue("artifact name has not been retained: " + cachePath,
            cachePath.endsWith("library.jar"));

        dReports = report.getConfigurationReport("default").getDownloadReports(
            ModuleRevisionId.newInstance("org14", "mod14.1", "1.1"));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct", 1, dReports.length);

        artifact = dReports[0].getArtifact();
        assertNotNull(artifact);

        cachePath = getArchivePathInCache(artifact);
        assertTrue("artifact name has not been retained: " + cachePath,
            cachePath.endsWith("mod14.1-1.1.jar"));
    }

    @Test
    public void testArtifactOrigin() throws Exception {
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);

        ArtifactDownloadReport[] dReports = report.getConfigurationReport("default")
                .getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct", 1, dReports.length);

        Artifact artifact = dReports[0].getArtifact();
        assertNotNull(artifact);

        String expectedLocation = new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar")
                .getAbsolutePath();

        // verify the origin in the report
        ArtifactOrigin reportOrigin = dReports[0].getArtifactOrigin();
        assertNotNull(reportOrigin);
        assertTrue("isLocal for artifact not correct", reportOrigin.isLocal());
        assertEquals("location for artifact not correct", expectedLocation,
            reportOrigin.getLocation());

        // verify the saved origin on disk
        ArtifactOrigin ivyOrigin = getSavedArtifactOrigin(artifact);
        assertNotNull(ivyOrigin);
        assertTrue("isLocal for artifact not correct", ivyOrigin.isLocal());
        assertEquals("location for artifact not correct", expectedLocation, ivyOrigin.getLocation());

        // now resolve the same artifact again and verify the origin of the (not-downloaded)
        // artifact
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);

        dReports = report.getConfigurationReport("default").getDownloadReports(
            ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct", 1, dReports.length);
        assertEquals("download status not correct", DownloadStatus.NO,
            dReports[0].getDownloadStatus());
        reportOrigin = dReports[0].getArtifactOrigin();
        assertNotNull(reportOrigin);
        assertTrue("isLocal for artifact not correct", reportOrigin.isLocal());
        assertEquals("location for artifact not correct", expectedLocation,
            reportOrigin.getLocation());
    }

    @Test
    public void testUseOrigin() throws Exception {
        ((DefaultRepositoryCacheManager) ivy.getSettings().getDefaultRepositoryCacheManager())
                .setUseOrigin(true);

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);

        ArtifactDownloadReport[] dReports = report.getConfigurationReport("default")
                .getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
        assertNotNull(dReports);
        assertEquals("number of downloaded artifacts not correct.", 1, dReports.length);
        assertEquals(
            "download status not correct: should not download the artifact in useOrigin mode.",
            DownloadStatus.NO, dReports[0].getDownloadStatus());

        Artifact artifact = dReports[0].getArtifact();
        assertNotNull(artifact);

        String expectedLocation = new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar")
                .getAbsolutePath();

        ArtifactOrigin origin = getSavedArtifactOrigin(artifact);
        File artInCache = new File(cache, getArchivePathInCache(artifact, origin));
        assertFalse("should not download artifact in useOrigin mode.", artInCache.exists());
        assertEquals("location for artifact not correct.", expectedLocation,
            getArchiveFileInCache(artifact).getAbsolutePath());
    }

    @Test
    public void testResolveSimple() throws Exception {
        // mod1.1 depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org1", "mod1.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveBadStatus() throws Exception {
        // mod1.4 depends on modfailure, modfailure has a bad status
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.1.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertTrue(report.hasError());
    }

    @Test
    public void testResolveWithXmlEntities() {
        testResolveWithXmlEntities(null, 0);
        testResolveWithXmlEntities("prohibit", 0);
        testResolveWithXmlEntities("ignore", 0);
        testResolveWithXmlEntities("local-only", 2);
        testResolveWithXmlEntities("LOCAL_ONLY", 2);
        testResolveWithXmlEntities("all", 2);
    }

    private void testResolveWithXmlEntities(String externalResourcesSystemProperty,
            int expectedNumberOfDependencies) {
        Ivy ivy = new Ivy();
        Throwable th = null;
        Properties p = System.getProperties();
        try {
            System.setProperties(new Properties());
            System.setProperty(XMLHelper.ALLOW_DOCTYPE_PROCESSING, "true");
            if (externalResourcesSystemProperty != null) {
                System.setProperty(XMLHelper.EXTERNAL_RESOURCES, externalResourcesSystemProperty);
            }
            ivy.configure(new File("test/repositories/xml-entities/ivysettings.xml"));
            ResolveReport report = ivy.resolve(new File("test/repositories/xml-entities/ivy.xml"),
                getResolveOptions(new String[] {"*"}));
            assertNotNull(report);
            assertFalse(report.hasError());
            assertNotNull(report.getDependencies());
            assertEquals("number of dependencies while setting " + externalResourcesSystemProperty,
                expectedNumberOfDependencies, report.getDependencies().size());
        } catch (Throwable e) {
            th = e;
        } finally {
            System.setProperties(p);
        }
        assertNull(th);
    }

    @Test
    public void testResolveWithXmlEntitiesButNoSystemProperty() {
        Ivy ivy = new Ivy();
        Throwable th = null;
        try {
            ivy.configure(new File("test/repositories/xml-entities/ivysettings.xml"));
            ResolveReport report = ivy.resolve(new File("test/repositories/xml-entities/ivy.xml"),
                getResolveOptions(new String[] {"*"}));
            assertNotNull(report);
            assertFalse(report.hasError());
        } catch (Throwable e) {
            th = e;
        }
        assertNotNull(th);
    }

    @Test
    public void testResolveNoRevisionInPattern() throws Exception {
        // module1 depends on latest version of module2, for which there is no revision in the
        // pattern
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/norev/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/norev/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());
    }

    @Test
    public void testResolveLatestWithNoRevisionInPattern() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/norev/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/norev/ivy-latest.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());
    }

    @Test
    public void testResolveNoRevisionInDep() throws Exception {
        // mod1.4 depends on mod1.6, in which the ivy file has no revision
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertTrue(report.hasError());
    }

    /**
     * Test case for IVY-258.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-258">IVY-258</a>
     */
    @Test
    public void testResolveNoRevisionNowhere() throws Exception {
        // module1 depends on latest version of module2, which contains no revision in its ivy file,
        // nor in the pattern
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-258/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-258/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        ((BasicResolver) ivy.getSettings().getResolver("myresolver")).setCheckconsistency(false);
        report = ivy.resolve(new File("test/repositories/IVY-258/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());
    }

    /**
     * Test case for IVY-448.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-448">IVY-448</a>
     */
    @Test
    public void testResolveWithConflictManagerPerModule() throws Exception {
        // all modules from myorg
        // module1
        // -> module2-1.0
        // -> module3-2.0
        // module2
        // -> module3-1.0
        // settings use 'all' as default conflict manager, and latest-revision for modules from
        // myorg
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-448/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-448/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // rev 1.0 should have been evicted by latest-revision conflict manager
        assertTrue(getArchiveFileInCache(ivy, "myorg", "module3", "2.0", "module3", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache(ivy, "myorg", "module3", "1.0", "module3", "jar", "jar")
                .exists());
    }

    /**
     * Test case for IVY-465.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-465">IVY-465</a>
     */
    @Test
    public void testResolveWithConflictManagerDefinedInModule() throws Exception {
        // #M1;1.0 -> #M2;1.0
        // #M2;1.0 -> {org1#mod1.2;1.1 org1#mod1.2;2.0} with
        // <conflict org="org1" module="mod1.2" rev="1.1,2.0" />

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/IVY-465/M1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        ArtifactDownloadReport[] adrs = report.getConfigurationReport("default")
                .getDownloadedArtifactsReports();
        assertEquals(2, adrs.length);
        assertEquals("1.1", adrs[0].getArtifact().getId().getRevision());
        assertEquals("2.0", adrs[1].getArtifact().getId().getRevision());
    }

    /**
     * Test case for IVY-1404.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1404">IVY-1404</a>
     * @throws Exception if something goes wrong
     */
    @Test
    public void testResolveWithConflictManagerDefinedAtHigherLevel() throws Exception {
        // #M1;1.0 -> #M2;1.0
        // #M1;2.0 -> {#M2;1.0 #M3;1.0}
        // #M2;1.0 -> org1#mod1.2;1.1
        // #M3;1.0 -> org1#mod1.2;2.0
        // #M1;1.0 has conflict manager: <conflict org="org1" module="mod1.2" rev="1.1,2.0" />

        ResolveReport report = ivy.resolve(new File(
                        "test/repositories/1/IVY-1404/M1/ivys/ivy-1.0.xml"),
                getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        ArtifactDownloadReport[] adrs = report.getConfigurationReport("default")
                .getDownloadedArtifactsReports();
        assertEquals(2, adrs.length);
        assertEquals("1.1", adrs[0].getArtifact().getId().getRevision());
        assertEquals("2.0", adrs[1].getArtifact().getId().getRevision());
    }

    @Test
    public void testResolveRequiresDescriptor() throws Exception {
        // mod1.1 depends on mod1.2, mod1.2 has no ivy file
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings.xml"));
        ((FileSystemResolver) ivy.getSettings().getResolver("1"))
                .setDescriptor(FileSystemResolver.DESCRIPTOR_REQUIRED);
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertTrue(report.hasError());
    }

    @Test
    public void testResolveOtherConfiguration() throws Exception {
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-other.xml"),
            getResolveOptions(new String[] {"test"}));

        assertNotNull(report);
        assertFalse(report.hasError());

        assertEquals("Number of artifacts not correct", 1, report.getConfigurationReport("test")
                .getArtifactsNumber());
    }

    /**
     * Test case for IVY-198.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-198">IVY-198</a>
     * @throws Exception if something goes wrong
     */
    @Test
    public void testResolveWithSlashes() throws Exception {
        // module depends on mod1.2
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-198.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("myorg/mydep", "system/module", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("yourorg/yourdep", "yoursys/yourmod", "1.0")).exists());
        assertTrue(getArchiveFileInCache("yourorg/yourdep", "yoursys/yourmod", "1.0", "yourmod",
            "jar", "jar").exists());
    }

    @Test
    public void testFromCache() throws Exception {
        // mod1.1 depends on mod1.2

        // we first do a simple resolve so that module is in cache
        ivy.resolve(new File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        // we now use a badly configured ivy, so that it can't find module in repository
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/bugIVY-56/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);
        ivy.getSettings().validate();

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}));
        assertFalse(report.hasError());

        ModuleDescriptor md = report.getModuleDescriptor();

        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org1", "mod1.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(ivy, mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testFromCache2() throws Exception {
        // mod1.1 depends on mod1.2

        Ivy ivy = ivyTestCache();

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        File art = new File("build/testCache2/mod1.2-2.0.jar");
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), art, null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // now we clean the repository to simulate repo not available (network pb for instance)
        FileUtil.forceDelete(new File("build/testCache2"));

        // now do a new resolve: it should use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        ModuleDescriptor md = report.getModuleDescriptor();

        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org1", "mod1.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(ivy, mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testDynamicFromCache() throws Exception {
        // mod1.4;1.0.2 depends on mod1.2;[1.0,2.0[

        Ivy ivy = ivyTestCache();
        ivy.getSettings().setVariable("ivy.cache.ttl.default", "10s", true);

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.5.jar"), null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // now we clean the repository to simulate repo not available (network pb for instance)
        FileUtil.forceDelete(new File("build/testCache2"));

        // now do a new resolve: it should use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());
    }

    @Test
    public void testDynamicFromCacheWithMD() throws Exception {
        // same as above, but this time the dependency has a module descriptor
        // mod1.4;1.0.2 depends on mod1.2;[1.0,2.0[

        Ivy ivy = ivyTestCache();
        ivy.getSettings().setVariable("ivy.cache.ttl.default", "10s", true);

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        FileUtil.copy(ResolveTest.class.getResourceAsStream("ivy-mod1.2-1.5.xml"), new File(
                "build/testCache2/ivy-mod1.2-1.5.xml"), null);
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.5.jar"), null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // now we clean the repository to simulate repo not available (network pb for instance)
        FileUtil.forceDelete(new File("build/testCache2"));

        // now do a new resolve: it should use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());
    }

    @Test
    public void testDynamicFromCacheWithMDAfterOneTTLExpiration() throws Exception {
        // same as above, but this time we make a second resolve after ttl expiration before trying
        // to use the cached resolved information
        // mod1.4;1.0.2 depends on mod1.2;[1.0,2.0[

        Ivy ivy = ivyTestCache();
        ivy.getSettings().setVariable("ivy.cache.ttl.default", "500ms", true);

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        FileUtil.copy(ResolveTest.class.getResourceAsStream("ivy-mod1.2-1.5.xml"), new File(
                "build/testCache2/ivy-mod1.2-1.5.xml"), null);
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.5.jar"), null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // now we wait for ttl expiration
        Thread.sleep(700);

        // we resolve again, it should work fine
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // now we clean the repository to simulate repo not available (network pb for instance)
        FileUtil.forceDelete(new File("build/testCache2"));

        // now do a new resolve: it should use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());
    }

    @Test
    public void testDynamicFromCacheWithTTL0() throws Exception {
        // mod1.4;1.0.2 depends on mod1.2;[1.0,2.0[

        Ivy ivy = ivyTestCache();
        ivy.getSettings().setVariable("ivy.cache.ttl.default", "0ms", true);

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.5.jar"), null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // now we update the repository
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.6.jar"), null);

        // now do a new resolve: it should not use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.6")),
                report.getConfigurationReport("default").getModuleRevisionIds());
    }

    @Test
    public void testDynamicFromCacheWithTTL() throws Exception {
        // mod1.4;1.0.2 depends on mod1.2;[1.0,2.0[
        Ivy ivy = ivyTestCache();
        ivy.getSettings().setVariable("ivy.cache.ttl.default", "10s", true);
        ((DefaultRepositoryCacheManager) ivy.getSettings().getDefaultRepositoryCacheManager())
                .addTTL(ModuleRevisionId.newInstance("org1", "*", "*").getAttributes(),
                    ExactPatternMatcher.INSTANCE, 500);

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.5.jar"), null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // now we update the repository
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.6.jar"), null);

        // now do a new resolve: it should use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // wait for org1 TTL to expire
        Thread.sleep(700);

        // now do a new resolve: it should resolve the dynamic revision again
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.6")),
                report.getConfigurationReport("default").getModuleRevisionIds());
    }

    @Test
    public void testRefreshDynamicFromCache() throws Exception {
        // mod1.4;1.0.2 depends on mod1.2;[1.0,2.0[
        Ivy ivy = ivyTestCache();
        ivy.getSettings().setVariable("ivy.cache.ttl.default", "10s", true);

        // set up repository
        FileUtil.forceDelete(new File("build/testCache2"));
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.5.jar"), null);

        // we first do a simple resolve so that module is in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // now we update the repository
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), new File(
                "build/testCache2/mod1.2-1.6.jar"), null);

        // now do a new resolve: it should use cached data
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.5")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        // resolve again with refresh: it should find the new version
        report = ivy.resolve(new File("test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"*"}).setRefresh(true));
        assertFalse(report.hasError());

        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org1", "mod1.2", "1.6")),
                report.getConfigurationReport("default").getModuleRevisionIds());

        FileUtil.forceDelete(new File("build/testCache2"));
    }

    /**
     * Configures an Ivy instance using a resolver locating modules on file system, in a
     * build/testCache2 location which is created for the test and removed after, and can thus
     * easily simulate a repository availability problem
     *
     * @return the configured ivy instance
     */
    private Ivy ivyTestCache() {
        Ivy ivy = Ivy.newInstance();
        DualResolver resolver = new DualResolver();
        resolver.setName("dual");
        FileSystemResolver r = new FileSystemResolver();
        r.setName("1");
        r.addIvyPattern(ivy.getSettings().getBaseDir().getPath()
                + "/build/testCache2/ivy-[module]-[revision].xml");
        resolver.add(r);
        r = new FileSystemResolver();
        r.setName("2");
        r.addArtifactPattern(ivy.getSettings().getBaseDir().getPath()
                + "/build/testCache2/[artifact]-[revision].[ext]");
        resolver.add(r);
        ivy.getSettings().addResolver(resolver);
        ivy.getSettings().setDefaultResolver("dual");
        return ivy;
    }

    @Test
    public void testFromCacheOnly() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/bugIVY-56/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        // ResolveReport report = ivy.resolve(new
        // File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
        // getResolveOptions(new String[] {"*"}));
        // // should have an error, the conf is bad and the dependency should not be found
        // assertTrue(report.hasError());

        // put necessary stuff in cache, and it should now be ok
        File ivyfile = getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
        File art = getArchiveFileInCache(ivy, "org1", "mod1.2", "2.0", "mod1.2", "jar", "jar");
        FileUtil.copy(ResolveTest.class.getResource("ivy-mod1.2.xml"), ivyfile, null, null);
        FileUtil.copy(new File("test/repositories/1/org1/mod1.2/jars/mod1.2-2.0.jar"), art, null);

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}));
        assertFalse(report.hasError());
    }

    @Test
    public void testChangeCacheLayout() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings.xml"));
        DefaultRepositoryCacheManager cacheMgr = (DefaultRepositoryCacheManager) ivy.getSettings()
                .getDefaultRepositoryCacheManager();

        cacheMgr.setIvyPattern("[module]/ivy.xml");
        cacheMgr.setArtifactPattern("[artifact].[ext]");

        // mod1.1 depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org1", "mod1.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(ivy, mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ivy, ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(new File(cache, "mod1.2/ivy.xml").exists());
        assertTrue(getArchiveFileInCache(ivy, "org1", "mod1.2", "2.0", "mod1.2", "jar", "jar")
                .exists());
        assertTrue(new File(cache, "mod1.2.jar").exists());
    }

    @Test
    public void testChangeCacheLayout2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings.xml"));
        ivy.getSettings().setDefaultRepositoryCacheBasedir(
            new File(ivy.getSettings().getDefaultCache(), "repository").getAbsolutePath());
        ivy.getSettings().setDefaultResolutionCacheBasedir(
            new File(ivy.getSettings().getDefaultCache(), "workspace").getAbsolutePath());
        ivy.getSettings().validate();
        DefaultRepositoryCacheManager cacheMgr = (DefaultRepositoryCacheManager) ivy.getSettings()
                .getDefaultRepositoryCacheManager();

        cacheMgr.setIvyPattern("[module]/ivy.xml");
        cacheMgr.setArtifactPattern("[artifact].[ext]");

        // mod1.1 depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org1", "mod1.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(ivy, mrid).toString().contains("workspace"));
        assertTrue(getResolvedIvyFileInCache(ivy, mrid).exists());
        assertTrue(getConfigurationResolveReportInCache(ivy, report.getResolveId(), "default")
                .exists());

        // dependencies
        assertTrue(getIvyFileInCache(ivy, ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(new File(cache, "repository/mod1.2/ivy.xml").exists());
        assertTrue(getArchiveFileInCache(ivy, "org1", "mod1.2", "2.0", "mod1.2", "jar", "jar")
                .exists());
        assertTrue(new File(cache, "repository/mod1.2.jar").exists());
    }

    @Test
    public void testMultipleCache() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings-multicache.xml"));

        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        // dependencies
        DefaultArtifact depArtifact = TestHelper.newArtifact("org1", "mod1.1", "1.0", "mod1.1",
            "jar", "jar");
        ModuleRevisionId depMrid = ModuleRevisionId.newInstance("org1", "mod1.1", "1.0");
        DefaultRepositoryCacheManager cacheMgr1 = (DefaultRepositoryCacheManager) ivy.getSettings()
                .getDefaultRepositoryCacheManager();
        DefaultRepositoryCacheManager cacheMgr2 = (DefaultRepositoryCacheManager) ivy.getSettings()
                .getRepositoryCacheManager("cache2");

        // ivy file should be cached in default cache, and artifact in cache2
        assertTrue(cacheMgr1.getIvyFileInCache(depMrid).exists());
        assertFalse(cacheMgr1.getArchiveFileInCache(depArtifact).exists());
        assertEquals(new File(cache, "repo1/mod1.1/ivy-1.0.xml").getCanonicalFile(), cacheMgr1
                .getIvyFileInCache(depMrid).getCanonicalFile());

        assertFalse(cacheMgr2.getIvyFileInCache(depMrid).exists());
        assertTrue(cacheMgr2.getArchiveFileInCache(depArtifact).exists());
        assertEquals(new File(cache, "repo2/mod1.1-1.0/mod1.1.jar").getCanonicalFile(), cacheMgr2
                .getArchiveFileInCache(depArtifact).getCanonicalFile());
    }

    @Test
    public void testForceLocal() throws Exception {
        // mod2.1 depends on mod1.1 which depends on mod1.2
        // a local build for mod1.2 is available
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings-local.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org1", "mod1.2", "local-20080708091023")).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "local-20080708091023", "mod1.2", "jar",
            "jar").exists());

        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testForceLocal2() throws Exception {
        // mod2.3 -> mod2.1;[0.0,0.4] -> mod1.1 -> mod1.2
        // a local build for mod2.1 and mod1.2 is available
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings-local.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.8.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org2", "mod2.1", "0.3-local-20050213110000")).exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3-local-20050213110000", "mod2.1",
            "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.1", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org1", "mod1.2", "local-20080708091023")).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "local-20080708091023", "mod1.2", "jar",
            "jar").exists());

        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.4"))
                .exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testForceLocal3() throws Exception {
        // mod2.1 depends on mod1.1 which depends on mod1.2
        // a local build for mod1.2 is available
        // we do a first resolve without local build so that cache contains mod1.2;2.0 module
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings-local.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org1", "mod1.2", "local-20080708091023")).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "local-20080708091023", "mod1.2", "jar",
            "jar").exists());

        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
    }

    @Test
    public void testResolveExtends() throws Exception {
        // mod6.1 depends on mod1.2 2.0 in conf default, and conf extension extends default
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"extension"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies from default
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveExtended() throws Exception {
        // mod6.1 depends on mod1.2 2.0 in conf default, and conf extension extends default
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies from default
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveExtendedAndExtends() throws Exception {
        // mod6.1 depends on mod1.2 2.0 in conf default, and conf extension extends default
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"default", "extension"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(1, crr.getArtifactsNumber());
        crr = report.getConfigurationReport("extension");
        assertNotNull(crr);
        assertEquals(1, crr.getArtifactsNumber());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveMultipleExtends() throws Exception {
        // mod6.2 has two confs default and extension
        // mod6.2 depends on mod6.1 in conf (default->extension)
        // conf extension extends default
        // mod6.1 has two confs default and extension
        // mod6.1 depends on mod1.2 2.0 in conf (default->default)
        // conf extension extends default
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.2/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"default", "extension"}));
        assertNotNull(report);
        assertFalse(report.hasError());
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.2", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(2, crr.getArtifactsNumber());
        crr = report.getConfigurationReport("extension");
        assertNotNull(crr);
        assertEquals(2, crr.getArtifactsNumber());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org6", "mod6.1", "0.4"))
                .exists());
        assertTrue(getArchiveFileInCache("org6", "mod6.1", "0.4", "mod6.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-240.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-240">IVY-240</a>
     */
    @Test
    public void testResolveMultipleExtendsAndConfs() throws Exception {
        // mod6.3 1.1 has four confs libraries, run (extends libraries), compile (extends run) and
        // test (extends libraries)
        // mod6.3 depends on mod6.2 2.0 in conf (run->default)
        // mod6.3 depends on mod6.1 2.+ in conf (test->default)
        // mod6.2 2.0 depends on mod6.1 2.0 in conf (default->standalone)
        // mod6.1 2.0 has two confs default and standalone
        // mod6.1 2.0 depends on mod1.2 2.2 in conf (default->default)
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.1.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ConfigurationResolveReport crr = report.getConfigurationReport("libraries");
        assertEquals(0, crr.getArtifactsNumber());

        crr = report.getConfigurationReport("run");
        assertEquals(2, crr.getArtifactsNumber());
        assertContainsArtifact("org6", "mod6.2", "2.0", "mod6.2", "jar", "jar", crr);
        assertContainsArtifact("org6", "mod6.1", "2.0", "mod6.1", "jar", "jar", crr);

        crr = report.getConfigurationReport("compile");
        assertEquals(2, crr.getArtifactsNumber());
        assertContainsArtifact("org6", "mod6.2", "2.0", "mod6.2", "jar", "jar", crr);
        assertContainsArtifact("org6", "mod6.1", "2.0", "mod6.1", "jar", "jar", crr);

        crr = report.getConfigurationReport("test");
        assertEquals(2, crr.getArtifactsNumber());
        assertContainsArtifact("org6", "mod6.1", "2.0", "mod6.1", "jar", "jar", crr);
        assertContainsArtifact("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar", crr);
    }

    /**
     * Test case for IVY-188.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-188">IVY-188</a>
     */
    @Test
    public void testResolveMultipleConfsWithLatest() throws Exception {
        // mod6.2 has two confs compile and run
        // depends on mod6.1 in conf (compile->default)
        // depends on mod1.2 latest (which is 2.2) in conf (run->default)
        // mod6.1
        // depends on mod1.2 2.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.2/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"compile", "run"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        ConfigurationResolveReport crr = report.getConfigurationReport("compile");
        assertNotNull(crr);
        assertEquals(2, crr.getArtifactsNumber());
        crr = report.getConfigurationReport("run");
        assertNotNull(crr);
        assertEquals(1, crr.getArtifactsNumber());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-173.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-173">IVY-173</a>
     */
    @Test
    public void testResolveMultipleConfsWithConflicts() throws Exception {
        // mod6.2 has two confs compile and run
        // depends on mod1.2 2.1 in conf (compile->default)
        // depends on mod1.1 1.0 in conf (*->default)
        // depends on mod6.1 in conf (*->default)
        // mod6.1
        // depends on mod1.2 2.1
        // mod1.1
        // depends on mod1.2 2.0
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.2/ivys/ivy-0.5.xml"),
            getResolveOptions(new String[] {"compile", "run"}));
        assertNotNull(report);
        assertFalse(report.hasError());
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.2", "0.5");
        assertEquals(mrid, md.getModuleRevisionId());
        ConfigurationResolveReport crr = report.getConfigurationReport("compile");
        assertNotNull(crr);
        assertEquals(3, crr.getArtifactsNumber());
        crr = report.getConfigurationReport("run");
        assertNotNull(crr);
        assertEquals(3, crr.getArtifactsNumber());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org6", "mod6.1", "0.5"))
                .exists());
        assertTrue(getArchiveFileInCache("org6", "mod6.1", "0.5", "mod6.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveMultipleExtends2() throws Exception {
        // same as before, except that mod6.2 depends on mod1.2 2.1 extension->default
        // so mod1.2 2.0 should be evicted in conf extension
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org6/mod6.2/ivys/ivy-0.4.xml"),
            getResolveOptions(new String[] {"default", "extension"}));
        assertNotNull(report);
        assertFalse(report.hasError());
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.2", "0.4");
        assertEquals(mrid, md.getModuleRevisionId());
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(2, crr.getArtifactsNumber());
        IvyNode node = crr.getDependency(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
        assertNotNull(node);
        assertFalse(node.isEvicted("default"));
        crr = report.getConfigurationReport("extension");
        assertNotNull(crr);
        assertEquals(2, crr.getArtifactsNumber());
        node = crr.getDependency(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"));
        assertNotNull(node);
        assertTrue(node.isEvicted("extension"));
        node = crr.getDependency(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"));
        assertNotNull(node);
        assertFalse(node.isEvicted("extension"));

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org6", "mod6.1", "0.4"))
                .exists());
        assertTrue(getArchiveFileInCache("org6", "mod6.1", "0.4", "mod6.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-261.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-261">IVY-261</a>
     */
    @Test
    public void testResolveSeveralDefaultWithArtifacts() throws Exception {
        // mod1.6 depends on
        // mod1.4, which depends on mod1.3 and selects one of its artifacts
        // mod1.3 and selects two of its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.6/ivys/ivy-1.0.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-B", "jar", "jar")
                .exists());
    }

    /**
     * Test case for IVY-537.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-537">IVY-537</a>
     */
    @Test
    public void testResolveConflictsWithArtifacts() throws Exception {
        // #mod2.6;0.12 -> {#mod1.6;1.0.4 #mod2.5;0.6.2 }
        // #mod1.6;1.0.4 -> #mod1.3;3.0 artifacts A and B
        // #mod2.5;0.6.2 -> #mod1.3;3.1 artifact C
        // #mod1.3;3.1 has only A and C artifacts, not B.
        // Both A and C should be downloaded, and a message should tell that B was not available.
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.12.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.1", "mod1.3-A", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.1", "mod1.3-C", "jar", "jar")
                .exists());
    }

    /**
     * Test case for IVY-283.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-283">IVY-283</a>
     */
    @Test
    public void testResolveSeveralDefaultWithArtifactsAndConfs() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-283/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-283/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("build");
        assertNotNull(crr);
        assertEquals(3,
            crr.getDownloadReports(ModuleRevisionId.newInstance("medicel", "C", "1.0")).length);

        assertTrue(getArchiveFileInCache(ivy, "medicel", "C", "1.0", "lib_c_a", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "C", "1.0", "lib_c_b", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "C", "1.0", "lib_c_d", "jar", "jar")
                .exists());
    }

    /**
     * Second test case for IVY-283.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-283">IVY-283</a>
     */
    @Test
    public void testResolveSeveralDefaultWithArtifactsAndConfs2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-283/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-283/ivy-d.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("build");
        assertNotNull(crr);
        assertEquals(
            9,
            crr.getDownloadReports(ModuleRevisionId.newInstance("medicel", "module_a", "local")).length);

        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_a", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_b", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_c", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_d", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_e", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_f", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_g", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_h", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "medicel", "module_a", "local", "lib_a_i", "jar",
            "jar").exists());
    }

    @Test
    public void testResolveWithStartPublicConf() throws Exception {
        // mod2.2 depends on mod1.3 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.2/ivys/ivy-0.8.xml"),
            getResolveOptions(new String[] {"*(public)"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.2", "0.8");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.3", "3.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-B", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithPrivateConf() throws Exception {
        // mod2.2 depends on mod1.3 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.2/ivys/ivy-0.8.xml"),
            getResolveOptions(new String[] {"*(private)"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.2", "0.8");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.3", "3.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-B", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3", "jar", "jar").exists());
    }

    @Test
    public void testResolveDefaultWithArtifactsConf1() throws Exception {
        // mod2.2 depends on mod1.3 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.2/ivys/ivy-0.5.xml"),
            getResolveOptions(new String[] {"myconf1"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.2", "0.5");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.3", "3.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-B", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3", "jar", "jar").exists());
    }

    @Test
    public void testResolveDefaultWithArtifactsConf2() throws Exception {
        // mod2.2 depends on mod1.3 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.2/ivys/ivy-0.5.xml"),
            getResolveOptions(new String[] {"myconf2"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.2", "0.5");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.3", "3.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-B", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3", "jar", "jar").exists());
    }

    @Test
    public void testResolveDefaultWithArtifactsAndConfMapping() throws Exception {
        // mod2.2 depends on mod1.3 and specify its artifacts and a conf mapping
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.2/ivys/ivy-0.5.1.xml"),
            getResolveOptions(new String[] {"myconf1"}));
        assertNotNull(report);
        assertFalse(report.hasError());
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.2", "0.5.1");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.3", "3.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-A", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3-B", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.3", "3.0", "mod1.3", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithIncludeArtifactsConf1() throws Exception {
        // mod2.3 depends on mod2.1 and selects its artifacts in myconf1
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.4.xml"),
            getResolveOptions(new String[] {"myconf1"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.4");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithIncludeArtifactsConf2() throws Exception {
        // mod2.3 depends on mod2.1 and selects its artifacts in myconf1
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.4.xml"),
            getResolveOptions(new String[] {"myconf2"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.4");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithIncludeArtifactsWithoutConf() throws Exception {
        // mod2.3 depends on mod2.1 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.5.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.5");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-541.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-541">IVY-541</a>
     */
    @Test
    public void testResolveWithIncludeArtifactsTransitive() throws Exception {
        // mod2.6 depends on mod2.3 and mod2.1
        // mod2.3 depends on mod2.1 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.5.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithExcludesArtifacts() throws Exception {
        // mod2.3 depends on mod2.1 and selects its artifacts
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.6");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithExcludesArtifacts2() throws Exception {
        // mod2.3 depends on mod2.1 and badly excludes artifacts with incorrect matcher
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.6.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.6.2");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithExcludesArtifacts3() throws Exception {
        // mod2.3 depends on mod2.1 and excludes artifacts with exact matcher
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.6.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.6.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithExcludesArtifacts4() throws Exception {
        // mod2.3 depends on mod2.1 and excludes artifacts with regexp matcher
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.6.4.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.6.4");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithExcludesArtifacts5() throws Exception {
        // mod2.3 depends on mod2.1 and excludes artifacts with glob matcher
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.3/ivys/ivy-0.6.5.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.3", "0.6.5");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "mod2.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveDependencies() throws Exception {
        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.1", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveDependenciesWithOverride() throws Exception {
        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.1", "0.6");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-1131.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1131">IVY-1131</a>
     */
    @Test
    public void testResolveTransitiveDependenciesWithOverrideAndDynamicResolveMode()
            throws Exception {
        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"})
                    .setResolveMode(ResolveOptions.RESOLVEMODE_DYNAMIC));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.1", "0.6");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveDisabled() throws Exception {
        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}).setTransitive(false));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.1", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testDependenciesOrder() throws Exception {
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-225.xml"),
            getResolveOptions(new String[] {"default"}));

        List<ModuleRevisionId> revisions = new ArrayList<>(report
                .getConfigurationReport("default").getModuleRevisionIds());
        assertTrue("number of revisions is not correct", revisions.size() >= 3);

        int mod12Index = revisions.indexOf(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"));
        int mod32Index = revisions.indexOf(ModuleRevisionId.newInstance("org3", "mod3.2", "1.4"));
        int mod51Index = revisions.indexOf(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2"));

        // verify the order of the modules in the ivy file
        assertTrue("[ org1 | mod1.2 | 1.1 ] was not found", mod12Index > -1);
        assertTrue("[ org1 | mod1.2 | 1.1 ] must come before [ org3 | mod3.2 | 1.4 ]",
            mod12Index < mod32Index);
        assertTrue("[ org3 | mod3.2 | 1.4 ] must come before [ org5 | mod5.1 | 4.2 ]",
            mod32Index < mod51Index);
    }

    @Test
    public void testDisableTransitivityPerConfiguration() throws Exception {
        // mod2.1 (compile, runtime) depends on mod1.1 which depends on mod1.2
        // compile conf is not transitive

        // first we resolve compile conf only
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.1.xml"),
            getResolveOptions(new String[] {"compile"}));

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // then we resolve runtime conf
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.1.xml"),
            getResolveOptions(new String[] {"runtime"}));

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // same as before, but resolve both confs in one call
        ResolveReport r = ivy.resolve(
            new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.1.xml"),
            getResolveOptions(new String[] {"runtime", "compile"}));
        assertFalse(r.hasError());
        assertEquals(1, r.getConfigurationReport("compile").getArtifactsNumber());
        assertEquals(2, r.getConfigurationReport("runtime").getArtifactsNumber());
    }

    @Test
    public void testDisableTransitivityPerConfiguration2() throws Exception {
        // mod2.1 (compile, runtime) depends on mod1.1 which depends on mod1.2
        // compile conf is not transitive
        // compile extends runtime

        // first we resolve compile conf only
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.2.xml"),
            getResolveOptions(new String[] {"compile"}));

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // then we resolve runtime conf
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.2.xml"),
            getResolveOptions(new String[] {"runtime"}));

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // same as before, but resolve both confs in one call
        ResolveReport r = ivy.resolve(
            new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.2.xml"),
            getResolveOptions(new String[] {"runtime", "compile"}));
        assertFalse(r.hasError());
        assertEquals(1, r.getConfigurationReport("compile").getArtifactsNumber());
        assertEquals(2, r.getConfigurationReport("runtime").getArtifactsNumber());
    }

    @Test
    public void testDisableTransitivityPerConfiguration3() throws Exception {
        // mod2.1 (compile, runtime) depends on mod1.1 which depends on mod1.2
        // compile conf is not transitive
        // runtime extends compile

        // first we resolve compile conf only
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.3.xml"),
            getResolveOptions(new String[] {"compile"}));

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // then we resolve runtime conf
        ivy.resolve(new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.3.xml"),
            getResolveOptions(new String[] {"runtime"}));

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // same as before, but resolve both confs in one call
        ResolveReport r = ivy.resolve(
            new File("test/repositories/1/org2/mod2.1/ivys/ivy-0.3.3.xml"),
            getResolveOptions(new String[] {"runtime", "compile"}));
        assertFalse(r.hasError());
        assertEquals(1, r.getConfigurationReport("compile").getArtifactsNumber());
        assertEquals(2, r.getConfigurationReport("runtime").getArtifactsNumber());
    }

    @Test
    public void testDisableTransitivityPerConfiguration4() throws Exception {
        // mod2.2 (A,B,compile) depends on mod 2.1 (A->runtime;B->compile)
        // compile is not transitive and extends A and B
        //
        // mod2.1 (compile, runtime) depends on mod1.1 which depends on mod1.2
        // compile conf is not transitive and extends runtime

        ResolveReport r = ivy.resolve(new File("test/repositories/1/org2/mod2.2/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(r.hasError());

        // here we should get all three recursive dependencies
        assertEquals(
                new HashSet<>(Arrays.asList(
                        ModuleRevisionId.newInstance("org2", "mod2.1", "0.3.2"),
                        ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"),
                        ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))),
            r.getConfigurationReport("A").getModuleRevisionIds());

        // here we should get only mod2.1 and mod1.1 cause compile is not transitive in mod2.1
        assertEquals(
                new HashSet<>(Arrays.asList(
                        ModuleRevisionId.newInstance("org2", "mod2.1", "0.3.2"),
                        ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))),
            r.getConfigurationReport("B").getModuleRevisionIds());

        // here we should get only mod2.1 cause compile is not transitive
        assertEquals(Collections.singleton(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3.2")),
                r.getConfigurationReport("compile").getModuleRevisionIds());
    }

    @Test
    public void testDisableTransitivityPerConfiguration5() throws Exception {
        // mod2.2 (A,B,compile) depends on
        // mod 2.1 (A->runtime;B->compile)
        // mod1.1 (A->*) ]0.9.9,1.0] (which resolves to 1.0)
        // compile is not transitive and extends A and B
        //
        // mod2.1 (compile, runtime) depends on mod1.1 1.0 which depends on mod1.2 2.0
        // compile conf is not transitive and extends runtime

        ResolveReport r = ivy.resolve(new File("test/repositories/1/org2/mod2.2/ivys/ivy-0.7.xml"),
            getResolveOptions(new String[] {"A", "B", "compile"}));
        assertFalse(r.hasError());

        // here we should get all three recursive dependencies
        assertEquals(
                new HashSet<>(Arrays.asList(
                        ModuleRevisionId.newInstance("org2", "mod2.1", "0.3.2"),
                        ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"),
                        ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))),
            r.getConfigurationReport("A").getModuleRevisionIds());

        // here we should get only mod2.1 and mod1.1 cause compile is not transitive in mod2.1
        assertEquals(
                new HashSet<>(Arrays.asList(
                        ModuleRevisionId.newInstance("org2", "mod2.1", "0.3.2"),
                        ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))),
            r.getConfigurationReport("B").getModuleRevisionIds());

        // here we should get only mod2.1 cause compile is not transitive
        assertEquals(
                new HashSet<>(Arrays.asList(
                        ModuleRevisionId.newInstance("org2", "mod2.1", "0.3.2"),
                        ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))),
            r.getConfigurationReport("compile").getModuleRevisionIds());
    }

    @Test
    public void testResolveDiamond() throws Exception {
        // mod4.1 depends on
        // - mod1.1 which depends on mod1.2
        // - mod3.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.0", "mod3.1", "jar", "jar").exists());
    }

    @Test
    public void testResolveConflict() throws Exception {
        // mod4.1 v 4.1 depends on
        // - mod1.1 v 1.0 which depends on mod1.2 v 2.0
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.1.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.1");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(0,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0")).length);
        assertEquals(1,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1")).length);

        File r = getConfigurationResolveReportInCache(ResolveOptions.getDefaultResolveId(md),
            "default");
        assertTrue(r.exists());
        final boolean[] found = new boolean[] {false};
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        saxParser.parse(r, new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName, String qName,
                                     Attributes attributes) {
                if ("revision".equals(qName) && "2.0".equals(attributes.getValue("name"))) {
                    found[0] = true;
                }
            }
        });
        assertTrue(found[0]); // the report should contain the evicted revision

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.1", "mod3.1", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveConflict2() throws Exception {
        // mod4.1 v 4.14 depends on
        // - mod1.1 v 1.0 which depends on mod1.2 v 2.0
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        // - mod6.1 v 0.3 which depends on mod1.2 v 2.0
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.14.xml"),
            getResolveOptions(new String[] {"*"}));

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(0,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0")).length);
        assertEquals(1,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1")).length);

        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.14");
        File r = getConfigurationResolveReportInCache(
            ResolveOptions.getDefaultResolveId(mrid.getModuleId()), "default");
        assertTrue(r.exists());
        final boolean[] found = new boolean[] {false};
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        saxParser.parse(r, new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName, String qName,
                    Attributes attributes) {
                if ("revision".equals(qName) && "2.0".equals(attributes.getValue("name"))) {
                    found[0] = true;
                }
            }
        });
        assertTrue(found[0]); // the report should contain the evicted revision

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.1", "mod3.1", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-264.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-264">IVY-264</a>
     */
    @Test
    public void testResolveConflict3() throws Exception {
        // a depends on x latest, y latest, z latest
        // x and z depends on commons-lang 1.0.1
        // y depends on commons-lang 2.0
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-264/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-264/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(
            0,
            crr.getDownloadReports(ModuleRevisionId.newInstance("myorg", "commons-lang", "1.0.1")).length);
        assertEquals(
            1,
            crr.getDownloadReports(ModuleRevisionId.newInstance("myorg", "commons-lang", "2.0")).length);

        assertFalse(getArchiveFileInCache(ivy, "myorg", "commons-lang", "1.0.1", "commons-lang",
            "jar", "jar").exists());

        assertTrue(getArchiveFileInCache(ivy, "myorg", "commons-lang", "2.0", "commons-lang",
            "jar", "jar").exists());
    }

    @Test
    public void testResolveMergeTransitiveAfterConflict() throws Exception {
        // mod20.4 -> mod20.3;1.0 mod20.2;1.0
        // mod20.3;1.0 -> mod20.1;1.0
        // mod20.2;1.0 -> mod20.1;1.1 (transitive false)
        // mod20.1;1.0 -> mod1.2;1.0
        // mod20.1;1.1 -> mod1.2;1.0
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org20/mod20.4/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(1,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org1", "mod1.2", "1.0")).length);

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-618.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-618">IVY-618</a>
     */
    @Test
    public void testResolveConflictFromPoms() throws Exception {
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod17.1/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());
    }

    @Test
    public void testTransitiveEviction() throws Exception {
        // mod7.3 depends on mod7.2 v1.0 and on mod7.1 v2.0
        // mod7.2 v1.0 depends on mod7.1 v1.0 (which then should be evicted)
        // mod7.1 v1.0 depends on mod 1.2 v2.0 (which should be evicted by transitivity)

        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod7.3/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org7", "mod7.3", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org7", "mod7.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org7", "mod7.2", "1.0", "mod7.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org7", "mod7.1", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org7", "mod7.1", "2.0", "mod7.1", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org7", "mod7.1", "1.0", "mod7.1", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-199.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-199">IVY-199</a>
     */
    @Test
    public void testTransitiveEviction2() throws Exception {
        // mod4.1 v 4.13 depends on
        // - mod3.2 v 1.2.1 which depends on
        // - mod3.1 v 1.0 which depends on mod1.2 v 2.0
        // - mod1.2 v 2.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.13.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-590.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-590">IVY-590</a>
     */
    @Test
    public void testTransitiveEvictionWithExtendingConf() throws Exception {
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-590.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // test eviction
        ConfigurationResolveReport compileReport = report.getConfigurationReport("compile");
        IvyNode[] evicted = compileReport.getEvictedNodes();
        assertNotNull(evicted);

        Collection<ModuleRevisionId> evictedModules = new ArrayList<>();
        for (IvyNode anEvicted : evicted) {
            evictedModules.add(anEvicted.getId());
        }

        assertTrue(evictedModules.contains(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0")));
    }

    @Test
    public void testResolveConflictInConf() throws Exception {
        // conflicts in separate confs are not conflicts

        // mod2.1 conf A depends on mod1.1 which depends on mod1.2 2.0
        // mod2.1 conf B depends on mod1.2 2.1
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.1/ivys/ivy-0.4.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.1", "0.4");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testEvictWithConf() throws Exception {
        // bug 105 - test #1

        // mod6.1 r1.0 depends on
        // mod5.1 r4.2 conf A
        // mod5.2 r1.0 which depends on mod5.1 r4.0 conf B
        //
        // mod5.1 r4.2 conf B depends on mod1.2 r2.0
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.1/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51B", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.2", "1.0", "mod5.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // should have been evicted before download
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    @Test
    public void testEvictWithConf2() throws Exception {
        // same as preceding one but with inverse order, so that
        // eviction is done after download
        // bug 105 - test #2

        // mod6.1 r1.1 depends on
        // mod5.2 r1.0 which depends on mod5.1 r4.0 conf B
        // mod5.1 r4.2 conf A
        //
        // mod5.1 r4.2 conf B depends on mod1.2 r2.0
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.1/ivy-1.1.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "1.1");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51B", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.2", "1.0", "mod5.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // even late eviction should avoid artifact downloading
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-681.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-681">IVY-681</a>
     */
    @Test
    public void testEvictWithConf3() throws Exception {
        // same as first one but the conf requested in evicted module is no longer present in
        // selected revision

        // mod6.1 r1.4 depends on
        // mod5.1 r4.3 conf A
        // mod5.2 r1.0 which depends on mod5.1 r4.0 conf B
        //
        // mod5.1 r4.3 has only conf A, not B
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.1/ivy-1.4.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.3", "art51A", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.2", "1.0", "mod5.2", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-861.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-861">IVY-861</a>
     */
    @Test
    public void testFailWithMissingConf() throws Exception {
        // mod6.1 r1.5 depends on
        // mod5.1 [1.0,4.3] conf unknown which doesn't exist in mod5.1;4.3
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.1/ivy-1.5.xml"),
            getResolveOptions(new String[] {"*"}));
        assertTrue("missing conf should have raised an error in report", report.hasError());
        assertTrue(joinArray(report.getAllProblemMessages().toArray(new String[0]), "\n").contains("'unknown'"));
    }

    @Test
    public void testEvictWithConfInMultiConf() throws Exception {
        // same as preceding ones but the conflict appears in several root confs
        // bug 105 - test #3

        // mod6.1 r1.2 conf A and conf B depends on
        // mod5.2 r1.0 which depends on mod5.1 r4.0 conf B
        // mod5.1 r4.2 conf A
        //
        // mod5.1 r4.2 conf B depends on mod1.2 r2.0
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.1/ivy-1.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "1.2");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51B", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.2", "1.0", "mod5.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // all artifacts should be present in both confs
        ConfigurationResolveReport crr = report.getConfigurationReport("A");
        assertNotNull(crr);
        assertEquals(2,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2")).length);

        crr = report.getConfigurationReport("B");
        assertNotNull(crr);
        assertEquals(2,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2")).length);

        // even late eviction should avoid artifact downloading
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    @Test
    public void testEvictWithConfInMultiConf2() throws Exception {
        // same as preceding one but the conflict appears in a root conf and not in another
        // which should keep the evicted
        // bug 105 - test #4

        // mod6.1 r1.3 conf A depends on
        // mod5.2 r1.0 which depends on mod5.1 r4.0 conf B
        //
        // mod6.1 r1.3 conf B depends on
        // mod5.2 r1.0 which depends on mod5.1 r4.0 conf B
        // mod5.1 r4.2 conf A
        //
        // mod5.1 r4.2 conf B depends on mod1.2 r2.0
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.1/ivy-1.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org6", "mod6.1", "1.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.2", "art51B", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.2", "1.0", "mod5.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        // 4.2 artifacts should be present in conf B only
        ConfigurationResolveReport crr = report.getConfigurationReport("A");
        assertNotNull(crr);
        assertEquals(0,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2")).length);

        crr = report.getConfigurationReport("B");
        assertNotNull(crr);
        assertEquals(2,
            crr.getDownloadReports(ModuleRevisionId.newInstance("org5", "mod5.1", "4.2")).length);
    }

    /**
     * Test case for IVY-644.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-644">IVY-644</a>
     */
    @Test
    public void testMultipleEviction() throws Exception {

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/IVY-644/M1/ivys/ivy-1.0.xml"), getResolveOptions(new String[] {
                "test", "runtime"})); // NB the order impact the bug
        assertFalse(report.hasError());
    }

    @Test
    public void testResolveForce() throws Exception {
        // mod4.1 v 4.2 depends on
        // - mod1.2 v 2.0 and forces it
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.2");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.1", "mod3.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-193.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-193">IVY-193</a>
     */
    @Test
    public void testResolveForceAfterConflictSolved() throws Exception {
        // mod4.1 v 4.9 depends on
        // - mod3.2 v 1.1 which depends on mod1.2 v 2.0
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        // - mod1.2 v 2.0 and forces it
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.9.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.9");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-193.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-193">IVY-193</a>
     */
    @Test
    public void testResolveForceAfterDependencyExist() throws Exception {
        // mod4.1 v 4.10 depends on
        // - mod3.1 v 1.0.1 which depends on mod1.2 v 2.0 and forces it
        // - mod3.2 v 1.2 which depends on mod1.2 v 2.1 and on mod3.1 v1.0.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.10.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // dependencies
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-193.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-193">IVY-193</a>
     */
    @Test
    public void testResolveForceInDepOnly() throws Exception {
        // mod4.1 v 4.11 depends on
        // - mod1.2 v 2.0
        // - mod3.2 v 1.3 which depends on
        // - mod3.1 v1.1 which depends on
        // - mod1.2 v 2.1
        // - mod1.2 v 1.0 and forces it
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.11.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "1.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-193.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-193">IVY-193</a>
     */
    @Test
    public void testResolveForceInDepOnly2() throws Exception {
        // mod4.1 v 4.12 depends on
        // - mod3.1 v1.0 which depends on
        // - mod1.2 v 2.0
        // - mod3.2 v 1.4 which depends on
        // - mod1.2 v 2.0 and forces it
        // - mod3.1 v1.1 which depends on
        // - mod1.2 v 2.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.12.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithDynamicRevisionsAndArtifactLockStrategy() throws Exception {
        // mod4.1 v 4.5 depends on
        // - mod1.2 v 1+ and forces it
        // - mod3.1 v 1.2 which depends on mod1.2 v 2+
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings-artifact-lock.xml"));
        ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.5.xml"),
            getResolveOptions(new String[] {"*"}));

        List<File> lockFiles = new ArrayList<>();
        findLockFiles(cache, lockFiles);
        assertTrue("There were lockfiles left in the cache: " + lockFiles, lockFiles.isEmpty());
    }

    private void findLockFiles(File dir, List<File> result) {
        File[] files = dir.listFiles();
        for (File file : files) {
            if (file.isDirectory()) {
                findLockFiles(file, result);
            } else if (file.getName().endsWith(".lck")) {
                result.add(file);
            }
        }
    }

    @Test
    public void testResolveForceWithDynamicRevisions() throws Exception {
        // mod4.1 v 4.5 depends on
        // - mod1.2 v 1+ and forces it
        // - mod3.1 v 1.2 which depends on mod1.2 v 2+
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.5.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.5");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.2", "mod3.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.1", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveForceWithDynamicRevisionsAndSeveralConfs() throws Exception {
        // mod4.1 v 4.6 (conf compile, runtime extends compile, test extends runtime) depends on
        // - mod1.2 v 1+ and forces it in conf compile
        // - mod3.1 v 1.2 in conf test which depends on mod1.2 v 2+
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.6.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.6");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.2", "mod3.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.1", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveForceWithDynamicRevisionsAndSeveralConfs2() throws Exception {
        // mod4.1 v 4.7 (conf compile, test extends compile) depends on
        // - mod1.2 v 1+ and forces it in conf compile
        // - mod3.1 v 1.3 in conf test->runtime
        // which defines confs compile, runtime extends compile
        // which depends on mod1.2 v 2+ in conf compile->default
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod4.1/ivy-4.7.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org4", "mod4.1", "4.7");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.3", "mod3.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.1", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-182.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-182">IVY-182</a>
     */
    @Test
    public void testResolveForceWithDynamicRevisionsAndCyclicDependencies() throws Exception {
        // * has no revision
        // * declares conf compile, test extends compile,
        // * depends on
        // - mod1.2 v 1+ and forces it in conf compile
        // - mod3.1 v 1+ in conf test->runtime excluding mod4.1 (to avoid cyclic dep failure)
        // which defines confs compile, runtime extends compile
        // which depends on mod1.2 v 2+ in conf compile->default
        // which depends on mod4.1 v 4+ in conf compile->compile
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-182.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleId mid = new ModuleId("test", "IVY-182");
        assertEquals(mid, md.getModuleRevisionId().getModuleId());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org3", "mod3.1", "1.4"))
                .exists());
        assertTrue(getArchiveFileInCache("org3", "mod3.1", "1.4", "mod3.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "1.1", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveContradictoryConflictResolution() throws Exception {
        // mod10.1 v 1.0 depends on
        // - mod1.2 v 2.0 and forces it
        // - mod4.1 v 4.1 (which selects mod1.2 v 2.1 and evicts mod1.2 v 2.0)
        // mod4.1 v 4.1 depends on
        // - mod1.1 v 1.0 which depends on mod1.2 v 2.0
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod10.1/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org10", "mod10.1", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // conflicting dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-130.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-130">IVY-130</a>
     */
    @Test
    public void testResolveContradictoryConflictResolution2() throws Exception {
        // Only mod1.2 v2.0 should be resolved and not v2.1 (because of force)
        // mod10.1 v 1.1 depends on
        // - mod1.2 v 2.0 and forces it
        // - mod4.1 v 4.3
        // mod4.1 v 4.3 depends on
        // - mod1.2 v 2.1
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        ivy.resolve(new File("test/repositories/2/mod10.1/ivy-1.1.xml"),
            getResolveOptions(new String[] {"*"}));

        // conflicting dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.1", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveContradictoryConflictResolution3() throws Exception {
        // mod 1.2 v2.0 should be selected (despite conflict manager in 4.1, because of force in
        // 10.1)
        // mod10.1 v 1.3 depends on
        // - mod1.2 v 2.0 and forces it
        // - mod4.1 v 4.4
        // mod4.1 v 4.4 depends on
        // - mod1.2 v 2.0 but selects mod1.2 v 2.1
        // - mod3.1 v 1.1 which depends on mod1.2 v 2.1
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod10.1/ivy-1.3.xml"),
            getResolveOptions(new String[] {"*"}));

        IvyNode[] evicted = report.getConfigurationReport("default").getEvictedNodes();
        assertEquals(1, evicted.length);
        assertEquals(ModuleRevisionId.newInstance("org1", "mod1.2", "2.1"),
            evicted[0].getResolvedId());
    }

    @Test
    public void testExtends() throws Exception {
        // mod 5.2 depends on mod5.1 conf B
        // mod5.1 conf B publishes art51B
        // mod5.1 conf B extends conf A
        // mod5.1 conf A publishes art51A
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod5.2/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org5", "mod5.2", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org5", "mod5.1", "4.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
    }

    @Test
    public void testMultiConfs() throws Exception {
        // mod 5.2 depends on mod5.1 conf B in its conf B and conf A in its conf A
        // mod5.1 conf B publishes art51B
        // mod5.1 conf A publishes art51A
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod5.2/ivy-2.0.xml"),
            getResolveOptions(new String[] {"B", "A"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org5", "mod5.2", "2.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        ModuleRevisionId depId = ModuleRevisionId.newInstance("org5", "mod5.1", "4.1");

        ConfigurationResolveReport crr = report.getConfigurationReport("A");
        assertNotNull(crr);
        assertEquals(1, crr.getDownloadReports(depId).length);

        File r = new File(cache, ResolveOptions.getDefaultResolveId(mrid.getModuleId()) + "-A.xml");
        assertTrue(r.exists());
        final boolean[] found = new boolean[] {false};
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        saxParser.parse(r, new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName, String qName,
                    Attributes attributes) {
                if ("artifact".equals(qName) && "art51B".equals(attributes.getValue("name"))) {
                    found[0] = true;
                }
            }
        });
        assertFalse(found[0]);

        assertTrue(getIvyFileInCache(depId).exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.1", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.1", "art51B", "jar", "jar").exists());
    }

    @Test
    public void testThisConfiguration() throws Exception {
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod14.4/ivy-1.1.xml"),
            getResolveOptions(new String[] {"compile"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);

        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org14", "mod14.4", "1.1");
        assertEquals(mrid, md.getModuleRevisionId());
        ConfigurationResolveReport crr = report.getConfigurationReport("compile");
        assertNotNull(crr);
        assertEquals(4, crr.getArtifactsNumber());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.3", "1.1"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.2", "1.1"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.1", "1.1"))
                .exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org8", "mod8.3", "1.0"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org8", "mod8.1", "1.0"))
                .exists());

        CacheCleaner.deleteDir(cache);
        createCache();
        report = ivy.resolve(new File("test/repositories/2/mod14.4/ivy-1.1.xml"),
            getResolveOptions(new String[] {"standalone"}));
        crr = report.getConfigurationReport("standalone");
        assertNotNull(crr);
        assertEquals(7, crr.getArtifactsNumber());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.3", "1.1"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.1", "1.1"))
                .exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.2", "1.1"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org14", "mod14.3", "1.1"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org8", "mod8.3", "1.0"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org8", "mod8.1", "1.0"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org8", "mod8.4", "1.1"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org8", "mod8.2", "1.1"))
                .exists());
    }

    @Test
    public void testLatest() throws Exception {
        // mod1.4 depends on latest mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.1.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org1", "mod1.4", "1.0.1");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        ModuleRevisionId depId = ModuleRevisionId.newInstance("org1", "mod1.2", "2.2");

        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(1, crr.getDownloadReports(depId).length);

        File r = getConfigurationResolveReportInCache(
            ResolveOptions.getDefaultResolveId(mrid.getModuleId()), "default");
        assertTrue(r.exists());
        final boolean[] found = new boolean[] {false};
        SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
        saxParser.parse(r, new DefaultHandler() {
            @Override
            public void startElement(String uri, String localName, String qName,
                    Attributes attributes) {
                if ("artifact".equals(qName) && "mod1.2".equals(attributes.getValue("name"))) {
                    found[0] = true;
                }
            }
        });
        assertTrue(found[0]);

        assertTrue(getIvyFileInCache(depId).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testLatestMultiple() throws Exception {
        // mod1.5 depends on
        // latest mod1.4, which depends on mod1.2 2.2
        // latest mod1.2 (which is 2.2)
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.5/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.4", "2.0"))
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.2"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testLatestWhenReleased() throws Exception {
        // The test verify that latest.integration dependencies can be resolved with released
        // version also.
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-latestreleased.xml"),
            getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod_released", "1.1"))
                .exists());
    }

    /**
     * Test case for IVY-602.
     * Verify that latest.integration dependencies can be resolved when using a resolver with
     * multiple patterns, when only the first pattern finds something
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-602">IVY-602</a>
     */
    @Test
    public void testLatestWithMultiplePatterns() throws Exception {
        // mod9.2 depends on latest.integration of mod6.2
        Ivy ivy = Ivy.newInstance();
        ivy.configure(new File("test/repositories/ivysettings-IVY602.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org9/mod9.2/ivys/ivy-1.3.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache("org6", "mod6.2", "2.0", "mod6.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveModeDynamic1() throws Exception {
        // mod1.1;1.0.1 -> mod1.2;2.0|latest.integration
        ResolveReport report = ivy.resolve(
            new File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.1.xml"),
            getResolveOptions(new String[] {"default"}).setResolveMode(
                ResolveOptions.RESOLVEMODE_DYNAMIC));
        assertNotNull(report);

        ModuleRevisionId depId = ModuleRevisionId.newInstance("org1", "mod1.2", "2.2");

        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertEquals(1, crr.getDownloadReports(depId).length);

        assertTrue(getIvyFileInCache(depId).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveModeDynamic2() throws Exception {
        // same as ResolveModeDynamic1, but resolve mode is set in settings
        Map<String, String> attributes = new HashMap<>();
        attributes.put("organisation", "org1");
        attributes.put("module", "mod1.2");
        ivy.getSettings().addModuleConfiguration(attributes, ExactPatternMatcher.INSTANCE, null,
            null, null, ResolveOptions.RESOLVEMODE_DYNAMIC);
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.1/ivys/ivy-1.0.1.xml"),
            getResolveOptions(new String[] {"default"}));
        assertNotNull(report);

        ModuleRevisionId depId = ModuleRevisionId.newInstance("org1", "mod1.2", "2.2");

        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertEquals(1, crr.getDownloadReports(depId).length);

        assertTrue(getIvyFileInCache(depId).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.2", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveModeDynamicWithBranch1() throws Exception {
        // bar1;5 -> foo1#branch1|;2|[0,4]
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/5/ivy.xml"),
            getResolveOptions(new String[] {"*"})
                    .setResolveMode(ResolveOptions.RESOLVEMODE_DYNAMIC));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#trunk;3", "foo1", "jar", "jar").exists());
    }

    @Test
    public void testResolveModeDynamicWithBranch2() throws Exception {
        // bar1;5 -> foo1#trunk|branch1;3|[0,4]
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/6/ivy.xml"),
            getResolveOptions(new String[] {"*"})
                    .setResolveMode(ResolveOptions.RESOLVEMODE_DYNAMIC));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#branch1;4", "foo1", "jar", "jar").exists());
    }

    @Test
    public void testResolveModeDefaultOverrideSettings() throws Exception {
        // same as ResolveModeDynamic2, but resolve mode is set in settings, and overridden when
        // calling resolve
        Map<String, String> attributes = new HashMap<>();
        attributes.put("organisation", "org1");
        attributes.put("module", "mod1.2");
        ivy.getSettings().addModuleConfiguration(attributes, ExactPatternMatcher.INSTANCE, null,
            null, null, ResolveOptions.RESOLVEMODE_DYNAMIC);
        ResolveReport report = ivy.resolve(
            new File("test/repositories/1/org1/mod1.1/ivys/ivy-1.0.1.xml"),
            getResolveOptions(new String[] {"default"}).setResolveMode(
                ResolveOptions.RESOLVEMODE_DEFAULT));
        assertNotNull(report);

        ModuleRevisionId depId = ModuleRevisionId.newInstance("org1", "mod1.2", "2.0");

        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertEquals(1, crr.getDownloadReports(depId).length);

        assertTrue(getIvyFileInCache(depId).exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testVersionRange1() throws Exception {
        // mod 1.4 depends on mod1.2 [1.0,2.0[
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.2.xml"),
            getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        // dependencies
        ModuleRevisionId depId = ModuleRevisionId.newInstance("org1", "mod1.2", "1.1");

        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(1, crr.getDownloadReports(depId).length);

        assertTrue(getIvyFileInCache(depId).exists());
    }

    @Test
    public void testVersionRange2() throws Exception {
        // mod 1.4 depends on mod1.2 [1.5,2.0[
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org1/mod1.4/ivys/ivy-1.0.3.xml"),
            getResolveOptions(new String[] {"default"}));
        assertTrue(report.hasError());
    }

    @Test
    public void testLatestMilestone() throws Exception {
        // mod9.2 depends on latest.milestone of mod6.4
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org9/mod9.2/ivys/ivy-1.1.xml"),
            getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        // dependencies
        ModuleRevisionId depId = ModuleRevisionId.newInstance("org6", "mod6.4", "3");

        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(1, crr.getDownloadReports(depId).length);

        assertTrue(getIvyFileInCache(depId).exists());
    }

    /**
     * Test case for IVY-318.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-318">IVY-318</a>
     */
    @Test
    public void testLatestMilestone2() throws Exception {
        // mod9.2 depends on latest.milestone of mod6.2, but there is no milestone
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org9/mod9.2/ivys/ivy-1.2.xml"),
            getResolveOptions(new String[] {"default"}));
        // we should have an error since there is no milestone version, it should be considered as a
        // non resolved dependency
        assertTrue(report.hasError());

        // dependencies
        ConfigurationResolveReport crr = report.getConfigurationReport("default");
        assertNotNull(crr);
        assertEquals(0, crr.getArtifactsNumber());
    }

    /**
     * Test case for IVY-56.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-56">IVY-56</a>
     */
    @Test
    public void testIVY56() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/bugIVY-56/ivysettings.xml"));

        try {
            ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-56.xml"),
                getResolveOptions(new String[] {"default"}));
            assertNotNull(report);
        } finally {
            FileUtil.forceDelete(ivy.getSettings().getDefaultCache());
        }
    }

    /**
     * Test case for IVY-214.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-214">IVY-214</a>
     */
    @Test
    public void testIVY214() throws Exception {
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-214.xml"),
            getResolveOptions(new String[] {"compile"}));

        assertNotNull(report);
        assertFalse(report.hasError());

        assertEquals("Number of artifacts not correct", 1, report.getConfigurationReport("compile")
                .getArtifactsNumber());
    }

    /**
     * Test case for IVY-218.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-218">IVY-218</a>
     */
    @Test
    public void testIVY218() throws Exception {
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-218.xml"),
            getResolveOptions(new String[] {"test"}));

        assertNotNull(report);
        assertFalse(report.hasError());

        assertEquals("Number of artifacts not correct", 3, report.getConfigurationReport("test")
                .getArtifactsNumber());
    }

    /**
     * Test case for IVY-729.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-729">IVY-729</a>
     */
    @Test
    public void testIVY729() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-729/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-729/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());
    }

    /**
     * Circular dependency: mod6.3 depends on mod6.2, which itself depends on mod6.3;
     * circular dependency strategy set to error.
     *
     * @throws Exception if something goes wrong
     */
    @Test
    public void testCircular() throws Exception {
        expExc.expect(CircularDependencyException.class);
        expExc.expectMessage("org6#mod6.3;1.0->org6#mod6.2;1.0->org6#mod6.3;latest.integration");

        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
                getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        ivy.getSettings().setCircularDependencyStrategy(
                IgnoreCircularDependencyStrategy.getInstance());
        report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
                getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        ivy.getSettings().setCircularDependencyStrategy(
                WarnCircularDependencyStrategy.getInstance());
        report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
                getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        ivy.getSettings().setCircularDependencyStrategy(
                ErrorCircularDependencyStrategy.getInstance());
        ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.0.xml"),
                getResolveOptions(new String[] {"default"}));
    }

    /**
     * Circular dependency: mod 9.1 (no revision) depends on mod9.2, which depends on mod9.1 2.+;
     * circular dependency strategy set to error.
     *
     * @throws Exception if something goes wrong
     */
    @Test
    public void testCircular2() throws Exception {
        expExc.expect(CircularDependencyException.class);
        expExc.expectMessage("org8#mod8.5;NONE->org8#mod8.6;2.+->org8#mod8.5;2.+");

        ResolveReport report = ivy.resolve(new File("test/repositories/circular/ivy.xml"),
                getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        ivy.getSettings().setCircularDependencyStrategy(
                ErrorCircularDependencyStrategy.getInstance());
        ivy.resolve(new File("test/repositories/circular/ivy.xml"),
                getResolveOptions(new String[] {"*"}));
    }

    /**
     * Test case for IVY-400.
     * Circular dependency: mod6.3 depends on mod6.2, which itself depends on mod6.3,
     * in both configuration default and test; circular dependency strategy set to error.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-400">IVY-400</a>
     */
    @Test
    public void testCircular3() throws Exception {
        expExc.expect(CircularDependencyException.class);
        expExc.expectMessage("org6#mod6.3;1.2->org6#mod6.2;1.1->...");

        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
                getResolveOptions(new String[] {"default", "test"}));
        assertFalse(report.hasError());
        // we should have mod 6.2 artifact in both configurations
        assertEquals(1, report.getConfigurationReport("default").getArtifactsNumber());
        assertEquals(1, report.getConfigurationReport("test").getArtifactsNumber());

        ivy.getSettings().setCircularDependencyStrategy(
                IgnoreCircularDependencyStrategy.getInstance());
        report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
                getResolveOptions(new String[] {"default", "test"}));
        assertFalse(report.hasError());
        assertEquals(1, report.getConfigurationReport("default").getArtifactsNumber());
        assertEquals(1, report.getConfigurationReport("test").getArtifactsNumber());

        ivy.getSettings().setCircularDependencyStrategy(
                WarnCircularDependencyStrategy.getInstance());
        report = ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
            getResolveOptions(new String[] {"default", "test"}));
        assertFalse(report.hasError());
        assertEquals(1, report.getConfigurationReport("default").getArtifactsNumber());
        assertEquals(1, report.getConfigurationReport("test").getArtifactsNumber());

        ivy.getSettings().setCircularDependencyStrategy(
                ErrorCircularDependencyStrategy.getInstance());
        ivy.resolve(new File("test/repositories/2/mod6.3/ivy-1.2.xml"),
                getResolveOptions(new String[] {"default", "test"}));
    }

    @Test
    public void testRegularCircular() throws Exception {
        // mod11.1 depends on mod11.2 but excludes itself
        // mod11.2 depends on mod11.1
        ivy.getSettings().setCircularDependencyStrategy(
            ErrorCircularDependencyStrategy.getInstance());
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod11.1/ivy-1.0.xml"),
            getResolveOptions(new String[] {"test"}));

        assertNotNull(report);
        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org11", "mod11.2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org11", "mod11.2", "1.0", "mod11.2", "jar", "jar")
                .exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org11", "mod11.1", "1.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org11", "mod11.1", "1.0", "mod11.1", "jar", "jar")
                .exists());
    }

    @Test
    public void testResolveDualChain() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(ResolveTest.class.getResource("dualchainresolverconf.xml"));

        DependencyResolver resolver = ivy.getSettings().getResolver("default");
        assertNotNull(resolver);
        assertTrue(resolver instanceof DualResolver);

        // first without cache
        ivy.resolve(ResolveTest.class.getResource("ivy-dualchainresolver.xml"),
            getResolveOptions(new String[] {"default"}));

        assertTrue(new File("build/cache/xerces/xerces/ivy-2.6.2.xml").exists());
        assertTrue(new File("build/cache/xerces/xerces/jars/xmlParserAPIs-2.6.2.jar").exists());
        assertTrue(new File("build/cache/xerces/xerces/jars/xercesImpl-2.6.2.jar").exists());

        // second with cache for ivy file only
        new File("build/cache/xerces/xerces/jars/xmlParserAPIs-2.6.2.jar").delete();
        new File("build/cache/xerces/xerces/jars/xercesImpl-2.6.2.jar").delete();
        assertFalse(new File("build/cache/xerces/xerces/jars/xmlParserAPIs-2.6.2.jar").exists());
        assertFalse(new File("build/cache/xerces/xerces/jars/xercesImpl-2.6.2.jar").exists());
        ivy.resolve(ResolveTest.class.getResource("ivy-dualchainresolver.xml"),
            getResolveOptions(new String[] {"default"}));

        assertTrue(new File("build/cache/xerces/xerces/ivy-2.6.2.xml").exists());
        assertTrue(new File("build/cache/xerces/xerces/jars/xmlParserAPIs-2.6.2.jar").exists());
        assertTrue(new File("build/cache/xerces/xerces/jars/xercesImpl-2.6.2.jar").exists());
    }

    @Test
    public void testBug148() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/bug148/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ivy.resolve(ResolveTest.class.getResource("ivy-148.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(new File("build/cache/jtv-foo/bar/ivy-1.1.0.0.xml").exists());
        assertTrue(new File("build/cache/jtv-foo/bar/jars/bar-1.1.0.0.jar").exists());
        assertTrue(new File("build/cache/idautomation/barcode/ivy-4.10.xml").exists());
        assertTrue(new File("build/cache/idautomation/barcode/jars/LinearBarCode-4.10.jar")
                .exists());
    }

    @Test
    public void testBug148b() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/bug148/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ivy.resolve(ResolveTest.class.getResource("ivy-148b.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(new File("build/cache/jtv-foo/bar/ivy-1.1.0.0.xml").exists());
        assertTrue(new File("build/cache/jtv-foo/bar/jars/bar-1.1.0.0.jar").exists());
        assertTrue(new File("build/cache/idautomation/barcode/ivy-4.10.xml").exists());
        assertTrue(new File("build/cache/idautomation/barcode/jars/LinearBarCode-4.10.jar")
                .exists());
    }

    /**
     * Test case for IVY-1178.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1178">IVY-1178</a>
     */
    @Test
    public void testIVY1178() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-1178/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-1178.xml"),
            getResolveOptions(new String[] {"*"}));

        assertNotNull(report);
        assertNotNull(report.getUnresolvedDependencies());
        assertEquals("Number of unresolved dependencies not correct", 0,
            report.getUnresolvedDependencies().length);

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("myorg", "modD", "1.1")).exists());
        assertTrue(getArchiveFileInCache("myorg", "modD", "1.1", "modD", "jar", "jar").exists());

        // evicted dependencies
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("myorg", "modD", "1.0"))
                .exists());
        assertFalse(getArchiveFileInCache("myorg", "modD", "1.0", "modD", "jar", "jar").exists());

        // transitive dependencies of modD-1.1 (must not exist: transitive="false" !)
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("myorg", "modE", "1.1"))
                .exists());
        assertFalse(getArchiveFileInCache("myorg", "modE", "1.1", "modE", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-1236.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1236">IVY-1236</a>
     */
    @Test
    public void testIVY1236() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-1236/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-1236/ivy.xml"),
            getResolveOptions(new String[] {"*"}));

        assertNotNull(report);
        assertNotNull(report.getUnresolvedDependencies());
        assertEquals("Number of unresolved dependencies not correct", 0,
            report.getUnresolvedDependencies().length);

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("myorg", "modB", "1.0")).exists());
        assertTrue(getArchiveFileInCache("myorg", "modB", "1.0", "modB", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("myorg", "modB", "1.0", "modB-A", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-1233.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1233">IVY-1233</a>
     */
    @Test
    public void testIVY1233() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-1233/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport rr = ivy.resolve(new File("test/repositories/IVY-1233/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        ConfigurationResolveReport crr = rr.getConfigurationReport("default");
        Set<ModuleRevisionId> modRevIds = crr.getModuleRevisionIds();
        assertEquals(3, modRevIds.size());
        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("test", "a", "1.0")));
        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("test", "b", "2.0")));
        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("test", "c", "3.0")));
    }

    /**
     * Test case for IVY-1333.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1333">IVY-1333</a>
     */
    @Test
    public void testIVY1333() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-1333/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport rr = ivy.resolve(new File("test/repositories/IVY-1333/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        ConfigurationResolveReport crr = rr.getConfigurationReport("default");
        Set<ModuleRevisionId> modRevIds = crr.getModuleRevisionIds();
        assertEquals(3, modRevIds.size());
        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("org", "dep1", "1.0")));
        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("org", "dep2", "1.0")));

        Map<String, String> extra = new HashMap<>();
        extra.put("o:a", "58701");
        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("org", "badArtifact",
            "1.0.0.m4", extra)));
    }

    /**
     * Test case for IVY-1347.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1347">IVY-1347</a>
     */
    @Test
    public void testIVY1347() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-1347/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport rr = ivy.resolve(new File(
                "test/repositories/IVY-1347/childone/childtwo/ivy.xml"),
            getResolveOptions(new String[] {"*"}));
        ModuleDescriptor md = rr.getModuleDescriptor();
        assertNotNull(md);

        ExtendsDescriptor[] parents = md.getInheritedDescriptors();
        assertNotNull(parents);
        assertEquals(1, parents.length);

        ModuleRevisionId parent = parents[0].getParentRevisionId();
        assertEquals(ModuleRevisionId.newInstance("foo", "parent", "1.0"), parent);
    }

    /**
     * Test case for IVY-999.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-999">IVY-999</a>
     */
    @Test
    public void testIVY999() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-999/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport rr = ivy.resolve(ResolveTest.class.getResource("ivy-999.xml"),
            getResolveOptions(new String[] {"*"}));
        ConfigurationResolveReport crr = rr.getConfigurationReport("default");
        Set<ModuleRevisionId> modRevIds = crr.getModuleRevisionIds();

        assertTrue(modRevIds.contains(ModuleRevisionId.newInstance("junit", "junit", "4.4")));
        assertFalse(modRevIds.contains(ModuleRevisionId.newInstance("junit", "junit", "3.8")));
    }

    /**
     * Test case for IVY-1366.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1366">IVY-1366</a>
     */
    @Test
    public void testIVY1366() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-1366/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-1366/ivy.xml"),
            new ResolveOptions().setConfs(new String[] {"runtime"}));
        assertFalse(report.hasError());

        List<Artifact> artifacts = report.getArtifacts();
        assertEquals(3, artifacts.size());
        assertEquals("test#a;1!a.jar", artifacts.get(0).toString());
        assertEquals("test#c;1!c.jar", artifacts.get(1).toString());
        assertEquals("test#b;1!b.jar", artifacts.get(2).toString());
    }

    @Test
    public void testBadFiles() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/badfile/ivysettings.xml"));

        ResolveReport report = ivy.resolve(
            new File("test/repositories/badfile/ivys/ivy-badorg.xml"),
            getResolveOptions(new String[] {"*"}));
        assertTrue("bad org should have raised an error in report", report.hasError());
        assertTrue(joinArray(report.getAllProblemMessages().toArray(new String[0]), "\n").contains("'badorg'"));

        report = ivy.resolve(new File("test/repositories/badfile/ivys/ivy-badmodule.xml"),
            getResolveOptions(new String[] {"*"}));
        assertTrue("bad module should have raised an error in report", report.hasError());
        assertTrue(joinArray(report.getAllProblemMessages().toArray(new String[0]), "\n").contains("'badmodule'"));

        report = ivy.resolve(new File("test/repositories/badfile/ivys/ivy-badbranch.xml"),
            getResolveOptions(new String[] {"*"}));
        assertTrue("bad branch should have raised an error in report", report.hasError());
        assertTrue(joinArray(report.getAllProblemMessages().toArray(new String[0]), "\n").contains("'badbranch'"));

        report = ivy.resolve(new File("test/repositories/badfile/ivys/ivy-badrevision.xml"),
            getResolveOptions(new String[] {"*"}));
        assertTrue("bad revision should have raised an error in report", report.hasError());
        assertTrue(joinArray(report.getAllProblemMessages().toArray(new String[0]), "\n").contains("'badrevision'"));

        report = ivy.resolve(new File("test/repositories/badfile/ivys/ivy-badxml.xml"),
            getResolveOptions(new String[] {"*"}));
        assertTrue("bad xml should have raised an error in report", report.hasError());
        assertTrue(joinArray(report.getAllProblemMessages().toArray(new String[0]), "\n").contains("badatt"));
    }

    @Test
    public void testTransitiveSetting() throws Exception {
        // mod2.4 depends on mod1.1 with transitive set to false
        // mod1.1 depends on mod1.2, which should not be resolved because of the transitive setting
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.4/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.4", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-105.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-105">IVY-105</a>
     */
    @Test
    public void testTransitiveSetting2() throws Exception {
        // mod2.7 depends on mod1.1 and mod2.4
        // mod2.4 depends on mod1.1 with transitive set to false
        // mod1.1 depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.7/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolverDirectlyUsingCache() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(ResolveTest.class.getResource("badcacheconf.xml"));
        File depIvyFileInCache = getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1",
            "1.0"));
        FileUtil.copy(File.createTempFile("test", "xml"), depIvyFileInCache, null); // creates a
        // fake
        // dependency
        // file in cache
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.4/ivys/ivy-0.3.xml"),
            getResolveOptions(new String[] {"*"}));

        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.4", "0.3");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(depIvyFileInCache.exists());
        assertFalse(getArchiveFileInCache(ivy, "org1", "mod1.1", "1.0", "mod1.1", "jar", "jar")
                .exists());
    }

    @Test
    public void testVisibility1() throws Exception {
        ivy.resolve(new File("test/repositories/2/mod8.2/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertFalse(getArchiveFileInCache("org8", "mod8.1", "1.0", "a-private", "txt", "txt")
                .exists());
    }

    @Test
    public void testVisibility2() throws Exception {
        ivy.resolve(new File("test/repositories/2/mod8.3/ivy-1.0.xml"),
            getResolveOptions(new String[] {"private"}));

        assertFalse(getArchiveFileInCache("org8", "mod8.1", "1.0", "a-private", "txt", "txt")
                .exists());
        assertTrue(getArchiveFileInCache("org8", "mod8.1", "1.0", "a", "txt", "txt").exists());
    }

    @Test
    public void testVisibility3() throws Exception {
        ivy.resolve(new File("test/repositories/2/mod8.4/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertFalse(getArchiveFileInCache("org8", "mod8.1", "1.0", "a-private", "txt", "txt")
                .exists());
        assertTrue(getArchiveFileInCache("org8", "mod8.1", "1.0", "a", "txt", "txt").exists());
    }

    @Test
    public void testVisibility4() throws Exception {
        ivy.resolve(new File("test/repositories/2/mod8.4/ivy-1.1.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org8", "mod8.1", "1.1", "a-private", "txt", "txt")
                .exists());
        assertTrue(getArchiveFileInCache("org8", "mod8.1", "1.1", "a", "txt", "txt").exists());
    }

    // /////////////////////////////////////////////////////////
    // here comes a series of test provided by Chris Rudd
    // about configuration mapping and eviction
    // /////////////////////////////////////////////////////////

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping1() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/1/ivy.xml"),
            getResolveOptions(new String[] {"*"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("default");

        assertContainsArtifact("test", "a", "1.0.2", "a", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.2", "a-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.2", "b", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.2", "b-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.2", "c", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.2", "c-bt", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/2/ivy.xml"),
            getResolveOptions(new String[] {"*"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("default");

        assertContainsArtifact("test", "a", "1.0.1", "a", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.1", "a-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.1", "b", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.1", "b-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.1", "c", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.1", "c-bt", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping3() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/3/ivy.xml"),
            getResolveOptions(new String[] {"buildtime"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("buildtime");

        assertContainsArtifact("test", "a", "1.0.2", "a-bt", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.2", "a", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.1", "b-bt", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.1", "b", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.1", "c-bt", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.1", "c", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping4() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/4/ivy.xml"),
            getResolveOptions(new String[] {"default"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("default");

        assertContainsArtifact("test", "a", "1.0.2", "a", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.2", "a-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.1", "b", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.1", "b-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.1", "c", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.1", "c-bt", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping5() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/5/ivy.xml"),
            getResolveOptions(new String[] {"*"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("default");

        assertContainsArtifact("test", "a", "1.0.2", "a", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.2", "a-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.1", "b", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.1", "b-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.1", "c", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.1", "c-bt", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping6() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/6/ivy.xml"),
            getResolveOptions(new String[] {"default", "buildtime"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("default");

        assertContainsArtifact("test", "a", "1.0.2", "a", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.2", "a-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.1", "b", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.1", "b-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.1", "c", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.1", "c-bt", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-84.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-84">IVY-84</a>
     */
    @Test
    public void testConfigurationMapping7() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/IVY-84/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-84/tests/7/ivy.xml"),
            getResolveOptions(new String[] {"buildtime", "default"}));

        ConfigurationResolveReport conf = report.getConfigurationReport("default");

        assertContainsArtifact("test", "a", "1.0.2", "a", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "a", "1.0.2", "a-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "b", "1.0.1", "b", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "b", "1.0.1", "b-bt", "txt", "txt", conf);
        assertContainsArtifact("test", "c", "1.0.1", "c", "txt", "txt", conf);
        assertDoesntContainArtifact("test", "c", "1.0.1", "c-bt", "txt", "txt", conf);
    }

    /**
     * Test case for IVY-97.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-97">IVY-97</a>
     */
    @Test
    public void testIVY97() throws Exception {
        // mod9.2 depends on mod9.1 and mod1.2
        // mod9.1 depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org9/mod9.2/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org9", "mod9.2", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org9", "mod9.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org9", "mod9.1", "1.0", "mod9.1", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveMultipleSameDependency() throws Exception {
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/multiple-same-deps/mod1/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("multiple-same-deps", "mod31", "1.0", "mod31", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache("multiple-same-deps", "mod32", "1.0", "mod32", "jar",
            "jar").exists());
        assertTrue(getArchiveFileInCache("multiple-same-deps", "mod33", "1.0", "mod33", "jar",
            "jar").exists());

        ConfigurationResolveReport runtimeReport = report.getConfigurationReport("runtime");
        runtimeReport.getModuleRevisionIds().contains(
            ModuleRevisionId.parse("multiple-same-deps#mod31;1.0"));
        runtimeReport.getModuleRevisionIds().contains(
            ModuleRevisionId.parse("multiple-same-deps#mod32;1.0"));
        runtimeReport.getModuleRevisionIds().contains(
            ModuleRevisionId.parse("multiple-same-deps#mod33;1.0"));
        ConfigurationResolveReport compileReport = report.getConfigurationReport("compile");
        compileReport.getModuleRevisionIds().contains(
            ModuleRevisionId.parse("multiple-same-deps#mod31;1.0"));
        compileReport.getModuleRevisionIds().contains(
            ModuleRevisionId.parse("multiple-same-deps#mod32;1.0"));
        compileReport.getModuleRevisionIds().contains(
            ModuleRevisionId.parse("multiple-same-deps#mod33;1.0"));
    }

    @Test
    public void testResolveTransitiveExcludesSimple() throws Exception {
        // mod2.5 depends on mod2.3 and excludes one artifact from mod2.1
        // mod2.3 depends on mod2.1
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.5/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org2", "mod2.5", "0.6");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.3", "0.7"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.3", "0.7", "mod2.3", "jar", "jar").exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.1", "0.3"))
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveExcludesDiamond1() throws Exception {
        // mod2.6 depends on mod2.3 and mod2.5
        // mod2.3 depends on mod2.1 and excludes art21B
        // mod2.5 depends on mod2.1 and excludes art21A
        ivy.resolve(new File("test/repositories/1/org2/mod2.6/ivys/ivy-0.6.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveExcludesDiamond2() throws Exception {
        // mod2.6 depends on mod2.3 and mod2.5
        // mod2.3 depends on mod2.1 and excludes art21B
        // mod2.5 depends on mod2.1 and excludes art21B
        ivy.resolve(new File("test/repositories/1/org2/mod2.6/ivys/ivy-0.7.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveExcludesDiamond3() throws Exception {
        // mod2.6 depends on mod2.3 and mod2.5 and on mod2.1 for which it excludes art21A
        // mod2.3 depends on mod2.1 and excludes art21B
        // mod2.5 depends on mod2.1 and excludes art21B
        ivy.resolve(new File("test/repositories/1/org2/mod2.6/ivys/ivy-0.8.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
    }

    @Test
    public void testResolveTransitiveExcludes2() throws Exception {
        // mod2.6 depends on mod2.3 for which it excludes art21A
        // mod2.3 depends on mod2.1 and excludes art21B
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.9.xml"),
            getResolveOptions(new String[] {"*"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org2", "mod2.6", "0.9"),
            md.getModuleRevisionId());

        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.3", "art21B", "jar", "jar").exists());
    }

    @Test
    public void testResolveExcludesModule() throws Exception {
        // mod2.6 depends on mod2.1 and excludes mod1.1
        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.10.xml"),
            getResolveOptions(new String[] {"*"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org2", "mod2.6", "0.10"),
            md.getModuleRevisionId());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveExcludesModule2() throws Exception {
        // root depends on a and (x 2 excluding y)
        // a depends on x 1
        // x 1 depends on y 1
        // x 2 depends on y 2
        ivy.configure(new File("test/repositories/IVY-1486/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                        "test/repositories/IVY-1486/org/root/ivy-1.xml"),
                getResolveOptions(new String[] {"*"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org", "root", "1"),
                md.getModuleRevisionId());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org", "x", "2"))
                .exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org", "y", "2"))
                .exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org", "y", "1"))
                .exists());
    }

    @Test
    public void testResolveExcludesModule3() throws Exception {
        // Ensure that search for unexcluded paths doesn't get confused by the exclusion
        // of parents.
        ivy.configure(new File("test/repositories/IVY-1486/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                        "test/repositories/IVY-1486/org/root/ivy-2.xml"),
                getResolveOptions(new String[] {"*"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org", "root", "2"),
                md.getModuleRevisionId());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org", "l", "1"))
                .exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org", "l", "2"))
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org", "h", "2"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org", "i", "2"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org", "j", "2"))
                .exists());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org", "k", "2"))
                .exists());
    }

    @Test
    public void testResolveExcludesModuleWide() throws Exception {
        // mod2.6 depends on mod2.1 and excludes mod1.1 module wide
        // mod2.1 depends on mod1.1 which depends on mod1.2
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.11.xml"),
            getResolveOptions(new String[] {"*"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org2", "mod2.6", "0.11"),
            md.getModuleRevisionId());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.1", "1.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.1", "1.0", "mod1.1", "jar", "jar").exists());
        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testResolveExcludesConf() throws Exception {
        // mod2.6 depends on mod2.3 in conf default and mod2.5 in conf exclude
        // mod2.5 depends on mod2.3
        // mod2.6 globally exclude mod2.3 in conf exclude
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.13.xml"),
            getResolveOptions(new String[] {"include"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org2", "mod2.6", "0.13"),
            md.getModuleRevisionId());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.3", "0.4"))
                .exists());
    }

    @Test
    public void testResolveExcludesConf2() throws Exception {
        // same as testResolveExcludesConf
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.13.xml"),
            getResolveOptions(new String[] {"exclude"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org2", "mod2.6", "0.13"),
            md.getModuleRevisionId());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.3", "0.4"))
                .exists());
    }

    @Test
    public void testResolveExcludesConf3() throws Exception {
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/org2/mod2.6/ivys/ivy-0.14.xml"),
            getResolveOptions(new String[] {"exclude"}));
        ModuleDescriptor md = report.getModuleDescriptor();
        assertEquals(ModuleRevisionId.newInstance("org2", "mod2.6", "0.14"),
            md.getModuleRevisionId());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org2", "mod2.5", "0.9"))
                .exists());
    }

    @Test
    public void testResolveExceptConfiguration() throws Exception {
        // mod10.2 depends on mod5.1 conf *, !A
        ivy.resolve(new File("test/repositories/2/mod10.2/ivy-2.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.1", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.1", "art51B", "jar", "jar").exists());
    }


    /**
     * Test for issues IVY-982 and IVY-1547,
     * which have to do with resolve engine ignoring negated configurations
     * on the left side of the maps-to operator.
     */

    @Test
    public void testResolveWithNegation() throws Exception {
        ConfigurationResolveReport crp;
        ResolveReport report = ivy.resolve(new File(
                "test/java/org/apache/ivy/core/resolve/ivy-982.xml"),
                getResolveOptions(new String[] {"*"}));

        // mod1.2: A->default
        // mod2.1: *,!A->A
        // mod2.2: *,!A->myconf1; *,!A,!B->myconf2
        assertFalse(report.hasError());

        ModuleRevisionId mod12 = ModuleRevisionId.newInstance("org1", "mod1.2", "2.0");
        ModuleRevisionId mod21 = ModuleRevisionId.newInstance("org2", "mod2.1", "0.5");
        ModuleRevisionId mod22 = ModuleRevisionId.newInstance("org2", "mod2.2", "0.9");

        crp = report.getConfigurationReport("A");
        assertTrue(crp.getDependency(mod12) != null);
        assertTrue(Arrays.asList(crp.getDependency(mod12).getConfigurations(crp.getConfiguration()))
            .containsAll(Collections.singletonList("default")));
        assertEquals(crp.getDependency(mod21), null);
        assertEquals(crp.getDependency(mod22), null);

        crp = report.getConfigurationReport("B");
        assertEquals(crp.getDependency(mod12), null);
        assertTrue(crp.getDependency(mod21) != null);
        assertTrue(Arrays.asList(crp.getDependency(mod21).getConfigurations(crp.getConfiguration()))
            .containsAll(Collections.singletonList("A")));
        assertTrue(crp.getDependency(mod22) != null);
        assertTrue(Arrays.asList(crp.getDependency(mod22).getConfigurations(crp.getConfiguration()))
            .containsAll(Collections.singletonList("myconf1")));

        crp = report.getConfigurationReport("C");
        assertEquals(crp.getDependency(mod12), null);
        assertTrue(crp.getDependency(mod21) != null);
        assertTrue(Arrays.asList(crp.getDependency(mod21).getConfigurations(crp.getConfiguration()))
            .containsAll(Collections.singletonList("A")));
        assertTrue(crp.getDependency(mod22) != null);
        assertTrue(Arrays.asList(crp.getDependency(mod22).getConfigurations(crp.getConfiguration()))
            .containsAll(Arrays.asList("myconf1", "myconf2")));
    }

    @Test
    public void testResolveIntersectConfiguration1() throws Exception {
        // mod5.2;3.0 -> mod5.1;4.4 (*->@)
        // mod5.1;4.4 -> mod1.2;2.0 (B,xplatform->default)
        // mod5.1;4.4 -> mod2.2;0.9 (B,windows->myconf1;B,linux->myconf2)
        // mod5.1;4.4 -> mod2.1;0.5 (B,windows->A+B)
        ivy.resolve(new File("test/repositories/2/mod5.2/ivy-3.0.xml"),
            getResolveOptions(new String[] {"A"}));

        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "dll", "dll").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "so", "so").exists());
    }

    @Test
    public void testResolveIntersectConfiguration2() throws Exception {
        // mod5.2;3.0 -> mod5.1;4.4 (*->@)
        // mod5.1;4.4 -> mod1.2;2.0 (B,xplatform->default)
        // mod5.1;4.4 -> mod2.2;0.9 (B,windows->myconf1;B,linux->myconf2)
        // mod5.1;4.4 -> mod2.1;0.5 (B,windows->A+B)
        ivy.resolve(new File("test/repositories/2/mod5.2/ivy-3.0.xml"),
            getResolveOptions(new String[] {"B"}));

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "dll", "dll").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "so", "so").exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-1", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-2", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21B", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21AB", "jar", "jar").exists());
    }

    @Test
    public void testResolveIntersectConfiguration3() throws Exception {
        // mod5.2;3.0 -> mod5.1;4.4 (*->@)
        // mod5.1;4.4 -> mod1.2;2.0 (B,xplatform->default)
        // mod5.1;4.4 -> mod2.2;0.9 (B,windows->myconf1;B,linux->myconf2)
        // mod5.1;4.4 -> mod2.1;0.5 (B,windows->A+B)
        ivy.resolve(new File("test/repositories/2/mod5.2/ivy-3.0.xml"),
            getResolveOptions(new String[] {"B+windows"}));

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "dll", "dll").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "so", "so").exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-1", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-2", "jar", "jar")
                .exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21B", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21AB", "jar", "jar").exists());
    }

    @Test
    public void testResolveIntersectConfiguration4() throws Exception {
        // mod5.2;3.0 -> mod5.1;4.4 (*->@)
        // mod5.1;4.4 -> mod1.2;2.0 (B,xplatform->default)
        // mod5.1;4.4 -> mod2.2;0.9 (B,windows->myconf1;B,linux->myconf2)
        // mod5.1;4.4 -> mod2.1;0.5 (B,windows->A+B)
        // mod5.1;4.4 -> mod2.8;0.6 (windows,linux->@+thread+debug;A,B->*)
        ivy.resolve(new File("test/repositories/2/mod5.2/ivy-3.0.xml"),
            getResolveOptions(new String[] {"B+linux"}));

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "dll", "dll").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.4", "art51B", "so", "so").exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-1", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-2", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21AB", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-linux-debug-thread",
            "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-linux-debug", "jar",
            "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-windows-debug-thread",
            "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-windows-debug", "jar",
            "jar").exists());
    }

    @Test
    public void testConfigurationGroups() throws Exception {
        // mod5.2;3.1 -> mod5.1;4.5 (*->@)
        // mod5.1;4.5 -> mod1.2;2.0 (B,*[axis=platform]->default)
        // mod5.1;4.5 -> mod2.2;0.9 (B,windows->myconf1;B,linux->myconf2)
        // mod5.1;4.5 -> mod2.1;0.5 (B,windows->A+B)
        // mod5.1;4.5 -> mod2.8;0.6 (windows,linux->@+thread+debug;A,B->*)
        ivy.resolve(new File("test/repositories/2/mod5.2/ivy-3.1.xml"),
            getResolveOptions(new String[] {"B+linux"}));

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.5", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.5", "art51B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.5", "art51B", "dll", "dll").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.5", "art51B", "so", "so").exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-1", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.2", "0.9", "art22-2", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21B", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.1", "0.5", "art21AB", "jar", "jar")
                .exists());
        assertTrue(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-linux-debug-thread",
            "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-linux-debug", "jar",
            "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-windows-debug-thread",
            "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org2", "mod2.8", "0.6", "art28-windows-debug", "jar",
            "jar").exists());
    }

    @Test
    public void testResolveFallbackConfiguration() throws Exception {
        // mod10.2 depends on mod5.1 conf runtime(default)
        ivy.resolve(new File("test/repositories/2/mod10.2/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
    }

    @Test
    public void testResolveFallbackConfiguration2() throws Exception {
        // mod10.2 depends on mod5.1 conf runtime(*)
        ivy.resolve(new File("test/repositories/2/mod10.2/ivy-1.1.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    @Test
    public void testResolveFallbackConfiguration3() throws Exception {
        // mod10.2 depends on mod5.1 conf runtime(*),compile(*)
        ivy.resolve(new File("test/repositories/2/mod10.2/ivy-1.2.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    @Test
    public void testResolveFallbackConfiguration4() throws Exception {
        // mod10.2 depends on mod5.1 conf runtime()
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod10.2/ivy-1.3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertFalse(report.hasError());

        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51A", "jar", "jar").exists());
        assertFalse(getArchiveFileInCache("org5", "mod5.1", "4.0", "art51B", "jar", "jar").exists());
    }

    @Test
    public void testResolveMaven2() throws Exception {
        // test3 depends on test2 which depends on test
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test3/1.0/test3-1.0.pom"),
            getResolveOptions(new String[] {"test"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache", "test3", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.0", "test2", "jar", "jar")
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.0", "test", "jar", "jar")
                .exists());
    }

    @Test
    public void testResolveMaven2WithConflict() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test3/1.1/test3-1.1.pom"),
            getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.1", "test2", "jar", "jar")
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.1"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.1", "test", "jar", "jar")
                .exists());

        assertContainsArtifact(report.getConfigurationReport("default"),
            getArtifact("org.apache", "test2", "1.1", "test2", "jar", "jar"));
        assertContainsArtifact(report.getConfigurationReport("default"),
            getArtifact("org.apache", "test", "1.1", "test", "jar", "jar"));
    }

    @Test
    public void testResolveMaven2WithConflict2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-874.xml"),
            getResolveOptions(new String[] {"default"}));
        assertFalse(report.hasError());

        assertContainsArtifact(report.getConfigurationReport("default"),
            getArtifact("org.apache", "test3", "1.1", "test3", "jar", "jar"));
        assertContainsArtifact(report.getConfigurationReport("default"),
            getArtifact("org.apache", "test2", "1.1", "test2", "jar", "jar"));
        assertContainsArtifact(report.getConfigurationReport("default"),
            getArtifact("org.apache", "test", "1.2", "test", "jar", "jar"));
    }

    @Test
    public void testResolveMaven2RelocationOfGroupId() throws Exception {
        // Same as testResolveMaven2 but with a relocated module pointing to the module
        // used in testResolveMaven2.
        ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ivy.pushContext();
        try {
            ResolveReport report = ivy.resolve(new File(
                    "test/repositories/m2/org/relocated/test3/1.0/test3-1.0.pom"),
                getResolveOptions(new String[] {"*"}));
            assertNotNull(report);

            // dependencies
            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.0", "test2", "jar",
                "jar").exists());

            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.0", "test", "jar", "jar")
                    .exists());
        } finally {
            ivy.popContext();
        }
    }

    @Test
    public void testResolveMaven2FullRelocation() throws Exception {
        // Same as testResolveMaven2 but with a relocated module pointing to the module
        // used in testResolveMaven2.
        ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ivy.pushContext();
        try {
            ResolveReport report = ivy.resolve(new File(
                    "test/repositories/m2/org/relocated/test3full/1.1/test3full-1.1.pom"),
                getResolveOptions(new String[] {"*"}));
            assertNotNull(report);

            // dependencies
            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.0", "test2", "jar",
                "jar").exists());

            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.0", "test", "jar", "jar")
                    .exists());
        } finally {
            ivy.popContext();
        }
    }

    @Test
    public void testResolveVersionRelocationChainedWithGroupRelocation() throws Exception {
        ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ivy.pushContext();
        try {
            ResolveReport report = ivy.resolve(new File(
                    "test/repositories/m2/org/relocated/test3/1.1/test3-1.1.pom"),
                getResolveOptions(new String[] {"*"}));
            assertNotNull(report);

            // dependencies
            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.0", "test2", "jar",
                "jar").exists());

            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.0", "test", "jar", "jar")
                    .exists());
        } finally {
            ivy.popContext();
        }
    }

    @Test
    public void testResolveTransitivelyToRelocatedPom() throws Exception {
        ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ivy.pushContext();
        try {
            ResolveReport report = ivy.resolve(new File(
                    "test/repositories/m2/org/relocated/testRelocationUser/1.0/"
                            + "testRelocationUser-1.0.pom"),
                getResolveOptions(new String[] {"compile"}));
            assertNotNull(report);
            assertFalse(report.hasError());
            // dependencies
            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.0", "test2", "jar",
                "jar").exists());

            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.0", "test", "jar", "jar")
                    .exists());
        } finally {
            ivy.popContext();
        }
    }

    @Test
    public void testResolveTransitivelyToPomRelocatedToNewVersion() throws Exception {
        ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ivy.pushContext();
        try {
            ResolveReport report = ivy.resolve(new File(
                    "test/repositories/m2/org/relocated/testRelocationUser/1.1/"
                            + "testRelocationUser-1.1.pom"),
                getResolveOptions(new String[] {"compile"}));
            assertNotNull(report);
            assertFalse(report.hasError());
            // dependencies
            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test2", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test2", "1.0", "test2", "jar",
                "jar").exists());

            assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test", "1.0"))
                    .exists());
            assertTrue(getArchiveFileInCache(ivy, "org.apache", "test", "1.0", "test", "jar", "jar")
                    .exists());
        } finally {
            ivy.popContext();
        }
    }

    /**
     * Test case for IVY-418.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-418">IVY-418</a>
     */
    @Test
    public void testResolveMaven2Classifiers() throws Exception {
        // test-classifier depends on test-classified with classifier asl
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test-classifier/1.0/test-classifier-1.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId
                .newInstance("org.apache", "test-classifier", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-classified", "1.0")).exists());

        Map<String, String> cmap = new HashMap<>();
        cmap.put("classifier", "asl");
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-classified", /* branch */ null,
            "1.0", "test-classified", "jar", "jar", cmap).exists());
    }

    /**
     * Test case for IVY-1041.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1041">IVY-1041</a>
     */
    @Test
    public void testResolveMaven2ClassifiersWithoutPOM() throws Exception {
        // test-classifier depends on test-classified with classifier asl
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test-classifier/2.0/test-classifier-2.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId
                .newInstance("org.apache", "test-classifier", "2.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-classified", "2.0")).exists());

        Map<String, String> cmap = new HashMap<>();
        cmap.put("classifier", "asl");
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-classified", /* branch */ null,
            "2.0", "test-classified", "jar", "jar", cmap).exists());
    }

    @Test
    public void testResolveMaven2GetSources() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-m2-with-sources.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-sources", "1.0")).exists());
        File jarFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-sources", "1.0",
            "test-sources", "jar", "jar");
        assertTrue(jarFileInCache.exists());
        File sourceFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-sources", null,
            "1.0", "test-sources", "source", "jar",
            Collections.singletonMap("classifier", "sources"));
        assertTrue(sourceFileInCache.exists());
        assertTrue(jarFileInCache.length() != sourceFileInCache.length());
    }

    /**
     * Test case for IVY-1138.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1138">IVY-1138</a>
     */
    @Test
    public void testResolveMaven2GetSourcesWithSrcClassifier() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-m2-with-src.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache", "test-src", "1.0"))
                .exists());
        File jarFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-src", "1.0",
            "test-src", "jar", "jar");
        assertTrue(jarFileInCache.exists());
        File sourceFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-src", null, "1.0",
            "test-src", "source", "jar", Collections.singletonMap("classifier", "src"));
        assertTrue(sourceFileInCache.exists());
        assertTrue(jarFileInCache.length() != sourceFileInCache.length());
    }

    @Test
    public void testResolveMaven2GetSourcesAndJavadocAuto() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-m2-with-sources-and-javadoc-auto.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-sources", "1.0")).exists());
        File jarFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-sources", "1.0",
            "test-sources", "jar", "jar");
        assertTrue(jarFileInCache.exists());
        File sourceFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-sources", null,
            "1.0", "test-sources", "source", "jar",
            Collections.singletonMap("classifier", "sources"));
        assertTrue(sourceFileInCache.exists());
        assertTrue(jarFileInCache.length() != sourceFileInCache.length());
        File javadocFileInCache = getArchiveFileInCache(ivy, "org.apache", "test-sources", null,
            "1.0", "test-sources", "javadoc", "jar",
            Collections.singletonMap("classifier", "javadoc"));
        assertTrue(javadocFileInCache.exists());
        assertTrue(jarFileInCache.length() != javadocFileInCache.length());
    }

    @Test
    public void testResolveMaven2WithVersionProperty() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test-version/1.0/test-version-1.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache", "test-version", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-classifier", "1.0")).exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-classifier", "1.0",
            "test-classifier", "jar", "jar").exists());
    }

    @Test
    public void testResolveMaven2ParentPomChainResolver() throws Exception {
        // test has a dependency on test2 but there is no version listed. test has a parent of
        // parent(2.0)
        // then parent2. Both parents have a dependencyManagement element for test2, and each list
        // the version as
        // ${pom.version}. The parent version should take precedence over parent2,
        // so the version should be test2 version 2.0. Test3 is also a dependency of parent, and
        // it's version is listed
        // as 1.0 in parent2 (dependencies inherited from parent comes after).
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentChain");

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/parentPom/org/apache/dm/test/1.0/test-1.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache.dm", "test", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // test the report to make sure the right dependencies are listed
        List<IvyNode> dependencies = report.getDependencies();
        assertEquals(2, dependencies.size());

        IvyNode ivyNode;
        ivyNode = dependencies.get(0);
        assertNotNull(ivyNode);

        // Bad assertions based on IVY-1301 bug, corrected below:
        // mrid = ModuleRevisionId.newInstance("org.apache.dm", "test2", "2.0");
        // assertEquals(mrid, ivyNode.getId());
        // // dependencies
        // assertTrue(getIvyFileInCache(
        // ModuleRevisionId.newInstance("org.apache.dm", "test2", "2.0")).exists());
        // assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test2", "2.0",
        // "test2", "jar", "jar").exists());

        mrid = ModuleRevisionId.newInstance("org.apache.dm", "test2", "1.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test2", "1.0", "test2", "jar",
            "jar").exists());

        ivyNode = dependencies.get(1);
        assertNotNull(ivyNode);
        mrid = ModuleRevisionId.newInstance("org.apache.dm", "test3", "1.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test3", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test3", "1.0", "test3", "jar",
            "jar").exists());
    }

    @Test
    public void testErrorResolveMaven2ParentPomWithCycle() throws Exception {
        // IVY-1545
        // test6 has parent parent4, parent4 parent is parent5, parent5 parent is parent4, a cycle.
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentChain");

        try {
            ivy.resolve(
                new File("test/repositories/parentPom/org/apache/dm/test6/1.0/test6-1.0.pom"),
                getResolveOptions(new String[] {"*"}));

            // don't expect to get here, should suffer StackOverflowError if cycle is not detected
            fail("Expected CircularDependencyException from parent cycle detection");
        } catch (CircularDependencyException e) {
            // ok
            assertEquals("org.apache.dm#parent4;1.0->org.apache.dm#parent5;1.0", e.getMessage());
        }
    }

    /**
     * Tests that when a pom {@code A1} has a {@code dependencyManagement} section with a {@code import} scoped
     * dependency and such a dependency has the same parent {@code P}, as {@code A1}, then a {@link CircularDependencyException}
     * isn't thrown
     *
     * @throws Exception
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1588">IVY-1588</a> for more details
     */
    @Test
    public void testDepMgmtImportWithSameParent() throws Exception {
        // - sibling1 has parent "org.apache.dm:parent:1.0"
        // - sibling1 further has dependencyManagement section with a dependency on sibling2 with scope=import
        // - sibling2 has parent "org.apache.dm:parent:1.0" (same parent as sibling1)
        // This should *not* trigger a CircularDependencyException for the parent
        final Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentChain");
        final File pom = new File("test/repositories/parentPom/org/apache/dm/sibling1/1.0/sibling1-1.0.pom");
        final ResolveReport report = ivy.resolve(pom, getResolveOptions(new String[]{"*"}));
        Assert.assertNotNull("Resolve report is null", report);
        Assert.assertFalse("Resolve report has errors", report.hasError());
    }

    @Test
    public void testErrorResolveMaven2SelfAsParent() throws Exception {
        // IVY-1545
        // test7 has parent == self
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentChain");

        try {
            ivy.resolve(
                new File("test/repositories/parentPom/org/apache/dm/test7/1.0/test7-1.0.pom"),
                getResolveOptions(new String[] {"*"}));

            // don't expect to get here, should suffer StackOverflowError if cycle is not detected
            fail("Expected CircularDependencyException from parent cycle detection");
        } catch (CircularDependencyException e) {
            // ok
            assertEquals("org.apache.dm#test7;1.0", e.getMessage());
        }
    }

    /**
     * Test case for IVY-1186.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1186">IVY-1186</a>
     */
    @Test
    public void testResolveMaven2ParentPomWithNamespace() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings-namespace.xml"));

        ResolveReport report = ivy.resolve(
            ModuleRevisionId.newInstance("org.apache.systemDm", "test", "1.0"),
            getResolveOptions(new String[] {"*(public)"}), true);
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        // assertEquals(mrid, md.getModuleRevisionId());
        // assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // test the report to make sure the right dependencies are listed
        List<IvyNode> dependencies = report.getDependencies();
        assertEquals(3, dependencies.size()); // the test module + it's 2 dependencies

        IvyNode ivyNode = dependencies.get(0);
        assertNotNull(ivyNode);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache.systemDm", "test", "1.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache.systemDm", "test", "1.0")).exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.systemDm", "test", "1.0", "test", "jar",
            "jar").exists());

        ivyNode = dependencies.get(1);
        assertNotNull(ivyNode);
        mrid = ModuleRevisionId.newInstance("org.apache.systemDm", "test2", "2.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache.systemDm", "test2", "2.0")).exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.systemDm", "test2", "2.0", "test2",
            "jar", "jar").exists());

        ivyNode = dependencies.get(2);
        assertNotNull(ivyNode);
        mrid = ModuleRevisionId.newInstance("org.apache.systemDm", "test3", "1.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache.systemDm", "test3", "1.0")).exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.systemDm", "test3", "1.0", "test3",
            "jar", "jar").exists());
    }

    @Test
    public void testResolveMaven2ParentPomDualResolver() throws Exception {
        // test has a dependency on test2 but there is no version listed. test
        // has a parent of parent(2.0) then parent2. Both parents have a
        // dependencyManagement element for test2, and each list the version as
        // ${pom.version}. The parent version should take precedence over
        // parent2, so the version should be test2 version 2.0. Test3 is also a
        // dependency of parent, and it's version is listed
        // as 1.0 in parent2. (dependencies inherited from parent comes after)

        // now run tests with dual resolver
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentDual");

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/parentPom/org/apache/dm/test/1.0/test-1.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache.dm", "test", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // test the report to make sure the right dependencies are listed
        List<IvyNode> dependencies = report.getDependencies();
        assertEquals(2, dependencies.size());

        IvyNode ivyNode;
        ivyNode = dependencies.get(0);
        assertNotNull(ivyNode);

        // Bad assertions based on IVY-1301 bug, corrected below:
        // mrid = ModuleRevisionId.newInstance("org.apache.dm", "test2", "2.0");
        // assertEquals(mrid, ivyNode.getId());
        // // dependencies
        // assertTrue(getIvyFileInCache(
        // ModuleRevisionId.newInstance("org.apache.dm", "test2", "2.0")).exists());
        // assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test2", "2.0",
        // "test2", "jar", "jar").exists());

        mrid = ModuleRevisionId.newInstance("org.apache.dm", "test2", "1.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test2", "1.0", "test2", "jar",
            "jar").exists());

        ivyNode = dependencies.get(1);
        assertNotNull(ivyNode);
        mrid = ModuleRevisionId.newInstance("org.apache.dm", "test3", "1.0");
        assertEquals(mrid, ivyNode.getId());
        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test3", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test3", "1.0", "test3", "jar",
            "jar").exists());
    }

    @Test
    public void testResolveMaven2ParentPomDependencyManagementOverrideTransitiveVersion()
            throws Exception {
        // test;2.0 has a dependency on test2;3.0.
        // test has a parent of parent(2.0) then parent2.
        // Both parents have a dependencyManagement element for test2, and each
        // list the version as ${pom.version}. The version for test2 in test
        // should take precedence, so the version should be test2 version 3.0.
        // test2;3.0 -> test4;2.0, but parent has a dependencyManagement
        // section specifying test4;1.0.
        // since maven 2.0.6, the information in parent should override
        // transitive dependency version, and thus we should get test4;1.0
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentChain");

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/parentPom/org/apache/dm/test/2.0/test-2.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // test the report to make sure the right dependencies are listed
        List<IvyNode> dependencies = report.getDependencies();
        assertEquals(3, dependencies.size());

        IvyNode ivyNode;
        ivyNode = dependencies.get(0);
        assertNotNull(ivyNode);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache.dm", "test2", "3.0");
        assertEquals(mrid, ivyNode.getId());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test2", "3.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test2", "3.0", "test2", "jar",
            "jar").exists());

        ivyNode = dependencies.get(2);
        assertNotNull(ivyNode);
        mrid = ModuleRevisionId.newInstance("org.apache.dm", "test4", "1.0");
        assertEquals(mrid, ivyNode.getId());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test4", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test4", "1.0", "test4", "jar",
            "jar").exists());
    }

    /**
     * Test case for IVY-1376.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1376">IVY-1376</a>
     */
    @Test
    public void testResolveMaven2ParentPomDependencyManagementWithImport() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/parentPom/ivysettings.xml"));
        ivy.getSettings().setDefaultResolver("parentChain");

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/parentPom/org/apache/dm/test/3.0/test-3.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);

        // test the report to make sure the right dependencies are listed
        List<IvyNode> dependencies = report.getDependencies();
        assertFalse(report.hasError());
        assertEquals(2, dependencies.size());

        IvyNode ivyNode;
        ivyNode = dependencies.get(0);
        assertNotNull(ivyNode);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("org.apache.dm", "test5", "2.0");
        assertEquals(mrid, ivyNode.getId());
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org.apache.dm", "test5", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache.dm", "test5", "2.0", "test5", "jar",
            "jar").exists());
    }

    /**
     * Test case for IVY-501.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-501">IVY-501</a>
     */
    @Test
    public void testResolveMaven2Snapshot1() throws Exception {
        // here we test maven SNAPSHOT versions handling,
        // with m2 snapshotRepository/uniqueVersion set to true
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test4/1.0/test4-1.0.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-SNAPSHOT1", "2.0.2-SNAPSHOT"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-SNAPSHOT1", "2.0.2-SNAPSHOT",
            "test-SNAPSHOT1", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-1036.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1036">IVY-1036</a>
     */
    @Test
    public void testResolveMaven2Snapshot1AsLatestIntegration() throws Exception {
        // here we test maven SNAPSHOT versions handling,
        // with m2 snapshotRepository/uniqueVersion set to true
        // but retrieving by latest.integration
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(
            ModuleRevisionId.newInstance("org.apache", "test-SNAPSHOT1", "latest.integration"),
            getResolveOptions(new String[] {"*(public)"}), true);
        assertNotNull(report);
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-SNAPSHOT1", "2.0.2-SNAPSHOT"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-SNAPSHOT1", "2.0.2-SNAPSHOT",
            "test-SNAPSHOT1", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-501.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-501">IVY-501</a>
     */
    @Test
    public void testResolveMaven2Snapshot2() throws Exception {
        // here we test maven SNAPSHOT versions handling,
        // without m2 snapshotRepository/uniqueVersion set to true
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/m2/org/apache/test4/1.1/test4-1.1.pom"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-SNAPSHOT2", "2.0.2-SNAPSHOT"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-SNAPSHOT2", "2.0.2-SNAPSHOT",
            "test-SNAPSHOT2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-1036.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1036">IVY-1036</a>
     */
    @Test
    public void testResolveMaven2Snapshot2AsLatestIntegration() throws Exception {
        // here we test maven SNAPSHOT versions handling,
        // with m2 snapshotRepository/uniqueVersion set to true
        // but retrieving by latest.integration
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/m2/ivysettings.xml"));
        ResolveReport report = ivy.resolve(
            ModuleRevisionId.newInstance("org.apache", "test-SNAPSHOT2", "latest.integration"),
            getResolveOptions(new String[] {"*(public)"}), true);
        assertNotNull(report);
        assertFalse(report.hasError());

        // dependencies
        assertTrue(getIvyFileInCache(
            ModuleRevisionId.newInstance("org.apache", "test-SNAPSHOT2", "2.0.2-SNAPSHOT"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "org.apache", "test-SNAPSHOT2", "2.0.2-SNAPSHOT",
            "test-SNAPSHOT2", "jar", "jar").exists());
    }

    @Test
    public void testNamespaceMapping() throws Exception {
        // the dependency is in another namespace
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/namespace/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-namespace.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("apache", "namespace", "1.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // ivy file
        File ivyFile = getIvyFileInCache(ModuleRevisionId.newInstance("systemorg", "systemmod",
            "1.0"));
        assertTrue(ivyFile.exists());
        ModuleDescriptor parsedMD = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), ivyFile.toURI().toURL(), true);
        assertEquals("systemorg", parsedMD.getModuleRevisionId().getOrganisation());
        assertEquals("systemmod", parsedMD.getModuleRevisionId().getName());

        // dependencies
        assertTrue(getArchiveFileInCache(ivy, "systemorg", "systemmod", "1.0", "A", "jar", "jar")
                .exists());
    }

    @Test
    public void testNamespaceMapping2() throws Exception {
        // the dependency is in another namespace and has itself a dependency on a module available
        // in the same namespace
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/namespace/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-namespace2.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("apache", "namespace", "2.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("systemorg", "systemmod2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "systemorg", "systemmod2", "1.0", "B", "jar", "jar")
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("systemorg", "systemmod", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "systemorg", "systemmod", "1.0", "A", "jar", "jar")
                .exists());
    }

    @Test
    public void testNamespaceMapping3() throws Exception {
        // same as 2 but with poms
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/namespace/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-namespace3.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("apache", "namespace", "3.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(getResolvedIvyFileInCache(mrid).exists());

        // dependencies
        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("systemorg2", "system-2", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "systemorg2", "system-2", "1.0", "2", "jar", "jar")
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("systemorg2", "system-1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache(ivy, "systemorg2", "system-1", "1.0", "1", "jar", "jar")
                .exists());
    }

    @Test
    public void testNamespaceMapping4() throws Exception {
        // same as 2 but with incorrect dependency asked: the first ivy file asks for a dependency
        // in the resolver namespace and not the system one: this should fail
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/namespace/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-namespace4.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleDescriptor md = report.getModuleDescriptor();
        assertNotNull(md);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("apache", "namespace", "4.0");
        assertEquals(mrid, md.getModuleRevisionId());

        assertTrue(report.hasError());
    }

    @Test
    public void testNamespaceMapping5() throws Exception {
        // Verifies that mapping version numbers works
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/namespace/ivysettings.xml"));
        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-namespace5.xml"),
            getResolveOptions(new String[] {"*"}));
        assertNotNull(report);
        ModuleRevisionId mrid = ModuleRevisionId.newInstance("systemorg3", "systemmod3", "1.0");
        assertTrue(getIvyFileInCache(mrid).exists());
    }

    /**
     * Test case for IVY-1151.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1151">IVY-1151</a>
     */
    @Test
    public void testIVY151() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/multirevisions/ivysettings.xml"));
        ResolveReport report = ivy.resolve(new File("test/repositories/multirevisions/ivy.xml"),
            getResolveOptions(new String[] {"compile", "test"}));

        assertNotNull(report);
        assertNotNull(report.getUnresolvedDependencies());
        assertEquals("Number of unresolved dependencies not correct", 0,
            report.getUnresolvedDependencies().length);
    }

    @Test
    public void testCheckRevision() throws Exception {
        // mod12.2 depends on mod12.1 1.0 which depends on mod1.2
        // mod12.1 doesn't have revision in its ivy file
        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod12.2/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertTrue(report.hasError());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org12", "mod12.1", "1.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org12", "mod12.1", "1.0", "mod12.1", "jar", "jar")
                .exists());

        assertFalse(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertFalse(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    @Test
    public void testTrustRevision() throws Exception {
        // mod12.2 depends on mod12.1 1.0 which depends on mod1.2
        // mod12.1 doesn't have revision in its ivy file

        ((BasicResolver) ivy.getSettings().getResolver("2-ivy")).setCheckconsistency(false);

        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod12.2/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertFalse(report.hasError());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org12", "mod12.1", "1.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org12", "mod12.1", "1.0", "mod12.1", "jar", "jar")
                .exists());

        assertTrue(getIvyFileInCache(ModuleRevisionId.newInstance("org1", "mod1.2", "2.0"))
                .exists());
        assertTrue(getArchiveFileInCache("org1", "mod1.2", "2.0", "mod1.2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-168.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-168">IVY-168</a>
     */
    @Test
    public void testTransitiveConfMapping() throws Exception {
        // mod13.3 depends on mod13.2 which depends on mod13.1
        // each module has two confs: j2ee and compile
        // each module only publishes one artifact in conf compile
        // each module has the following conf mapping on its dependencies: *->@
        // moreover, mod13.1 depends on mod1.2 in with the following conf mapping: compile->default
        // thus conf j2ee should be empty for each modules

        ResolveReport report = ivy.resolve(new File("test/repositories/2/mod13.3/ivy-1.0.xml"),
            getResolveOptions(new String[] {"*"}));

        assertFalse(report.hasError());

        assertEquals(3, report.getConfigurationReport("compile").getArtifactsNumber());
        assertEquals(0, report.getConfigurationReport("j2ee").getArtifactsNumber());
    }

    @Test
    public void testExtraAttributes() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/extra-attributes/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        FileSystemResolver fResolver = (FileSystemResolver) ivy.getSettings().getDefaultResolver();
        fResolver.setCheckconsistency(false); // important for testing IVY-929

        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-extra-att.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(new File(cache, "apache/mymodule/task1/1854/ivy.xml").exists());
        assertTrue(new File(cache, "apache/mymodule/task1/1854/mymodule-windows.jar").exists());
        assertTrue(new File(cache, "apache/mymodule/task1/1854/mymodule-linux.jar").exists());

        Set<ModuleRevisionId> moduleRevisions = report.getConfigurationReport("default")
                .getModuleRevisionIds();
        assertEquals(1, moduleRevisions.size());
        ModuleRevisionId resolveModRevId = moduleRevisions.iterator().next();
        assertEquals("apache", resolveModRevId.getOrganisation());
        assertEquals("mymodule", resolveModRevId.getName());
        assertEquals("1854", resolveModRevId.getRevision());
        assertEquals("task1", resolveModRevId.getExtraAttribute("eatt"));
        assertEquals("another", resolveModRevId.getExtraAttribute("eatt2"));
    }

    /**
     * Test case for IVY-773.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-773">IVY-773</a>
     */
    @Test
    public void testExtraAttributes2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/extra-attributes/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);
        ivy.getSettings().validate();

        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-extra-att2.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(new File(cache, "apache/mymodule/task2/1748/ivy.xml").exists());
        assertTrue(new File(cache, "apache/mymodule/task2/1748/ivy.xml.original").exists());
        assertTrue(new File(cache, "apache/mymodule/task2/1748/mymodule-windows.jar").exists());
        assertTrue(new File(cache, "apache/mymodule/task2/1748/mymodule-linux.jar").exists());

        assertTrue(new File(cache, "apache/module2/task2/1976/ivy.xml").exists());
        assertTrue(new File(cache, "apache/module2/task2/1976/module2-windows.jar").exists());
        assertTrue(new File(cache, "apache/module2/task2/1976/module2-linux.jar").exists());
    }

    /**
     * Test case for IVY-745.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-745">IVY-745</a>
     */
    @Test
    public void testExtraAttributes3() throws Exception {
        MockMessageLogger mockLogger = new MockMessageLogger();
        Ivy ivy = new Ivy();
        ivy.getLoggerEngine().setDefaultLogger(mockLogger);
        ivy.configure(new File("test/repositories/extra-attributes/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);
        ivy.getSettings().validate();

        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-extra-att3.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));

        assertTrue(report.hasError());
        // should report error about missing extra attribute in dependency module descriptor
        mockLogger.assertLogContains("expected='task2' found='null'");
    }

    /**
     * Second test case for IVY-745.¨
     * Now we disable consistency checking, everything must work fine.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-745">IVY-745</a>
     */
    @Test
    public void testExtraAttributes4() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/extra-attributes/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);
        ((FileSystemResolver) ivy.getSettings().getResolver("default")).setCheckconsistency(false);
        ivy.getSettings().validate();

        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-extra-att3.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));

        assertFalse(report.hasError());

        assertTrue(new File(cache, "apache/mymodule/task2/1749/ivy.xml").exists());
        assertTrue(new File(cache, "apache/mymodule/task2/1749/ivy.xml.original").exists());
        assertTrue(new File(cache, "apache/mymodule/task2/1749/mymodule-windows.jar").exists());
        assertTrue(new File(cache, "apache/mymodule/task2/1749/mymodule-linux.jar").exists());
    }

    @Test
    public void testNamespaceExtraAttributes() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/extra-attributes/ivysettings.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-extra-att-ns.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(true));
        assertFalse(report.hasError());

        assertTrue(new File(cache, "apache/mymodule/task1/1855/ivy.xml").exists());
        assertTrue(new File(cache, "apache/mymodule/task1/1855/mymodule-windows.jar").exists());
        assertTrue(new File(cache, "apache/mymodule/task1/1855/mymodule-linux.jar").exists());
    }

    @Test
    public void testBranches1() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/1/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#trunk;3", "foo1", "jar", "jar").exists());
    }

    @Test
    public void testBranches2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/2/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#branch1;4", "foo1", "jar", "jar").exists());
    }

    @Test
    public void testBranches3() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings-defaultbranch1.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/1/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#branch1;4", "foo1", "jar", "jar").exists());
    }

    @Test
    public void testBranches4() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/3/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#trunk;3", "foo1", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "bar#bar2#trunk;2", "bar2", "jar", "jar").exists());
    }

    @Test
    public void testBranches5() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings-fooonbranch1.xml"));

        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/3/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#branch1;4", "foo1", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "bar#bar2#trunk;2", "bar2", "jar", "jar").exists());
    }

    /**
     * Test case for IVY-717.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-717">IVY-717</a>
     */
    @Test
    public void testBranches6() throws Exception {
        // bar1;4 -> foo#foo1#${ivy.branch};5
        // foo#foo1#branch1;5 -> foo#foo2#${ivy.branch};1
        // foo#foo1#trunk;5 -> {}

        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/branches/ivysettings.xml"));

        ivy.setVariable("ivy.branch", "branch1");
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/branches/bar/bar1/trunk/4/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#branch1;5", "foo1", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "foo#foo2#branch1;1", "foo2", "jar", "jar").exists());

        ivy.setVariable("ivy.branch", "trunk");
        report = ivy.resolve(new File("test/repositories/branches/bar/bar1/trunk/4/ivy.xml"),
            getResolveOptions(new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());
        assertEquals(1, report.getConfigurationReport("default").getNodesNumber());
        assertTrue(getArchiveFileInCache(ivy, "foo#foo1#trunk;5", "foo1", "jar", "jar").exists());
    }

    @Test
    public void testExternalArtifacts() throws Exception {
        Ivy ivy = Ivy.newInstance();
        ivy.getSettings().setVariable("test.base.url",
            new File("test/repositories/external-artifacts").toURI().toURL().toExternalForm());
        ivy.configure(new File("test/repositories/external-artifacts/ivysettings.xml"));

        ResolveReport report = ivy.resolve(
            new File("test/repositories/external-artifacts/ivy.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        assertTrue(getArchiveFileInCache(ivy, "apache", "A", "1.0", "a", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "apache", "B", "2.0", "b", "jar", "jar").exists());
        assertTrue(getArchiveFileInCache(ivy, "apache", "C", "3.0", "C", "jar", "jar").exists());
    }

    @Test
    public void testResolveWithMultipleIvyPatterns() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File("test/repositories/multi-ivypattern/ivysettings.xml"));

        ModuleRevisionId module = ModuleRevisionId.newInstance("org1", "mod1.1", "1.+");

        // use non-default options and settings
        ivy.getSettings().setDefaultUseOrigin(true);
        ResolveOptions options = getResolveOptions(ivy.getSettings(), new String[] {"*"});
        options.setTransitive(false);
        options.setDownload(false);
        ResolveReport report = ivy.getResolveEngine().resolve(module, options, false);

        List<IvyNode> dependencies = report.getDependencies();
        assertNotNull(dependencies);
        assertEquals(1, dependencies.size());
        IvyNode dependency = dependencies.get(0);
        assertEquals("1.1", dependency.getResolvedId().getRevision());
    }

    @Test
    public void testPrivateConfigurationTransferWhenConflict() throws Exception {
        ResolveReport report = ivy.resolve(new File(
                "test/repositories/1/orgConflictAndPrivateConf/root/ivys/ivy-1.0.xml"),
            getResolveOptions(new String[] {"assembly"}));
        assertFalse(report.hasError());
    }

    // //////////////////////////////////////////////////////////
    // helper methods to ease the tests
    // //////////////////////////////////////////////////////////

    private void assertContainsArtifact(String org, String module, String rev, String artName,
            String type, String ext, ConfigurationResolveReport conf) {
        Artifact art = getArtifact(org, module, rev, artName, type, ext);
        assertContainsArtifact(conf, art);
    }

    private void assertContainsArtifact(ConfigurationResolveReport conf, Artifact art) {
        assertTrue("artifact " + art + " should be part of " + conf.getConfiguration()
                + " from " + conf.getModuleDescriptor().getModuleRevisionId(),
                containsArtifact(art, conf.getDownloadedArtifactsReports()));
    }

    private void assertDoesntContainArtifact(String org, String module, String rev, String artName,
            String type, String ext, ConfigurationResolveReport conf) {
        Artifact art = getArtifact(org, module, rev, artName, type, ext);
        assertFalse("artifact " + art + " should NOT be part of " + conf.getConfiguration()
                + " from " + conf.getModuleDescriptor().getModuleRevisionId(),
                containsArtifact(art, conf.getDownloadedArtifactsReports()));
    }

    private Artifact getArtifact(String org, String module, String rev, String artName,
            String type, String ext) {
        return new DefaultArtifact(ModuleRevisionId.newInstance(org, module, rev), new Date(),
                artName, type, ext);
    }

    private boolean containsArtifact(Artifact art, ArtifactDownloadReport[] adrs) {
        for (ArtifactDownloadReport adr : adrs) {
            Artifact artifact = adr.getArtifact();
            if (artifact.getModuleRevisionId().equals(art.getModuleRevisionId())
                    && artifact.getName().equals(art.getName())
                    && artifact.getType().equals(art.getType())
                    && artifact.getExt().equals(art.getExt())) {
                return true;
            }
        }
        return false;
    }

    private String getArchivePathInCache(Artifact artifact) {
        return getRepositoryCacheManager(artifact.getModuleRevisionId()).getArchivePathInCache(
            artifact);
    }

    private String getArchivePathInCache(Artifact artifact, ArtifactOrigin origin) {
        return getRepositoryCacheManager(artifact.getModuleRevisionId()).getArchivePathInCache(
            artifact, origin);
    }

    private File getArchiveFileInCache(Artifact artifact) {
        return getRepositoryCacheManager(artifact.getModuleRevisionId()).getArchiveFileInCache(
            artifact);
    }

    private ArtifactOrigin getSavedArtifactOrigin(Artifact artifact) {
        return getRepositoryCacheManager(artifact.getModuleRevisionId()).getSavedArtifactOrigin(
            artifact);
    }

    private File getIvyFileInCache(ModuleRevisionId id) {
        return getRepositoryCacheManager(id).getIvyFileInCache(id);
    }

    private File getIvyFileInCache(Ivy ivy, ModuleRevisionId id) {
        return TestHelper.getRepositoryCacheManager(ivy, id).getIvyFileInCache(id);
    }

    private DefaultRepositoryCacheManager getRepositoryCacheManager(ModuleRevisionId id) {
        return TestHelper.getRepositoryCacheManager(ivy, id);
    }

    private File getResolvedIvyFileInCache(ModuleRevisionId mrid) {
        return ivy.getResolutionCacheManager().getResolvedIvyFileInCache(mrid);
    }

    private File getResolvedIvyFileInCache(Ivy ivy, ModuleRevisionId mrid) {
        return ivy.getResolutionCacheManager().getResolvedIvyFileInCache(mrid);
    }

    private File getConfigurationResolveReportInCache(String resolveId, String conf) {
        return ivy.getResolutionCacheManager()
                .getConfigurationResolveReportInCache(resolveId, conf);
    }

    private File getConfigurationResolveReportInCache(Ivy ivy, String resolveId, String conf) {
        return ivy.getResolutionCacheManager()
                .getConfigurationResolveReportInCache(resolveId, conf);
    }

    private File getArchiveFileInCache(String organisation, String module, String revision,
            String artifactName, String type, String ext) {
        return getArchiveFileInCache(ivy, organisation, module, revision, artifactName, type, ext);
    }

    private File getArchiveFileInCache(Ivy ivy, String organisation, String module, String branch,
            String revision, String artifactName, String type, String ext,
            Map<String, String> extraAttrs) {
        ModuleRevisionId mrid = ModuleRevisionId
                .newInstance(organisation, module, branch, revision);
        DefaultArtifact artifact = new DefaultArtifact(mrid, new Date(), artifactName, type, ext,
                extraAttrs);
        return TestHelper.getRepositoryCacheManager(ivy, mrid).getArchiveFileInCache(artifact);
    }

    private File getArchiveFileInCache(Ivy ivy, String organisation, String module,
            String revision, String artifactName, String type, String ext) {
        return TestHelper.getArchiveFileInCache(ivy, organisation, module, revision, artifactName,
            type, ext);
    }

    private File getArchiveFileInCache(Ivy ivy, String mrid, String artifactName, String type,
            String ext) {
        return TestHelper.getArchiveFileInCache(ivy, mrid, artifactName, type, ext);
    }

    private ResolveOptions getResolveOptions(String[] confs) {
        return getResolveOptions(ivy.getSettings(), confs);
    }

    private ResolveOptions getResolveOptions(IvySettings settings, String[] confs) {
        return new ResolveOptions().setConfs(confs);
    }

    @Test
    public void testExtraAttributesForcedDependencies() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File(
                "test/repositories/extra-attributes-forceddependencies/ivysettings-filerepo-attribs.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-extra-attrib-forced-dependencies.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        ivy.deliver("1.0.0", deliverDir.getAbsolutePath() + "/ivy-1.0.0.xml", new DeliverOptions()
                .setResolveId(report.getResolveId()).setValidate(false).setPubdate(new Date()));

        File deliveredIvyFile = new File(deliverDir, "ivy-1.0.0.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(
            ModuleRevisionId.newInstance("CAE-Visualization-Components", "SGL", "MAIN", "6.2.34.7"),
            dds[1].getDependencyRevisionId());

    }

    @Test
    public void testNoAttributesForcedDependencies() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File(
                "test/repositories/extra-attributes-forceddependencies/ivysettings-filerepo-noattribs.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-extra-attrib-forced-dependencies.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());

        ivy.deliver("1.0.0", deliverDir.getAbsolutePath() + "/ivy-1.0.0.xml", new DeliverOptions()
                .setResolveId(report.getResolveId()).setValidate(false).setPubdate(new Date()));

        File deliveredIvyFile = new File(deliverDir, "ivy-1.0.0.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(
            ModuleRevisionId.newInstance("CAE-Visualization-Components", "SGL", "MAIN", "6.2.34.7"),
            dds[1].getDependencyRevisionId());
    }

    @Test
    public void testExtraAttributesMultipleDependenciesHang() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File(
                "test/repositories/extra-attributes-multipledependencies/ivysettings-filerepo-attribs.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-extra-att-multipledependencies.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());
    }

    @Test
    public void testExtraAttributesMultipleDependenciesNoHang() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File(
                "test/repositories/extra-attributes-multipledependencies/ivysettings-filerepo-noattribs.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-extra-att-multipledependencies.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());
    }

    @Test
    public void testExtraAttributesMultipleDependenciesHang2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File(
                "test/repositories/extra-attributes-multipledependencies/ivysettings-filerepo-attribs.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-extra-att-multipledependencies2.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());
    }

    @Test
    public void testExtraAttributesMultipleDependenciesNoHang2() throws Exception {
        Ivy ivy = new Ivy();
        ivy.configure(new File(
                "test/repositories/extra-attributes-multipledependencies/ivysettings-filerepo-noattribs.xml"));
        ivy.getSettings().setDefaultCache(cache);

        ResolveReport report = ivy.resolve(
            ResolveTest.class.getResource("ivy-extra-att-multipledependencies2.xml"),
            getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
        assertFalse(report.hasError());
    }

    /**
     * Test case for IVY-956.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-956">IVY-956</a>
     */
    @Test(expected = StrictConflictException.class)
    public void testIVY956() throws Exception {
        ivy.getSettings().setDefaultConflictManager(
                ivy.getSettings().getConflictManager("latest-compatible"));
        ivy.resolve(ResolveTest.class.getResource("ivy-956.xml"),
                getResolveOptions(ivy.getSettings(), new String[] {"*"}).setValidate(false));
    }

    /**
     * Test case for IVY-1159.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1159">IVY-1159</a>
     */
    @Test
    public void testIVY1159_orderIsModAModB() throws Exception {
        testIVY1159("ivy-depsorder_modA_then_modB.xml", false);

        File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "0"),
            dds[0].getDependencyRevisionId());
        assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "0"),
            dds[1].getDependencyRevisionId());
    }

    /**
     * Test case for IVY-1159.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1159">IVY-1159</a>
     */
    @Test
    public void testIVY1159_orderIsModAModBReplaceForced() throws Exception {
        testIVY1159("ivy-depsorder_modA_then_modB.xml", true);

        File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "1"),
            dds[0].getDependencyRevisionId());
        assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "1"),
            dds[1].getDependencyRevisionId());
    }

    /**
     * Test case for IVY-1159.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1159">IVY-1159</a>
     */
    @Test
    public void testIVY1159_orderIsModBModA() throws Exception {
        testIVY1159("ivy-depsorder_modB_then_modA.xml", false);

        File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "0"),
            dds[0].getDependencyRevisionId());
        assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "0"),
            dds[1].getDependencyRevisionId());
    }

    /**
     * Test case for IVY-1159.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1159">IVY-1159</a>
     */
    @Test
    public void testIVY1159_orderIsModBModAReplaceForced() throws Exception {
        testIVY1159("ivy-depsorder_modB_then_modA.xml", true);

        File deliveredIvyFile = new File("build/test/deliver/ivy-1.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "1"),
            dds[0].getDependencyRevisionId());
        assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "1"),
            dds[1].getDependencyRevisionId());
    }

    private void testIVY1159(String modCIvyFile, boolean replaceForced) throws Exception {
        ivy = Ivy.newInstance();
        ivy.configure(new File("test/repositories/IVY-1159/ivysettings.xml"));

        ResolveOptions opts = new ResolveOptions();
        opts.setConfs(new String[] {"*"});
        opts.setResolveId("resolveid");
        opts.setRefresh(true);
        opts.setTransitive(true);

        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-1159/" + modCIvyFile),
            opts);
        assertFalse(report.hasError());

        assertEquals(
                new HashSet<>(Arrays.asList(
                        ModuleRevisionId.newInstance("myorg", "modA", "1"),
                        ModuleRevisionId.newInstance("myorg", "modB", "1"))), report
                    .getConfigurationReport("default").getModuleRevisionIds());

        DeliverOptions dopts = new DeliverOptions();
        dopts.setReplaceForcedRevisions(replaceForced);
        dopts.setGenerateRevConstraint(true);
        dopts.setConfs(new String[] {"*"});
        dopts.setStatus("release");
        dopts.setPubdate(new Date());
        dopts.setResolveId("resolveid");
        String pubrev = "1";
        String deliveryPattern = "build/test/deliver/ivy-[revision].xml";

        ivy.deliver(pubrev, deliveryPattern, dopts);
    }

    /**
     * Test case for IVY-1300.
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1300">IVY-1300</a>
     */
    @Test
    public void testIVY1300() throws Exception {
        ivy = Ivy.newInstance();
        ivy.configure(new File("test/repositories/IVY-1300/ivysettings.xml"));

        ResolveOptions opts = new ResolveOptions();
        opts.setConfs(new String[] {"*"});
        opts.setResolveId("resolveid");
        opts.setTransitive(true);

        ResolveReport report = ivy.resolve(new File("test/repositories/IVY-1300/assembly-ivy.xml"),
            opts);
        assertFalse(report.hasError());

        ModuleRevisionId modAExpectedRevId = ModuleRevisionId.newInstance("myorg", "modA", "trunk",
            "5");
        ModuleRevisionId modBExpectedRevId = ModuleRevisionId.newInstance("myorg", "modB",
            "releasebranch", "1");

        // check that the resolve report has the expected results, namely that
        // trunk/5 is considered later than branch/1 purely because 5>1. Of
        // course it is more likely that we would want to consider this a
        // 'bad comparison', but this Unit Test is not about that. It is about
        // inconsistency of results between the resolve report and the
        // delivered descriptor. In fact the delivered descriptor is out of
        // step, because retrieve and the report both agree that trunk/5 is
        // selected. Deliver begs to differ.

        Set<ModuleRevisionId> reportMrids = report.getConfigurationReport("default")
                .getModuleRevisionIds();
        assertEquals(
                new HashSet<>(Arrays.asList(modAExpectedRevId, modBExpectedRevId)),
            reportMrids);

        DeliverOptions dopts = new DeliverOptions();
        dopts.setGenerateRevConstraint(true);
        dopts.setConfs(new String[] {"*"});
        dopts.setStatus("release");
        dopts.setPubdate(new Date());
        dopts.setResolveId("resolveid");
        String pubrev = "1";
        String deliveryPattern = "build/test/deliver/assembly-[revision].xml";

        ivy.deliver(pubrev, deliveryPattern, dopts);

        // now check that the resolve report has the same info as the delivered descriptor

        File deliveredIvyFile = new File("build/test/deliver/assembly-1.xml");
        assertTrue(deliveredIvyFile.exists());
        ModuleDescriptor md = XmlModuleDescriptorParser.getInstance().parseDescriptor(
            ivy.getSettings(), deliveredIvyFile.toURI().toURL(), false);
        DependencyDescriptor[] dds = md.getDependencies();
        assertEquals(2, dds.length);
        assertEquals(ModuleRevisionId.newInstance("myorg", "modB", "releasebranch", "1"),
            dds[1].getDependencyRevisionId());
        assertEquals(ModuleRevisionId.newInstance("myorg", "modA", "trunk", "5"),
            dds[0].getDependencyRevisionId());
    }

    @Test
    public void testUseCacheOnly() throws Exception {
        ResolveOptions option = getResolveOptions(new String[] {"*"}).setValidate(false);
        URL url = new File("test/repositories/1/usecacheonly/mod1/ivys/ivy-1.0.xml").toURI()
                .toURL();

        // normal resolve, the file goes in the cache
        ResolveReport report = ivy.resolve(url, option);
        assertFalse(report.hasError());

        option.setUseCacheOnly(true);

        // use cache only, hit the cache
        report = ivy.resolve(url, option);
        assertFalse(report.hasError());

        CacheCleaner.deleteDir(cache);
        createCache();

        // no more in the cache, missed
        report = ivy.resolve(url, option);
        assertTrue(report.hasError());

        option.setUseCacheOnly(false);

        // try with use origin: should fail as the cache is empty
        ivy.getSettings().setDefaultUseOrigin(true);
        option.setUseCacheOnly(true);
        report = ivy.resolve(url, option);
        assertTrue(report.hasError());

        // populate the cache
        option.setUseCacheOnly(false);
        report = ivy.resolve(url, option);
        assertFalse(report.hasError());

        // use origin should now work
        option.setUseCacheOnly(true);
        report = ivy.resolve(url, option);
        assertFalse(report.hasError());

        // ensure that we hit only the cache and never try to hit in the repository
        FileSystemResolver resolver = (FileSystemResolver) ivy.getSettings().getResolver("1");
        resolver.setRepository(new AbstractRepository() {
            public List<String> list(String parent) {
                throw new UnsupportedOperationException();
            }

            public Resource getResource(String source) {
                throw new UnsupportedOperationException();
            }

            public void get(String source, File destination) {
                throw new UnsupportedOperationException();
            }
        });
        report = ivy.resolve(url, option);
        assertFalse(report.hasError());
    }

    @Test
    public void testUseCacheOnlyWithRange() throws Exception {
        ResolveOptions option = getResolveOptions(new String[] {"*"});
        option.setValidate(false);

        ivy.getSettings().setDefaultUseOrigin(true);
        ivy.getSettings().setDefaultResolveMode("dynamic");

        URL url = new File("test/repositories/1/usecacheonly/mod3/ivys/ivy-1.0.xml").toURI()
                .toURL();

        // normal resolve, the file goes in the cache
        ResolveReport report = ivy.resolve(url, option);
        assertFalse(report.hasError());

        option.setUseCacheOnly(true);

        // use cache only, hit the cache
        report = ivy.resolve(url, option);
        assertFalse(report.hasError());
    }

    @Test
    public void testUseCacheOnlyWithChanging() throws Exception {
        ResolveOptions option = getResolveOptions(new String[] {"*"});
        option.setValidate(false);

        ivy.getSettings().setDefaultUseOrigin(true);

        URL url = new File("test/repositories/1/usecacheonly/mod4/ivys/ivy-1.0.xml").toURI()
                .toURL();

        // normal resolve, the file goes in the cache
        ResolveReport report = ivy.resolve(url, option);
        assertFalse(report.hasError());

        option.setUseCacheOnly(true);

        // use cache only, hit the cache
        report = ivy.resolve(url, option);
        assertFalse(report.hasError());

    }

    @Test
    public void testUnpack() throws Exception {
        ResolveOptions options = getResolveOptions(new String[] {"*"});

        URL url = new File("test/repositories/1/packaging/module1/ivys/ivy-1.0.xml").toURI()
                .toURL();

        // normal resolve, the file goes in the cache
        ResolveReport report = ivy.resolve(url, options);
        assertFalse(report.hasError());

        ArtifactDownloadReport adr = report.getAllArtifactsReports()[0];
        File cacheDir = ivy.getSettings().getDefaultRepositoryCacheBasedir();
        assertEquals(new File(cacheDir, "packaging/module2/jars/module2-1.0.jar"),
            adr.getLocalFile());
        assertEquals(new File(cacheDir, "packaging/module2/jar_unpackeds/module2-1.0"),
            adr.getUnpackedLocalFile());

        File[] jarContents = adr.getUnpackedLocalFile().listFiles();
        Arrays.sort(jarContents);
        assertEquals(new File(adr.getUnpackedLocalFile(), "META-INF"), jarContents[0]);
        assertEquals(new File(adr.getUnpackedLocalFile(), "test.txt"), jarContents[1]);
        assertEquals(new File(adr.getUnpackedLocalFile(), "META-INF/MANIFEST.MF"),
            jarContents[0].listFiles()[0]);
    }

    /**
     * Tests that if a pom.xml has multiple dependencies for the same module, but for different Maven classifiers,
     * then the resolution of such dependencies, preserves those multiple (Ivy) artifacts against the dependency
     *
     * @throws Exception if something goes wrong
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1576">IVY-1576</a> for more details
     */
    @Test
    public void testMultiClassifierMavenDepResolution() throws Exception {
        final File pomFile = new File("test/repositories/m2/org/apache/test-classifier/1.0/test-classifier-1.0.pom");
        final ResolveReport resolveReport = ivy.resolve(pomFile.toURI().toURL(), new ResolveOptions().setConfs(new String[]{"*"}));
        assertFalse(resolveReport.hasError());
        final ModuleRevisionId dependencyId = ModuleRevisionId.newInstance("org.apache", "test-classified", "1.0");
        final ArtifactDownloadReport[] adrs = resolveReport.getArtifactsReports(dependencyId);
        assertNotNull("Artifact download reports is null for dependency " + dependencyId, adrs);
        assertEquals("Unexpected number of artifact download reports for dependency " + dependencyId, 3, adrs.length);
        final Set<String> classifiers = new HashSet<>();
        Collections.addAll(classifiers, "other", "asl", "unix");
        for (final ArtifactDownloadReport adr : adrs) {
            final Artifact artifact = adr.getArtifact();
            assertNotNull("Artifact is null for dependency " + dependencyId, artifact);
            final ArtifactRevisionId artifactId = artifact.getId();
            assertEquals("Unexpected artifact " + artifactId.getName(), "test-classified", artifactId.getName());
            final String classifier = artifact.getExtraAttribute("m:classifier");
            assertNotNull("No classifier extra attribute on artifact for dependency " + dependencyId, classifier);
            assertTrue("Unexpected classifier " + classifier + " on artifact " + artifact, classifiers.remove(classifier));
            // just make sure it's the correct jar file
            assertJarContains(adr.getLocalFile(), classifier + ".txt");
        }
        assertTrue("Missing artifact(s) with classifiers " + classifiers, classifiers.isEmpty());
    }


    /**
     * Tests the issue noted in IVY-1580.
     * <pre>
     *  org.apache:1580:1.0.0 depends on (Maven modules):
     *      -> org.apache:1580-foo-api:1.2.3
     *      -> org.apache:1580-foo-impl:1.2.3 which in turn depends on:
     *          -> org.apache:1580-foo-api:1.2.3 (in compile scope)
     *          -> org.apache:1580-foo-api:1.2.3 (type = test-jar, in test scope)
     * </pre>
     * It's expected that the resolution of org.apache:1580:1.0.0, correctly gets both the regular
     * jar of org.apache:1580-foo-api as well as the test-jar of the same org.apache:1580-foo-api.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1580">IVY-1580</a>
     *
     * @throws Exception
     */
    @Test
    public void testIvy1580() throws Exception {
        final File ivyXML = new File("test/repositories/1/ivy-1580/ivy-1580.xml");
        final ResolveReport resolveReport = ivy.resolve(ivyXML.toURI().toURL(),
                new ResolveOptions().setConfs(new String[]{"*"}));
        assertFalse("Resolution report has failures", resolveReport.hasError());
        final String rootModuleConf = "default";
        // get the "default" conf, resolution report for the org.apache:1580:1.0.0 module (represented by the
        // ivy-1580.xml module descriptor)
        final ConfigurationResolveReport confReport = resolveReport.getConfigurationReport(rootModuleConf);
        assertNotNull(rootModuleConf + " conf resolution report for " +
                resolveReport.getModuleDescriptor().getModuleRevisionId() + " is null", confReport);

        final ModuleRevisionId apiDependencyId = ModuleRevisionId.newInstance("org.apache", "1580-foo-api", "1.2.3");
        final IvyNode apiDepNode = confReport.getDependency(apiDependencyId);
        assertNotNull("Dependency " + apiDependencyId + " not found in conf resolve report", apiDepNode);
        final Artifact[] apiArtifacts = apiDepNode.getArtifacts(rootModuleConf);
        assertNotNull("No artifacts available for dependency " + apiDependencyId, apiArtifacts);
        assertEquals("Unexpected number of artifacts for dependency " + apiDependencyId, 2, apiArtifacts.length);
        boolean foundTestJarType = false;
        boolean foundJarType = false;
        for (final Artifact apiArtifact : apiArtifacts) {
            assertEquals("Unexpected artifact name", "1580-foo-api", apiArtifact.getName());
            assertNotNull("Artifact type is null for " + apiArtifact, apiArtifact.getType());
            ArtifactDownloadReport apiDownloadReport = null;
            for (final ArtifactDownloadReport artifactDownloadReport : confReport.getAllArtifactsReports()) {
                if (artifactDownloadReport.getArtifact().equals(apiArtifact)) {
                    apiDownloadReport = artifactDownloadReport;
                    break;
                }
            }
            assertNotNull("No download report found for artifact " + apiArtifact, apiDownloadReport);
            final File apiJar = apiDownloadReport.getLocalFile();
            assertNotNull("artifact jar file is null for " + apiArtifact, apiJar);
            switch (apiArtifact.getType()) {
                case "test-jar" : {
                    assertFalse("More than 1 test-jar artifact found", foundTestJarType);
                    foundTestJarType = true;
                    assertJarContains(apiJar, "api-test-file.txt");
                    break;
                }
                case "jar" : {
                    assertFalse("More than 1 jar artifact found", foundJarType);
                    foundJarType = true;
                    assertJarContains(apiJar, "api-file.txt");
                    break;
                }
                default: {
                    fail("unexpected artifact type " + apiArtifact.getType() + " for artifact " + apiArtifact);
                }
            }
        }
        assertTrue("No test-jar artifact found for dependency " + apiDependencyId, foundTestJarType);
        assertTrue("No jar artifact found for dependency " + apiDependencyId, foundJarType);

        // just do some basic check on the impl module as well
        final ModuleRevisionId implDepId = ModuleRevisionId.newInstance("org.apache", "1580-foo-impl", "1.2.3");
        final IvyNode implDepNode = confReport.getDependency(implDepId);
        assertNotNull("Dependency " + implDepId + " not found in conf resolve report", implDepNode);

    }


    /**
     * Tests the issue noted in IVY-1586.
     * <pre>
     *  org.apache:1586:1.0.0 depends on (Maven modules):
     *      -> org.apache:1580-foo-api:1.2.3
     *      -> org.apache:1580-foo-impl:1.2.3 conf="default", which in turn depends on:
     *          -> org.apache:1580-foo-api:1.2.3 (in compile scope)
     *          -> org.apache:1580-foo-api:1.2.3 (type = test-jar, in test scope)
     * </pre>
     * It's expected that the resolution of org.apache:1586:1.0.0, gets the
     * "jar" type of org.apache:1580-foo-api and not the test-jar of the same org.apache:1580-foo-api,
     * since only the "default" conf is demanded via the org.apache:1580-foo-impl:1.2.3 dependency.
     *
     * @see <a href="https://issues.apache.org/jira/browse/IVY-1586">IVY-1586</a>
     *
     * @throws Exception
     */
    @Test
    public void testIvy1586() throws Exception {
        // do it twice (once in fresh cache and once with the cache populated)
        for (int i = 0; i < 2; i++) {
            if (i == 0) {
                ivy.getLoggerEngine().info("ResolveTest#testIvy1586 - Using a clean Ivy cache");
            } else {
                ivy.getLoggerEngine().info("ResolveTest#testIvy1586 - Using an already populated Ivy cache");
            }
            final File ivyXML = new File("test/repositories/1/ivy-1586/ivy-1586.xml");
            final ResolveReport resolveReport = ivy.resolve(ivyXML.toURI().toURL(),
                    new ResolveOptions().setConfs(new String[]{"*"}));
            assertFalse("Resolution report has failures", resolveReport.hasError());
            final String rootModuleConf = "default";
            // get the "default" conf, resolution report for the org.apache:1586:1.0.0 module (represented by the
            // ivy-1586.xml module descriptor)
            final ConfigurationResolveReport confReport = resolveReport.getConfigurationReport(rootModuleConf);
            assertNotNull(rootModuleConf + " conf resolution report for " +
                    resolveReport.getModuleDescriptor().getModuleRevisionId() + " is null", confReport);

            final ModuleRevisionId apiDependencyId = ModuleRevisionId.newInstance("org.apache", "1580-foo-api", "1.2.3");
            final IvyNode apiDepNode = confReport.getDependency(apiDependencyId);
            assertNotNull("Dependency " + apiDependencyId + " not found in conf resolve report", apiDepNode);
            final Artifact[] apiArtifacts = apiDepNode.getArtifacts(rootModuleConf);
            assertNotNull("No artifacts available for dependency " + apiDependencyId, apiArtifacts);
            assertEquals("Unexpected number of artifacts for dependency " + apiDependencyId, 1, apiArtifacts.length);
            final Artifact apiArtifact = apiArtifacts[0];
            assertEquals("Unexpected artifact name", "1580-foo-api", apiArtifact.getName());
            assertEquals("Unexpected type for artifact", "jar", apiArtifact.getType());
            ArtifactDownloadReport apiDownloadReport = null;
            for (final ArtifactDownloadReport artifactDownloadReport : confReport.getAllArtifactsReports()) {
                if (artifactDownloadReport.getArtifact().equals(apiArtifact)) {
                    apiDownloadReport = artifactDownloadReport;
                    break;
                }
            }
            assertNotNull("No download report found for artifact " + apiArtifact, apiDownloadReport);
            final File apiJar = apiDownloadReport.getLocalFile();
            assertNotNull("artifact jar file is null for " + apiArtifact, apiJar);
            assertJarContains(apiJar, "api-file.txt");

            // just do some basic check on the impl module as well
            final ModuleRevisionId implDepId = ModuleRevisionId.newInstance("org.apache", "1580-foo-impl", "1.2.3");
            final IvyNode implDepNode = confReport.getDependency(implDepId);
            assertNotNull("Dependency " + implDepId + " not found in conf resolve report", implDepNode);
        }
    }


    /**
     * Tests that when the internal metadata file containing the artifact origin location
     * points to {@code file:} URI, then the location is correctly parsed.
     * See IVY-1616
     */
    @Test
    public void testCacheUseOrigin() throws Exception {
        final Ivy current = new Ivy();
        current.configure(new File("test/repositories/ivysettings-caches-use-origin.xml"));
        // resolve and download an artifact and let the origin details be stored in the internal metadata files
        // in ivy cache
        ResolveReport report = current.resolve(ModuleRevisionId.newInstance("org.apache",
                "test","1.0"),
                getResolveOptions(new String[] {"*"}).setDownload(true), false);
        assertNotNull("Resolve report is null", report);
        assertFalse("Resolution has errors", report.hasError());
        // now set the "useOrigin" on caches to true, so that the next resolution uses the artifact origin
        // that was saved in previous resolution
        current.getSettings().setDefaultUseOrigin(true);
        // trigger the resolution again
        report = current.resolve(ModuleRevisionId.newInstance("org.apache",
                "test","1.0"),
                getResolveOptions(new String[] {"*"}).setDownload(true), false);
        assertNotNull("Resolve report is null", report);
        assertFalse("Resolution has errors", report.hasError());
    }

    private void assertJarContains(final File jar, final String jarEntryPath) throws IOException {
        try (final JarFile jarFile = new JarFile(jar)) {
            final JarEntry entry = jarFile.getJarEntry(jarEntryPath);
            assertNotNull(jarEntryPath + " is missing from jar file " + jar, entry);
        }
    }
}
