/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed 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
 *
 *      http://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 com.android.build.gradle

import com.android.annotations.NonNull
import com.android.annotations.Nullable
import com.android.build.gradle.api.AndroidSourceSet
import com.android.build.gradle.api.BaseVariant
import com.android.build.gradle.internal.BadPluginException
import com.android.build.gradle.internal.LoggerWrapper
import com.android.build.gradle.internal.ProductFlavorData
import com.android.build.gradle.internal.Sdk
import com.android.build.gradle.internal.api.DefaultAndroidSourceSet
import com.android.build.gradle.internal.dependency.DependencyChecker
import com.android.build.gradle.internal.dependency.LibraryDependencyImpl
import com.android.build.gradle.internal.dependency.ManifestDependencyImpl
import com.android.build.gradle.internal.dependency.SymbolFileProviderImpl
import com.android.build.gradle.internal.dependency.VariantDependencies
import com.android.build.gradle.internal.dsl.SigningConfigDsl
import com.android.build.gradle.internal.model.ArtifactMetaDataImpl
import com.android.build.gradle.internal.model.JavaArtifactImpl
import com.android.build.gradle.internal.model.ModelBuilder
import com.android.build.gradle.internal.tasks.AndroidReportTask
import com.android.build.gradle.internal.tasks.DependencyReportTask
import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestLibraryTask
import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
import com.android.build.gradle.internal.tasks.InstallTask
import com.android.build.gradle.internal.tasks.OutputFileTask
import com.android.build.gradle.internal.tasks.PrepareDependenciesTask
import com.android.build.gradle.internal.tasks.PrepareLibraryTask
import com.android.build.gradle.internal.tasks.SigningReportTask
import com.android.build.gradle.internal.tasks.TestServerTask
import com.android.build.gradle.internal.tasks.UninstallTask
import com.android.build.gradle.internal.tasks.ValidateSigningTask
import com.android.build.gradle.internal.test.report.ReportType
import com.android.build.gradle.internal.variant.ApkVariantData
import com.android.build.gradle.internal.variant.ApplicationVariantData
import com.android.build.gradle.internal.variant.BaseVariantData
import com.android.build.gradle.internal.variant.DefaultSourceProviderContainer
import com.android.build.gradle.internal.variant.LibraryVariantData
import com.android.build.gradle.internal.variant.TestVariantData
import com.android.build.gradle.internal.variant.TestedVariantData
import com.android.build.gradle.tasks.AidlCompile
import com.android.build.gradle.tasks.Dex
import com.android.build.gradle.tasks.GenerateBuildConfig
import com.android.build.gradle.tasks.Lint
import com.android.build.gradle.tasks.MergeAssets
import com.android.build.gradle.tasks.MergeResources
import com.android.build.gradle.tasks.NdkCompile
import com.android.build.gradle.tasks.PackageApplication
import com.android.build.gradle.tasks.PreDex
import com.android.build.gradle.tasks.ProcessAndroidResources
import com.android.build.gradle.tasks.ProcessAppManifest
import com.android.build.gradle.tasks.ProcessTestManifest
import com.android.build.gradle.tasks.RenderscriptCompile
import com.android.build.gradle.tasks.ZipAlign
import com.android.builder.AndroidBuilder
import com.android.builder.DefaultProductFlavor
import com.android.builder.SdkParser
import com.android.builder.VariantConfiguration
import com.android.builder.dependency.JarDependency
import com.android.builder.dependency.LibraryDependency
import com.android.builder.model.AndroidArtifact
import com.android.builder.model.AndroidProject
import com.android.builder.model.ArtifactMetaData
import com.android.builder.model.BuildType
import com.android.builder.model.JavaArtifact
import com.android.builder.model.ProductFlavor
import com.android.builder.model.SigningConfig
import com.android.builder.model.SourceProvider
import com.android.builder.model.SourceProviderContainer
import com.android.builder.testing.ConnectedDeviceProvider
import com.android.builder.testing.api.DeviceProvider
import com.android.builder.testing.api.TestServer
import com.android.utils.ILogger
import com.google.common.collect.ArrayListMultimap
import com.google.common.collect.ListMultimap
import com.google.common.collect.Lists
import com.google.common.collect.Maps
import com.google.common.collect.Multimap
import com.google.common.collect.Sets
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.artifacts.Configuration
import org.gradle.api.artifacts.ModuleVersionIdentifier
import org.gradle.api.artifacts.ProjectDependency
import org.gradle.api.artifacts.ResolvedArtifact
import org.gradle.api.artifacts.SelfResolvingDependency
import org.gradle.api.artifacts.result.DependencyResult
import org.gradle.api.artifacts.result.ResolvedDependencyResult
import org.gradle.api.artifacts.result.ResolvedModuleVersionResult
import org.gradle.api.artifacts.result.UnresolvedDependencyResult
import org.gradle.api.logging.LogLevel
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPlugin
import org.gradle.api.specs.Specs
import org.gradle.api.tasks.Copy
import org.gradle.api.tasks.compile.JavaCompile
import org.gradle.internal.reflect.Instantiator
import org.gradle.language.jvm.tasks.ProcessResources
import org.gradle.tooling.BuildException
import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
import org.gradle.util.GUtil
import proguard.gradle.ProGuardTask

import java.util.jar.Attributes
import java.util.jar.Manifest

import static com.android.builder.BuilderConstants.CONNECTED
import static com.android.builder.BuilderConstants.DEVICE
import static com.android.builder.BuilderConstants.EXT_LIB_ARCHIVE
import static com.android.builder.BuilderConstants.FD_FLAVORS
import static com.android.builder.BuilderConstants.FD_FLAVORS_ALL
import static com.android.builder.BuilderConstants.FD_INSTRUMENT_RESULTS
import static com.android.builder.BuilderConstants.FD_INSTRUMENT_TESTS
import static com.android.builder.BuilderConstants.FD_REPORTS
import static com.android.builder.BuilderConstants.INSTRUMENT_TEST
import static java.io.File.separator

/**
 * Base class for all Android plugins
 */
public abstract class BasePlugin {
    protected final static String DIR_BUNDLES = "bundles";

    public static final String GRADLE_MIN_VERSION = "1.9"
    public static final String[] GRADLE_SUPPORTED_VERSIONS = [ GRADLE_MIN_VERSION ]

    public static final String INSTALL_GROUP = "Install"

    public static File TEST_SDK_DIR;

    protected Instantiator instantiator
    private ToolingModelBuilderRegistry registry

    private final Map<Object, AndroidBuilder> builders = Maps.newIdentityHashMap()

    final List<BaseVariantData> variantDataList = []
    final Map<LibraryDependencyImpl, PrepareLibraryTask> prepareTaskMap = [:]
    final Map<SigningConfig, ValidateSigningTask> validateSigningTaskMap = [:]

    protected Project project
    private LoggerWrapper loggerWrapper
    private Sdk sdk
    private String creator

    private boolean hasCreatedTasks = false

    private ProductFlavorData<DefaultProductFlavor> defaultConfigData
    private final Collection<String> unresolvedDependencies = Sets.newHashSet();

    protected DefaultAndroidSourceSet mainSourceSet
    protected DefaultAndroidSourceSet testSourceSet

    protected Task mainPreBuild
    protected Task uninstallAll
    protected Task assembleTest
    protected Task deviceCheck
    protected Task connectedCheck
    protected Task lint
    protected Task lintCompile

    protected BasePlugin(Instantiator instantiator, ToolingModelBuilderRegistry registry) {
        this.instantiator = instantiator
        this.registry = registry
        String pluginVersion = getLocalVersion()
        if (pluginVersion != null) {
            creator = "Android Gradle " + pluginVersion
        } else  {
            creator = "Android Gradle"
        }
    }

    protected abstract BaseExtension getExtension()
    protected abstract void doCreateAndroidTasks()

    protected void apply(Project project) {
        this.project = project

        checkGradleVersion()
        sdk = new Sdk(project, logger)

        project.apply plugin: JavaBasePlugin

        // Register a builder for the custom tooling model
        registry.register(new ModelBuilder());

        project.tasks.assemble.description =
            "Assembles all variants of all applications and secondary packages."

        uninstallAll = project.tasks.create("uninstallAll")
        uninstallAll.description = "Uninstall all applications."
        uninstallAll.group = INSTALL_GROUP

        deviceCheck = project.tasks.create("deviceCheck")
        deviceCheck.description = "Runs all device checks using Device Providers and Test Servers."
        deviceCheck.group = JavaBasePlugin.VERIFICATION_GROUP

        connectedCheck = project.tasks.create("connectedCheck")
        connectedCheck.description = "Runs all device checks on currently connected devices."
        connectedCheck.group = JavaBasePlugin.VERIFICATION_GROUP

        mainPreBuild = project.tasks.create("preBuild")

        lint = project.tasks.create("lint", Lint)
        lint.description = "Runs lint on all variants."
        lint.group = JavaBasePlugin.VERIFICATION_GROUP
        lint.setPlugin(this)
        int count = variantDataList.size()
        for (int i = 0 ; i < count ; i++) {
            final BaseVariantData baseVariantData = variantDataList.get(i)
            if (isLintVariant(baseVariantData)) {
                lint.dependsOn baseVariantData.javaCompileTask
            }
        }
        project.tasks.check.dependsOn lint

        project.afterEvaluate {
            createAndroidTasks(false)
        }
    }

    protected void setBaseExtension(@NonNull BaseExtension extension) {
        sdk.setExtension(extension)
        mainSourceSet = (DefaultAndroidSourceSet) extension.sourceSets.create(extension.defaultConfig.name)
        testSourceSet = (DefaultAndroidSourceSet) extension.sourceSets.create(INSTRUMENT_TEST)

        defaultConfigData = new ProductFlavorData<DefaultProductFlavor>(
                extension.defaultConfig, mainSourceSet,
                testSourceSet, project)
    }

