// Path: arquillian-chameleon-container-model/src/main/java/org/arquillian/container/chameleon/spi/model/ContainerAdapter.java
// public class ContainerAdapter {
// 
//     private String version;
//     private Target.Type targetType;
//     private Adapter adapter;
//     private Dist dist;
//     private String[] gavExcludeExpression;
//     private String defaultProtocol;
// 
//     public ContainerAdapter(String version, Target.Type targetType, Adapter adapter, Dist dist,
//         String[] gavExcludeExpression, String defaultProtocol) {
//         this.version = version;
//         this.targetType = targetType;
//         this.adapter = adapter;
//         this.dist = dist;
//         this.gavExcludeExpression = gavExcludeExpression;
//         this.defaultProtocol = defaultProtocol;
//     }
// 
//     public Target.Type type() {
//         return targetType;
//     }
// 
//     public boolean overrideDefaultProtocol() {
//         return this.defaultProtocol != null;
//     }
// 
//     public String getDefaultProtocol() {
//         return defaultProtocol;
//     }
// 
//     public String adapterClass() {
//         return adapter.adapterClass();
//     }
// 
//     public String[] dependencies() {
//         return resolve(adapter.dependencies());
//     }
// 
//     public String distribution() {
//         return resolve(dist.coordinates());
//     }
// 
//     public String[] excludes() {
//         return resolve(gavExcludeExpression);
//     }
// 
//     public String[] configurationKeys() {
//         return adapter.configuration().keySet().toArray(new String[] {});
//     }
// 
//     public boolean requireDistribution() {
//         return adapter.requireDist();
//     }
// 
//     public Map<String, String> resolveConfiguration(Map<String, String> parameters) {
//         Map<String, String> configuration = adapter.configuration();
//         for (Map.Entry<String, String> entry : configuration.entrySet()) {
//             for (Map.Entry<String, String> parameter : parameters.entrySet()) {
//                 entry.setValue(resolve(parameter.getKey(), parameter.getValue(), entry.getValue()));
//             }
//         }
//         return configuration;
//     }
// 
//     private String[] resolve(String[] values) {
//         if (values == null) {
//             return new String[0];
//         }
//         String[] resolved = new String[values.length];
//         for (int i = 0; i < values.length; i++) {
//             resolved[i] = resolve(values[i]);
//         }
//         return resolved;
//     }
// 
//     private String resolve(String value) {
//         return resolve("version", version, value);
//     }
// 
//     private String resolve(String parameter, String value, String target) {
//         return target.replaceAll(Pattern.quote("${" + parameter + "}"), Matcher.quoteReplacement(value));
//     }
// }
// 
// Path: arquillian-chameleon-container-model/src/main/java/org/arquillian/container/chameleon/spi/model/Target.java
// public enum Type {
//     Remote, Managed, Embedded, Default;
// 
//     public static Type from(String name) {
//         for (Type type : Type.values()) {
//             if (type.name().equalsIgnoreCase(name)) {
//                 return type;
//             }
//         }
//         return null;
//     }
// 
// }
// 
// Path: arquillian-chameleon-extension/src/main/java/org/arquillian/container/chameleon/Utils.java
// public static MavenCoordinate toMavenCoordinate(String dep) {
//     return MavenCoordinates.createCoordinate(dep);
// }


