diff --git a/build.gradle b/build.gradle
index ccb7679..b3fcda7 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,688 +1,37 @@
-import android.support.checkapi.ApiXmlConversionTask
-import android.support.checkapi.CheckApiTask
-import android.support.checkapi.UpdateApiTask
-import android.support.doclava.DoclavaMultilineJavadocOptionFileOption
-import android.support.doclava.DoclavaTask
-import android.support.jdiff.JDiffTask
-
-import com.android.build.gradle.internal.coverage.JacocoPlugin
-import com.android.build.gradle.internal.coverage.JacocoReportTask
-import com.android.build.gradle.internal.tasks.DeviceProviderInstrumentTestTask
-import org.gradle.internal.os.OperatingSystem
-
-import com.google.common.base.Charsets
-import com.google.common.hash.HashCode
-import com.google.common.hash.HashFunction
-import com.google.common.hash.Hashing
-import com.google.common.io.Files
-
-import groovy.io.FileType
+/*
+ * Copyright (C) 2017 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.
+ */
 
 buildscript {
-    apply from: 'buildSrc/dependencies.gradle'
-
-    repositories {
-        maven { url '../../prebuilts/gradle-plugin' }
-        maven { url '../../prebuilts/tools/common/m2/repository' }
-        maven { url '../../prebuilts/tools/common/m2/internal' }
-        maven { url '../../prebuilts/maven_repo/android' }
-    }
+    ext.supportRootFolder = project.projectDir
+    apply from: 'buildSrc/init.gradle'
+    init.addMavenRepositories(repositories)
     dependencies {
         classpath libs.gradle
     }
 }
+init.loadDefaultVersions()
 
-apply from: 'buildSrc/dependencies.gradle'
+init.setSdkInLocalPropertiesFile()
 
-repositories {
-    maven { url '../../prebuilts/tools/common/m2/repository' }
-}
+init.addMavenRepositories(repositories)
 
-configurations {
-    doclava
-    jdiff
-}
+init.setupRepoOutAndBuildNumber()
 
-dependencies {
-    doclava project(':doclava')
-    jdiff project(':jdiff')
-    jdiff libs.xml_parser_apis
-    jdiff libs.xerces_impl
-}
+init.configureSubProjects()
 
-// Version code components.
-ext.supportVersion = "26.0.0-SNAPSHOT"
+init.setupRelease()
 