    private void checkGradleVersion() {
        boolean foundMatch = false
        for (String version : GRADLE_SUPPORTED_VERSIONS) {
            if (project.getGradle().gradleVersion.startsWith(version)) {
                foundMatch = true
                break
            }
        }

        if (!foundMatch) {
            File file = new File("gradle" + separator + "wrapper" + separator +
                    "gradle-wrapper.properties");
            throw new BuildException(
                String.format(
                    "Gradle version %s is required. Current version is %s. " +
                    "If using the gradle wrapper, try editing the distributionUrl in %s " +
                    "to gradle-%s-all.zip",
                    GRADLE_MIN_VERSION, project.getGradle().gradleVersion, file.getAbsolutePath(),
                    GRADLE_MIN_VERSION), null);

        }
    }

    final void createAndroidTasks(boolean force) {
        // get current plugins and look for the default Java plugin.
        if (project.plugins.hasPlugin(JavaPlugin.class)) {
            throw new BadPluginException(
                    "The 'java' plugin has been applied, but it is not compatible with the Android plugins.")
        }

        // don't do anything if the project was not initialized.
        // Unless TEST_SDK_DIR is set in which case this is unit tests and we don't return.
        // This is because project don't get evaluated in the unit test setup.
        // See AppPluginDslTest
        if (!force && (!project.state.executed || project.state.failure != null) && TEST_SDK_DIR == null) {
            return
        }

        if (hasCreatedTasks) {
            return
        }
        hasCreatedTasks = true

        doCreateAndroidTasks()
        createReportTasks()
    }

    void checkTasksAlreadyCreated() {
        if (hasCreatedTasks) {
            throw new GradleException(
                    "Android tasks have already been created.\n" +
                    "This happens when calling android.applicationVariants,\n" +
                    "android.libraryVariants or android.testVariants.\n" +
                    "Once these methods are called, it is not possible to\n" +
                    "continue configuring the model.")
        }
    }


    ProductFlavorData getDefaultConfigData() {
        return defaultConfigData
    }

    Collection<String> getUnresolvedDependencies() {
        return unresolvedDependencies
    }

    SdkParser getSdkParser() {
        return sdk.parser
    }

    SdkParser getLoadedSdkParser() {
        return sdk.loadParser()
    }

    File getSdkDirectory() {
        return sdk.sdkDirectory
    }

    File getNdkDirectory() {
        return sdk.ndkDirectory
    }

    ILogger getLogger() {
        if (loggerWrapper == null) {
            loggerWrapper = new LoggerWrapper(project.logger)
        }

        return loggerWrapper
    }

    boolean isVerbose() {
        return project.logger.isEnabled(LogLevel.DEBUG)
    }

    AndroidBuilder getAndroidBuilder(BaseVariantData variantData) {
        AndroidBuilder androidBuilder = builders.get(variantData)

        if (androidBuilder == null) {
            SdkParser parser = getLoadedSdkParser()
            androidBuilder = new AndroidBuilder(parser, creator, logger, verbose)
            if (this instanceof LibraryPlugin) {
                androidBuilder.setBuildingLibrary(true);
            }

            builders.put(variantData, androidBuilder)
        }

        return androidBuilder
    }


    protected String getRuntimeJars() {
        return runtimeJarList.join(File.pathSeparator)
    }

    public List<String> getRuntimeJarList() {
        SdkParser sdkParser = getLoadedSdkParser()
        return AndroidBuilder.getBootClasspath(sdkParser);
    }

    protected void createProcessManifestTask(BaseVariantData variantData,
                                             String manifestOurDir) {
        def processManifestTask = project.tasks.create(
                "process${variantData.variantConfiguration.fullName.capitalize()}Manifest",
                ProcessAppManifest)
        variantData.processManifestTask = processManifestTask
        processManifestTask.dependsOn variantData.prepareDependenciesTask

        processManifestTask.plugin = this
        processManifestTask.variant = variantData

        VariantConfiguration config = variantData.variantConfiguration
        ProductFlavor mergedFlavor = config.mergedFlavor

        processManifestTask.conventionMapping.mainManifest = {
            config.mainManifest
        }
        processManifestTask.conventionMapping.manifestOverlays = {
            config.manifestOverlays
        }
        processManifestTask.conventionMapping.packageNameOverride = {
            config.packageOverride
        }
        processManifestTask.conventionMapping.versionName = {
            config.versionName
        }
        processManifestTask.conventionMapping.libraries = {
            getManifestDependencies(config.directLibraries)
        }
        processManifestTask.conventionMapping.versionCode = {
            config.versionCode
        }
        processManifestTask.conventionMapping.minSdkVersion = {
            mergedFlavor.minSdkVersion
        }
        processManifestTask.conventionMapping.targetSdkVersion = {
            mergedFlavor.targetSdkVersion
        }
        processManifestTask.conventionMapping.manifestOutputFile = {
            project.file(
                    "$project.buildDir/${manifestOurDir}/${variantData.variantConfiguration.dirName}/AndroidManifest.xml")
        }
    }

    protected void createProcessTestManifestTask(BaseVariantData variantData,
                                                 String manifestOurDir) {
        def processTestManifestTask = project.tasks.create(
                "process${variantData.variantConfiguration.fullName.capitalize()}Manifest",
                ProcessTestManifest)
        variantData.processManifestTask = processTestManifestTask
        processTestManifestTask.dependsOn variantData.prepareDependenciesTask

        processTestManifestTask.plugin = this
        processTestManifestTask.variant = variantData

        VariantConfiguration config = variantData.variantConfiguration

        processTestManifestTask.conventionMapping.testPackageName = {
            config.packageName
        }
        processTestManifestTask.conventionMapping.minSdkVersion = {
            config.minSdkVersion
        }
        processTestManifestTask.conventionMapping.targetSdkVersion = {
            config.targetSdkVersion
        }
        processTestManifestTask.conventionMapping.testedPackageName = {
            config.testedPackageName
        }
        processTestManifestTask.conventionMapping.instrumentationRunner = {
            config.instrumentationRunner
        }
        processTestManifestTask.conventionMapping.handleProfiling = {
            config.handleProfiling
        }
        processTestManifestTask.conventionMapping.functionalTest = {
            config.functionalTest
        }
        processTestManifestTask.conventionMapping.libraries = {
            getManifestDependencies(config.directLibraries)
        }
        processTestManifestTask.conventionMapping.manifestOutputFile = {
            project.file(
                    "$project.buildDir/${manifestOurDir}/${variantData.variantConfiguration.dirName}/AndroidManifest.xml")
        }
    }

    protected void createRenderscriptTask(BaseVariantData variantData) {
        VariantConfiguration config = variantData.variantConfiguration

        def renderscriptTask = project.tasks.create(
                "compile${variantData.variantConfiguration.fullName.capitalize()}Renderscript",
                RenderscriptCompile)
        variantData.renderscriptCompileTask = renderscriptTask

        ProductFlavor mergedFlavor = config.mergedFlavor
        boolean ndkMode = mergedFlavor.renderscriptNdkMode

        // only put this dependency if rs will generate Java code
        if (!ndkMode) {
            variantData.sourceGenTask.dependsOn renderscriptTask
        }

        renderscriptTask.dependsOn variantData.prepareDependenciesTask
        renderscriptTask.plugin = this
        renderscriptTask.variant = variantData

        renderscriptTask.targetApi = mergedFlavor.renderscriptTargetApi
        renderscriptTask.supportMode = mergedFlavor.renderscriptSupportMode
        renderscriptTask.ndkMode = ndkMode
        renderscriptTask.debugBuild = config.buildType.renderscriptDebugBuild
        renderscriptTask.optimLevel = config.buildType.renderscriptOptimLevel

        renderscriptTask.conventionMapping.sourceDirs = { config.renderscriptSourceList }
        renderscriptTask.conventionMapping.importDirs = { config.renderscriptImports }

        renderscriptTask.conventionMapping.sourceOutputDir = {
            project.file("$project.buildDir/source/rs/${variantData.variantConfiguration.dirName}")
        }
        renderscriptTask.conventionMapping.resOutputDir = {
            project.file("$project.buildDir/res/rs/${variantData.variantConfiguration.dirName}")
        }
        renderscriptTask.conventionMapping.objOutputDir = {
            project.file("$project.buildDir/rs/${variantData.variantConfiguration.dirName}/obj")
        }
        renderscriptTask.conventionMapping.libOutputDir = {
            project.file("$project.buildDir/rs/${variantData.variantConfiguration.dirName}/lib")
        }
        renderscriptTask.conventionMapping.ndkConfig = { config.ndkConfig }
    }

    protected void createMergeResourcesTask(@NonNull BaseVariantData variantData,
                                            final boolean process9Patch) {
        MergeResources mergeResourcesTask = basicCreateMergeResourcesTask(
                variantData,
                "merge",
                "$project.buildDir/res/all/${variantData.variantConfiguration.dirName}",
                true /*includeDependencies*/,
                process9Patch)
        variantData.mergeResourcesTask = mergeResourcesTask
    }