import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.arquillian.container.chameleon.spi.model.ContainerAdapter;
import org.arquillian.container.chameleon.spi.model.Target.Type;
import org.arquillian.spacelift.Spacelift;
import org.arquillian.spacelift.execution.Execution;
import org.arquillian.spacelift.task.net.DownloadTool;
import org.jboss.arquillian.config.descriptor.api.ContainerDef;
import org.jboss.arquillian.core.api.threading.ExecutorService;
import org.jboss.shrinkwrap.api.GenericArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenCoordinate;
import static org.arquillian.container.chameleon.Utils.toMavenCoordinate;
            serverName);

        if (serverAlreadyDownloaded(targetDirectory)) {
            return getDistributionHome(targetDirectory);
        }

        System.out.println("Arquillian Chameleon: downloading distribution from " + distribution);
        final String targetArchive = targetDirectory + "/" + serverName + ".zip";
        final Execution<File> download =
            Spacelift.task(DownloadTool.class).from(distribution).to(targetArchive).execute();
        try {
            while (!download.isFinished()) {
                System.out.print(PROGRESS_INDICATOR);
                Thread.sleep(HALF_A_SECOND);
            }
            System.out.print(PROGRESS_INDICATOR);

            final File compressedServer = download.await();
            ShrinkWrap.create(ZipImporter.class, serverName)
                .importFrom(compressedServer)
                .as(ExplodedExporter.class)
                .exportExploded(targetDirectory, ".");
            compressedServer.delete();
            return getDistributionHome(targetDirectory);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private File fetchFromMavenRepository(ExecutorService executor) {
// Path: arquillian-chameleon-container-model/src/main/java/org/arquillian/container/chameleon/spi/model/ContainerAdapter.java
// public class ContainerAdapter {
// 
//     private String version;
//     private Target.Type targetType;
//     private Adapter adapter;
//     private Dist dist;
//     private String[] gavExcludeExpression;
//     private String defaultProtocol;
// 
//     public ContainerAdapter(String version, Target.Type targetType, Adapter adapter, Dist dist,
//         String[] gavExcludeExpression, String defaultProtocol) {
//         this.version = version;
//         this.targetType = targetType;
//         this.adapter = adapter;
//         this.dist = dist;
//         this.gavExcludeExpression = gavExcludeExpression;
//         this.defaultProtocol = defaultProtocol;
//     }
// 
//     public Target.Type type() {
//         return targetType;
//     }
// 
//     public boolean overrideDefaultProtocol() {
//         return this.defaultProtocol != null;
//     }
// 
//     public String getDefaultProtocol() {
//         return defaultProtocol;
//     }
// 
//     public String adapterClass() {
//         return adapter.adapterClass();
//     }
// 
//     public String[] dependencies() {
//         return resolve(adapter.dependencies());
//     }
// 
//     public String distribution() {
//         return resolve(dist.coordinates());
//     }
// 
//     public String[] excludes() {
//         return resolve(gavExcludeExpression);
//     }
// 
//     public String[] configurationKeys() {
//         return adapter.configuration().keySet().toArray(new String[] {});
//     }
// 
//     public boolean requireDistribution() {
//         return adapter.requireDist();
//     }
// 
//     public Map<String, String> resolveConfiguration(Map<String, String> parameters) {
//         Map<String, String> configuration = adapter.configuration();
//         for (Map.Entry<String, String> entry : configuration.entrySet()) {
//             for (Map.Entry<String, String> parameter : parameters.entrySet()) {
//                 entry.setValue(resolve(parameter.getKey(), parameter.getValue(), entry.getValue()));
//             }
//         }
//         return configuration;
//     }
// 
//     private String[] resolve(String[] values) {
//         if (values == null) {
//             return new String[0];
//         }
//         String[] resolved = new String[values.length];
//         for (int i = 0; i < values.length; i++) {
//             resolved[i] = resolve(values[i]);
//         }
//         return resolved;
//     }
// 
//     private String resolve(String value) {
//         return resolve("version", version, value);
//     }
// 
//     private String resolve(String parameter, String value, String target) {
//         return target.replaceAll(Pattern.quote("${" + parameter + "}"), Matcher.quoteReplacement(value));
//     }
// }
// 
// Path: arquillian-chameleon-container-model/src/main/java/org/arquillian/container/chameleon/spi/model/Target.java
// public enum Type {
//     Remote, Managed, Embedded, Default;
// 
//     public static Type from(String name) {
//         for (Type type : Type.values()) {
//             if (type.name().equalsIgnoreCase(name)) {
//                 return type;
//             }
//         }
//         return null;
//     }
// 
// }
// 
// Path: arquillian-chameleon-extension/src/main/java/org/arquillian/container/chameleon/Utils.java
// public static MavenCoordinate toMavenCoordinate(String dep) {
//     return MavenCoordinates.createCoordinate(dep);
// }


// Path: arquillian-chameleon-extension/src/main/java/org/arquillian/container/chameleon/controller/DistributionController.java
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import org.arquillian.container.chameleon.spi.model.ContainerAdapter;
import org.arquillian.container.chameleon.spi.model.Target.Type;
import org.arquillian.spacelift.Spacelift;
import org.arquillian.spacelift.execution.Execution;
import org.arquillian.spacelift.task.net.DownloadTool;
import org.jboss.arquillian.config.descriptor.api.ContainerDef;
import org.jboss.arquillian.core.api.threading.ExecutorService;
import org.jboss.shrinkwrap.api.GenericArchive;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.exporter.ExplodedExporter;
import org.jboss.shrinkwrap.api.importer.ZipImporter;
import org.jboss.shrinkwrap.resolver.api.maven.Maven;
import org.jboss.shrinkwrap.resolver.api.maven.coordinate.MavenCoordinate;
import static org.arquillian.container.chameleon.Utils.toMavenCoordinate;

            serverName);

        if (serverAlreadyDownloaded(targetDirectory)) {
            return getDistributionHome(targetDirectory);
        }

        System.out.println("Arquillian Chameleon: downloading distribution from " + distribution);
        final String targetArchive = targetDirectory + "/" + serverName + ".zip";
        final Execution<File> download =
            Spacelift.task(DownloadTool.class).from(distribution).to(targetArchive).execute();
        try {
            while (!download.isFinished()) {
                System.out.print(PROGRESS_INDICATOR);
                Thread.sleep(HALF_A_SECOND);
            }
            System.out.print(PROGRESS_INDICATOR);

            final File compressedServer = download.await();
            ShrinkWrap.create(ZipImporter.class, serverName)
                .importFrom(compressedServer)
                .as(ExplodedExporter.class)
                .exportExploded(targetDirectory, ".");
            compressedServer.delete();
            return getDistributionHome(targetDirectory);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    private File fetchFromMavenRepository(ExecutorService executor) {
        final MavenCoordinate distributableCoordinate = toMavenCoordinate(targetAdapter.distribution());