Merge "Force annotation project evaluation before everything else." into oc-mr1-jetpack-dev
diff --git a/app-toolkit/core-testing/build.gradle b/app-toolkit/core-testing/build.gradle
index 94b845f..8e7ccfb 100644
--- a/app-toolkit/core-testing/build.gradle
+++ b/app-toolkit/core-testing/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(project(":arch:runtime"))
     api(SUPPORT_ANNOTATIONS)
diff --git a/app-toolkit/gradle/wrapper/gradle-wrapper.jar b/app-toolkit/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..d6e2637
--- /dev/null
+++ b/app-toolkit/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/app-toolkit/gradle/wrapper/gradle-wrapper.properties b/app-toolkit/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..9d09896
--- /dev/null
+++ b/app-toolkit/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Aug 16 10:43:36 PDT 2016
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=../../../../../tools/external/gradle/gradle-4.3-bin.zip
diff --git a/app-toolkit/gradlew b/app-toolkit/gradlew
deleted file mode 120000
index 502f5a2..0000000
--- a/app-toolkit/gradlew
+++ /dev/null
@@ -1 +0,0 @@
-../gradlew
\ No newline at end of file
diff --git a/app-toolkit/gradlew b/app-toolkit/gradlew
new file mode 100755
index 0000000..4ef3a87
--- /dev/null
+++ b/app-toolkit/gradlew
@@ -0,0 +1,171 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+for s in "${@}" ; do
+    s=\"$s\"
+    APP_ARGS=$APP_ARGS" "$s
+done
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- "$DEFAULT_JVM_OPTS" "$JAVA_OPTS" "$GRADLE_OPTS" "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/app-toolkit/gradlew.bat b/app-toolkit/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/app-toolkit/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windows variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/app-toolkit/init.gradle b/app-toolkit/init.gradle
index 1bf6f98..4a334b6 100644
--- a/app-toolkit/init.gradle
+++ b/app-toolkit/init.gradle
@@ -15,15 +15,10 @@
  */
 
 import android.support.DacOptions
-import android.support.LibraryVersions
 import org.gradle.internal.os.OperatingSystem
 
-ext.inAppToolkitProject = rootProject.name == "app-toolkit"
-
-if (ext.inAppToolkitProject) {
-    apply from: "${ext.supportRootFolder}/buildSrc/init.gradle"
-    init.setSdkInLocalPropertiesFile()
-}
+apply from: "${ext.supportRootFolder}/buildSrc/init.gradle"
+init.setSdkInLocalPropertiesFile()
 
 apply from: "${ext.supportRootFolder}/app-toolkit/dependencies.gradle"
 
@@ -31,19 +26,13 @@
 def buildServerAnchorTask = rootProject.tasks.create(name : "runBuildServerCompilationTasks",
     description: "Anchor task for everything we want to run in build server.")
 