    protected MergeResources basicCreateMergeResourcesTask(
            @NonNull BaseVariantData variantData,
            @NonNull String taskNamePrefix,
            @NonNull String outputLocation,
            final boolean includeDependencies,
            final boolean process9Patch) {
        MergeResources mergeResourcesTask = project.tasks.create(
                "$taskNamePrefix${variantData.variantConfiguration.fullName.capitalize()}Resources",
                MergeResources)

        mergeResourcesTask.dependsOn variantData.prepareDependenciesTask, variantData.renderscriptCompileTask
        mergeResourcesTask.plugin = this
        mergeResourcesTask.variant = variantData
        mergeResourcesTask.incrementalFolder = project.file(
                "$project.buildDir/incremental/${taskNamePrefix}Resources/${variantData.variantConfiguration.dirName}")

        mergeResourcesTask.process9Patch = process9Patch

        mergeResourcesTask.conventionMapping.inputResourceSets = {
            variantData.variantConfiguration.getResourceSets(
                    variantData.renderscriptCompileTask.getResOutputDir(),
                    includeDependencies)
        }

        mergeResourcesTask.conventionMapping.outputDir = { project.file(outputLocation) }

        return mergeResourcesTask
    }

    protected void createMergeAssetsTask(@NonNull BaseVariantData variantData,
                                         @Nullable String outputLocation,
                                         final boolean includeDependencies) {
        if (outputLocation == null) {
            outputLocation = "$project.buildDir/assets/${variantData.variantConfiguration.dirName}"
        }

        def mergeAssetsTask = project.tasks.create(
                "merge${variantData.variantConfiguration.fullName.capitalize()}Assets",
                MergeAssets)
        variantData.mergeAssetsTask = mergeAssetsTask

        mergeAssetsTask.dependsOn variantData.prepareDependenciesTask
        mergeAssetsTask.plugin = this
        mergeAssetsTask.variant = variantData
        mergeAssetsTask.incrementalFolder =
                project.file("$project.buildDir/incremental/mergeAssets/${variantData.variantConfiguration.dirName}")

        mergeAssetsTask.conventionMapping.inputAssetSets = {
            variantData.variantConfiguration.getAssetSets(includeDependencies)
        }
        mergeAssetsTask.conventionMapping.outputDir = { project.file(outputLocation) }
    }

    protected void createBuildConfigTask(BaseVariantData variantData) {
        def generateBuildConfigTask = project.tasks.create(
                "generate${variantData.variantConfiguration.fullName.capitalize()}BuildConfig",
                GenerateBuildConfig)
        variantData.generateBuildConfigTask = generateBuildConfigTask

        VariantConfiguration variantConfiguration = variantData.variantConfiguration

        variantData.sourceGenTask.dependsOn generateBuildConfigTask
        if (variantConfiguration.type == VariantConfiguration.Type.TEST) {
            // in case of a test project, the manifest is generated so we need to depend
            // on its creation.
            generateBuildConfigTask.dependsOn variantData.processManifestTask
        }

        generateBuildConfigTask.plugin = this
        generateBuildConfigTask.variant = variantData

        generateBuildConfigTask.conventionMapping.buildConfigPackageName = {
            variantConfiguration.originalPackageName
        }

        generateBuildConfigTask.conventionMapping.appPackageName = {
            variantConfiguration.packageName
        }

        generateBuildConfigTask.conventionMapping.versionName = {
            variantConfiguration.versionName
        }

        generateBuildConfigTask.conventionMapping.versionCode = {
            variantConfiguration.versionCode
        }

        generateBuildConfigTask.conventionMapping.debuggable = {
            variantConfiguration.buildType.isDebuggable()
        }

        generateBuildConfigTask.conventionMapping.buildTypeName = {
            variantConfiguration.buildType.name
        }

        generateBuildConfigTask.conventionMapping.flavorName = {
            variantConfiguration.flavorName
        }

        generateBuildConfigTask.conventionMapping.flavorNamesWithDimensionNames = {
            variantConfiguration.flavorNamesWithDimensionNames
        }

        generateBuildConfigTask.conventionMapping.items = {
            variantConfiguration.buildConfigItems
        }

        generateBuildConfigTask.conventionMapping.sourceOutputDir = {
            project.file("$project.buildDir/source/buildConfig/${variantData.variantConfiguration.dirName}")
        }
    }

    protected void createProcessResTask(BaseVariantData variantData) {
        createProcessResTask(variantData, "$project.buildDir/symbols/${variantData.variantConfiguration.dirName}")
    }

    protected void createProcessResTask(BaseVariantData variantData, final String symbolLocation) {
        def processResources = project.tasks.create(
                "process${variantData.variantConfiguration.fullName.capitalize()}Resources",
                ProcessAndroidResources)
        variantData.processResourcesTask = processResources

        variantData.sourceGenTask.dependsOn processResources
        processResources.dependsOn variantData.processManifestTask, variantData.mergeResourcesTask, variantData.mergeAssetsTask

        processResources.plugin = this
        processResources.variant = variantData

        VariantConfiguration variantConfiguration = variantData.variantConfiguration

        processResources.conventionMapping.manifestFile = {
            variantData.processManifestTask.manifestOutputFile
        }

        processResources.conventionMapping.resDir = {
            variantData.mergeResourcesTask.outputDir
        }

        processResources.conventionMapping.assetsDir =  {
            variantData.mergeAssetsTask.outputDir
        }

        processResources.conventionMapping.libraries = {
            getTextSymbolDependencies(variantConfiguration.allLibraries)
        }
        processResources.conventionMapping.packageForR = {
            variantConfiguration.originalPackageName
        }

        // TODO: unify with generateBuilderConfig, compileAidl, and library packaging somehow?
        processResources.conventionMapping.sourceOutputDir = {
            project.file("$project.buildDir/source/r/${variantData.variantConfiguration.dirName}")
        }
        processResources.conventionMapping.textSymbolOutputDir = {
            project.file(symbolLocation)
        }
        processResources.conventionMapping.packageOutputFile = {
            project.file(
                    "$project.buildDir/libs/${project.archivesBaseName}-${variantData.variantConfiguration.baseName}.ap_")
        }
        if (variantConfiguration.buildType.runProguard) {
            processResources.conventionMapping.proguardOutputFile = {
                project.file("$project.buildDir/proguard/${variantData.variantConfiguration.dirName}/aapt_rules.txt")
            }
        }

        processResources.conventionMapping.type = { variantConfiguration.type }
        processResources.conventionMapping.debuggable = { variantConfiguration.buildType.debuggable }
        processResources.conventionMapping.aaptOptions = { extension.aaptOptions }
        processResources.conventionMapping.resourceConfigs = { variantConfiguration.mergedFlavor.resourceConfigurations }
    }

    protected void createProcessJavaResTask(BaseVariantData variantData) {
        VariantConfiguration variantConfiguration = variantData.variantConfiguration

        Copy processResources = project.tasks.create(
                "process${variantData.variantConfiguration.fullName.capitalize()}JavaRes",
                ProcessResources);
        variantData.processJavaResourcesTask = processResources

        // set the input
        processResources.from(((AndroidSourceSet) variantConfiguration.defaultSourceSet).resources)

        if (variantConfiguration.type != VariantConfiguration.Type.TEST) {
            processResources.from(
                    ((AndroidSourceSet) variantConfiguration.buildTypeSourceSet).resources)
        }
        if (variantConfiguration.hasFlavors()) {
            for (SourceProvider flavorSourceSet : variantConfiguration.flavorSourceProviders) {
                processResources.from(((AndroidSourceSet) flavorSourceSet).resources)
            }
        }

        processResources.conventionMapping.destinationDir = {
            project.file("$project.buildDir/javaResources/${variantData.variantConfiguration.dirName}")
        }
    }

    protected void createAidlTask(BaseVariantData variantData) {
        VariantConfiguration variantConfiguration = variantData.variantConfiguration

        def compileTask = project.tasks.create(
                "compile${variantData.variantConfiguration.fullName.capitalize()}Aidl",
                AidlCompile)
        variantData.aidlCompileTask = compileTask

        variantData.sourceGenTask.dependsOn compileTask
        variantData.aidlCompileTask.dependsOn variantData.prepareDependenciesTask

        compileTask.plugin = this
        compileTask.variant = variantData
        compileTask.incrementalFolder =
                project.file("$project.buildDir/incremental/aidl/${variantData.variantConfiguration.dirName}")

        compileTask.conventionMapping.sourceDirs = { variantConfiguration.aidlSourceList }
        compileTask.conventionMapping.importDirs = { variantConfiguration.aidlImports }

        compileTask.conventionMapping.sourceOutputDir = {
            project.file("$project.buildDir/source/aidl/${variantData.variantConfiguration.dirName}")
        }
    }

    protected void createCompileTask(BaseVariantData variantData,
                                     BaseVariantData testedVariantData) {
        def compileTask = project.tasks.create(
                "compile${variantData.variantConfiguration.fullName.capitalize()}Java",
                JavaCompile)
        variantData.javaCompileTask = compileTask
        compileTask.dependsOn variantData.sourceGenTask

        VariantConfiguration config = variantData.variantConfiguration

        List<Object> sourceList = Lists.newArrayList()
        sourceList.add(((AndroidSourceSet) config.defaultSourceSet).java)
        sourceList.add({ variantData.processResourcesTask.sourceOutputDir })
        sourceList.add({ variantData.generateBuildConfigTask.sourceOutputDir })
        sourceList.add({ variantData.aidlCompileTask.sourceOutputDir })
        if (!config.mergedFlavor.renderscriptNdkMode) {
            sourceList.add({ variantData.renderscriptCompileTask.sourceOutputDir })
        }

        if (config.getType() != VariantConfiguration.Type.TEST) {
            sourceList.add(((AndroidSourceSet) config.buildTypeSourceSet).java)
        }
        if (config.hasFlavors()) {
            for (SourceProvider flavorSourceProvider : config.flavorSourceProviders) {
                sourceList.add(((AndroidSourceSet) flavorSourceProvider).java)
            }
        }
        compileTask.source = sourceList.toArray()

        // if the tested variant is an app, add its classpath. For the libraries,
        // it's done automatically since the classpath includes the library output as a normal
        // dependency.
        if (testedVariantData instanceof ApplicationVariantData) {
            compileTask.conventionMapping.classpath =  {
                project.files(getAndroidBuilder(variantData).getCompileClasspath(config)) + testedVariantData.javaCompileTask.classpath + testedVariantData.javaCompileTask.outputs.files
            }
        } else {
            compileTask.conventionMapping.classpath =  {
                project.files(getAndroidBuilder(variantData).getCompileClasspath(config))
            }
        }

        // TODO - dependency information for the compile classpath is being lost.
        // Add a temporary approximation
        compileTask.dependsOn project.configurations.compile.buildDependencies

        compileTask.conventionMapping.destinationDir = {
            project.file("$project.buildDir/classes/${variantData.variantConfiguration.dirName}")
        }
        compileTask.conventionMapping.dependencyCacheDir = {
            project.file("$project.buildDir/dependency-cache/${variantData.variantConfiguration.dirName}")
        }

        // set source/target compatibility
        compileTask.conventionMapping.sourceCompatibility = {
            extension.compileOptions.sourceCompatibility.toString()
        }
        compileTask.conventionMapping.targetCompatibility = {
            extension.compileOptions.targetCompatibility.toString()
        }
        compileTask.options.encoding = extension.compileOptions.encoding

        // setup the boot classpath just before the task actually runs since this will
        // force the sdk to be parsed.
        compileTask.doFirst {
            compileTask.options.bootClasspath = getRuntimeJars()
        }
    }

