Merge "Proguard support."
diff --git a/.gitignore b/.gitignore
index 505f40b..f529dfa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@
 tests/libsTest/*/build
 tests/multiproject/*/build
 tests/localJars/*/build
+tests/proguardLib/*/build
 tests/renderscriptInLib/*/build
 tests/repo/*/build
 tests/tictactoe/*/build
diff --git a/builder-model/src/main/java/com/android/builder/model/BuildConfig.java b/builder-model/src/main/java/com/android/builder/model/BuildConfig.java
index f0c4844..6c1c353 100644
--- a/builder-model/src/main/java/com/android/builder/model/BuildConfig.java
+++ b/builder-model/src/main/java/com/android/builder/model/BuildConfig.java
@@ -31,4 +31,7 @@
      */
     @NonNull
     List<String> getBuildConfig();
+
+    @NonNull
+    List<Object> getProguardFiles();
 }
diff --git a/builder/src/main/java/com/android/builder/AndroidBuilder.java b/builder/src/main/java/com/android/builder/AndroidBuilder.java
index 5a7373c..d63854b 100644
--- a/builder/src/main/java/com/android/builder/AndroidBuilder.java
+++ b/builder/src/main/java/com/android/builder/AndroidBuilder.java
@@ -83,7 +83,7 @@
  * {@link #processTestManifest(String, int, int, String, String, java.util.List, String)}
  * {@link #processResources(java.io.File, java.io.File, java.io.File, java.util.List, String, String, String, String, String, com.android.builder.VariantConfiguration.Type, boolean, AaptOptions)}
  * {@link #compileAllAidlFiles(java.util.List, java.io.File, java.util.List, com.android.builder.compiling.DependencyFileProcessor)}
- * {@link #convertByteCode(Iterable, Iterable, String, DexOptions, boolean)}
+ * {@link #convertByteCode(Iterable, Iterable, File, String, DexOptions, boolean)}
  * {@link #packageApk(String, String, java.util.List, String, String, boolean, com.android.builder.signing.SigningConfig, String)}
  *
  * Java compilation is not handled but the builder provides the runtime classpath with
@@ -904,6 +904,7 @@
     public void convertByteCode(
             @NonNull Iterable<File> classesLocation,
             @NonNull Iterable<File> libraries,
+            @Nullable File proguardFile,
             @NonNull String outDexFile,
             @NonNull DexOptions dexOptions,
             boolean incremental) throws IOException, InterruptedException {
@@ -940,6 +941,7 @@
         command.add("--output");
         command.add(outDexFile);
 
+        // clean up and add class inputs
         List<String> classesList = Lists.newArrayList();
         for (File f : classesLocation) {
             if (f != null && f.exists()) {
@@ -947,6 +949,12 @@
             }
         }
 
+        if (!classesList.isEmpty()) {
+            mLogger.verbose("Dex class inputs: " + classesList);
+            command.addAll(classesList);
+        }
+
+        // clean up and add library inputs.
         List<String> libraryList = Lists.newArrayList();
         for (File f : libraries) {
             if (f != null && f.exists()) {
@@ -954,16 +962,15 @@
             }
         }
 
+        if (!libraryList.isEmpty()) {
+            mLogger.verbose("Dex library inputs: " + libraryList);
+            command.addAll(libraryList);
+        }
 
-        mLogger.info("dx command: %s", command.toString());
-
-        mLogger.verbose("Dex class inputs: " + classesList);
-
-        command.addAll(classesList);
-
-        mLogger.verbose("Dex library inputs: " + libraryList);
-
-        command.addAll(libraryList);
+        if (proguardFile != null && proguardFile.exists()) {
+            mLogger.verbose("ProGuarded inputs " + proguardFile);
+            command.add(proguardFile.getAbsolutePath());
+        }
 
         mCmdLineRunner.runCmdLine(command);
     }
diff --git a/builder/src/main/java/com/android/builder/VariantConfiguration.java b/builder/src/main/java/com/android/builder/VariantConfiguration.java
index 97d4474..2da3a8b 100644
--- a/builder/src/main/java/com/android/builder/VariantConfiguration.java
+++ b/builder/src/main/java/com/android/builder/VariantConfiguration.java
@@ -826,6 +826,31 @@
         return signingConfig != null && signingConfig.isSigningReady();
     }
 
+    @NonNull
+    public List<Object> getProguardFiles(boolean includeLibraries) {
+        List<Object> fullList = Lists.newArrayList();
+
+        // add the config files from the build type, main config and flavors
+        fullList.addAll(mDefaultConfig.getProguardFiles());
+        fullList.addAll(mBuildType.getProguardFiles());
+
+        for (DefaultProductFlavor flavor : mFlavorConfigs) {
+            fullList.addAll(flavor.getProguardFiles());
+        }
+
+        // now add the one coming from the library dependencies
+        if (includeLibraries) {
+            for (LibraryDependency libraryDependency : mFlatLibraries) {
+                File proguardRules = libraryDependency.getProguardRules();
+                if (proguardRules.exists()) {
+                    fullList.add(proguardRules);
+                }
+            }
+        }
+
+        return fullList;
+    }
+
     protected void validate() {
         if (mType != Type.TEST) {
             File manifest = mDefaultSourceProvider.getManifestFile();
diff --git a/builder/src/main/java/com/android/builder/dependency/LibraryBundle.java b/builder/src/main/java/com/android/builder/dependency/LibraryBundle.java
index 2130818..3718414 100644
--- a/builder/src/main/java/com/android/builder/dependency/LibraryBundle.java
+++ b/builder/src/main/java/com/android/builder/dependency/LibraryBundle.java
@@ -31,6 +31,8 @@
  */
 public abstract class LibraryBundle implements LibraryDependency {
 
+    public static final String FN_PROGUARD_TXT = "proguard.txt";
+
     private final String mName;
     private final File mBundleFolder;
     private List<File> mLocalJars;
@@ -152,7 +154,7 @@
     @Override
     @NonNull
     public File getProguardRules() {
-        return new File(mBundleFolder, "proguard.txt");
+        return new File(mBundleFolder, FN_PROGUARD_TXT);
     }
 
     @Override
diff --git a/builder/src/main/java/com/android/builder/internal/BuildConfigImpl.java b/builder/src/main/java/com/android/builder/internal/BuildConfigImpl.java
index 400eef7..dab9c50 100644
--- a/builder/src/main/java/com/android/builder/internal/BuildConfigImpl.java
+++ b/builder/src/main/java/com/android/builder/internal/BuildConfigImpl.java
@@ -18,10 +18,11 @@
 
 import com.android.annotations.NonNull;
 import com.android.builder.model.BuildConfig;
+import com.google.common.collect.Lists;
 
 import java.io.Serializable;
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -30,7 +31,7 @@
 public class BuildConfigImpl implements Serializable, BuildConfig {
     private static final long serialVersionUID = 1L;
 
-    private final List<String> mBuildConfigLines = new ArrayList<String>();
+    private final List<String> mBuildConfigLines = Lists.newArrayList();
 
     public void setBuildConfig(String... lines) {
         mBuildConfigLines.clear();
@@ -49,6 +50,12 @@
     }
 
     @Override
+    @NonNull
+    public List<Object> getProguardFiles() {
+        return Collections.emptyList();
+    }
+
+    @Override
     public boolean equals(Object o) {
         if (this == o) return true;
         if (o == null || getClass() != o.getClass()) return false;
diff --git a/builder/src/main/java/com/android/builder/internal/compiler/SourceSearcher.java b/builder/src/main/java/com/android/builder/internal/compiler/SourceSearcher.java
index e5d51e7..2d4774e 100644
--- a/builder/src/main/java/com/android/builder/internal/compiler/SourceSearcher.java
+++ b/builder/src/main/java/com/android/builder/internal/compiler/SourceSearcher.java
@@ -16,6 +16,7 @@
 
 package com.android.builder.internal.compiler;
 
+import com.android.annotations.Nullable;
 import com.android.ide.common.internal.WaitableExecutor;
 
 import java.io.File;
@@ -31,7 +32,8 @@
 
     private final List<File> mSourceFolders;
     private final String[] mExtensions;
-    private WaitableExecutor mExecutor;
+    @Nullable
+    private WaitableExecutor<Void> mExecutor;
 
     public interface SourceFileProcessor {
         void processFile(File sourceFile) throws IOException, InterruptedException;
@@ -44,7 +46,7 @@
 
     public void setUseExecutor(boolean useExecutor) {
         if (useExecutor) {
-            mExecutor = new WaitableExecutor();
+            mExecutor = new WaitableExecutor<Void>();
         } else {
             mExecutor = null;
         }
@@ -67,9 +69,9 @@
             // get the extension of the file.
             if (checkExtension(file)) {
                 if (mExecutor != null) {
-                    mExecutor.execute(new Callable() {
+                    mExecutor.execute(new Callable<Void>() {
                         @Override
-                        public Object call() throws Exception {
+                        public Void call() throws Exception {
                             processor.processFile(file);
                             return null;
                         }
diff --git a/changelog.txt b/changelog.txt
index 55048fc..71d83b9 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -1,5 +1,10 @@
 0.4
 
+* Support for ProGuard 4.9
+   - enable with BuildType.runProguard
+   - add proguard config files with BuiltType.proguardFile or ProductFlavor.proguardFile
+   - default proguard files accessible through android.getDefaultProguardFile(name) with name
+     being 'proguard-android.txt' or 'proguard-android-optimize.txt'
 * Fixes:
    - Fix support for subfolders in assets/
    - Fix cases where Android Libraries have local Jars dependencies
diff --git a/gradle/build.gradle b/gradle/build.gradle
index 3b5734b..78613a7 100644
--- a/gradle/build.gradle
+++ b/gradle/build.gradle
@@ -30,6 +30,8 @@
     compile project(':builder')
     compile project(':gradle-model')
 
+    runtime 'net.sf.proguard:proguard-gradle:4.9'
+
     testCompile 'junit:junit:3.8.1'
 
     buildTestCompile sourceSets.main.output
@@ -61,6 +63,8 @@
 idea {
     module {
         testSourceDirs += files('src/build-test/groovy', 'src/device-test/groovy').files
+
+        scopes.COMPILE.plus += configurations.provided
     }
 }
 
diff --git a/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java b/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java
index 3fff47c..e1b7dd9 100644
--- a/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java
+++ b/gradle/src/device-test/groovy/com/android/build/gradle/DeviceTest.java
@@ -40,6 +40,7 @@
     private static final String[] sBuiltProjects = new String[] {
         "api", "assets", "applibtest", "attrOrder", "basic", "flavored", "flavorlib",
         "flavors", "libsTest", "migrated", "multires", "overlay1", "overlay2", "pkgOverride",
+        "proguard", "proguardLib",
     };
 
     public static Test suite() {
diff --git a/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy b/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy
index 47a92ac..4408760 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/BaseExtension.groovy
@@ -15,6 +15,7 @@
  */
 package com.android.build.gradle
 
+import com.android.SdkConstants
 import com.android.build.gradle.api.AndroidSourceSet
 import com.android.build.gradle.api.TestVariant
 import com.android.build.gradle.internal.CompileOptions
@@ -166,4 +167,15 @@
     public FullRevision getBuildToolsRevision() {
         return buildToolsRevision
     }
+
+    public File getSdkDir() {
+        return plugin.getSdkDir()
+    }
+
+    public File getDefaultProguardFile(String name) {
+        return new File(plugin.sdkDir,
+                SdkConstants.FD_TOOLS + File.separatorChar
+                        + SdkConstants.FD_PROGUARD + File.separatorChar
+                        + name);
+    }
 }
diff --git a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
index dc80790..4ae8279 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/BasePlugin.groovy
@@ -90,6 +90,7 @@
 import org.gradle.tooling.BuildException
 import org.gradle.tooling.provider.model.ToolingModelBuilderRegistry
 import org.gradle.util.GUtil
+import proguard.gradle.ProGuardTask
 
 import static com.android.builder.BuilderConstants.EXT_LIB_ARCHIVE
 import static com.android.builder.BuilderConstants.FLAVORS
@@ -120,6 +121,8 @@
 
     protected Project project
     protected SdkParser androidSdkParser
+    private File androidSdkDir
+    private boolean isPlatformSdk = false
     private LoggerWrapper loggerWrapper
 
     private boolean hasCreatedTasks = false
@@ -146,6 +149,7 @@
         this.project = project
 
         checkGradleVersion()
+        findSdkLocation()
 
         project.apply plugin: JavaBasePlugin
 
@@ -193,7 +197,7 @@
                     "The 'java' plugin has been applied, but it is not compatible with the Android plugins.")
         }
 
-        findSdk(project)
+        loadSdk()
 
         if (hasCreatedTasks) {
             return
@@ -218,7 +222,12 @@
     }
 
     SdkParser getSdkParser() {
-        return androidSdkParser;
+        return androidSdkParser
+    }
+
+    File getSdkDir() {
+        checkSdkLocation()
+        return androidSdkDir
     }
 
     ILogger getLogger() {
@@ -257,16 +266,12 @@
         return androidBuilder
     }
 
-    private void findSdk(Project project) {
-        // if already set through tests.
+    private void findSdkLocation() {
         if (TEST_SDK_DIR != null) {
-            androidSdkParser = new DefaultSdkParser(TEST_SDK_DIR.absolutePath)
+            androidSdkDir = TEST_SDK_DIR
             return
         }
 
-        boolean defaultParser = true
-        File sdkDir = null
-
         def rootDir = project.rootDir
         def localProperties = new File(rootDir, SdkConstants.FN_LOCAL_PROPERTIES)
         if (localProperties.exists()) {
@@ -277,38 +282,54 @@
             def sdkDirProp = properties.getProperty('sdk.dir')
 
             if (sdkDirProp != null) {
-                sdkDir = new File(sdkDirProp)
+                androidSdkDir = new File(sdkDirProp)
             } else {
                 sdkDirProp = properties.getProperty('android.dir')
                 if (sdkDirProp != null) {
-                    sdkDir = new File(rootDir, sdkDirProp)
-                    defaultParser = false
+                    androidSdkDir = new File(rootDir, sdkDirProp)
+                    isPlatformSdk = true
                 } else {
                     throw new RuntimeException(
                             "No sdk.dir property defined in local.properties file.")
                 }
             }
         } else {
-            def envVar = System.getenv("ANDROID_HOME")
+            String envVar = System.getenv("ANDROID_HOME")
             if (envVar != null) {
-                sdkDir = new File(envVar)
+                androidSdkDir = new File(envVar)
+            } else {
+                String property = System.getProperty("android.home")
+                if (property != null) {
+                    androidSdkDir = new File(property)
+                }
             }
         }
+    }
 
-        if (sdkDir == null) {
+    private void checkSdkLocation() {
+        // don't complain in test mode
+        if (TEST_SDK_DIR != null) {
+            return
+        }
+
+        if (androidSdkDir == null) {
             throw new RuntimeException(
                     "SDK location not found. Define location with sdk.dir in the local.properties file or with an ANDROID_HOME environment variable.")
         }
 
-        if (!sdkDir.directory) {
+        if (!androidSdkDir.isDirectory()) {
             throw new RuntimeException(
-                    "The SDK directory '$sdkDir' specified in local.properties does not exist.")
+                    "The SDK directory '$androidSdkDir.absolutePath' does not exist.")
         }
+    }
 
-        if (defaultParser) {
-            androidSdkParser = new DefaultSdkParser(sdkDir.absolutePath)
+    private void loadSdk() {
+        checkSdkLocation()
+        //noinspection GroovyIfStatementWithIdenticalBranches
+        if (isPlatformSdk) {
+            androidSdkParser = new PlatformSdkParser(androidSdkDir.absolutePath)
         } else {
-            androidSdkParser = new PlatformSdkParser(sdkDir.absolutePath)
+            androidSdkParser = new DefaultSdkParser(androidSdkDir.absolutePath)
         }
     }
 
@@ -789,19 +810,75 @@
      *                assembleTask is always set in the Variant.
      */
     protected void addPackageTasks(ApkVariantData variantData, Task assembleTask) {
+
+        VariantConfiguration variantConfig = variantData.variantConfiguration
+
+        Closure libraryClosure = { project.files({ variantConfig.packagedJars }) }
+        Closure sourceClosure = { variantData.javaCompileTask.outputs.files }
+        Closure proguardFileClosure = { }
+
+        if (!(variantData instanceof TestVariantData) && variantConfig.buildType.runProguard) {
+
+            def proguardTask = project.tasks.create("proguard${variantData.name}", ProGuardTask);
+            proguardTask.dependsOn variantData.javaCompileTask
+            variantData.proguardTask = proguardTask
+
+            File outFile = project.file(
+                    "${project.buildDir}/libs/proguard-${variantData.baseName}.jar")
+
+            libraryClosure = { Collections.emptyList() }
+            sourceClosure = { Collections.emptyList() }
+            proguardFileClosure = { outFile }
+
+            // because the Proguard task acts on all the config right away and not when the
+            // task actually runs, let's configure it in its doFirst
+
+            proguardTask.doFirst {
+
+                // all the config files coming from build type, product flavors.
+                List<Object> proguardFiles = variantConfig.getProguardFiles(true /*includeLibs*/);
+                for (Object proguardFile : proguardFiles) {
+                    proguardTask.configuration(proguardFile)
+                }
+
+                // also the config file output by aapt
+                proguardTask.configuration(variantData.processResourcesTask.proguardOutputFile)
+
+                // injar: the compilation output
+                proguardTask.injars(variantData.javaCompileTask.destinationDir)
+
+                // injar: the dependencies
+                for (File inJar : variantConfig.packagedJars) {
+                    proguardTask.injars(inJar)
+                }
+
+                // libraryJars: the runtime jars
+                for (String runtimeJar : getRuntimeJarList(variantData)) {
+                    proguardTask.libraryjars(runtimeJar)
+                }
+
+                proguardTask.outjars(outFile)
+            }
+        }
+
         // Add a dex task
         def dexTaskName = "dex${variantData.name}"
         def dexTask = project.tasks.create(dexTaskName, Dex)
         variantData.dexTask = dexTask
-        dexTask.dependsOn variantData.javaCompileTask
+        if (variantData.proguardTask != null) {
+            dexTask.dependsOn variantData.proguardTask
+        } else {
+            dexTask.dependsOn variantData.javaCompileTask
+        }
 
         dexTask.plugin = this
         dexTask.variant = variantData
         dexTask.incrementalFolder =
                 project.file("$project.buildDir/incremental/dex/$variantData.dirName")
 
-        dexTask.conventionMapping.libraries = { project.files({ variantData.variantConfiguration.packagedJars }) }
-        dexTask.conventionMapping.sourceFiles = { variantData.javaCompileTask.outputs.files } // this creates a dependency
+        dexTask.conventionMapping.libraries = libraryClosure
+        dexTask.conventionMapping.sourceFiles = sourceClosure
+        dexTask.conventionMapping.proguardedJar = proguardFileClosure
         dexTask.conventionMapping.outputFile = {
             project.file(
                     "${project.buildDir}/libs/${project.archivesBaseName}-${variantData.baseName}.dex")
diff --git a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
index a593c80..9868d10 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/LibraryPlugin.groovy
@@ -23,6 +23,7 @@
 import com.android.build.gradle.internal.api.LibraryVariantImpl
 import com.android.build.gradle.internal.api.TestVariantImpl
 import com.android.build.gradle.internal.dependency.ConfigurationDependencies
+import com.android.build.gradle.internal.tasks.MergeFileTask
 import com.android.build.gradle.internal.variant.LibraryVariantData
 import com.android.build.gradle.internal.variant.TestVariantData
 import com.android.builder.BuilderConstants
@@ -240,8 +241,17 @@
         packageLocalJar.into(project.file(
                 "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$SdkConstants.LIBS_FOLDER"))
 
+        // merge the proguard files together
+        MergeFileTask mergeFileTask = project.tasks.create("merge${variantData.name}ProguardFiles",
+                MergeFileTask)
+        mergeFileTask.conventionMapping.inputFiles = { project.files(variantConfig.getProguardFiles(false)).files }
+        mergeFileTask.conventionMapping.outputFile = {
+            project.file(
+                    "$project.buildDir/$DIR_BUNDLES/${variantData.dirName}/$LibraryBundle.FN_PROGUARD_TXT")
+        }
+
         Zip bundle = project.tasks.create("bundle${variantData.name}", Zip)
-        bundle.dependsOn jar, packageAidl, packageRenderscript, packageLocalJar
+        bundle.dependsOn jar, packageAidl, packageRenderscript, packageLocalJar, mergeFileTask
         bundle.setDescription("Assembles a bundle containing the library in ${variantData.name}.");
         bundle.destinationDir = project.file("$project.buildDir/libs")
         bundle.extension = BuilderConstants.EXT_LIB_ARCHIVE
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy
index ae1bc53..b2c164e 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/BuildTypeDsl.groovy
@@ -20,6 +20,7 @@
 import com.android.builder.DefaultBuildType
 import com.android.builder.BuilderConstants
 import com.android.builder.signing.SigningConfig
+import com.google.common.collect.Lists
 
 /**
  * DSL overlay to make methods that accept String... work.
@@ -27,6 +28,8 @@
 public class BuildTypeDsl extends DefaultBuildType implements Serializable {
     private static final long serialVersionUID = 1L
 
+    private List<Object> proguardFiles = Lists.newArrayList();
+
     BuildTypeDsl(@NonNull String name) {
         super(name)
     }
@@ -57,7 +60,6 @@
         return this;
     }
 
-
     @Override
     boolean equals(o) {
         if (this.is(o)) return true
@@ -76,4 +78,31 @@
     public void buildConfig(String line) {
         setBuildConfig(line)
     }
+
+    @NonNull
+    public BuildTypeDsl proguardFile(Object proguardFile) {
+        proguardFiles.add(proguardFile);
+        return this;
+    }
+
+    @NonNull
+    public BuildTypeDsl proguardFiles(Object... proguardFileArray) {
+        Collections.addAll(proguardFiles, proguardFileArray);
+        return this;
+    }
+
+    @NonNull
+    public BuildTypeDsl setProguardFiles(Iterable<?> proguardFileIterable) {
+        proguardFiles.clear();
+        for (Object proguardFile : proguardFileIterable) {
+            proguardFiles.add(proguardFile);
+        }
+        return this;
+    }
+
+    @Override
+    @NonNull
+    public List<Object> getProguardFiles() {
+        return proguardFiles;
+    }
 }
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy
index 2c8565b..5c62930 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/dsl/ProductFlavorDsl.groovy
@@ -15,15 +15,17 @@
  */
 
 package com.android.build.gradle.internal.dsl
-
+import com.android.annotations.NonNull
 import com.android.builder.DefaultProductFlavor
-
+import com.google.common.collect.Lists
 /**
  * DSL overlay to make methods that accept String... work.
  */
 class ProductFlavorDsl extends DefaultProductFlavor {
     private static final long serialVersionUID = 1L
 
+    private List<Object> proguardFiles = Lists.newArrayList();
+
     ProductFlavorDsl(String name) {
         super(name)
     }
@@ -38,4 +40,30 @@
         setBuildConfig(line)
     }
 
+    @NonNull
+    public ProductFlavorDsl proguardFile(Object srcDir) {
+        proguardFiles.add(srcDir);
+        return this;
+    }
+
+    @NonNull
+    public ProductFlavorDsl proguardFiles(Object... srcDirs) {
+        Collections.addAll(proguardFiles, srcDirs);
+        return this;
+    }
+
+    @NonNull
+    public ProductFlavorDsl setProguardFiles(Iterable<?> srcDirs) {
+        proguardFiles.clear();
+        for (Object srcDir : srcDirs) {
+            proguardFiles.add(srcDir);
+        }
+        return this;
+    }
+
+    @Override
+    @NonNull
+    public List<Object> getProguardFiles() {
+        return proguardFiles;
+    }
 }
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java
index 7fa049a..ed8f059 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/BuildTypeImpl.java
@@ -113,4 +113,9 @@
     public List<String> getBuildConfig() {
         return Collections.emptyList();
     }
+
+    @Override
+    public @NonNull List<Object> getProguardFiles() {
+        return Collections.emptyList();
+    }
 }
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java
index 9ff41c9..0d46f77 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/model/ProductFlavorImpl.java
@@ -135,4 +135,11 @@
     public List<String> getBuildConfig() {
         return Collections.emptyList();
     }
+
+    @NonNull
+    @Override
+    public List<Object> getProguardFiles() {
+        return Collections.emptyList();
+    }
+
 }
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/MergeFileTask.groovy b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/MergeFileTask.groovy
new file mode 100644
index 0000000..bab61bd
--- /dev/null
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/tasks/MergeFileTask.groovy
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.build.gradle.internal.tasks
+
+import com.google.common.base.Charsets
+import com.google.common.io.Files
+import org.gradle.api.DefaultTask
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+
+/**
+ * Task to merge files. This appends all the files together into an output file.
+ */
+class MergeFileTask extends DefaultTask {
+
+    @InputFiles
+    Set<File> inputFiles
+
+    @OutputFile
+    File outputFile
+
+    @TaskAction
+    void mergeFiles() {
+
+        Set<File> files = getInputFiles();
+        File output = getOutputFile()
+
+        if (files.size() == 1) {
+            Files.copy(files.iterator().next(), output);
+            return
+        }
+
+        // first delete the current file
+        output.delete();
+
+        // no input? done.
+        if (files.isEmpty()) {
+            return
+        }
+
+        // otherwise put the all the files together
+        for (File file : files) {
+            String content = Files.toString(file, Charsets.UTF_8);
+            Files.append(content, output, Charsets.UTF_8);
+            Files.append("\n", output, Charsets.UTF_8);
+        }
+    }
+}
diff --git a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java
index ef74235..822cdfe 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java
+++ b/gradle/src/main/groovy/com/android/build/gradle/internal/variant/ApkVariantData.java
@@ -21,12 +21,14 @@
 import com.android.build.gradle.tasks.ZipAlign;
 import com.android.builder.VariantConfiguration;
 import org.gradle.api.DefaultTask;
+import proguard.gradle.ProGuardTask;
 
 /**
  * Base data about a variant that generates an APK file.
  */
 public abstract class ApkVariantData extends BaseVariantData {
 
+    public ProGuardTask proguardTask;
     public Dex dexTask;
     public PackageApplication packageApplicationTask;
     public ZipAlign zipAlignTask;
diff --git a/gradle/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy b/gradle/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy
index 89e3b28..cf1ad28 100644
--- a/gradle/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy
+++ b/gradle/src/main/groovy/com/android/build/gradle/tasks/Dex.groovy
@@ -18,8 +18,10 @@
 import com.android.build.gradle.internal.tasks.IncrementalTask
 import com.android.builder.DexOptions
 import com.android.ide.common.res2.FileStatus
+import org.gradle.api.tasks.InputFile
 import org.gradle.api.tasks.InputFiles
 import org.gradle.api.tasks.Nested
+import org.gradle.api.tasks.Optional
 import org.gradle.api.tasks.OutputFile
 
 public class Dex extends IncrementalTask {
@@ -37,6 +39,9 @@
     @InputFiles
     Iterable<File> libraries
 
+    @InputFile @Optional
+    File proguardedJar
+
     @Nested
     DexOptions dexOptions
 
@@ -45,6 +50,7 @@
         getBuilder().convertByteCode(
                 getSourceFiles(),
                 getLibraries(),
+                getProguardedJar(),
                 getOutputFile().absolutePath,
                 getDexOptions(),
                 false)
@@ -55,6 +61,7 @@
         getBuilder().convertByteCode(
                 getSourceFiles(),
                 getLibraries(),
+                getProguardedJar(),
                 getOutputFile().absolutePath,
                 getDexOptions(),
                 true)
diff --git a/tests/aidl/build.gradle b/tests/aidl/build.gradle
index 056d567..9b46579 100644
--- a/tests/aidl/build.gradle
+++ b/tests/aidl/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/api/build.gradle b/tests/api/build.gradle
index b56cb14..7981280 100644
--- a/tests/api/build.gradle
+++ b/tests/api/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/applibtest/build.gradle b/tests/applibtest/build.gradle
index b56cb14..7981280 100644
--- a/tests/applibtest/build.gradle
+++ b/tests/applibtest/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/assets/build.gradle b/tests/assets/build.gradle
index aa283a0..2fe645b 100644
--- a/tests/assets/build.gradle
+++ b/tests/assets/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/attrOrder/build.gradle b/tests/attrOrder/build.gradle
index b56cb14..7981280 100644
--- a/tests/attrOrder/build.gradle
+++ b/tests/attrOrder/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/basic/build.gradle b/tests/basic/build.gradle
index 7a415a7..1ad3105 100644
--- a/tests/basic/build.gradle
+++ b/tests/basic/build.gradle
@@ -1,10 +1,8 @@
-//
-// A basic Android application that follows all the conventions
-//
 buildscript {
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/dependencies/build.gradle b/tests/dependencies/build.gradle
index d832af5..775f904 100644
--- a/tests/dependencies/build.gradle
+++ b/tests/dependencies/build.gradle
@@ -1,10 +1,8 @@
-//
-// A basic Android application that follows all the conventions
-//
 buildscript {
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/flavored/build.gradle b/tests/flavored/build.gradle
index a5455fd..3785785 100644
--- a/tests/flavored/build.gradle
+++ b/tests/flavored/build.gradle
@@ -1,10 +1,8 @@
-//
-// A basic Android application that follows all the conventions
-//
 buildscript {
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/flavorlib/build.gradle b/tests/flavorlib/build.gradle
index aa283a0..2fe645b 100644
--- a/tests/flavorlib/build.gradle
+++ b/tests/flavorlib/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/flavorlibWithFailedTests/build.gradle b/tests/flavorlibWithFailedTests/build.gradle
index aa283a0..2fe645b 100644
--- a/tests/flavorlibWithFailedTests/build.gradle
+++ b/tests/flavorlibWithFailedTests/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/flavors/build.gradle b/tests/flavors/build.gradle
index 7d1fc45..3593d04 100644
--- a/tests/flavors/build.gradle
+++ b/tests/flavors/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/libsTest/build.gradle b/tests/libsTest/build.gradle
index aa283a0..2fe645b 100644
--- a/tests/libsTest/build.gradle
+++ b/tests/libsTest/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/localJars/build.gradle b/tests/localJars/build.gradle
index cd7e13d..573f6dc 100644
--- a/tests/localJars/build.gradle
+++ b/tests/localJars/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/migrated/build.gradle b/tests/migrated/build.gradle
index d73ea88..3a09dd6 100644
--- a/tests/migrated/build.gradle
+++ b/tests/migrated/build.gradle
@@ -2,7 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
-
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/multiproject/build.gradle b/tests/multiproject/build.gradle
index cd7e13d..573f6dc 100644
--- a/tests/multiproject/build.gradle
+++ b/tests/multiproject/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/multires/build.gradle b/tests/multires/build.gradle
index 31134b9..ce3dfd8 100644
--- a/tests/multires/build.gradle
+++ b/tests/multires/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/overlay1/build.gradle b/tests/overlay1/build.gradle
index 9dfca6b..25a15a2 100644
--- a/tests/overlay1/build.gradle
+++ b/tests/overlay1/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/overlay2/build.gradle b/tests/overlay2/build.gradle
index d47963f..811230e 100644
--- a/tests/overlay2/build.gradle
+++ b/tests/overlay2/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/pkgOverride/build.gradle b/tests/pkgOverride/build.gradle
index 1594805..628f6f5 100644
--- a/tests/pkgOverride/build.gradle
+++ b/tests/pkgOverride/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/proguard/build.gradle b/tests/proguard/build.gradle
new file mode 100644
index 0000000..07fb58e
--- /dev/null
+++ b/tests/proguard/build.gradle
@@ -0,0 +1,37 @@
+buildscript {
+    repositories {
+        maven { url '../../repo' }
+        maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
+    }
+}
+apply plugin: 'android'
+
+android {
+    compileSdkVersion 15
+    buildToolsVersion "17.0"
+
+    testBuildType "proguard"
+
+    defaultConfig {
+        versionCode 12
+        versionName "2.0"
+        minSdkVersion 16
+        targetSdkVersion 16
+    }
+
+    buildTypes {
+        proguard.initWith(buildTypes.debug)
+        proguard {
+            runProguard true
+            proguardFile getDefaultProguardFile('proguard-android.txt')
+        }
+    }
+
+    dexOptions {
+        incremental false
+    }
+}
\ No newline at end of file
diff --git a/tests/proguard/src/instrumentTest/java/com/android/tests/basic/MainTest.java b/tests/proguard/src/instrumentTest/java/com/android/tests/basic/MainTest.java
new file mode 100644
index 0000000..cbbc52b
--- /dev/null
+++ b/tests/proguard/src/instrumentTest/java/com/android/tests/basic/MainTest.java
@@ -0,0 +1,42 @@
+package com.android.tests.basic;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.TextView;
+
+public class MainTest extends ActivityInstrumentationTestCase2<Main> {
+
+    private TextView mTextView;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Main} activity.
+     */
+    public MainTest() {
+        super(Main.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Main a = getActivity();
+        // ensure a valid handle to the activity has been returned
+        assertNotNull(a);
+        mTextView = (TextView) a.findViewById(R.id.dateText);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertNotNull(mTextView);
+    }
+
+    public void testTextViewContent() {
+        assertEquals("1234", mTextView.getText());
+    }
+}
+
diff --git a/tests/proguard/src/main/AndroidManifest.xml b/tests/proguard/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..4f8d570
--- /dev/null
+++ b/tests/proguard/src/main/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.tests.basic">
+    <application android:label="@string/app_name" android:icon="@drawable/icon">
+        <activity android:name=".Main"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <uses-permission android:name="com.blah" />
+
+    <permission-group android:name="foo.permission-group.COST_MONEY"
+        android:label="@string/app_name"
+        android:description="@string/app_name" />
+
+    <permission android:name="foo.permission.SEND_SMS"
+        android:permissionGroup="foo.permission-group.COST_MONEY"
+        android:label="@string/app_name"
+        android:description="@string/app_name" />
+
+    <permission android:name="foo.blah.SEND_SMS"
+        android:permissionGroup="foo.permission-group.COST_MONEY"
+        android:label="@string/app_name"
+        android:description="@string/app_name" />
+
+</manifest>
diff --git a/tests/proguard/src/main/java/com/android/tests/basic/Main.java b/tests/proguard/src/main/java/com/android/tests/basic/Main.java
new file mode 100644
index 0000000..6d3ae10
--- /dev/null
+++ b/tests/proguard/src/main/java/com/android/tests/basic/Main.java
@@ -0,0 +1,23 @@
+package com.android.tests.basic;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+
+public class Main extends Activity
+{
+
+    private int foo = 1234;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        TextView tv = (TextView) findViewById(R.id.dateText);
+        StringProvider stringProvider = new StringProvider();
+        tv.setText(stringProvider.getString(foo));
+    }
+}
diff --git a/tests/proguard/src/main/java/com/android/tests/basic/StringProvider.java b/tests/proguard/src/main/java/com/android/tests/basic/StringProvider.java
new file mode 100644
index 0000000..6659418
--- /dev/null
+++ b/tests/proguard/src/main/java/com/android/tests/basic/StringProvider.java
@@ -0,0 +1,8 @@
+package com.android.tests.basic;
+
+public class StringProvider {
+
+    public String getString(int foo) {
+        return Integer.toString(foo);
+    }
+}
diff --git a/tests/proguard/src/main/res/drawable/icon.png b/tests/proguard/src/main/res/drawable/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/tests/proguard/src/main/res/drawable/icon.png
Binary files differ
diff --git a/tests/proguard/src/main/res/layout/main.xml b/tests/proguard/src/main/res/layout/main.xml
new file mode 100644
index 0000000..89ab091
--- /dev/null
+++ b/tests/proguard/src/main/res/layout/main.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:text="Test App - Basic"
+    android:id="@+id/text"
+    />
+<TextView
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:text=""
+    android:id="@+id/dateText"
+    />
+</LinearLayout>
+
diff --git a/tests/proguard/src/main/res/values/strings.xml b/tests/proguard/src/main/res/values/strings.xml
new file mode 100644
index 0000000..60ea2d0
--- /dev/null
+++ b/tests/proguard/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">_Test-Basic</string>
+</resources>
diff --git a/tests/proguardLib/app/build.gradle b/tests/proguardLib/app/build.gradle
new file mode 100644
index 0000000..6b35651
--- /dev/null
+++ b/tests/proguardLib/app/build.gradle
@@ -0,0 +1,31 @@
+apply plugin: 'android'
+
+dependencies {
+    compile project(':lib')
+}
+
+android {
+    compileSdkVersion 15
+    buildToolsVersion "17.0"
+
+    testBuildType "proguard"
+
+    defaultConfig {
+        versionCode 12
+        versionName "2.0"
+        minSdkVersion 16
+        targetSdkVersion 16
+    }
+
+    buildTypes {
+        proguard.initWith(buildTypes.debug)
+        proguard {
+            runProguard true
+            proguardFile getDefaultProguardFile('proguard-android.txt')
+        }
+    }
+
+    dexOptions {
+        incremental false
+    }
+}
\ No newline at end of file
diff --git a/tests/proguardLib/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java b/tests/proguardLib/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java
new file mode 100644
index 0000000..cbbc52b
--- /dev/null
+++ b/tests/proguardLib/app/src/instrumentTest/java/com/android/tests/basic/MainTest.java
@@ -0,0 +1,42 @@
+package com.android.tests.basic;
+
+import android.test.ActivityInstrumentationTestCase2;
+import android.test.suitebuilder.annotation.MediumTest;
+import android.widget.TextView;
+
+public class MainTest extends ActivityInstrumentationTestCase2<Main> {
+
+    private TextView mTextView;
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2} that tests the {@link Main} activity.
+     */
+    public MainTest() {
+        super(Main.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+        final Main a = getActivity();
+        // ensure a valid handle to the activity has been returned
+        assertNotNull(a);
+        mTextView = (TextView) a.findViewById(R.id.dateText);
+    }
+
+    /**
+     * The name 'test preconditions' is a convention to signal that if this
+     * test doesn't pass, the test case was not set up properly and it might
+     * explain any and all failures in other tests.  This is not guaranteed
+     * to run before other tests, as junit uses reflection to find the tests.
+     */
+    @MediumTest
+    public void testPreconditions() {
+        assertNotNull(mTextView);
+    }
+
+    public void testTextViewContent() {
+        assertEquals("1234", mTextView.getText());
+    }
+}
+
diff --git a/tests/proguardLib/app/src/main/AndroidManifest.xml b/tests/proguardLib/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..4f8d570
--- /dev/null
+++ b/tests/proguardLib/app/src/main/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.tests.basic">
+    <application android:label="@string/app_name" android:icon="@drawable/icon">
+        <activity android:name=".Main"
+                  android:label="@string/app_name">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+
+    <uses-permission android:name="com.blah" />
+
+    <permission-group android:name="foo.permission-group.COST_MONEY"
+        android:label="@string/app_name"
+        android:description="@string/app_name" />
+
+    <permission android:name="foo.permission.SEND_SMS"
+        android:permissionGroup="foo.permission-group.COST_MONEY"
+        android:label="@string/app_name"
+        android:description="@string/app_name" />
+
+    <permission android:name="foo.blah.SEND_SMS"
+        android:permissionGroup="foo.permission-group.COST_MONEY"
+        android:label="@string/app_name"
+        android:description="@string/app_name" />
+
+</manifest>
diff --git a/tests/proguardLib/app/src/main/java/com/android/tests/basic/Main.java b/tests/proguardLib/app/src/main/java/com/android/tests/basic/Main.java
new file mode 100644
index 0000000..77edc4c
--- /dev/null
+++ b/tests/proguardLib/app/src/main/java/com/android/tests/basic/Main.java
@@ -0,0 +1,31 @@
+package com.android.tests.basic;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.widget.TextView;
+import java.lang.reflect.Method;
+
+public class Main extends Activity
+{
+
+    private int foo = 1234;
+
+    /** Called when the activity is first created. */
+    @Override
+    public void onCreate(Bundle savedInstanceState)
+    {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.main);
+
+        TextView tv = (TextView) findViewById(R.id.dateText);
+
+        try {
+            // use reflection to make sure the class wasn't obfuscated
+            Class<?> theClass = Class.forName("com.android.tests.basic.StringProvider");
+            Method method = theClass.getDeclaredMethod("getString", int.class);
+            tv.setText((String) method.invoke(null, foo));
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/tests/proguardLib/app/src/main/res/drawable/icon.png b/tests/proguardLib/app/src/main/res/drawable/icon.png
new file mode 100644
index 0000000..a07c69f
--- /dev/null
+++ b/tests/proguardLib/app/src/main/res/drawable/icon.png
Binary files differ
diff --git a/tests/proguardLib/app/src/main/res/layout/main.xml b/tests/proguardLib/app/src/main/res/layout/main.xml
new file mode 100644
index 0000000..89ab091
--- /dev/null
+++ b/tests/proguardLib/app/src/main/res/layout/main.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:orientation="vertical"
+    android:layout_width="fill_parent"
+    android:layout_height="fill_parent"
+    >
+<TextView
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:text="Test App - Basic"
+    android:id="@+id/text"
+    />
+<TextView
+    android:layout_width="fill_parent"
+    android:layout_height="wrap_content"
+    android:text=""
+    android:id="@+id/dateText"
+    />
+</LinearLayout>
+
diff --git a/tests/proguardLib/app/src/main/res/values/strings.xml b/tests/proguardLib/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..60ea2d0
--- /dev/null
+++ b/tests/proguardLib/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">_Test-Basic</string>
+</resources>
diff --git a/tests/proguardLib/build.gradle b/tests/proguardLib/build.gradle
new file mode 100644
index 0000000..7981280
--- /dev/null
+++ b/tests/proguardLib/build.gradle
@@ -0,0 +1,10 @@
+buildscript {
+    repositories {
+        maven { url '../../repo' }
+        maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
+    }
+    dependencies {
+        classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
+    }
+}
diff --git a/tests/proguardLib/lib/build.gradle b/tests/proguardLib/lib/build.gradle
new file mode 100644
index 0000000..49f4759
--- /dev/null
+++ b/tests/proguardLib/lib/build.gradle
@@ -0,0 +1,14 @@
+apply plugin: 'android-library'
+
+android {
+    compileSdkVersion 15
+    buildToolsVersion "17.0"
+
+    defaultConfig {
+        versionCode 12
+        versionName "2.0"
+        minSdkVersion 16
+        targetSdkVersion 16
+        proguardFile 'config.pro'
+    }
+}
\ No newline at end of file
diff --git a/tests/proguardLib/lib/config.pro b/tests/proguardLib/lib/config.pro
new file mode 100644
index 0000000..3416f5d
--- /dev/null
+++ b/tests/proguardLib/lib/config.pro
@@ -0,0 +1,4 @@
+-keep public class com.android.tests.basic.StringProvider {
+    public static java.lang.String getString(int);
+}
+
diff --git a/tests/proguardLib/lib/src/main/AndroidManifest.xml b/tests/proguardLib/lib/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..593a287
--- /dev/null
+++ b/tests/proguardLib/lib/src/main/AndroidManifest.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+      package="com.android.tests.basic">
+</manifest>
diff --git a/tests/proguardLib/lib/src/main/java/com/android/tests/basic/StringProvider.java b/tests/proguardLib/lib/src/main/java/com/android/tests/basic/StringProvider.java
new file mode 100644
index 0000000..6d81901
--- /dev/null
+++ b/tests/proguardLib/lib/src/main/java/com/android/tests/basic/StringProvider.java
@@ -0,0 +1,8 @@
+package com.android.tests.basic;
+
+public class StringProvider {
+
+    public static String getString(int foo) {
+        return Integer.toString(foo);
+    }
+}
diff --git a/tests/proguardLib/settings.gradle b/tests/proguardLib/settings.gradle
new file mode 100644
index 0000000..eedb2a1
--- /dev/null
+++ b/tests/proguardLib/settings.gradle
@@ -0,0 +1,2 @@
+include 'app'
+include 'lib'
diff --git a/tests/renderscript/build.gradle b/tests/renderscript/build.gradle
index aea8a72..a0dd20b 100644
--- a/tests/renderscript/build.gradle
+++ b/tests/renderscript/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/renderscriptInLib/build.gradle b/tests/renderscriptInLib/build.gradle
index b56cb14..7981280 100644
--- a/tests/renderscriptInLib/build.gradle
+++ b/tests/renderscriptInLib/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/renderscriptMultiSrc/build.gradle b/tests/renderscriptMultiSrc/build.gradle
index f4b747b..0e0b05c 100644
--- a/tests/renderscriptMultiSrc/build.gradle
+++ b/tests/renderscriptMultiSrc/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/repo/app/build.gradle b/tests/repo/app/build.gradle
index f91e054..06f020e 100644
--- a/tests/repo/app/build.gradle
+++ b/tests/repo/app/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../../repo' }
         maven { url '../../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/repo/baseLibrary/build.gradle b/tests/repo/baseLibrary/build.gradle
index 7e05eef..031edb6 100644
--- a/tests/repo/baseLibrary/build.gradle
+++ b/tests/repo/baseLibrary/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../../repo' }
         maven { url '../../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/repo/library/build.gradle b/tests/repo/library/build.gradle
index 3ec3583..4aba1b1 100644
--- a/tests/repo/library/build.gradle
+++ b/tests/repo/library/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../../repo' }
         maven { url '../../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'
diff --git a/tests/tictactoe/build.gradle b/tests/tictactoe/build.gradle
index b56cb14..7981280 100644
--- a/tests/tictactoe/build.gradle
+++ b/tests/tictactoe/build.gradle
@@ -2,6 +2,7 @@
     repositories {
         maven { url '../../repo' }
         maven { url '../../../../prebuilts/tools/common/m2/repository' }
+        maven { url '../../../../prebuilts/tools/common/m2/internal' }
     }
     dependencies {
         classpath 'com.android.tools.build:gradle:0.4-SNAPSHOT'