-// This number gets incremented for each public release.
-ext.extraVersion = 44
-
-// Enforce the use of prebuilt dependencies in all sub-projects. This is
-// required for the doclava dependency.
-ext.usePrebuilts = "true"
-
-final String platform = OperatingSystem.current().isMacOsX() ? 'darwin' : 'linux'
-System.setProperty('android.dir', "${rootDir}/../../")
-final String fullSdkPath = "${rootDir}/../../prebuilts/fullsdk-${platform}"
-if (file(fullSdkPath).exists()) {
-    gradle.ext.currentSdk = 26
-    ext.buildToolsVersion = '26.0.0'
-    project.ext.androidJar = files("${fullSdkPath}/platforms/android-${gradle.ext.currentSdk}/android.jar")
-    System.setProperty('android.home', "${rootDir}/../../prebuilts/fullsdk-${platform}")
-    File props = file("local.properties")
-    props.write "sdk.dir=${fullSdkPath}"
-} else {
-    gradle.ext.currentSdk = 'current'
-    ext.buildToolsVersion = '24.0.1'
-    project.ext.androidJar = files("${project.rootDir}/../../prebuilts/sdk/${gradle.ext.currentSdk}/android.jar")
-    File props = file("local.properties")
-    props.write "android.dir=../../"
-}
-
-ext.supportRepoOut = ''
-ext.buildNumber = Integer.toString(ext.extraVersion)
-
-/*
- * With the build server you are given two env variables.
- * The OUT_DIR is a temporary directory you can use to put things during the build.
- * The DIST_DIR is where you want to save things from the build.
- *
- * The build server will copy the contents of DIST_DIR to somewhere and make it available.
- */
-if (System.env.DIST_DIR != null && System.env.OUT_DIR != null) {
-    buildDir = new File(System.env.OUT_DIR + '/gradle/frameworks/support/build').getCanonicalFile()
-    project.ext.distDir = new File(System.env.DIST_DIR).getCanonicalFile()
-
-    // the build server does not pass the build number so we infer it from the last folder of the dist path.
-    ext.buildNumber = project.ext.distDir.getName()
-} else {
-    buildDir = file("${project.rootDir}/../../out/host/gradle/frameworks/support/build")
-    project.ext.distDir = file("${project.rootDir}/../../out/dist")
-}
-
-subprojects {
-    // Change buildDir first so that all plugins pick up the new value.
-    project.buildDir = project.file("$project.parent.buildDir/../$project.name/build")
-}
-
-ext.docsDir = new File(buildDir, 'javadoc')
-ext.supportRepoOut = new File(buildDir, 'support_repo')
-ext.testApkDistOut = ext.distDir
-
-// Main task called by the build server.
-task(createArchive)
-
-// upload anchor for subprojects to upload their artifacts
-// to the local repo.
-task(mainUpload)
-
-// repository creation task
-task createRepository(type: Zip, dependsOn: mainUpload) {
-    from project.ext.supportRepoOut
-    destinationDir project.ext.distDir
-    into 'm2repository'
-    baseName = String.format("sdk-repo-linux-m2repository-%s", project.ext.buildNumber)
-}
-createArchive.dependsOn createRepository
-
-// prepare repository with older versions
-task unzipRepo(type: Copy) {
-    from "${project.rootDir}/../../prebuilts/maven_repo/android"
-    into project.ext.supportRepoOut
-}
-
-unzipRepo.doFirst {
-    project.ext.supportRepoOut.deleteDir()
-    project.ext.supportRepoOut.mkdirs()
-}
-
-// anchor for prepare repo. This is post unzip + sourceProp.
-task(prepareRepo)
-
-// lint every library
-task(lint)
-
-task(createXml).doLast({
-    def repoArchive = createRepository.archivePath
-    def repoArchiveName = createRepository.archiveName
-    def size = repoArchive.length()
-    def sha1 = getSha1(repoArchive)
-
-    def xml =
-"<sdk:sdk-addon xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sdk=\"http://schemas.android.com/sdk/android/addon/6\">\n\
-  <sdk:extra>\n\
-    <sdk:revision>\n\
-      <sdk:major>${project.ext.extraVersion}</sdk:major>\n\
-    </sdk:revision>\n\
-    <sdk:vendor-display>Android</sdk:vendor-display>\n\
-    <sdk:vendor-id>android</sdk:vendor-id>\n\
-    <sdk:name-display>Local Maven repository for Support Libraries</sdk:name-display>\n\
-    <sdk:path>m2repository</sdk:path>\n\
-    <sdk:archives>\n\
-      <sdk:archive>\n\
-       <sdk:size>${size}</sdk:size>\n\
-       <sdk:checksum type=\"sha1\">${sha1}</sdk:checksum>\n\
-       <sdk:url>${repoArchiveName}</sdk:url>\n\
-      </sdk:archive>\n\
-    </sdk:archives>\n\
-  </sdk:extra>\n\
-</sdk:sdk-addon>"
-
-    Files.write(xml, new File(project.ext.distDir, 'repo-extras.xml'), Charsets.UTF_8)
-})
-createArchive.dependsOn createXml
-createXml.dependsOn createRepository
-
-task(createSourceProp).doLast({
-    def sourceProp =
-"Extra.VendorDisplay=Android\n\
-Extra.Path=m2repository\n\
-Archive.Arch=ANY\n\
-Extra.NameDisplay=Android Support Repository\n\
-Archive.Os=ANY\n\
-Pkg.Desc=Local Maven repository for Support Libraries\n\
-Pkg.Revision=${project.ext.extraVersion}.0.0\n\
-Extra.VendorId=android"
-
-    Files.write(sourceProp, new File(project.ext.supportRepoOut, 'source.properties'), Charsets.UTF_8)
-})
-createSourceProp.dependsOn unzipRepo
-prepareRepo.dependsOn createSourceProp
-
-import java.nio.charset.Charset
-
-/**
- * Generates SHA1 hash for the specified file's absolute path.
- *
- * @param inputFile file to hash
- * @return SHA1 hash
- */
-String getSha1(File inputFile) {
-    HashFunction hashFunction = Hashing.sha1()
-    HashCode hashCode = hashFunction.hashString(inputFile.getAbsolutePath(), Charset.forName("UTF-8"))
-    return hashCode.toString()
-}
-
-void registerForDocsTask(Task task, Project subProject, releaseVariant) {
-    task.dependsOn releaseVariant.javaCompile
-    task.source {
-        def buildConfig = fileTree(releaseVariant.getGenerateBuildConfig().sourceOutputDir)
-        return releaseVariant.javaCompile.source.minus(buildConfig) +
-            fileTree(releaseVariant.aidlCompile.sourceOutputDir) +
-            fileTree(releaseVariant.outputs[0].processResources.sourceOutputDir)
-    }
-    task.classpath += files(releaseVariant.javaCompile.classpath) +
-            files(releaseVariant.javaCompile.destinationDir)
-}
-
-// Generates online docs.
-task generateDocs(type: DoclavaTask, dependsOn: configurations.doclava) {
-    group = JavaBasePlugin.DOCUMENTATION_GROUP
-    description = 'Generates d.android.com style documentation.'
-
-    docletpath = configurations.doclava.resolve()
-    destinationDir = new File(project.docsDir, "online")
-
-    // Base classpath is Android SDK, sub-projects add their own.
-    classpath = project.ext.androidJar
-
-    def hdfOption = new DoclavaMultilineJavadocOptionFileOption('hdf')
-    hdfOption.add(
-            ['android.whichdoc', 'online'],
-            ['android.hasSamples', 'true']);
-
-    // Default hidden errors + hidden superclass (111) and
-    // deprecation mismatch (113) to match framework docs.
-    final def hidden = [105, 107, 111, 112, 113, 115, 116, 121]
-
-    doclavaErrors = (101..122) - hidden
-    doclavaWarnings = []
-    doclavaHidden += hidden
-
-    options {
-        addStringOption "templatedir",
-                "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
-        addStringOption "federate Android", "http://developer.android.com"
-        addStringOption "stubpackages", "android.support.*"
-        addStringOption "samplesdir", "${project.rootDir}/samples"
-        addOption hdfOption
-    }
-
-    exclude '**/BuildConfig.java'
-}
-
-JDiffTask createApiDiffsTask(String taskName, File oldApiXml, File newApiXml, File outDir,
-                             Configuration jdiff, Task... dependencies) {
-    return tasks.create(name: taskName, type: JDiffTask.class) {
-        dependsOn jdiff
-        dependsOn dependencies
-
-        docletpath = jdiff.resolve()
-
-        oldApiXmlFile oldApiXml
-        newApiXmlFile newApiXml
-        destinationDir = outDir
-
-        // This prefix is based on the assumption that the output diffs will
-        // ultimately land in frameworks/base/docs/html/sdk/support_api_diff/.
-        newJavadocPrefix = "../reference/"
-    }
-}
-
-// Generates API files.
-task generateApi(type: DoclavaTask, dependsOn: configurations.doclava) {
-    docletpath = configurations.doclava.resolve()
-    destinationDir = project.docsDir
-
-    // Base classpath is Android SDK, sub-projects add their own.
-    classpath = project.ext.androidJar
-
-    apiFile = new File(project.docsDir, 'release/current.txt')
-    removedApiFile = new File(project.docsDir, 'release/removed.txt')
-    generateDocs = false
-
-    options {
-        addStringOption "templatedir",
-                "${project.rootDir}/../../build/tools/droiddoc/templates-sdk"
-        addStringOption "federate Android", "http://developer.android.com"
-        addStringOption "stubpackages", "android.support.*"
-    }
-    exclude '**/BuildConfig.java'
-    exclude '**/R.java'
-}
-
-// Copies generated API files to current version.
-task updateApi(type: UpdateApiTask, dependsOn: generateApi) {
-    group JavaBasePlugin.VERIFICATION_GROUP
-    description 'Invoke Doclava\'s ApiCheck tool to update current.txt based on current changes.'
-
-    newApiFile = new File(project.docsDir, 'release/current.txt')
-    oldApiFile = new File(project.rootDir, 'api/current.txt')
-    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
-    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
-}
-
-// Checks generated API files against current version.
-task checkApi(type: CheckApiTask, dependsOn: generateApi) {
-    doclavaClasspath = generateApi.docletpath
-
-    checkApiTaskPath = name
-    updateApiTaskPath = updateApi.name
-
-    // Check that the API we're building hasn't changed from the development
-    // version. These typed of changes require an explicit API file update.
-    checkApiErrors = (2..30)-[22]
-    checkApiWarnings = []
-    checkApiHidden = [22]
-
-    newApiFile = new File(project.docsDir, 'release/current.txt')
-    oldApiFile = new File(project.rootDir, 'api/current.txt')
-    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
-    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
-}
-createArchive.dependsOn checkApi
-
-// Checks generated API files against current version.
-task checkApiStable(type: CheckApiTask, dependsOn: generateApi) {
-    doclavaClasspath = generateApi.docletpath
-
-    checkApiTaskPath = name
-    updateApiTaskPath = updateApi.name
-
-    // Check that the API we're building hasn't broken the last-released
-    // library version. These types of changes are forbidden.
-    checkApiErrors = (7..18)
-    checkApiWarnings = [23, 24]
-    checkApiHidden = (2..6) + (19..22) + (25..30)
-
-    newApiFile = new File(project.docsDir, 'release/current.txt')
-    oldApiFile = getReleasedApiFile()
-    newRemovedApiFile = new File(project.docsDir, 'release/removed.txt')
-    oldRemovedApiFile = new File(project.rootDir, 'api/removed.txt')
-}
-checkApi.dependsOn checkApiStable
-
-/**
- * Converts the <code>toApi</code>.txt file (or current.txt if not explicitly
- * defined using -PtoAPi=<file>) to XML format for use by JDiff.
- */
-task newApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
-    classpath configurations.doclava.resolve()
-
-    if (project.hasProperty("toApi")) {
-        // Use an explicit API file.
-        inputApiFile = new File(project.rootDir, "api/${toApi}.txt")
-    } else {
-        // Use the current API file (e.g. current.txt).
-        inputApiFile = generateApi.apiFile
-        dependsOn generateApi
-    }
-
-    int lastDot = inputApiFile.name.lastIndexOf('.')
-    outputApiXmlFile = new File(project.docsDir,
-            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
-}
-
-/**
- * Converts the <code>fromApi</code>.txt file (or the most recently released
- * X.Y.Z.txt if not explicitly defined using -PfromAPi=<file>) to XML format
- * for use by JDiff.
- */
-task oldApiXml(type: ApiXmlConversionTask, dependsOn: configurations.doclava) {
-    classpath configurations.doclava.resolve()
-
-    if (project.hasProperty("fromApi")) {
-        // Use an explicit API file.
-        inputApiFile = new File(project.rootDir, "api/${fromApi}.txt")
-    } else if (project.hasProperty("toApi") && toApi.matches(~/(\d+\.){2}\d+/)) {
-        // If toApi matches released API (X.Y.Z) format, use the most recently
-        // released API file prior to toApi.
-        inputApiFile = getReleasedApiFile(toApi)
-    } else {
-        // Use the most recently released API file.
-        inputApiFile = getReleasedApiFile();
-    }
-
-    int lastDot = inputApiFile.name.lastIndexOf('.')
-    outputApiXmlFile = new File(project.docsDir,
-            "release/" + inputApiFile.name.substring(0, lastDot) + ".xml")
-}
-
-/**
- * Generates API diffs.
- * <p>
- * By default, diffs are generated for the delta between current.txt and the
- * next most recent X.Y.Z.txt API file. Behavior may be changed by specifying
- * one or both of -PtoApi and -PfromApi.
- * <p>
- * If both fromApi and toApi are specified, diffs will be generated for
- * fromApi -> toApi. For example, 25.0.0 -> 26.0.0 diffs could be generated by
- * using:
- * <br><code>
- *   ./gradlew generateDiffs -PfromApi=25.0.0 -PtoApi=26.0.0
- * </code>
- * <p>
- * If only toApi is specified, it MUST be specified as X.Y.Z and diffs will be
- * generated for (release before toApi) -> toApi. For example, 24.2.0 -> 25.0.0
- * diffs could be generated by using:
- * <br><code>
- *   ./gradlew generateDiffs -PtoApi=25.0.0
- * </code>
- * <p>
- * If only fromApi is specified, diffs will be generated for fromApi -> current.
- * For example, lastApiReview -> current diffs could be generated by using:
- * <br><code>
- *   ./gradlew generateDiffs -PfromApi=lastApiReview
- * </code>
- * <p>
- */
-task generateDiffs(type: JDiffTask, dependsOn: [configurations.jdiff, configurations.doclava,
-                                                oldApiXml, newApiXml, generateDocs]) {
-    // Base classpath is Android SDK, sub-projects add their own.
-    classpath = project.ext.androidJar
-
-    // JDiff properties.
-    oldApiXmlFile = oldApiXml.outputApiXmlFile
-    newApiXmlFile = newApiXml.outputApiXmlFile
-    newJavadocPrefix = "../../../../reference/"
-
-    String newApi = newApiXmlFile.name
-    int lastDot = newApi.lastIndexOf('.')
-    newApi = newApi.substring(0, lastDot)
-
-    // Javadoc properties.
-    docletpath = configurations.jdiff.resolve()
-    destinationDir = new File(project.docsDir, "online/sdk/support_api_diff/$newApi")
-    title = "Support&nbsp;Library&nbsp;API&nbsp;Differences&nbsp;Report"
-
-    exclude '**/BuildConfig.java'
-    exclude '**/R.java'
-}
-
-/**
- * Returns the most recently released API, optionally restricting to APIs
- * before <code>beforeApi</code>.
- *
- * @param beforeApi the API to find an API file before, ex. 25.0.0
- * @return the most recently released API file
- */
-File getReleasedApiFile(String beforeApi = null) {
-    String beforeApiFileName = beforeApi != null ? beforeApi + ".txt" : null
-    File lastReleasedApiFile = null
-    File apiDir = new File(project.rootDir, 'api')
-
-    apiDir.eachFileMatch FileType.FILES, ~/(\d+\.){3}txt/, { File apiFile ->
-        // Is the current API file newer than the last one we saw?
-        if (lastReleasedApiFile == null || apiFile.name > lastReleasedApiFile.name) {
-            // Is the current API file older than the "before" API?
-            if (beforeApiFileName == null || apiFile.name < beforeApiFileName) {
-                lastReleasedApiFile = apiFile
-            }
-        }
-    }
-
-    return lastReleasedApiFile
-}
-
-subprojects {
-    // Only modify Android projects.
-    if (project.name.equals('doclava') || project.name.equals('jdiff')) return;
-
-    // Current SDK is set in studioCompat.gradle.
-    project.ext.currentSdk = gradle.ext.currentSdk
-    apply plugin: 'maven'
-
-    version = rootProject.ext.supportVersion
-    group = 'com.android.support'
-
-    repositories {
-        maven { url "${project.parent.projectDir}/../../prebuilts/tools/common/m2/repository" }
-        maven { url "${project.parent.projectDir}/../../prebuilts/tools/common/m2/internal" }
-        maven { url "${project.parent.projectDir}/../../prebuilts/maven_repo/android" }
-    }
-
-    project.plugins.whenPluginAdded { plugin ->
-        def isAndroidLibrary = "com.android.build.gradle.LibraryPlugin".equals(plugin.class.name)
-        def isAndroidApp = "com.android.build.gradle.AppPlugin".equals(plugin.class.name)
-        def isJavaLibrary = "org.gradle.api.plugins.JavaPlugin".equals(plugin.class.name)
-
-        if (isAndroidLibrary || isAndroidApp) {
-            project.android.buildToolsVersion = rootProject.buildToolsVersion
-
-            // Enable code coverage for debug builds only if we are not running inside the IDE,
-            // since enabling coverage reports breaks the method parameter resolution in the IDE
-            // debugger.
-            project.android.buildTypes.debug.testCoverageEnabled = !hasProperty('android.injected.invoked.from.ide')
-
-            // Copy the class files in a jar to be later used to generate code coverage report
-            project.android.testVariants.all { v ->
-                // check if the variant has any source files
-                // and test coverage is enabled
-                if (v.buildType.testCoverageEnabled
-                        && v.sourceSets.any { !it.java.sourceFiles.isEmpty() }) {
-                    def jarifyTask = project.tasks.create(
-                            name: "package${v.name.capitalize()}ClassFilesForCoverageReport",
-                            type: Jar) {
-                        from v.testedVariant.javaCompile.destinationDir
-                        exclude "**/R.class"
-                        exclude "**/R\$*.class"
-                        exclude "**/BuildConfig.class"
-                        destinationDir file(project.distDir)
-                        archiveName "${project.archivesBaseName}-${v.baseName}-allclasses.jar"
-                    }
-                    def jacocoAntConfig =
-                            project.configurations[JacocoPlugin.ANT_CONFIGURATION_NAME]
-                    def jacocoAntArtifacts = jacocoAntConfig.resolvedConfiguration.resolvedArtifacts
-                    def version = jacocoAntArtifacts.find { "org.jacoco.ant".equals(it.name) }
-                            .moduleVersion.id.version
-                    def collectJacocoAntPackages = project.tasks.create(
-                            name: "collectJacocoAntPackages",
-                            type: Jar) {
-                        from (jacocoAntArtifacts.collect { zipTree(it.getFile()) }) {
-                            // exclude all the signatures the jar might have
-                            exclude "META-INF/*.SF"
-                            exclude "META-INF/*.DSA"
-                            exclude "META-INF/*.RSA"
-                        }
-                        destinationDir file(project.distDir)
-                        archiveName "jacocoant-" + version  + ".jar"
-                    }
-                    jarifyTask.dependsOn v.getJavaCompiler()
-                    v.assemble.dependsOn jarifyTask, collectJacocoAntPackages
-                }
-            }
-
-            // Enforce NewApi lint check as fatal.
-            project.android.lintOptions.check 'NewApi'
-            project.android.lintOptions.fatal 'NewApi'
-            project.parent.lint.dependsOn project.lint
-        }
-
-        if (isAndroidLibrary || isJavaLibrary) {
-            // Add library to the aggregate dependency report.
-            task allDeps(type: DependencyReportTask) {}
-
-            // Create release and separate zip task for library.
-            task release(type: Upload) {
-                configuration = configurations.archives
-                repositories {
-                    mavenDeployer {
-                        repository(url: uri("$rootProject.ext.supportRepoOut"))
-
-                        // Disable unique names for SNAPSHOTS so they can be updated in place.
-                        setUniqueVersion(false)
-                        doLast {
-                            // Remove any invalid maven-metadata.xml files that may have been
-                            // created for SNAPSHOT versions that are *not* uniquely versioned.
-                            pom*.each { pom ->
-                                if (pom.version.endsWith('-SNAPSHOT')) {
-                                    final File artifactDir = new File(
-                                            rootProject.ext.supportRepoOut,
-                                            pom.groupId.replace('.', '/')
-                                                    + '/' + pom.artifactId
-                                                    + '/' + pom.version)
-                                    delete fileTree(dir: artifactDir,
-                                            include: 'maven-metadata.xml*')
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-            def deployer = release.repositories.mavenDeployer
-            deployer.pom*.whenConfigured { pom ->
-                pom.dependencies.findAll { dep ->
-                    dep.groupId == 'com.android.support' && dep.artifactId != 'support-annotations'
-                }*.type = 'aar'
-            }
-
-            ext.versionDir = {
-                def groupDir = new File(rootProject.ext.supportRepoOut,
-                        project.group.replace('.','/'))
-                def artifactDir = new File(groupDir, archivesBaseName)
-                return new File(artifactDir, version)
-            }
-
-            task generateSourceProps(dependsOn: createRepository)
-            generateSourceProps.doLast({
-                def content = "Maven.GroupId=$deployer.pom.groupId\n" +
-                        "Maven.ArtifactId=$deployer.pom.artifactId\n" +
-                        "Maven.Version=$deployer.pom.version\n" +
-                        "Extra.VendorDisplay=Android\n" +
-                        "Extra.VendorId=android\n" +
-                        "Pkg.Desc=$project.name\n" +
-                        "Pkg.Revision=1\n" +
-                        "Maven.Dependencies=" +
-                        String.join(",", project.configurations.compile.allDependencies.collect {
-                            def p = parent.findProject(it.name)
-                            return p ? "$p.group:$p.archivesBaseName:$p.version" : null
-                        }.grep()) +
-                        "\n"
-                Files.write(content, new File(versionDir(), 'source.properties'), Charsets.UTF_8)
-            })
-
-            task createSeparateZip(type: Zip, dependsOn: generateSourceProps)  {
-                into archivesBaseName
-                destinationDir project.parent.ext.distDir
-                baseName = project.group
-                version = project.parent.ext.buildNumber
-            }
-            project.parent.createArchive.dependsOn createSeparateZip
-
-            // Before the upload, make sure the repo is ready.
-            release.dependsOn rootProject.tasks.prepareRepo
-
-            // Make the mainupload depend on this one.
-            mainUpload.dependsOn release
-        }
-    }
-
-    project.afterEvaluate {
-        // The archivesBaseName isn't available initially, so set it now
-        def createZipTask = project.tasks.findByName("createSeparateZip")
-        if (createZipTask != null) {
-            createZipTask.appendix = archivesBaseName
-            createZipTask.from versionDir()
-        }
-
-        // Copy instrumentation test APK into the dist dir
-        def assembleTestTask = project.tasks.findByPath('assembleAndroidTest')
-        if (assembleTestTask != null) {
-            assembleTestTask.doLast {
-                // If the project actually has some instrumentation tests, copy its APK
-                if (!project.android.sourceSets.androidTest.java.sourceFiles.isEmpty()) {
-                    def pkgTask = project.tasks.findByPath('packageDebugAndroidTest')
-                    copy {
-                        from(pkgTask.outputFile)
-                        into(rootProject.ext.testApkDistOut)
-                    }
-                }
-            }
-        }
-    }
-
-    project.afterEvaluate { p ->
-        // remove dependency on the test so that we still get coverage even if some tests fail
-        p.tasks.findAll { it instanceof JacocoReportTask}.each { task ->
-            def toBeRemoved = new ArrayList()
-            def dependencyList = task.taskDependencies.values
-            dependencyList.each { dep ->
-                if (dep instanceof String) {
-                    def t = tasks.findByName(dep)
-                    if (t instanceof DeviceProviderInstrumentTestTask) {
-                        toBeRemoved.add(dep)
-                        task.mustRunAfter(t)
-                    }
-                }
-            }
-            toBeRemoved.each { dep ->
-                dependencyList.remove(dep)
-            }
-        }
-    }
-
-    project.afterEvaluate { p ->
-        if (p.hasProperty('android')
-                && p.android.hasProperty('libraryVariants')
-                && !(p.android.hasProperty('noDocs') && p.android.noDocs)) {
-            p.android.libraryVariants.all { v ->
-                if (v.name == 'release') {
-                    registerForDocsTask(rootProject.generateDocs, p, v)
-                    registerForDocsTask(rootProject.generateApi, p, v)
-                    registerForDocsTask(rootProject.generateDiffs, p, v)
-                }
-            }
-        }
-    }
-}
-
-project.gradle.buildFinished { buildResult ->
-    if (buildResult.getFailure() != null) {
-        println()
-        println 'Build failed. Possible causes include:'
-        println '    1) Bad codes'
-        println '    2) Out of date prebuilts in prebuilts/sdk'
-        println '    3) Need to update the compileSdkVersion in a library\'s build.gradle'
-        println()
-    }
-}
+init.enableDoclavaAndJDiff(this)
\ No newline at end of file