    protected void createNdkTasks(@NonNull BaseVariantData variantData) {
        createNdkTasks(
                variantData,
                { project.file("$project.buildDir/ndk/${variantData.variantConfiguration.dirName}/lib") }
        )
    }

    protected void createNdkTasks(@NonNull BaseVariantData variantData,
                                  @NonNull Closure<File> soFolderClosure) {
        NdkCompile ndkCompile = project.tasks.create(
                "compile${variantData.variantConfiguration.fullName.capitalize()}Ndk",
                NdkCompile)

        ndkCompile.plugin = this
        ndkCompile.variant = variantData
        variantData.ndkCompileTask = ndkCompile

        VariantConfiguration variantConfig = variantData.variantConfiguration

        if (variantConfig.mergedFlavor.renderscriptNdkMode) {
            ndkCompile.ndkRenderScriptMode = true
            ndkCompile.dependsOn variantData.renderscriptCompileTask
        } else {
            ndkCompile.ndkRenderScriptMode = false
        }

        ndkCompile.conventionMapping.sourceFolders = {
            List<File> sourceList = variantConfig.jniSourceList
            if (variantConfig.mergedFlavor.renderscriptNdkMode) {
                sourceList.add(variantData.renderscriptCompileTask.sourceOutputDir)
            }

            return sourceList
        }

        ndkCompile.conventionMapping.generatedMakefile = {
            project.file("$project.buildDir/ndk/${variantData.variantConfiguration.dirName}/Android.mk")
        }

        ndkCompile.conventionMapping.ndkConfig = { variantConfig.ndkConfig }

        ndkCompile.conventionMapping.debuggable = {
            variantConfig.buildType.jniDebugBuild
        }

        ndkCompile.conventionMapping.objFolder = {
            project.file("$project.buildDir/ndk/${variantData.variantConfiguration.dirName}/obj")
        }
        ndkCompile.conventionMapping.soFolder = soFolderClosure
    }

    /**
     * Creates the tasks to build the test apk.
     *
     * @param variant the test variant
     * @param testedVariant the tested variant
     * @param configDependencies the list of config dependencies
     */
    protected void createTestApkTasks(@NonNull TestVariantData variantData,
                                      @NonNull BaseVariantData testedVariantData) {
        // The test app is signed with the same info as the tested app so there's no need
        // to test both.
        if (!variantData.isSigned()) {
            throw new GradleException(
                    "Tested Variant '${testedVariantData.variantConfiguration.fullName}' is not configured to create a signed APK.")
        }

        createAnchorTasks(variantData)

        // Add a task to process the manifest
        createProcessTestManifestTask(variantData, "manifests")

        // Add a task to compile renderscript files.
        createRenderscriptTask(variantData)

        // Add a task to merge the resource folders
        createMergeResourcesTask(variantData, true /*process9Patch*/)

        // Add a task to merge the assets folders
        createMergeAssetsTask(variantData, null /*default location*/, true /*includeDependencies*/)

        if (testedVariantData.variantConfiguration.type == VariantConfiguration.Type.LIBRARY) {
            // in this case the tested library must be fully built before test can be built!
            if (testedVariantData.assembleTask != null) {
                variantData.processManifestTask.dependsOn testedVariantData.assembleTask
                variantData.mergeResourcesTask.dependsOn testedVariantData.assembleTask
            }
        }

        // Add a task to create the BuildConfig class
        createBuildConfigTask(variantData)

        // Add a task to generate resource source files
        createProcessResTask(variantData)

        // process java resources
        createProcessJavaResTask(variantData)

        createAidlTask(variantData)

        // Add a task to compile the test application
        createCompileTask(variantData, testedVariantData)

        // Add NDK tasks
        createNdkTasks(variantData)

        addPackageTasks(variantData, null)

        if (assembleTest != null) {
            assembleTest.dependsOn variantData.assembleTask
        }
    }

    // TODO - should compile src/lint/java from src/lint/java and jar it into build/lint/lint.jar
    protected void createLintCompileTask() {
        lintCompile = project.tasks.create("compileLint", Task)
        File outputDir = new File("$project.buildDir/lint")

        lintCompile.doFirst{
            // create the directory for lint output if it does not exist.
            if (!outputDir.exists()) {
                boolean mkdirs = outputDir.mkdirs();
                if (!mkdirs) {
                    throw new GradleException("Unable to create lint output directory.")
                }
            }
        }
    }

    /** Is the given variant relevant for lint? */
    private static boolean isLintVariant(@NonNull BaseVariantData baseVariantData) {
        // Only create lint targets for variants like debug and release, not debugTest
        VariantConfiguration config = baseVariantData.variantConfiguration
        return config.getType() != VariantConfiguration.Type.TEST;
    }

    // Add tasks for running lint on individual variants. We've already added a
    // lint task earlier which runs on all variants.
    protected void createLintTasks() {
        int count = variantDataList.size()
        for (int i = 0 ; i < count ; i++) {
            final BaseVariantData baseVariantData = variantDataList.get(i)
            if (!isLintVariant(baseVariantData)) {
                continue;
            }

            String variantName = baseVariantData.variantConfiguration.fullName
            def capitalizedVariantName = variantName.capitalize()
            Task lintCheck = project.tasks.create("lint" + capitalizedVariantName, Lint)
            lintCheck.dependsOn baseVariantData.javaCompileTask, lintCompile
            // Note that we don't do "lint.dependsOn lintCheck"; the "lint" target will
            // on its own run through all variants (and compare results), it doesn't delegate
            // to the individual tasks (since it needs to coordinate data collection and
            // reporting)
            lintCheck.setPlugin(this)
            lintCheck.setVariantName(variantName)
            lintCheck.description = "Runs lint on the " + capitalizedVariantName + " build"
            lintCheck.group = JavaBasePlugin.VERIFICATION_GROUP
        }
    }