-if (ext.inAppToolkitProject) {
-    // always build offline docs for flatfoot specific builds.
-    ext.docsDac = new DacOptions("android/arch", "ARCH_DATA")
-    repos.addMavenRepositories(repositories)
-    init.setupRepoOutAndBuildNumber()
-    init.configureSubProjects()
-    init.setupRelease()
-    init.enableDoclavaAndJDiff(this)
-    rootProject.tasks["generateDocs"].exclude '**/R.java'
-}
-
-ext.testApkDistOut = distDir
-ext.testResultsDistDir = new File(distDir, "host-test-reports")
+repos.addMavenRepositories(repositories)
+init.setupRepoOutAndBuildNumber()
+init.configureSubProjects()
+init.setupRelease()
+// always build offline docs for flatfoot specific builds.
+init.enableDoclavaAndJDiff(this, new DacOptions("android/arch", "ARCH_DATA"))
+rootProject.tasks["generateDocs"].exclude '**/R.java'
 
 // flatfoot docs
 def zipFlatfootDocsTask = rootProject.tasks.create(name : "createFlatfootDocsArchive", type : Zip) {
@@ -58,8 +47,6 @@
 buildServerAnchorTask.dependsOn createArchive
 
 subprojects {
-    repos.addMavenRepositories(project.repositories)
-
     project.tasks.whenTaskAdded { task ->
         if (task.name.startsWith("assembleAndroidTest")) {
             buildServerAnchorTask.dependsOn task
diff --git a/app-toolkit/runtime/build.gradle b/app-toolkit/runtime/build.gradle
index 4d341ae..cd74aae 100644
--- a/app-toolkit/runtime/build.gradle
+++ b/app-toolkit/runtime/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(SUPPORT_ANNOTATIONS)
     api(project(":arch:common"))
diff --git a/build.gradle b/build.gradle
index 560bbda..7bbeb56 100644
--- a/build.gradle
+++ b/build.gradle
@@ -13,6 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+import android.support.DacOptions
 
 buildscript {
     ext.supportRootFolder = project.projectDir
@@ -39,7 +40,7 @@
 
 init.setupRelease()
 
-init.enableDoclavaAndJDiff(this)
+init.enableDoclavaAndJDiff(this, new DacOptions("android/support", "SUPPORT_DATA"))
 
 ///// FLATFOOT START
 
diff --git a/buildSrc/dependencies.gradle b/buildSrc/dependencies.gradle
index 5ce814a..fe664e0 100644
--- a/buildSrc/dependencies.gradle
+++ b/buildSrc/dependencies.gradle
@@ -21,6 +21,11 @@
     transitive = true
 }
 
+libs.exclude_annotations_transitive = {
+    exclude module: 'support-annotations'
+    transitive = true
+}
+
 libs.exclude_bytebuddy = {
     exclude group: 'net.bytebuddy'
 }
diff --git a/buildSrc/init.gradle b/buildSrc/init.gradle
index 2bb38b9..ee2c1cc 100644
--- a/buildSrc/init.gradle
+++ b/buildSrc/init.gradle
@@ -15,7 +15,6 @@
  */
 
 
-import android.support.DacOptions
 import android.support.DiffAndDocs
 import android.support.gmaven.GMavenVersionChecker
 import com.android.build.gradle.internal.coverage.JacocoPlugin
@@ -36,9 +35,8 @@
 
 apply from: "${supportRoot}/buildSrc/dependencies.gradle"
 apply from: "${supportRoot}/buildSrc/build_dependencies.gradle"
-ext.docsDac = new DacOptions("android/support", "SUPPORT_DATA")
 
-def enableDoclavaAndJDiff(p) {
+def enableDoclavaAndJDiff(p, dacOptions) {
     p.configurations {
         doclava
         jdiff
@@ -50,7 +48,8 @@
         jdiff build_libs.xml_parser_apis
         jdiff build_libs.xerces_impl
     }
-    DiffAndDocs.configureDiffAndDocs(rootProject, createArchive, supportRootFolder)
+    def allChecks = DiffAndDocs.configureDiffAndDocs(rootProject, supportRootFolder, dacOptions)
+    createArchive.dependsOn(allChecks)
 }
 
 def getFullSdkPath() {
diff --git a/buildSrc/repos.gradle b/buildSrc/repos.gradle
index 156ec66..ad5a621 100644
--- a/buildSrc/repos.gradle
+++ b/buildSrc/repos.gradle
@@ -37,7 +37,6 @@
 
 ext.repoNames = ["${repos.prebuiltsRoot}/gradle-plugin",
                  "${repos.prebuiltsRoot}/tools/common/m2/repository",
-                 "${repos.prebuiltsRoot}/tools/common/m2/internal",
                  "${repos.prebuiltsRoot}/maven_repo/android",
                  "${getFullSdkPath(repos.prebuiltsRoot)}/extras/m2repository"]
 
diff --git a/buildSrc/src/main/java/android/support/Version.java b/buildSrc/src/main/java/android/support/Version.java
index 69b7f5e..36c7728 100644
--- a/buildSrc/src/main/java/android/support/Version.java
+++ b/buildSrc/src/main/java/android/support/Version.java
@@ -16,6 +16,7 @@
 
 package android.support;
 
+import java.io.File;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -23,17 +24,28 @@
  * Utility class which represents a version
  */
 public class Version implements Comparable<Version> {
+    private static final Pattern VERSION_FILE_REGEX = Pattern.compile("^(\\d+\\.\\d+\\.\\d+).txt$");
+    private static final Pattern VERSION_REGEX = Pattern
+            .compile("^(\\d+)\\.(\\d+)\\.(\\d+)(-.+)?$");
+
     private final int mMajor;
     private final int mMinor;
     private final int mPatch;
     private final String mExtra;
 
     public Version(String versionString) {
-        Pattern compile = Pattern.compile("^(\\d+)\\.(\\d+)\\.(\\d+)(-.+)?$");
-        Matcher matcher = compile.matcher(versionString);
+        this(checkedMatcher(versionString));
+    }
+
+    private static Matcher checkedMatcher(String versionString) {
+        Matcher matcher = VERSION_REGEX.matcher(versionString);
         if (!matcher.matches()) {
             throw new IllegalArgumentException("Can not parse version: " + versionString);
         }
+        return matcher;
+    }
+
+    private Version(Matcher matcher) {
         mMajor = Integer.parseInt(matcher.group(1));
         mMinor = Integer.parseInt(matcher.group(2));
         mPatch = Integer.parseInt(matcher.group(3));
@@ -117,4 +129,29 @@
         result = 31 * result + (mExtra != null ? mExtra.hashCode() : 0);
         return result;
     }
+
+    /**
+     * @return Version or null, if a name of the given file doesn't match
+     */
+    public static Version from(File file) {
+        if (!file.isFile()) {
+            return null;
+        }
+        Matcher matcher = VERSION_FILE_REGEX.matcher(file.getName());
+        if (!matcher.matches()) {
+            return null;
+        }
+        return new Version(matcher.group(1));
+    }
+
+    /**
+     * @return Version or null, if the given string doesn't match
+     */
+    public static Version from(String versionString) {
+        Matcher matcher = VERSION_REGEX.matcher(versionString);
+        if (!matcher.matches()) {
+            return null;
+        }
+        return new Version(matcher);
+    }
 }
diff --git a/buildSrc/src/main/kotlin/android/support/DiffAndDocs.kt b/buildSrc/src/main/kotlin/android/support/DiffAndDocs.kt
index 4c57721..fefc3ed 100644
--- a/buildSrc/src/main/kotlin/android/support/DiffAndDocs.kt
+++ b/buildSrc/src/main/kotlin/android/support/DiffAndDocs.kt
@@ -20,6 +20,7 @@
 import android.support.checkapi.CheckApiTask
 import android.support.checkapi.UpdateApiTask
 import android.support.doclava.DoclavaTask
+import android.support.docs.GenerateDocsTask
 import android.support.jdiff.JDiffTask
 import com.android.build.gradle.LibraryExtension
 import com.android.build.gradle.api.LibraryVariant
@@ -42,8 +43,8 @@
     @JvmStatic
     fun configureDiffAndDocs(
             root: Project,
-            createArchiveTask: Task,
-            supportRootFolder: File) = configure(root, createArchiveTask, supportRootFolder)
+            supportRootFolder: File,
+            dacOptions: DacOptions) = configure(root, supportRootFolder, dacOptions)
 }
 
 private data class CheckApiConfig(
@@ -58,6 +59,7 @@
                 "visibility, you may exclude it from public API by using the @hide javadoc\n" +
                 "annotation paired with the @RestrictTo(LIBRARY_GROUP) code annotation."
 
+@Suppress("DEPRECATION")
 private fun hasJavaSources(variant: LibraryVariant) = !variant.javaCompile.source
         .filter { file -> file.name != "R.java" && file.name != "BuildConfig.java" }
         .isEmpty
@@ -98,22 +100,17 @@
 
 private fun stripExtension(fileName: String) = fileName.substringBeforeLast('.')
 
-private fun getLastReleasedApiFile(rootFolder: File, refApi: String): File? {
-    val refVersion = Version(refApi)
+private fun getLastReleasedApiFile(rootFolder: File, refVersion: Version): File? {
     val apiDir = File(rootFolder, "api")
 
     var lastFile: File? = null
     var lastVersion: Version? = null
-    val regex = Regex("(\\d+)\\.(\\d+)\\.0\\.txt")
-    // Only look at released versions and snapshots thereof, ex. X.Y.0.txt.
-    apiDir.listFiles().filter { file ->
-        regex.matches(file.name) && file.isFile
-    }.forEach { file ->
-        val version = Version(stripExtension(file.name))
-
-        if ((lastFile == null || lastVersion!! < version) && version < refVersion) {
-            lastFile = file
-            lastVersion = version
+    apiDir.listFiles().forEach { file ->
+        Version.from(file)?.let { version ->
+            if ((lastFile == null || lastVersion!! < version) && version < refVersion) {
+                lastFile = file
+                lastVersion = version
+            }
         }
     }
     return lastFile
@@ -215,12 +212,15 @@
 
 // configuration file for setting up api diffs and api docs
 private fun registerAndroidProjectForDocsTask(task: Javadoc, releaseVariant: LibraryVariant) {
+    @Suppress("DEPRECATION")
     task.dependsOn(releaseVariant.javaCompile)
     val packageDir = releaseVariant.applicationId.replace('.', '/')
+    @Suppress("DEPRECATION")
     val sources = releaseVariant.javaCompile.source.filter { file ->
         file.name != "R.java" || file.parent.endsWith(packageDir)
     }
     task.source(sources)
+    @Suppress("DEPRECATION")
     task.classpath += releaseVariant.getCompileClasspath(null) +
             task.project.files(releaseVariant.javaCompile.destinationDir)
 }
@@ -247,15 +247,14 @@
  */
 private fun createOldApiXml(project: Project, doclavaConfig: Configuration) =
         project.tasks.createWithConfig("oldApiXml", ApiXmlConversionTask::class.java) {
-            val regex = Regex("(\\d+\\.){2}\\d+")
-            val toApi = project.processProperty("toApi")
+            val toApi = project.processProperty("toApi")?.let(Version::from)
             val fromApi = project.processProperty("fromApi")
             classpath = project.files(doclavaConfig.resolve())
             val rootFolder = project.projectDir
             if (fromApi != null) {
                 // Use an explicit API file.
                 inputApiFile = File(rootFolder, "api/$fromApi.txt")
-            } else if (toApi != null && regex.matches(toApi)) {
+            } else if (toApi != null) {
                 // If toApi matches released API (X.Y.Z) format, use the most recently
                 // released API file prior to toApi.
                 inputApiFile = getLastReleasedApiFile(rootFolder, toApi)
@@ -401,7 +400,8 @@
         project: Project,
         generateSdkApiTask: Task,
         doclavaConfig: Configuration,
-        supportRootFolder: File) =
+        supportRootFolder: File,
+        dacOptions: DacOptions) =
         project.tasks.createWithConfig("generateDocs", GenerateDocsTask::class.java) {
             dependsOn(generateSdkApiTask, doclavaConfig)
             group = JavaBasePlugin.DOCUMENTATION_GROUP
@@ -439,8 +439,8 @@
                 if (!offline) {
                     addStringOption("toroot", "/")
                     addBooleanOption("devsite", true)
-                    addStringOption("dac_libraryroot", project.docsDac().libraryroot)
-                    addStringOption("dac_dataname", project.docsDac().dataname)
+                    addStringOption("dac_libraryroot", dacOptions.libraryroot)
+                    addStringOption("dac_dataname", dacOptions.dataname)
                 }
 
                 exclude("**/BuildConfig.java")
@@ -449,10 +449,12 @@
             addArtifactsAndSince()
         }
 
-private fun initializeApiChecksForProject(
-        project: Project,
-        generateDocs: GenerateDocsTask,
-        createArchive: Task): Pair<DoclavaTask, JDiffTask> {
+private data class Tasks(
+        val generateApi: DoclavaTask,
+        val generateDiffs: JDiffTask,
+        val checkApiTask: CheckApiTask)
+
+private fun initializeApiChecksForProject(project: Project, generateDocs: GenerateDocsTask): Tasks {
     if (!project.hasProperty("docsDir")) {
         project.extensions.add("docsDir", File(project.rootProject.docsDir(), project.name))
     }
@@ -467,7 +469,7 @@
     val verifyUpdateTask = createVerifyUpdateApiAllowedTask(project)
 
     // Make sure the API surface has not broken since the last release.
-    val lastReleasedApiFile = getLastReleasedApiFile(workingDir, version.toString())
+    val lastReleasedApiFile = getLastReleasedApiFile(workingDir, version)
 
     val whitelistFile = lastReleasedApiFile?.let { apiFile ->
         File(lastReleasedApiFile.parentFile, stripExtension(apiFile.name) + ".ignore")
@@ -520,56 +522,16 @@
     // Associate current API surface with the Maven artifact.
     generateDocs.addArtifact(generateApi.apiFile!!.absolutePath, artifact)
     generateDocs.dependsOn(generateApi)
-    createArchive.dependsOn(checkApi)
-    return (generateApi to generateDiffTask)
+    return Tasks(generateApi, generateDiffTask, checkApi)
 }
 
-private open class GenerateDocsTask : DoclavaTask() {
-
-    private data class Since(val path: String, val apiLevel: String)
-    private data class Artifact(val path: String, val artifact: String)
-
-    private val sinces = mutableListOf<Since>()
-    private val artifacts = mutableListOf<Artifact>()
-
-    fun addArtifactsAndSince() {
-        doFirst {
-            coreJavadocOptions {
-                if (sinces.isNotEmpty()) {
-                    addMultilineMultiValueOption("since").value = sinces.map { (path, apiLevel) ->
-                        listOf(path, apiLevel)
-                    }
-                }
-
-                if (artifacts.isNotEmpty()) {
-                    addMultilineMultiValueOption("artifact").value = artifacts.map { artifact ->
-                        listOf(artifact.path, artifact.artifact)
-                    }
-                }
-            }
-        }
-    }
-
-    fun addSinceFilesFrom(dir: File) {
-        val regex = Regex("(\\d+\\.\\d+\\.\\d).txt")
-        val apiDir = File(dir, "api")
-        apiDir.listFiles { file ->
-            file.isFile && regex.matches(file.name)
-        }.forEach { apiFile ->
-            val matchResult = regex.matchEntire(apiFile.name)!!
-            sinces.add(Since(apiFile.absolutePath, matchResult.groups[1]!!.value))
-        }
-    }
-
-    fun addArtifact(path: String, artifact: String) = artifacts.add(Artifact(path, artifact))
-}
-
-private fun configure(root: Project, createArchiveTask: Task, supportRootFolder: File) {
+private fun configure(root: Project, supportRootFolder: File, dacOptions: DacOptions): Task {
+    val allChecks = root.tasks.create("AnchorCheckApis")
     val doclavaConfiguration = root.configurations.getByName("doclava")
     val generateSdkApiTask = createGenerateSdkApiTask(root, doclavaConfiguration)
 
     val generateDocsTask = createGenerateDocsTask(root, generateSdkApiTask,
-            doclavaConfiguration, supportRootFolder)
+            doclavaConfiguration, supportRootFolder, dacOptions)
     createDistDocsTask(root, generateDocsTask)
 
     root.subprojects { subProject ->
@@ -603,10 +565,10 @@
                                     "an api folder, ignoring API tasks.")
                             return@all
                         }
-                        val (generateApi, generateDiffs) = initializeApiChecksForProject(project,
-                                generateDocsTask, createArchiveTask)
-                        registerAndroidProjectForDocsTask(generateApi, variant)
-                        registerAndroidProjectForDocsTask(generateDiffs, variant)
+                        val tasks = initializeApiChecksForProject(project, generateDocsTask)
+                        registerAndroidProjectForDocsTask(tasks.generateApi, variant)
+                        registerAndroidProjectForDocsTask(tasks.generateDiffs, variant)
+                        allChecks.dependsOn(tasks.checkApiTask)
                     }
                 }
             } else if (project.hasProperty("compileJava")) {
@@ -618,15 +580,15 @@
                     return@afterEvaluate
                 }
                 project.afterEvaluate { proj ->
-                    val (generateApi, generateDiffs) = initializeApiChecksForProject(proj,
-                            generateDocsTask,
-                            createArchiveTask)
-                    registerJavaProjectForDocsTask(generateApi, compileJava)
-                    registerJavaProjectForDocsTask(generateDiffs, compileJava)
+                    val tasks = initializeApiChecksForProject(proj, generateDocsTask)
+                    registerJavaProjectForDocsTask(tasks.generateApi, compileJava)
+                    registerJavaProjectForDocsTask(tasks.generateDiffs, compileJava)
+                    allChecks.dependsOn(tasks.checkApiTask)
                 }
             }
         }
     }
+    return allChecks
 }
 
 private fun sdkApiFile(project: Project) = File(project.docsDir(), "release/sdk_current.txt")
@@ -647,14 +609,12 @@
 
 private fun Project.androidSrcJar() = rootProject.properties["androidSrcJar"] as File
 
-private fun Project.version() = Version(project.properties["version"] as String)
+private fun Project.version() = Version(project.version as String)
 
 private fun Project.buildNumber() = properties["buildNumber"] as String
 
 private fun Project.androidApiTxt() = properties["androidApiTxt"] as? File
 
-private fun Project.docsDac() = properties["docsDac"] as DacOptions
-
 private fun Project.processProperty(name: String) =
         if (hasProperty(name)) {
             properties[name] as String
diff --git a/buildSrc/src/main/kotlin/android/support/SupportAndroidLibraryPlugin.kt b/buildSrc/src/main/kotlin/android/support/SupportAndroidLibraryPlugin.kt
index b804125..8b94cd7 100644
--- a/buildSrc/src/main/kotlin/android/support/SupportAndroidLibraryPlugin.kt
+++ b/buildSrc/src/main/kotlin/android/support/SupportAndroidLibraryPlugin.kt
@@ -43,6 +43,8 @@
             val library = project.extensions.findByType(LibraryExtension::class.java)
                     ?: return@afterEvaluate
 
+            library.defaultConfig.minSdkVersion(supportLibraryExtension.minSdkVersion)
+
             if (supportLibraryExtension.legacySourceLocation) {
                 // We use a non-standard manifest path.
                 library.sourceSets.getByName("main").manifest.srcFile("AndroidManifest.xml")
@@ -166,6 +168,9 @@
     lintOptions.isAbortOnError = true
     lintOptions.isIgnoreWarnings = true
 
+    // Skip lintVital tasks on assemble. We explicitly run lintRelease for libraries.
+    lintOptions.isCheckReleaseBuilds = false
+
     // Write output directly to the console (and nowhere else).
     lintOptions.textOutput("stderr")
     lintOptions.textReport = true
diff --git a/buildSrc/src/main/kotlin/android/support/SupportLibraryExtension.kt b/buildSrc/src/main/kotlin/android/support/SupportLibraryExtension.kt
index d5519c7..82f1e91 100644
--- a/buildSrc/src/main/kotlin/android/support/SupportLibraryExtension.kt
+++ b/buildSrc/src/main/kotlin/android/support/SupportLibraryExtension.kt
@@ -41,6 +41,10 @@
      * support using it as a library.
      */
     var generateDocs = true
+    /**
+     * If unset minSdkVersion will be 14.
+     */
+    var minSdkVersion: Int = 14
 
     fun license(closure: Closure<*>): License {
         val license = project.configure(License(), closure) as License
diff --git a/buildSrc/src/main/kotlin/android/support/docs/GenerateDocsTask.kt b/buildSrc/src/main/kotlin/android/support/docs/GenerateDocsTask.kt
new file mode 100644
index 0000000..2183b88
--- /dev/null
+++ b/buildSrc/src/main/kotlin/android/support/docs/GenerateDocsTask.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright 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.
+ */
+
+package android.support.docs
+
+import android.support.Version
+import android.support.doclava.DoclavaTask
+import java.io.File
+
+open class GenerateDocsTask : DoclavaTask() {
+
+    private data class Since(val path: String, val apiLevel: String)
+    private data class Artifact(val path: String, val artifact: String)
+
+    private val sinces = mutableListOf<Since>()
+    private val artifacts = mutableListOf<Artifact>()
+
+    fun addArtifactsAndSince() {
+        doFirst {
+            coreJavadocOptions {
+                if (sinces.isNotEmpty()) {
+                    addMultilineMultiValueOption("since").value = sinces.map { (path, apiLevel) ->
+                        listOf(path, apiLevel)
+                    }
+                }
+
+                if (artifacts.isNotEmpty()) {
+                    addMultilineMultiValueOption("artifact").value = artifacts.map { artifact ->
+                        listOf(artifact.path, artifact.artifact)
+                    }
+                }
+            }
+        }
+    }
+
+    fun addSinceFilesFrom(dir: File) {
+        File(dir, "api").listFiles().forEach { file ->
+            Version.from(file)?.let { version ->
+                sinces.add(Since(file.absolutePath, version.toString()))
+            }
+        }
+    }
+
+    fun addArtifact(path: String, artifact: String) = artifacts.add(Artifact(path, artifact))
+}
\ No newline at end of file
diff --git a/car/build.gradle b/car/build.gradle
index 3970df9..7ea0873 100644
--- a/car/build.gradle
+++ b/car/build.gradle
@@ -1,5 +1,6 @@
 import static android.support.dependencies.DependenciesKt.*
 import android.support.LibraryGroups
+import android.support.LibraryVersions
 
 plugins {
     id("SupportAndroidLibraryPlugin")
@@ -20,10 +21,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 24
-    }
-
     sourceSets {
         main.res.srcDirs 'res', 'res-public'
     }
@@ -32,9 +29,11 @@
 supportLibrary {
     name = "Android Car Support UI"
     publish = false
+    mavenVersion = LibraryVersions.SUPPORT_LIBRARY
     mavenGroup = LibraryGroups.SUPPORT
     inceptionYear = "2017"
     description = "Android Car Support UI"
     java8Library = true
     legacySourceLocation = true
+    minSdkVersion = 24
 }
diff --git a/car/res/layout/car_paged_list_item_content.xml b/car/res/layout/car_paged_list_item_content.xml
index 0e6b809..5d01c59 100644
--- a/car/res/layout/car_paged_list_item_content.xml
+++ b/car/res/layout/car_paged_list_item_content.xml
@@ -32,9 +32,10 @@
         android:id="@+id/title"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_toStartOf="@id/supplemental_actions"
+        android:layout_toStartOf="@+id/supplemental_actions"
         android:singleLine="true"
         android:ellipsize="end"/>
+
     <TextView
         android:id="@+id/body"
         android:layout_width="match_parent"
@@ -43,7 +44,7 @@
 
     <!-- Supplemental action(s) - supports either 1 supplemental icon or up to 2 action buttons. -->
     <LinearLayout
-        android:id="@+id/supplemental_actions"
+        android:id="@id/supplemental_actions"
         android:layout_width="wrap_content"
         android:layout_height="match_parent"
         android:layout_alignParentEnd="true"
diff --git a/compat/build.gradle b/compat/build.gradle
index c104d7a..8f44285 100644
--- a/compat/build.gradle
+++ b/compat/build.gradle
@@ -20,10 +20,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.aidl.srcDirs = ['src/main/java']
         main.res.srcDirs 'res', 'res-public'
diff --git a/content/build.gradle b/content/build.gradle
index 9091053..cff7db7 100644
--- a/content/build.gradle
+++ b/content/build.gradle
@@ -31,12 +31,6 @@
     androidTestImplementation(ESPRESSO_CORE)
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     name = "Android Support Content"
     publish = true
diff --git a/core-ui/build.gradle b/core-ui/build.gradle
index f7cd2d7..4ff27cb 100644
--- a/core-ui/build.gradle
+++ b/core-ui/build.gradle
@@ -23,17 +23,12 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.res.srcDirs = [
                 'res',
                 'res-public'
         ]
     }
-
     buildTypes.all {
         consumerProguardFiles 'proguard-rules.pro'
     }
diff --git a/core-utils/build.gradle b/core-utils/build.gradle
index 3f1efa1..75555c0 100644
--- a/core-utils/build.gradle
+++ b/core-utils/build.gradle
@@ -17,10 +17,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.java.srcDirs = [
                 'kitkat',
diff --git a/customtabs/build.gradle b/customtabs/build.gradle
index 75e28f7..cf1c775 100644
--- a/customtabs/build.gradle
+++ b/customtabs/build.gradle
@@ -16,10 +16,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion(15)
-    }
-
     sourceSets {
         main.aidl.srcDirs = ["src/main/java"]
     }
@@ -33,4 +29,5 @@
     inceptionYear = "2015"
     description = "Android Support Custom Tabs"
     legacySourceLocation = true
+    minSdkVersion = 15
 }
diff --git a/design/build.gradle b/design/build.gradle
index e7ebc91..baa94ea 100644
--- a/design/build.gradle
+++ b/design/build.gradle
@@ -22,7 +22,6 @@
 
 android {
     defaultConfig {
-        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
diff --git a/dynamic-animation/build.gradle b/dynamic-animation/build.gradle
index ac5623d..10e49e0 100644
--- a/dynamic-animation/build.gradle
+++ b/dynamic-animation/build.gradle
@@ -15,12 +15,6 @@
     androidTestImplementation(DEXMAKER_MOCKITO, libs.exclude_bytebuddy) // DexMaker has it"s own MockMaker
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     name = "Android Support DynamicAnimation"
     publish = true
diff --git a/emoji/appcompat/build.gradle b/emoji/appcompat/build.gradle
index 3fe04d8..a4aaff2 100644
--- a/emoji/appcompat/build.gradle
+++ b/emoji/appcompat/build.gradle
@@ -22,17 +22,10 @@
 }
 
 dependencies {
-    api fileTree(include: ['*.jar'], dir: 'libs')
     api(project(":support-emoji"))
     api(project(":appcompat-v7"))
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     name = "Android Emoji AppCompat"
     publish = true
diff --git a/emoji/bundled/build.gradle b/emoji/bundled/build.gradle
index 013ab85..a2760d3 100644
--- a/emoji/bundled/build.gradle
+++ b/emoji/bundled/build.gradle
@@ -10,10 +10,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.assets.srcDirs new File(fontDir, "font").getAbsolutePath()
     }
diff --git a/emoji/core/build.gradle b/emoji/core/build.gradle
index a311f25..8d470f0 100644
--- a/emoji/core/build.gradle
+++ b/emoji/core/build.gradle
@@ -32,10 +32,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main {
             // We use a non-standard manifest path.
diff --git a/exifinterface/build.gradle b/exifinterface/build.gradle
index fa4d7b4..67b458f 100644
--- a/exifinterface/build.gradle
+++ b/exifinterface/build.gradle
@@ -12,12 +12,6 @@
     androidTestImplementation(TEST_RUNNER)
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     name = "Android Support ExifInterface"
     publish = true
diff --git a/fragment/build.gradle b/fragment/build.gradle
index b1cc47e..d5371f5 100644
--- a/fragment/build.gradle
+++ b/fragment/build.gradle
@@ -21,12 +21,6 @@
     }
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     name = "Android Support Library fragment"
     publish = true
diff --git a/graphics/drawable/animated/build.gradle b/graphics/drawable/animated/build.gradle
index e76f846..30827a9 100644
--- a/graphics/drawable/animated/build.gradle
+++ b/graphics/drawable/animated/build.gradle
@@ -16,7 +16,6 @@
 
 android {
     defaultConfig {
-        minSdkVersion(14)
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
diff --git a/graphics/drawable/static/build.gradle b/graphics/drawable/static/build.gradle
index 8575d6a..f0ac9f0 100644
--- a/graphics/drawable/static/build.gradle
+++ b/graphics/drawable/static/build.gradle
@@ -15,7 +15,6 @@
 
 android {
     defaultConfig {
-        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
diff --git a/leanback/build.gradle b/leanback/build.gradle
index 036f08f..05a91df 100644
--- a/leanback/build.gradle
+++ b/leanback/build.gradle
@@ -20,10 +20,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 17
-    }
-
     sourceSets {
         main.java.srcDirs = [
                 'common',
@@ -44,4 +40,5 @@
     inceptionYear = "2014"
     description = "Android Support Leanback v17"
     legacySourceLocation = true
+    minSdkVersion = 17
 }
diff --git a/lifecycle/extensions/build.gradle b/lifecycle/extensions/build.gradle
index 0b30e23..070394d 100644
--- a/lifecycle/extensions/build.gradle
+++ b/lifecycle/extensions/build.gradle
@@ -24,10 +24,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-
     buildTypes.all {
         consumerProguardFiles 'proguard-rules.pro'
     }
diff --git a/lifecycle/gradle/wrapper/gradle-wrapper.jar b/lifecycle/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..13372ae
--- /dev/null
+++ b/lifecycle/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/lifecycle/gradle/wrapper/gradle-wrapper.properties b/lifecycle/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..b519e0a
--- /dev/null
+++ b/lifecycle/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Mon Dec 28 10:00:20 PST 2015
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-bin.zip
diff --git a/lifecycle/gradlew b/lifecycle/gradlew
deleted file mode 120000
index 502f5a2..0000000
--- a/lifecycle/gradlew
+++ /dev/null
@@ -1 +0,0 @@
-../gradlew
\ No newline at end of file
diff --git a/lifecycle/gradlew b/lifecycle/gradlew
new file mode 100755
index 0000000..9d82f78
--- /dev/null
+++ b/lifecycle/gradlew
@@ -0,0 +1,160 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/lifecycle/gradlew.bat b/lifecycle/gradlew.bat
new file mode 100644
index 0000000..aec9973
--- /dev/null
+++ b/lifecycle/gradlew.bat
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windowz variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+if "%@eval[2+2]" == "4" goto 4NT_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+goto execute

+

+:4NT_args

+@rem Get arguments from the 4NT Shell from JP Software

+set CMD_LINE_ARGS=%$

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/lifecycle/reactivestreams/build.gradle b/lifecycle/reactivestreams/build.gradle
index 976f6ba..fbbc82f 100644
--- a/lifecycle/reactivestreams/build.gradle
+++ b/lifecycle/reactivestreams/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(project(":arch:common"))
     api(project(":lifecycle:common"))
diff --git a/lifecycle/runtime/build.gradle b/lifecycle/runtime/build.gradle
index 3c29c13..aee73c0 100644
--- a/lifecycle/runtime/build.gradle
+++ b/lifecycle/runtime/build.gradle
@@ -8,10 +8,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-
     buildTypes.all {
         consumerProguardFiles 'proguard-rules.pro'
     }
diff --git a/media-compat/build.gradle b/media-compat/build.gradle
index 18ff5a3..ffa6e93 100644
--- a/media-compat/build.gradle
+++ b/media-compat/build.gradle
@@ -18,10 +18,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.java.srcDirs = [
                 'api21',
diff --git a/media-compat/version-compat-tests/current/client/build.gradle b/media-compat/version-compat-tests/current/client/build.gradle
index aeb82c1..9c4f879 100644
--- a/media-compat/version-compat-tests/current/client/build.gradle
+++ b/media-compat/version-compat-tests/current/client/build.gradle
@@ -27,12 +27,6 @@
     androidTestImplementation(TEST_RUNNER)
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     legacySourceLocation = true
 }
\ No newline at end of file
diff --git a/media-compat/version-compat-tests/current/service/build.gradle b/media-compat/version-compat-tests/current/service/build.gradle
index cf82918..3cb3a49 100644
--- a/media-compat/version-compat-tests/current/service/build.gradle
+++ b/media-compat/version-compat-tests/current/service/build.gradle
@@ -27,12 +27,6 @@
     androidTestImplementation(TEST_RUNNER)
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     legacySourceLocation = true
 }
diff --git a/paging/runtime/build.gradle b/paging/runtime/build.gradle
index 085925c..180e399 100644
--- a/paging/runtime/build.gradle
+++ b/paging/runtime/build.gradle
@@ -24,12 +24,6 @@
     id("kotlin-android")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(project(":arch:runtime"))
     api(project(":paging:common"))
diff --git a/percent/build.gradle b/percent/build.gradle
index 7d5a651..951a0e0 100644
--- a/percent/build.gradle
+++ b/percent/build.gradle
@@ -14,10 +14,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.res.srcDir 'res'
     }
diff --git a/persistence/db-framework/build.gradle b/persistence/db-framework/build.gradle
index c0ab887..bae3d02 100644
--- a/persistence/db-framework/build.gradle
+++ b/persistence/db-framework/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(SUPPORT_ANNOTATIONS)
     api(project(":persistence:db"))
diff --git a/persistence/db/build.gradle b/persistence/db/build.gradle
index 0dfdeb7..657ef1e 100644
--- a/persistence/db/build.gradle
+++ b/persistence/db/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(SUPPORT_ANNOTATIONS)
 }
diff --git a/preference-leanback/build.gradle b/preference-leanback/build.gradle
index f4d2fd6..c5fb9f5 100644
--- a/preference-leanback/build.gradle
+++ b/preference-leanback/build.gradle
@@ -15,10 +15,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 17
-    }
-
     sourceSets {
         main.java.srcDirs = [
                 'api21',
@@ -36,4 +32,5 @@
     inceptionYear = "2015"
     description = "Android Support Leanback Preference v17"
     legacySourceLocation = true
+    minSdkVersion = 17
 }
\ No newline at end of file
diff --git a/recommendation/build.gradle b/recommendation/build.gradle
index 83fa375..bf2265d 100644
--- a/recommendation/build.gradle
+++ b/recommendation/build.gradle
@@ -9,12 +9,6 @@
     api(project(":support-annotations"))
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 21
-    }
-}
-
 supportLibrary {
     name = "Android Support Recommendation"
     publish = true
@@ -23,4 +17,5 @@
     inceptionYear = "2015"
     description = "Android Support Recommendation"
     legacySourceLocation = true
+    minSdkVersion = 21
 }
diff --git a/room/gradle/wrapper/gradle-wrapper.jar b/room/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..d6e2637
--- /dev/null
+++ b/room/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/room/gradle/wrapper/gradle-wrapper.properties b/room/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..2f8bf03
--- /dev/null
+++ b/room/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Fri Dec 09 13:07:04 PST 2016
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.4-bin.zip
diff --git a/room/gradlew b/room/gradlew
deleted file mode 120000
index 502f5a2..0000000
--- a/room/gradlew
+++ /dev/null
@@ -1 +0,0 @@
-../gradlew
\ No newline at end of file
diff --git a/room/gradlew b/room/gradlew
new file mode 100755
index 0000000..4ef3a87
--- /dev/null
+++ b/room/gradlew
@@ -0,0 +1,171 @@
+#!/usr/bin/env sh
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+for s in "${@}" ; do
+    s=\"$s\"
+    APP_ARGS=$APP_ARGS" "$s
+done
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- "$DEFAULT_JVM_OPTS" "$JAVA_OPTS" "$GRADLE_OPTS" "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+  cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
diff --git a/room/gradlew.bat b/room/gradlew.bat
new file mode 100644
index 0000000..e95643d
--- /dev/null
+++ b/room/gradlew.bat
@@ -0,0 +1,84 @@
+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS=

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windows variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/room/runtime/build.gradle b/room/runtime/build.gradle
index eda45df..1022616 100644
--- a/room/runtime/build.gradle
+++ b/room/runtime/build.gradle
@@ -24,10 +24,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-
     buildTypes.all {
         consumerProguardFiles 'proguard-rules.pro'
     }
diff --git a/room/rxjava2/build.gradle b/room/rxjava2/build.gradle
index e099fae..d3d7bc9 100644
--- a/room/rxjava2/build.gradle
+++ b/room/rxjava2/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(project(":room:common"))
     api(project(":room:runtime"))
diff --git a/room/testing/build.gradle b/room/testing/build.gradle
index 8ca2908..d584b54 100644
--- a/room/testing/build.gradle
+++ b/room/testing/build.gradle
@@ -23,12 +23,6 @@
     id("SupportAndroidLibraryPlugin")
 }
 
-android {
-    defaultConfig {
-        minSdkVersion flatfoot.min_sdk
-    }
-}
-
 dependencies {
     api(project(":room:common"))
     api(project(":room:runtime"))
diff --git a/testutils/build.gradle b/testutils/build.gradle
index 074ab34..6a340b0 100644
--- a/testutils/build.gradle
+++ b/testutils/build.gradle
@@ -32,9 +32,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
     lintOptions {
         disable 'InvalidPackage' // Lint is unhappy about junit package
     }
diff --git a/transition/build.gradle b/transition/build.gradle
index dcf3a76..7aef8b5 100644
--- a/transition/build.gradle
+++ b/transition/build.gradle
@@ -20,10 +20,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.res.srcDirs = [
                 'res',
diff --git a/tv-provider/build.gradle b/tv-provider/build.gradle
index 7090108..8cb0c9e 100644
--- a/tv-provider/build.gradle
+++ b/tv-provider/build.gradle
@@ -13,12 +13,6 @@
     androidTestImplementation(TEST_RUNNER)
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 21
-    }
-}
-
 supportLibrary {
     name = "Android Support TV Provider"
     publish = true
@@ -27,4 +21,5 @@
     inceptionYear = "2017"
     description = "Android Support Library for TV Provider"
     legacySourceLocation = true
+    minSdkVersion = 21
 }
\ No newline at end of file
diff --git a/v13/build.gradle b/v13/build.gradle
index 425a31f..88e0bc0 100644
--- a/v13/build.gradle
+++ b/v13/build.gradle
@@ -17,10 +17,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.java.srcDirs = [
                 'java'
diff --git a/v14/preference/build.gradle b/v14/preference/build.gradle
index c129cba..5c657b1 100644
--- a/v14/preference/build.gradle
+++ b/v14/preference/build.gradle
@@ -29,10 +29,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.res.srcDir 'res'
     }
diff --git a/v4/build.gradle b/v4/build.gradle
index ac5a9f5..0558659 100644
--- a/v4/build.gradle
+++ b/v4/build.gradle
@@ -15,7 +15,6 @@
 
 android {
     defaultConfig {
-        minSdkVersion 14
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
diff --git a/v7/appcompat/build.gradle b/v7/appcompat/build.gradle
index a3b80a8..106d0aa 100644
--- a/v7/appcompat/build.gradle
+++ b/v7/appcompat/build.gradle
@@ -24,7 +24,6 @@
 
 android {
     defaultConfig {
-        minSdkVersion(14)
         // This disables the builds tools automatic vector -> PNG generation
         generatedDensities = []
     }
diff --git a/v7/cardview/build.gradle b/v7/cardview/build.gradle
index a6f98e1..742376d 100644
--- a/v7/cardview/build.gradle
+++ b/v7/cardview/build.gradle
@@ -10,10 +10,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion(14)
-    }
-
     sourceSets {
         main.res.srcDir("res")
     }
diff --git a/v7/gridlayout/build.gradle b/v7/gridlayout/build.gradle
index 7df5397..ae8bac0 100644
--- a/v7/gridlayout/build.gradle
+++ b/v7/gridlayout/build.gradle
@@ -15,10 +15,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.res.srcDir 'res'
     }
diff --git a/v7/mediarouter/build.gradle b/v7/mediarouter/build.gradle
index dbf3da5..a3fd18e 100644
--- a/v7/mediarouter/build.gradle
+++ b/v7/mediarouter/build.gradle
@@ -17,10 +17,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.java.srcDirs = [
                 'jellybean',
diff --git a/v7/palette/build.gradle b/v7/palette/build.gradle
index a1b1fc9..b1b12c7 100644
--- a/v7/palette/build.gradle
+++ b/v7/palette/build.gradle
@@ -13,12 +13,6 @@
     androidTestImplementation(TEST_RUNNER)
 }
 
-android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-}
-
 supportLibrary {
     name = "Android Support Palette v7"
     publish = true
diff --git a/v7/preference/build.gradle b/v7/preference/build.gradle
index 698afb6..2000ddd 100644
--- a/v7/preference/build.gradle
+++ b/v7/preference/build.gradle
@@ -34,10 +34,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 14
-    }
-
     sourceSets {
         main.res.srcDirs = [
                 'res',
diff --git a/v7/recyclerview/build.gradle b/v7/recyclerview/build.gradle
index 0a83989..a14ea97 100644
--- a/v7/recyclerview/build.gradle
+++ b/v7/recyclerview/build.gradle
@@ -24,10 +24,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion(14)
-    }
-
     sourceSets {
         main.res.srcDirs "res", "res-public"
     }
diff --git a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
index de23213..dd2c650 100644
--- a/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
+++ b/v7/recyclerview/tests/src/android/support/v7/widget/LinearLayoutManagerTest.java
@@ -800,7 +800,7 @@
         });
     }
 
-    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.JELLY_BEAN)
+    @SdkSuppress(minSdkVersion = Build.VERSION_CODES.KITKAT)
     @Test
     public void hiddenNoneRemoveViewAccessibility() throws Throwable {
         final Config config = new Config();
diff --git a/wear/build.gradle b/wear/build.gradle
index 79c69ee..4878dab 100644
--- a/wear/build.gradle
+++ b/wear/build.gradle
@@ -22,10 +22,6 @@
 }
 
 android {
-    defaultConfig {
-        minSdkVersion 23
-    }
-
     sourceSets {
         main.res.srcDirs 'res', 'res-public'
         main.resources {
@@ -45,4 +41,5 @@
     mavenGroup = LibraryGroups.SUPPORT
     inceptionYear = "2016"
     description = "Android Wear Support UI"
+    minSdkVersion = 23
 }