    protected void createCheckTasks(boolean hasFlavors, boolean isLibraryTest) {
        List<AndroidReportTask> reportTasks = Lists.newArrayListWithExpectedSize(2)

        List<DeviceProvider> providers = extension.deviceProviders
        List<TestServer> servers = extension.testServers

        Task mainConnectedTask = connectedCheck
        String connectedRootName = "${CONNECTED}${INSTRUMENT_TEST.capitalize()}"
        // if more than one flavor, create a report aggregator task and make this the parent
        // task for all new connected tasks.
        if (hasFlavors) {
            mainConnectedTask = project.tasks.create(connectedRootName, AndroidReportTask)
            mainConnectedTask.group = JavaBasePlugin.VERIFICATION_GROUP
            mainConnectedTask.description = "Installs and runs instrumentation tests for all flavors on connected devices."
            mainConnectedTask.reportType = ReportType.MULTI_FLAVOR
            connectedCheck.dependsOn mainConnectedTask

            mainConnectedTask.conventionMapping.resultsDir = {
                String rootLocation = extension.testOptions.resultsDir != null ?
                    extension.testOptions.resultsDir : "$project.buildDir/$FD_INSTRUMENT_RESULTS"

                project.file("$rootLocation/connected/$FD_FLAVORS_ALL")
            }
            mainConnectedTask.conventionMapping.reportsDir = {
                String rootLocation = extension.testOptions.reportDir != null ?
                    extension.testOptions.reportDir :
                    "$project.buildDir/$FD_REPORTS/$FD_INSTRUMENT_TESTS"

                project.file("$rootLocation/connected/$FD_FLAVORS_ALL")
            }

            reportTasks.add(mainConnectedTask)
        }

        Task mainProviderTask = deviceCheck
        // if more than one provider tasks, either because of several flavors, or because of
        // more than one providers, then create an aggregate report tasks for all of them.
        if (providers.size() > 1 || hasFlavors) {
            mainProviderTask = project.tasks.create("${DEVICE}${INSTRUMENT_TEST.capitalize()}",
                    AndroidReportTask)
            mainProviderTask.group = JavaBasePlugin.VERIFICATION_GROUP
            mainProviderTask.description = "Installs and runs instrumentation tests using all Device Providers."
            mainProviderTask.reportType = ReportType.MULTI_FLAVOR
            deviceCheck.dependsOn mainProviderTask

            mainProviderTask.conventionMapping.resultsDir = {
                String rootLocation = extension.testOptions.resultsDir != null ?
                    extension.testOptions.resultsDir : "$project.buildDir/$FD_INSTRUMENT_RESULTS"

                project.file("$rootLocation/devices/$FD_FLAVORS_ALL")
            }
            mainProviderTask.conventionMapping.reportsDir = {
                String rootLocation = extension.testOptions.reportDir != null ?
                    extension.testOptions.reportDir :
                    "$project.buildDir/$FD_REPORTS/$FD_INSTRUMENT_TESTS"

                project.file("$rootLocation/devices/$FD_FLAVORS_ALL")
            }

            reportTasks.add(mainProviderTask)
        }

        // now look for the testedvariant and create the check tasks for them.
        // don't use an auto loop as we can't reuse baseVariantData or the closure lower
        // gets broken.
        int count = variantDataList.size();
        for (int i = 0 ; i < count ; i++) {
            final BaseVariantData baseVariantData = variantDataList.get(i);
            if (baseVariantData instanceof TestedVariantData) {
                final TestVariantData testVariantData = ((TestedVariantData) baseVariantData).testVariantData
                if (testVariantData == null) {
                    continue
                }

                // create the check tasks for this test

                // first the connected one.
                def connectedTask = createDeviceProviderInstrumentTestTask(
                        hasFlavors ?
                            "${connectedRootName}${baseVariantData.variantConfiguration.fullName.capitalize()}" : connectedRootName,
                        "Installs and runs the tests for Build '${baseVariantData.variantConfiguration.fullName}' on connected devices.",
                        isLibraryTest ?
                            DeviceProviderInstrumentTestLibraryTask :
                            DeviceProviderInstrumentTestTask,
                        testVariantData,
                        baseVariantData,
                        new ConnectedDeviceProvider(getSdkParser()),
                        CONNECTED
                )

                mainConnectedTask.dependsOn connectedTask
                testVariantData.connectedTestTask = connectedTask

                // now the providers.
                for (DeviceProvider deviceProvider : providers) {
                    DefaultTask providerTask = createDeviceProviderInstrumentTestTask(
                            hasFlavors ?
                                "${deviceProvider.name}${INSTRUMENT_TEST.capitalize()}${baseVariantData.variantConfiguration.fullName.capitalize()}" :
                                "${deviceProvider.name}${INSTRUMENT_TEST.capitalize()}",
                            "Installs and runs the tests for Build '${baseVariantData.variantConfiguration.fullName}' using Provider '${deviceProvider.name.capitalize()}'.",
                            isLibraryTest ?
                                DeviceProviderInstrumentTestLibraryTask :
                                DeviceProviderInstrumentTestTask,
                            testVariantData,
                            baseVariantData,
                            deviceProvider,
                            "$DEVICE/$deviceProvider.name"
                    )

                    mainProviderTask.dependsOn providerTask
                    testVariantData.providerTestTaskList.add(providerTask)

                    if (!deviceProvider.isConfigured()) {
                        providerTask.enabled = false;
                    }
                }

                // now the test servers
                // don't use an auto loop as it'll break the closure inside.
                for (TestServer testServer : servers) {
                    DefaultTask serverTask = project.tasks.create(
                            hasFlavors ?
                                "${testServer.name}${"upload".capitalize()}${baseVariantData.variantConfiguration.fullName}" :
                                "${testServer.name}${"upload".capitalize()}",
                            TestServerTask)
                    serverTask.description = "Uploads APKs for Build '${baseVariantData.variantConfiguration.fullName}' to Test Server '${testServer.name.capitalize()}'."
                    serverTask.group = JavaBasePlugin.VERIFICATION_GROUP
                    serverTask.dependsOn testVariantData.assembleTask, baseVariantData.assembleTask

                    serverTask.testServer = testServer

                    serverTask.conventionMapping.testApk = { testVariantData.outputFile }
                    if (!(baseVariantData instanceof LibraryVariantData)) {
                        serverTask.conventionMapping.testedApk = { baseVariantData.outputFile }
                    }

                    serverTask.conventionMapping.variantName = { baseVariantData.variantConfiguration.fullName }

                    deviceCheck.dependsOn serverTask

                    if (!testServer.isConfigured()) {
                        serverTask.enabled = false;
                    }
                }
            }
        }

        // If gradle is launched with --continue, we want to run all tests and generate an
        // aggregate report (to help with the fact that we may have several build variants, or
        // or several device providers).
        // To do that, the report tasks must run even if one of their dependent tasks (flavor
        // or specific provider tasks) fails, when --continue is used, and the report task is
        // meant to run (== is in the task graph).
        // To do this, we make the children tasks ignore their errors (ie they won't fail and
        // stop the build).
        if (!reportTasks.isEmpty() && project.gradle.startParameter.continueOnFailure) {
            project.gradle.taskGraph.whenReady { taskGraph ->
                for (AndroidReportTask reportTask : reportTasks) {
                    if (taskGraph.hasTask(reportTask)) {
                        reportTask.setWillRun()
                    }
                }
            }
        }
    }

    private DeviceProviderInstrumentTestTask createDeviceProviderInstrumentTestTask(
            @NonNull String taskName,
            @NonNull String description,
            @NonNull Class<? extends DeviceProviderInstrumentTestTask> taskClass,
            @NonNull TestVariantData variantData,
            @NonNull BaseVariantData testedVariantData,
            @NonNull DeviceProvider deviceProvider,
            @NonNull String subFolder) {

        def testTask = project.tasks.create(taskName, taskClass)
        testTask.description = description
        testTask.group = JavaBasePlugin.VERIFICATION_GROUP
        testTask.dependsOn testedVariantData.assembleTask, variantData.assembleTask

        testTask.plugin = this
        testTask.variant = variantData
        testTask.flavorName = variantData.variantConfiguration.flavorName.capitalize()
        testTask.deviceProvider = deviceProvider

        testTask.conventionMapping.testApp = { variantData.outputFile }
        if (testedVariantData.variantConfiguration.type != VariantConfiguration.Type.LIBRARY) {
            testTask.conventionMapping.testedApp = { testedVariantData.outputFile }
        }

        testTask.conventionMapping.resultsDir = {
            String rootLocation = extension.testOptions.resultsDir != null ?
                extension.testOptions.resultsDir :
                "$project.buildDir/$FD_INSTRUMENT_RESULTS"

            String flavorFolder = variantData.variantConfiguration.flavorName
            if (!flavorFolder.isEmpty()) {
                flavorFolder = "$FD_FLAVORS/" + flavorFolder
            }

            project.file("$rootLocation/$subFolder/$flavorFolder")
        }
        testTask.conventionMapping.reportsDir = {
            String rootLocation = extension.testOptions.reportDir != null ?
                extension.testOptions.reportDir :
                "$project.buildDir/$FD_REPORTS/$FD_INSTRUMENT_TESTS"

            String flavorFolder = variantData.variantConfiguration.flavorName
            if (!flavorFolder.isEmpty()) {
                flavorFolder = "$FD_FLAVORS/" + flavorFolder
            }

            project.file("$rootLocation/$subFolder/$flavorFolder")
        }

        return testTask
    }

    /**
     * Creates the packaging tasks for the given Variant.
     * @param variantData the variant data.
     * @param assembleTask an optional assembleTask to be used. If null a new one is created. The
     *                assembleTask is always set in the Variant.
     */
    protected void addPackageTasks(@NonNull ApkVariantData variantData,
                                   @Nullable Task assembleTask) {
        VariantConfiguration variantConfig = variantData.variantConfiguration

        boolean runProguard = variantConfig.buildType.runProguard &&
                (variantConfig.type != VariantConfiguration.Type.TEST ||
                        (variantConfig.type == VariantConfiguration.Type.TEST &&
                                variantConfig.testedConfig.type != VariantConfiguration.Type.LIBRARY))

        // common dex task configuration
        String dexTaskName = "dex${variantData.variantConfiguration.fullName.capitalize()}"
        Dex dexTask = project.tasks.create(dexTaskName, Dex)
        variantData.dexTask = dexTask

        dexTask.plugin = this
        dexTask.variant = variantData

        dexTask.conventionMapping.outputFile = {
            project.file(
                    "${project.buildDir}/libs/${project.archivesBaseName}-${variantData.variantConfiguration.baseName}.dex")
        }
        dexTask.dexOptions = extension.dexOptions

        if (runProguard) {

            // first proguard task.
            BaseVariantData testedVariantData = variantData instanceof TestVariantData ? variantData.testedVariantData : null as BaseVariantData
            File outFile = createProguardTasks(variantData, testedVariantData)

            // then dexing task
            dexTask.dependsOn variantData.proguardTask
            dexTask.conventionMapping.inputFiles = { project.files(outFile) }
            dexTask.conventionMapping.preDexedLibraries = { Collections.emptyList() }

        } else {

            // if required, pre-dexing task.
            PreDex preDexTask = null;
            boolean runPreDex = extension.dexOptions.preDexLibraries
            if (runPreDex) {
                def preDexTaskName = "preDex${variantData.variantConfiguration.fullName.capitalize()}"
                preDexTask = project.tasks.create(preDexTaskName, PreDex)

                preDexTask.dependsOn variantData.javaCompileTask
                preDexTask.plugin = this
                preDexTask.dexOptions = extension.dexOptions

                preDexTask.conventionMapping.inputFiles = {
                    project.files(getAndroidBuilder(variantData).getPackagedJars(variantConfig))
                }
                preDexTask.conventionMapping.outputFolder = {
                    project.file(
                            "${project.buildDir}/pre-dexed/${variantData.variantConfiguration.dirName}")
                }
            }

            // then dexing task
            dexTask.dependsOn variantData.javaCompileTask
            if (runPreDex) {
                dexTask.dependsOn preDexTask
            }

            dexTask.conventionMapping.inputFiles = { variantData.javaCompileTask.outputs.files }
            if (runPreDex) {
                dexTask.conventionMapping.preDexedLibraries = {
                    project.fileTree(preDexTask.outputFolder).files
                }
            } else {
                dexTask.conventionMapping.preDexedLibraries = {
                    project.files(getAndroidBuilder(variantData).getPackagedJars(variantConfig))
                }
            }
        }

        // Add a task to generate application package
        def packageApp = project.tasks.create(
                "package${variantData.variantConfiguration.fullName.capitalize()}",
                PackageApplication)
        variantData.packageApplicationTask = packageApp
        packageApp.dependsOn variantData.processResourcesTask, dexTask, variantData.processJavaResourcesTask, variantData.ndkCompileTask

        packageApp.plugin = this
        packageApp.variant = variantData

        packageApp.conventionMapping.resourceFile = {
            variantData.processResourcesTask.packageOutputFile
        }
        packageApp.conventionMapping.dexFile = { dexTask.outputFile }
        packageApp.conventionMapping.packagedJars = { getAndroidBuilder(variantData).getPackagedJars(variantConfig) }
        packageApp.conventionMapping.javaResourceDir = {
            getOptionalDir(variantData.processJavaResourcesTask.destinationDir)
        }
        packageApp.conventionMapping.jniFolders = {
            // for now only the project's compilation output.
            Set<File> set = Sets.newHashSet()
            set.addAll(variantData.ndkCompileTask.soFolder)
            set.addAll(variantData.renderscriptCompileTask.libOutputDir)
            set.addAll(variantConfig.libraryJniFolders)

            if (variantConfig.mergedFlavor.renderscriptSupportMode) {
                File rsLibs = getAndroidBuilder(variantData).getSupportNativeLibFolder()
                if (rsLibs.isDirectory()) {
                    set.add(rsLibs);
                }
            }

            return set
        }
        packageApp.conventionMapping.abiFilters = { variantConfig.supportedAbis }
        packageApp.conventionMapping.jniDebugBuild = { variantConfig.buildType.jniDebugBuild }

        SigningConfigDsl sc = (SigningConfigDsl) variantConfig.signingConfig
        packageApp.conventionMapping.signingConfig = { sc }
        if (sc != null) {
            ValidateSigningTask validateSigningTask = validateSigningTaskMap.get(sc)
            if (validateSigningTask == null) {
                validateSigningTask = project.tasks.create("validate${sc.name.capitalize()}Signing",
                    ValidateSigningTask)
                validateSigningTask.plugin = this
                validateSigningTask.signingConfig = sc

                validateSigningTaskMap.put(sc, validateSigningTask)
            }

            packageApp.dependsOn validateSigningTask
        }

        def signedApk = variantData.isSigned()
        def apkName = signedApk ?
            "${project.archivesBaseName}-${variantData.variantConfiguration.baseName}-unaligned.apk" :
            "${project.archivesBaseName}-${variantData.variantConfiguration.baseName}-unsigned.apk"

        packageApp.conventionMapping.outputFile = {
            project.file("$project.buildDir/apk/${apkName}")
        }

        Task appTask = packageApp
        OutputFileTask outputFileTask = packageApp

        if (signedApk) {
            if (variantData.zipAlign) {
                // Add a task to zip align application package
                def zipAlignTask = project.tasks.create(
                        "zipalign${variantData.variantConfiguration.fullName.capitalize()}",
                        ZipAlign)
                variantData.zipAlignTask = zipAlignTask

                zipAlignTask.dependsOn packageApp
                zipAlignTask.conventionMapping.inputFile = { packageApp.outputFile }
                zipAlignTask.conventionMapping.outputFile = {
                    project.file(
                            "$project.buildDir/apk/${project.archivesBaseName}-${variantData.variantConfiguration.baseName}.apk")
                }
                zipAlignTask.conventionMapping.zipAlignExe = { getSdkParser().zipAlign }

                appTask = zipAlignTask
                outputFileTask = zipAlignTask
                variantData.outputFile = project.file(
                        "$project.buildDir/apk/${project.archivesBaseName}-${variantData.variantConfiguration.baseName}.apk")
            }

            // Add a task to install the application package
            def installTask = project.tasks.create(
                    "install${variantData.variantConfiguration.fullName.capitalize()}",
                    InstallTask)
            installTask.description = "Installs the " + variantData.description
            installTask.group = INSTALL_GROUP
            installTask.dependsOn appTask
            installTask.conventionMapping.packageFile = { outputFileTask.outputFile }
            installTask.conventionMapping.adbExe = { getSdkParser().adb }

            variantData.installTask = installTask
        }

        // Add an assemble task
        if (assembleTask == null) {
            assembleTask = project.tasks.create("assemble${variantData.variantConfiguration.fullName.capitalize()}")
            assembleTask.description = "Assembles the " + variantData.description
            assembleTask.group = org.gradle.api.plugins.BasePlugin.BUILD_GROUP
        }
        assembleTask.dependsOn appTask
        variantData.assembleTask = assembleTask

        variantData.outputFile = { outputFileTask.outputFile }

        // add an uninstall task
        def uninstallTask = project.tasks.create(
                "uninstall${variantData.variantConfiguration.fullName.capitalize()}",
                UninstallTask)
        uninstallTask.description = "Uninstalls the " + variantData.description
        uninstallTask.group = INSTALL_GROUP
        uninstallTask.variant = variantData
        uninstallTask.conventionMapping.adbExe = { getSdkParser().adb }

        variantData.uninstallTask = uninstallTask
        uninstallAll.dependsOn uninstallTask
    }

    /**
     * Creates the proguarding task for the given Variant.
     * @param variantData the variant data.
     * @param testedVariantData optional. variant data representing the tested variant, null if the
     *                          variant is not a test variant
     * @return outFile file outputted by proguard
     */
    @NonNull
    protected File createProguardTasks(@NonNull BaseVariantData variantData,
                                       @Nullable BaseVariantData testedVariantData) {
        VariantConfiguration variantConfig = variantData.variantConfiguration

        def proguardTask = project.tasks.create(
                "proguard${variantData.variantConfiguration.fullName.capitalize()}",
                ProGuardTask)
        proguardTask.dependsOn variantData.javaCompileTask
        if (testedVariantData != null) {
            proguardTask.dependsOn testedVariantData.proguardTask
        }

        variantData.proguardTask = proguardTask

        // --- Output File ---

        File outFile;
        if (variantData instanceof LibraryVariantData) {
            outFile = project.file(
                    "${project.buildDir}/$DIR_BUNDLES/${variantData.variantConfiguration.dirName}/classes.jar")
        } else {
            outFile = project.file(
                    "${project.buildDir}/classes-proguard/${variantData.variantConfiguration.dirName}/classes.jar")
        }

        // --- Proguard Config ---

        if (testedVariantData != null) {
            // don't remove any code in tested app
            proguardTask.dontshrink()
            proguardTask.keepnames("class * extends junit.framework.TestCase")
            proguardTask.keepclassmembers("class * extends junit.framework.TestCase {\n" +
                    "    void test*(...);\n" +
                    "}")

            // input the mapping from the tested app so that we can deal with obfuscated code
            proguardTask.applymapping("${project.buildDir}/proguard/${testedVariantData.variantConfiguration.dirName}/mapping.txt")

            // for tested app, we only care about their aapt config since the base
            // configs are the same files anyway.
            proguardTask.configuration(testedVariantData.processResourcesTask.proguardOutputFile)
        }

        // all the config files coming from build type, product flavors.
        List<Object> proguardFiles = variantConfig.getProguardFiles(true /*includeLibs*/)
        for (Object proguardFile : proguardFiles) {
            proguardTask.configuration(proguardFile)
        }

        // also the config file output by aapt
        proguardTask.configuration(variantData.processResourcesTask.proguardOutputFile)

        // --- InJars / LibraryJars ---

        List<File> packagedJars = getAndroidBuilder(variantData).getPackagedJars(variantConfig)

        if (variantData instanceof LibraryVariantData) {
            String packageName = variantConfig.getPackageFromManifest()
            if (packageName == null) {
                throw new BuildException("Failed to read manifest", null)
            }
            packageName = packageName.replace('.', '/');

            // injar: the compilation output
            // exclude R files and such from output
            String exclude = '!' + packageName + "/R.class"
            exclude += (', !' + packageName + "/R\$*.class")
            exclude += (', !' + packageName + "/Manifest.class")
            exclude += (', !' + packageName + "/Manifest\$*.class")
            exclude += (', !' + packageName + "/BuildConfig.class")
            proguardTask.injars(variantData.javaCompileTask.destinationDir, filter: exclude)

            // include R files and such for compilation
            String include = exclude.replace('!', '')
            proguardTask.libraryjars(variantData.javaCompileTask.destinationDir, filter: include)

            // injar: the local dependencies, filter out local jars from packagedJars
            Object[] jars = LibraryPlugin.getLocalJarFileList(variantData.variantDependency)
            for (Object inJar : jars) {
                if (packagedJars.contains(inJar)) {
                    packagedJars.remove(inJar);
                }
                proguardTask.injars((File) inJar, filter: '!META-INF/MANIFEST.MF')
            }

            // libjar: the library dependencies
            for (File libJar : packagedJars) {
                proguardTask.libraryjars(libJar, filter: '!META-INF/MANIFEST.MF')
            }

            // ensure local jars keep their package names
            proguardTask.keeppackagenames()
        } else {
            // injar: the compilation output
            proguardTask.injars(variantData.javaCompileTask.destinationDir)

            // injar: the dependencies
            for (File inJar : packagedJars) {
                proguardTask.injars(inJar, filter: '!META-INF/MANIFEST.MF')
            }
        }

        // libraryJars: the runtime jars
        for (String runtimeJar : getRuntimeJarList()) {
            proguardTask.libraryjars(runtimeJar)
        }

        if (testedVariantData != null) {
            // input the tested app as library
            proguardTask.libraryjars(testedVariantData.javaCompileTask.destinationDir)
            // including its dependencies
            List<File> testedPackagedJars = getAndroidBuilder(testedVariantData).getPackagedJars(testedVariantData.variantConfiguration)
            for (File inJar : testedPackagedJars) {
                proguardTask.libraryjars(inJar, filter: '!META-INF/MANIFEST.MF')
            }
        }

        // --- Out files ---

        proguardTask.outjars(outFile)

        proguardTask.dump("${project.buildDir}/proguard/${variantData.variantConfiguration.dirName}/dump.txt")
        proguardTask.printseeds(
                "${project.buildDir}/proguard/${variantData.variantConfiguration.dirName}/seeds.txt")
        proguardTask.printusage(
                "${project.buildDir}/proguard/${variantData.variantConfiguration.dirName}/usage.txt")
        proguardTask.printmapping(
                "${project.buildDir}/proguard/${variantData.variantConfiguration.dirName}/mapping.txt")

        return outFile
    }

    private void createReportTasks() {
        def dependencyReportTask = project.tasks.create("androidDependencies", DependencyReportTask)
        dependencyReportTask.setDescription("Displays the Android dependencies of the project")
        dependencyReportTask.setVariants(variantDataList)
        dependencyReportTask.setGroup("Android")

        def signingReportTask = project.tasks.create("signingReport", SigningReportTask)
        signingReportTask.setDescription("Displays the signing info for each variant")
        signingReportTask.setVariants(variantDataList)
        signingReportTask.setGroup("Android")
    }

    protected void createAnchorTasks(@NonNull BaseVariantData variantData) {
        variantData.preBuildTask = project.tasks.create(
                "pre${variantData.variantConfiguration.fullName.capitalize()}Build")
        variantData.preBuildTask.dependsOn mainPreBuild

        def prepareDependenciesTask = project.tasks.create(
                "prepare${variantData.variantConfiguration.fullName.capitalize()}Dependencies",
                PrepareDependenciesTask)

        variantData.prepareDependenciesTask = prepareDependenciesTask
        prepareDependenciesTask.dependsOn variantData.preBuildTask

        prepareDependenciesTask.plugin = this
        prepareDependenciesTask.variant = variantData

        // for all libraries required by the configurations of this variant, make this task
        // depend on all the tasks preparing these libraries.
        VariantDependencies configurationDependencies = variantData.variantDependency
        prepareDependenciesTask.addChecker(configurationDependencies.checker)

        for (LibraryDependencyImpl lib : configurationDependencies.libraries) {
            addDependencyToPrepareTask(variantData, prepareDependenciesTask, lib)
        }

        // also create sourceGenTask
        variantData.sourceGenTask = project.tasks.create(
                "generate${variantData.variantConfiguration.fullName.capitalize()}Sources")
    }


    private final Map<String, ArtifactMetaData> extraArtifactMap = Maps.newHashMap()
    private final ListMultimap<String, AndroidArtifact> extraAndroidArtifacts = ArrayListMultimap.create()
    private final ListMultimap<String, JavaArtifact> extraJavaArtifacts = ArrayListMultimap.create()
    private final ListMultimap<String, SourceProviderContainer> extraVariantSourceProviders = ArrayListMultimap.create()
    private final ListMultimap<String, SourceProviderContainer> extraBuildTypeSourceProviders = ArrayListMultimap.create()
    private final ListMultimap<String, SourceProviderContainer> extraProductFlavorSourceProviders = ArrayListMultimap.create()
    private final ListMultimap<String, SourceProviderContainer> extraMultiFlavorSourceProviders = ArrayListMultimap.create()


    public Collection<ArtifactMetaData> getExtraArtifacts() {
        return extraArtifactMap.values()
    }

    public Collection<AndroidArtifact> getExtraAndroidArtifacts(@NonNull String variantName) {
        return extraAndroidArtifacts.get(variantName)
    }

    public Collection<JavaArtifact> getExtraJavaArtifacts(@NonNull String variantName) {
        return extraJavaArtifacts.get(variantName)
    }

    public Collection<SourceProviderContainer> getExtraVariantSourceProviders(@NonNull String variantName) {
        return extraVariantSourceProviders.get(variantName)
    }

    public Collection<SourceProviderContainer> getExtraFlavorSourceProviders(@NonNull String flavorName) {
        return extraProductFlavorSourceProviders.get(flavorName)
    }

    public Collection<SourceProviderContainer> getExtraBuildTypeSourceProviders(@NonNull String buildTypeName) {
        return extraBuildTypeSourceProviders.get(buildTypeName)
    }

    public void registerArtifactType(@NonNull String name,
                                     boolean isTest,
                                     int artifactType) {

        if (extraArtifactMap.get(name) != null) {
            throw new IllegalArgumentException("Artifact with name $name already registered.")
        }

        extraArtifactMap.put(name, new ArtifactMetaDataImpl(name, isTest, artifactType))
    }

    public void registerBuildTypeSourceProvider(@NonNull String name,
                                                @NonNull BuildType buildType,
                                                @NonNull SourceProvider sourceProvider) {
        if (extraArtifactMap.get(name) == null) {
            throw new IllegalArgumentException(
                    "Artifact with name $name is not yet registered. Use registerArtifactType()")
        }

        extraBuildTypeSourceProviders.put(buildType.name,
                new DefaultSourceProviderContainer(name, sourceProvider))

    }

    public void registerProductFlavorSourceProvider(@NonNull String name,
                                                    @NonNull ProductFlavor productFlavor,
                                                    @NonNull SourceProvider sourceProvider) {
        if (extraArtifactMap.get(name) == null) {
            throw new IllegalArgumentException(
                    "Artifact with name $name is not yet registered. Use registerArtifactType()")
        }

        extraProductFlavorSourceProviders.put(productFlavor.name,
                new DefaultSourceProviderContainer(name, sourceProvider))

    }

    public void registerMultiFlavorSourceProvider(@NonNull String name,
                                                  @NonNull String flavorName,
                                                  @NonNull SourceProvider sourceProvider) {
        if (extraArtifactMap.get(name) == null) {
            throw new IllegalArgumentException(
                    "Artifact with name $name is not yet registered. Use registerArtifactType()")
        }

        extraMultiFlavorSourceProviders.put(flavorName,
                new DefaultSourceProviderContainer(name, sourceProvider))
    }

    public void registerJavaArtifact(
            @NonNull String name,
            @NonNull BaseVariant variant,
            @NonNull String assembleTaskName,
            @NonNull String javaCompileTaskName,
            @NonNull File classesFolder,
            @Nullable SourceProvider sourceProvider) {
        ArtifactMetaData artifactMetaData = extraArtifactMap.get(name)
        if (artifactMetaData == null) {
            throw new IllegalArgumentException(
                    "Artifact with name $name is not yet registered. Use registerArtifactType()")
        }
        if (artifactMetaData.type != ArtifactMetaData.TYPE_JAVA) {
            throw new IllegalArgumentException(
                    "Artifact with name $name is not of type JAVA")
        }

        JavaArtifact artifact = new JavaArtifactImpl(
                name, assembleTaskName, javaCompileTaskName, classesFolder,
                null, sourceProvider, null)
        extraJavaArtifacts.put(variant.name, artifact)
    }

    //----------------------------------------------------------------------------------------------
    //------------------------------ START DEPENDENCY STUFF ----------------------------------------
    //----------------------------------------------------------------------------------------------

    def addDependencyToPrepareTask(@NonNull BaseVariantData variantData,
                                   @NonNull PrepareDependenciesTask prepareDependenciesTask,
                                   @NonNull LibraryDependencyImpl lib) {
        def prepareLibTask = prepareTaskMap.get(lib)
        if (prepareLibTask != null) {
            prepareDependenciesTask.dependsOn prepareLibTask
            prepareLibTask.dependsOn variantData.preBuildTask
        }

        for (LibraryDependencyImpl childLib : lib.dependencies) {
            addDependencyToPrepareTask(variantData, prepareDependenciesTask, childLib)
        }
    }

    def resolveDependencies(VariantDependencies variantDeps) {
        Map<ModuleVersionIdentifier, List<LibraryDependencyImpl>> modules = [:]
        Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts = [:]
        Multimap<LibraryDependency, VariantDependencies> reverseMap = ArrayListMultimap.create()

        resolveDependencyForConfig(variantDeps, modules, artifacts, reverseMap)

        modules.values().each { List list ->

            if (!list.isEmpty()) {
                // get the first item only
                LibraryDependencyImpl androidDependency = (LibraryDependencyImpl) list.get(0)

                String bundleName = GUtil.toCamelCase(androidDependency.name.replaceAll("\\:", " "))

                def prepareLibraryTask = prepareTaskMap.get(androidDependency)
                if (prepareLibraryTask == null) {
                    prepareLibraryTask = project.tasks.create("prepare${bundleName}Library",
                            PrepareLibraryTask)
                    prepareLibraryTask.description = "Prepare ${androidDependency.name}"
                    prepareLibraryTask.bundle = androidDependency.bundle
                    prepareLibraryTask.explodedDir = androidDependency.bundleFolder

                    prepareTaskMap.put(androidDependency, prepareLibraryTask)
                }

                // Use the reverse map to find all the configurations that included this android
                // library so that we can make sure they are built.
                List<VariantDependencies> configDepList = reverseMap.get(androidDependency)
                if (configDepList != null && !configDepList.isEmpty()) {
                    for (VariantDependencies configDependencies: configDepList) {
                        prepareLibraryTask.dependsOn configDependencies.compileConfiguration.buildDependencies
                    }
                }
            }
        }
    }

    def resolveDependencyForConfig(
            VariantDependencies variantDeps,
            Map<ModuleVersionIdentifier, List<LibraryDependencyImpl>> modules,
            Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,
            Multimap<LibraryDependency, VariantDependencies> reverseMap) {

        Configuration compileClasspath = variantDeps.compileConfiguration

        // TODO - shouldn't need to do this - fix this in Gradle
        ensureConfigured(compileClasspath)

        variantDeps.checker = new DependencyChecker(variantDeps, logger)

        Set<String> currentUnresolvedDependencies = Sets.newHashSet()

        // TODO - defer downloading until required -- This is hard to do as we need the info to build the variant config.
        List<LibraryDependencyImpl> bundles = []
        List<JarDependency> jars = []
        List<JarDependency> localJars = []
        collectArtifacts(compileClasspath, artifacts)
        def dependencies = compileClasspath.incoming.resolutionResult.root.dependencies
        dependencies.each { DependencyResult dep ->
            if (dep instanceof ResolvedDependencyResult) {
                addDependency(dep.selected, variantDeps, bundles, jars, modules, artifacts, reverseMap)
            } else if (dep instanceof UnresolvedDependencyResult) {
                def attempted = dep.attempted;
                if (attempted != null) {
                    currentUnresolvedDependencies.add(attempted.toString())
                }
            }
        }

        // also need to process local jar files, as they are not processed by the
        // resolvedConfiguration result. This only includes the local jar files for this project.
        compileClasspath.allDependencies.each { dep ->
            if (dep instanceof SelfResolvingDependency &&
                    !(dep instanceof ProjectDependency)) {
                Set<File> files = ((SelfResolvingDependency) dep).resolve()
                for (File f : files) {
                    // TODO: support compile only dependencies.
                    localJars << new JarDependency(f)
                }
            }
        }

        // handle package dependencies. We'll refuse aar libs only in package but not
        // in compile and remove all dependencies already in compile to get package-only jar
        // files.
        Configuration packageClasspath = variantDeps.packageConfiguration

        if (!compileClasspath.resolvedConfiguration.hasError()) {
            Set<File> compileFiles = compileClasspath.files
            Set<File> packageFiles = packageClasspath.files

            for (File f : packageFiles) {
                if (compileFiles.contains(f)) {
                    continue
                }

                if (f.getName().toLowerCase().endsWith(".jar")) {
                    jars.add(new JarDependency(f, false /*compiled*/, true /*packaged*/))
                } else {
                    throw new RuntimeException("Package-only dependency '" +
                            f.absolutePath +
                            "' is not supported")
                }
            }
        } else if (!currentUnresolvedDependencies.isEmpty()) {
            unresolvedDependencies.addAll(currentUnresolvedDependencies)
        }

        variantDeps.addLibraries(bundles)
        variantDeps.addJars(jars)
        variantDeps.addLocalJars(localJars)

        // TODO - filter bundles out of source set classpath

        configureBuild(variantDeps)
    }

    def ensureConfigured(Configuration config) {
        config.allDependencies.withType(ProjectDependency).each { dep ->
            project.evaluationDependsOn(dep.dependencyProject.path)
            ensureConfigured(dep.projectConfiguration)
        }
    }

    static def collectArtifacts(Configuration configuration, Map<ModuleVersionIdentifier,
                         List<ResolvedArtifact>> artifacts) {
        boolean buildModelOnly = Boolean.getBoolean(AndroidProject.BUILD_MODEL_ONLY_SYSTEM_PROPERTY);
        def allArtifacts
        if (buildModelOnly) {
            allArtifacts = configuration.resolvedConfiguration.lenientConfiguration.getArtifacts(Specs.satisfyAll())
        } else {
            allArtifacts = configuration.resolvedConfiguration.resolvedArtifacts
        }

        allArtifacts.each { ResolvedArtifact artifact ->
            def id = artifact.moduleVersion.id
            List<ResolvedArtifact> moduleArtifacts = artifacts[id]
            if (moduleArtifacts == null) {
                moduleArtifacts = []
                artifacts[id] = moduleArtifacts
            }
            moduleArtifacts << artifact
        }
    }

    def addDependency(ResolvedModuleVersionResult moduleVersion,
                      VariantDependencies configDependencies,
                      Collection<LibraryDependencyImpl> bundles,
                      List<JarDependency> jars,
                      Map<ModuleVersionIdentifier, List<LibraryDependencyImpl>> modules,
                      Map<ModuleVersionIdentifier, List<ResolvedArtifact>> artifacts,
                      Multimap<LibraryDependency, VariantDependencies> reverseMap) {
        def id = moduleVersion.id
        if (configDependencies.checker.excluded(id)) {
            return
        }

        List<LibraryDependencyImpl> bundlesForThisModule = modules[id]
        if (bundlesForThisModule == null) {
            bundlesForThisModule = []
            modules[id] = bundlesForThisModule

            def nestedBundles = []
            def dependencies = moduleVersion.dependencies
            dependencies.each { DependencyResult dep ->
                if (dep instanceof ResolvedDependencyResult) {
                    addDependency(dep.selected, configDependencies, nestedBundles,
                            jars, modules, artifacts, reverseMap)
                }
            }

            def moduleArtifacts = artifacts[id]
            moduleArtifacts?.each { artifact ->
                if (artifact.type == EXT_LIB_ARCHIVE) {
                    String bundleName = GUtil.toCamelCase(id.group + " " + id.name + " " + id.version)
                    def explodedDir = project.file(
                            "$project.buildDir/exploded-bundles/${bundleName}.aar")
                    LibraryDependencyImpl adep = new LibraryDependencyImpl(
                            artifact.file, explodedDir, nestedBundles,
                            id.group + ":" + id.name + ":" + id.version)
                    bundlesForThisModule << adep
                    reverseMap.put(adep, configDependencies)
                } else {
                    // TODO: support compile only dependencies.
                    jars << new JarDependency(artifact.file)
                }
            }

            if (bundlesForThisModule.empty && !nestedBundles.empty) {
                throw new GradleException("Module version $id depends on libraries but is not a library itself")
            }
        } else {
            for (LibraryDependency adep : bundlesForThisModule) {
                reverseMap.put(adep, configDependencies)
            }
        }

        bundles.addAll(bundlesForThisModule)
    }

    private void configureBuild(VariantDependencies configurationDependencies) {
        addDependsOnTaskInOtherProjects(
                project.getTasks().getByName(JavaBasePlugin.BUILD_NEEDED_TASK_NAME), true,
                JavaBasePlugin.BUILD_NEEDED_TASK_NAME, "compile");
        addDependsOnTaskInOtherProjects(
                project.getTasks().getByName(JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME), false,
                JavaBasePlugin.BUILD_DEPENDENTS_TASK_NAME, "compile");
    }

    /**
     * Adds a dependency on tasks with the specified name in other projects.  The other projects
     * are determined from project lib dependencies using the specified configuration name.
     * These may be projects this project depends on or projects that depend on this project
     * based on the useDependOn argument.
     *
     * @param task Task to add dependencies to
     * @param useDependedOn if true, add tasks from projects this project depends on, otherwise
     * use projects that depend on this one.
     * @param otherProjectTaskName name of task in other projects
     * @param configurationName name of configuration to use to find the other projects
     */
    private static void addDependsOnTaskInOtherProjects(final Task task, boolean useDependedOn,
                                                 String otherProjectTaskName,
                                                 String configurationName) {
        Project project = task.getProject();
        final Configuration configuration = project.getConfigurations().getByName(
                configurationName);
        task.dependsOn(configuration.getTaskDependencyFromProjectDependency(
                useDependedOn, otherProjectTaskName));
    }

    //----------------------------------------------------------------------------------------------
    //------------------------------- END DEPENDENCY STUFF -----------------------------------------
    //----------------------------------------------------------------------------------------------

    protected static File getOptionalDir(File dir) {
        if (dir.isDirectory()) {
            return dir
        }

        return null
    }

    @NonNull
    protected List<ManifestDependencyImpl> getManifestDependencies(
            List<LibraryDependency> libraries) {

        List<ManifestDependencyImpl> list = Lists.newArrayListWithCapacity(libraries.size())

        for (LibraryDependency lib : libraries) {
            // get the dependencies
            List<ManifestDependencyImpl> children = getManifestDependencies(lib.dependencies)
            list.add(new ManifestDependencyImpl(lib.manifest, children))
        }

        return list
    }

    @NonNull
    protected static List<SymbolFileProviderImpl> getTextSymbolDependencies(
            List<LibraryDependency> libraries) {

        List<SymbolFileProviderImpl> list = Lists.newArrayListWithCapacity(libraries.size())

        for (LibraryDependency lib : libraries) {
            list.add(new SymbolFileProviderImpl(lib.manifest, lib.symbolFile))
        }

        return list
    }

    private static String getLocalVersion() {
        try {
            Class clazz = BasePlugin.class
            String className = clazz.getSimpleName() + ".class"
            String classPath = clazz.getResource(className).toString()
            if (!classPath.startsWith("jar")) {
                // Class not from JAR, unlikely
                return null
            }
            String manifestPath = classPath.substring(0, classPath.lastIndexOf("!") + 1) +
                    "/META-INF/MANIFEST.MF";
            Manifest manifest = new Manifest(new URL(manifestPath).openStream());
            Attributes attr = manifest.getMainAttributes();
            return attr.getValue("Plugin-Version");
        } catch (Throwable t) {
            return null;
        }
    }

    public Project getProject() {
        return project
    }
}
