Merge "Revert "Enforce class access flags to be valid.""
diff --git a/build.gradle b/build.gradle
index d93cbf1..c351aca 100644
--- a/build.gradle
+++ b/build.gradle
@@ -16,23 +16,23 @@
     '-XepDisableAllChecks',
     // D8 want to use reference equality, thus disable the checker explicitly
     '-Xep:ReferenceEquality:OFF',
-    '-Xep:ClassCanBeStatic:WARN',
-    '-Xep:OperatorPrecedence:WARN',
-    '-Xep:RemoveUnusedImports:WARN',
-    '-Xep:MissingOverride:WARN',
-    '-Xep:OvershadowingSubclassFields:WARN',
-    '-Xep:IntLongMath:WARN',
-    '-Xep:EqualsHashCode:WARN',
-    '-Xep:InconsistentOverloads:WARN',
-    '-Xep:ArrayHashCode:WARN',
-    '-Xep:EqualsIncompatibleType:WARN',
-    '-Xep:NonOverridingEquals:WARN',
-    '-Xep:FallThrough:WARN',
-    '-Xep:MissingCasesInEnumSwitch:WARN',
-    '-Xep:MissingDefault:WARN',
-    '-Xep:MultipleTopLevelClasses:WARN',
-    '-Xep:NarrowingCompoundAssignment:WARN',
-    '-Xep:BoxedPrimitiveConstructor:WARN']
+    '-Xep:ClassCanBeStatic:ERROR',
+    '-Xep:OperatorPrecedence:ERROR',
+    '-Xep:RemoveUnusedImports:ERROR',
+    '-Xep:MissingOverride:ERROR',
+    '-Xep:OvershadowingSubclassFields:ERROR',
+    '-Xep:IntLongMath:ERROR',
+    '-Xep:EqualsHashCode:ERROR',
+    '-Xep:InconsistentOverloads:ERROR',
+    '-Xep:ArrayHashCode:ERROR',
+    '-Xep:EqualsIncompatibleType:ERROR',
+    '-Xep:NonOverridingEquals:ERROR',
+    '-Xep:FallThrough:ERROR',
+    '-Xep:MissingCasesInEnumSwitch:ERROR',
+    '-Xep:MissingDefault:ERROR',
+    '-Xep:MultipleTopLevelClasses:ERROR',
+    '-Xep:NarrowingCompoundAssignment:ERROR',
+    '-Xep:BoxedPrimitiveConstructor:ERROR']
 
 apply from: 'copyAdditionalJctfCommonFiles.gradle'
 
diff --git a/src/main/java/com/android/tools/r8/ExtractMarker.java b/src/main/java/com/android/tools/r8/ExtractMarker.java
index a32aa20..24dfb07 100644
--- a/src/main/java/com/android/tools/r8/ExtractMarker.java
+++ b/src/main/java/com/android/tools/r8/ExtractMarker.java
@@ -12,137 +12,40 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Timing;
-import com.google.common.collect.ImmutableList;
 import java.io.IOException;
 import java.nio.file.Path;
-import java.nio.file.Paths;
-import java.util.ArrayList;
-import java.util.List;
 import java.util.concurrent.ExecutionException;
 
 public class ExtractMarker {
-  private static class Command {
 
-    public static class Builder {
-      private boolean printHelp = false;
-      private boolean verbose;
-      private boolean summary;
-      private List<Path> programFiles = new ArrayList<>();
+  public static Marker extractMarkerFromDexFile(Path file) throws IOException, ExecutionException {
+    AndroidApp.Builder appBuilder = AndroidApp.builder();
+    appBuilder.setVdexAllowed();
+    appBuilder.addProgramFiles(FilteredClassPath.unfiltered(file));
+    return extractMarker(appBuilder.build());
+  }
 
-      public Builder setPrintHelp(boolean printHelp) {
-        this.printHelp = printHelp;
-        return this;
-      }
+  public static Marker extractMarkerFromDexProgramData(byte[] data)
+      throws IOException, ExecutionException {
+    AndroidApp app = AndroidApp.fromDexProgramData(data);
+    return extractMarker(app);
+  }
 
-      public boolean isPrintHelp() {
-        return printHelp;
-      }
-
-      public Builder setVerbose(boolean verbose) {
-        this.verbose = verbose;
-        return this;
-      }
-
-      public Builder setSummary(boolean summary) {
-        this.summary = summary;
-        return this;
-      }
-
-      public Builder addProgramFile(Path programFile) {
-        programFiles.add(programFile);
-        return this;
-      }
-
-      public ExtractMarker.Command build() throws CompilationException, IOException {
-        // If printing versions ignore everything else.
-        if (isPrintHelp()) {
-          return new ExtractMarker.Command(isPrintHelp());
-        }
-        return new ExtractMarker.Command(verbose, summary, programFiles);
-      }
-    }
-
-    static final String USAGE_MESSAGE = String.join("\n", ImmutableList.of(
-        "Usage: extractmarker [options] <input-files>",
-        " where <input-files> are dex or vdex files",
-        "  --verbose               # More verbose output.",
-        "  --summary               # Print summary at the end.",
-        "  --help                  # Print this message."));
-
-    public static ExtractMarker.Command.Builder builder() {
-      return new Builder();
-    }
-
-    public static ExtractMarker.Command.Builder parse(String[] args)
-        throws CompilationException, IOException {
-      ExtractMarker.Command.Builder builder = builder();
-      parse(args, builder);
-      return builder;
-    }
-
-    private static void parse(String[] args, ExtractMarker.Command.Builder builder)
-        throws CompilationException, IOException {
-      for (int i = 0; i < args.length; i++) {
-        String arg = args[i].trim();
-        if (arg.length() == 0) {
-          continue;
-        } else if (arg.equals("--verbose")) {
-          builder.setVerbose(true);
-        } else if (arg.equals("--summary")) {
-          builder.setSummary(true);
-        } else if (arg.equals("--help")) {
-          builder.setPrintHelp(true);
-        } else {
-          if (arg.startsWith("--")) {
-            throw new CompilationException("Unknown option: " + arg);
-          }
-          builder.addProgramFile(Paths.get(arg));
-        }
-      }
-    }
-
-    private final boolean printHelp;
-    private final boolean verbose;
-    private final boolean summary;
-    private final List<Path> programFiles;
-
-    private Command(boolean verbose, boolean summary, List<Path> programFiles) {
-      this.printHelp = false;
-      this.verbose = verbose;
-      this.summary = summary;
-      this.programFiles = programFiles;
-    }
-
-    private Command(boolean printHelp) {
-      this.printHelp = printHelp;
-      this.verbose = false;
-      this.summary = false;
-      programFiles = ImmutableList.of();
-    }
-
-    public boolean isPrintHelp() {
-      return printHelp;
-    }
-
-    public List<Path> getProgramFiles() {
-      return programFiles;
-    }
-
-    public boolean getVerbose() {
-      return verbose;
-    }
-
-    public boolean getSummary() {
-      return summary;
-    }
+  private static Marker extractMarker(AndroidApp app) throws IOException, ExecutionException {
+    InternalOptions options = new InternalOptions();
+    options.skipReadingDexCode = true;
+    options.minApiLevel = AndroidApiLevel.P.getLevel();
+    DexApplication dexApp =
+        new ApplicationReader(app, options, new Timing("ExtractMarker")).read();
+    return dexApp.dexItemFactory.extractMarker();
   }
 
   public static void main(String[] args)
       throws IOException, CompilationException, ExecutionException {
-    ExtractMarker.Command.Builder builder = ExtractMarker.Command.parse(args);
-    ExtractMarker.Command command = builder.build();
+    ExtractMarkerCommand.Builder builder = ExtractMarkerCommand.parse(args);
+    ExtractMarkerCommand command = builder.build();
     if (command.isPrintHelp()) {
-      System.out.println(ExtractMarker.Command.USAGE_MESSAGE);
+      System.out.println(ExtractMarkerCommand.USAGE_MESSAGE);
       return;
     }
 
@@ -153,26 +56,17 @@
     int otherCount = 0;
     for (Path programFile : command.getProgramFiles()) {
       try {
-        InternalOptions options = new InternalOptions();
-        options.skipReadingDexCode = true;
-        options.minApiLevel = AndroidApiLevel.P.getLevel();
-        AndroidApp.Builder appBuilder = AndroidApp.builder();
-        appBuilder.setVdexAllowed();
-        appBuilder.addProgramFiles(FilteredClassPath.unfiltered(programFile));
-        DexApplication dexApp =
-            new ApplicationReader(appBuilder.build(), options, new Timing("ExtractMarker"))
-                .read();
-        Marker readMarker = dexApp.dexItemFactory.extractMarker();
         if (command.getVerbose()) {
           System.out.print(programFile);
           System.out.print(": ");
         }
-        if (readMarker == null) {
+        Marker marker = extractMarkerFromDexFile(programFile);
+        if (marker == null) {
           System.out.println("D8/R8 marker not found.");
           otherCount++;
         } else {
-          System.out.println(readMarker.toString());
-          if (readMarker.isD8()) {
+          System.out.println(marker.toString());
+          if (marker.isD8()) {
             d8Count++;
           } else {
             r8Count++;
diff --git a/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
new file mode 100644
index 0000000..729b50a
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ExtractMarkerCommand.java
@@ -0,0 +1,127 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+import com.google.common.collect.ImmutableList;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+
+class ExtractMarkerCommand {
+
+  public static class Builder {
+    private boolean printHelp = false;
+    private boolean verbose;
+    private boolean summary;
+    private List<Path> programFiles = new ArrayList<>();
+
+    public Builder setPrintHelp(boolean printHelp) {
+      this.printHelp = printHelp;
+      return this;
+    }
+
+    public boolean isPrintHelp() {
+      return printHelp;
+    }
+
+    public Builder setVerbose(boolean verbose) {
+      this.verbose = verbose;
+      return this;
+    }
+
+    public Builder setSummary(boolean summary) {
+      this.summary = summary;
+      return this;
+    }
+
+    public Builder addProgramFile(Path programFile) {
+      programFiles.add(programFile);
+      return this;
+    }
+
+    public ExtractMarkerCommand build() throws CompilationException, IOException {
+      // If printing versions ignore everything else.
+      if (isPrintHelp()) {
+        return new ExtractMarkerCommand(isPrintHelp());
+      }
+      return new ExtractMarkerCommand(verbose, summary, programFiles);
+    }
+  }
+
+  static final String USAGE_MESSAGE = String.join("\n", ImmutableList.of(
+      "Usage: extractmarker [options] <input-files>",
+      " where <input-files> are dex or vdex files",
+      "  --verbose               # More verbose output.",
+      "  --summary               # Print summary at the end.",
+      "  --help                  # Print this message."));
+
+  public static Builder builder() {
+    return new Builder();
+  }
+
+  public static Builder parse(String[] args)
+      throws CompilationException, IOException {
+    Builder builder = builder();
+    parse(args, builder);
+    return builder;
+  }
+
+  private static void parse(String[] args, Builder builder)
+      throws CompilationException, IOException {
+    for (int i = 0; i < args.length; i++) {
+      String arg = args[i].trim();
+      if (arg.length() == 0) {
+        continue;
+      } else if (arg.equals("--verbose")) {
+        builder.setVerbose(true);
+      } else if (arg.equals("--summary")) {
+        builder.setSummary(true);
+      } else if (arg.equals("--help")) {
+        builder.setPrintHelp(true);
+      } else {
+        if (arg.startsWith("--")) {
+          throw new CompilationException("Unknown option: " + arg);
+        }
+        builder.addProgramFile(Paths.get(arg));
+      }
+    }
+  }
+
+  private final boolean printHelp;
+  private final boolean verbose;
+  private final boolean summary;
+  private final List<Path> programFiles;
+
+  private ExtractMarkerCommand(boolean verbose, boolean summary, List<Path> programFiles) {
+    this.printHelp = false;
+    this.verbose = verbose;
+    this.summary = summary;
+    this.programFiles = programFiles;
+  }
+
+  private ExtractMarkerCommand(boolean printHelp) {
+    this.printHelp = printHelp;
+    this.verbose = false;
+    this.summary = false;
+    programFiles = ImmutableList.of();
+  }
+
+  public boolean isPrintHelp() {
+    return printHelp;
+  }
+
+  public List<Path> getProgramFiles() {
+    return programFiles;
+  }
+
+  public boolean getVerbose() {
+    return verbose;
+  }
+
+  public boolean getSummary() {
+    return summary;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/Version.java b/src/main/java/com/android/tools/r8/Version.java
index 44e1bf4..4368013 100644
--- a/src/main/java/com/android/tools/r8/Version.java
+++ b/src/main/java/com/android/tools/r8/Version.java
@@ -8,6 +8,8 @@
 
 public final class Version {
 
+  // This field is accessed from release scripts using simple pattern matching.
+  // Therefore, changing this field could break our release scripts.
   public static final String LABEL = "v0.2.0-dev";
 
   private Version() {
diff --git a/src/main/java/com/android/tools/r8/dex/Marker.java b/src/main/java/com/android/tools/r8/dex/Marker.java
index 463d484..e1f3316 100644
--- a/src/main/java/com/android/tools/r8/dex/Marker.java
+++ b/src/main/java/com/android/tools/r8/dex/Marker.java
@@ -51,6 +51,10 @@
     return tool == Tool.R8;
   }
 
+  public String getVersion() {
+    return (String) content.get("version");
+  }
+
   public Marker put(String key, int value) {
     // value is converted to Long ensuring equals works with the parsed json string.
     return internalPut(key, Long.valueOf(value));
diff --git a/src/test/java/com/android/tools/r8/ExtractMarkerTest.java b/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
new file mode 100644
index 0000000..fd1bfcb
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ExtractMarkerTest.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package com.android.tools.r8;
+
+import com.android.tools.r8.dex.Marker;
+import com.android.tools.r8.dex.Marker.Tool;
+import com.android.tools.r8.utils.CompilationFailedException;
+import com.google.common.io.ByteStreams;
+import java.io.IOException;
+import java.nio.file.Paths;
+import java.util.concurrent.ExecutionException;
+import org.junit.Test;
+
+public class ExtractMarkerTest {
+
+  @Test
+  public void extractMarkerTest()
+      throws CompilationFailedException, IOException, ExecutionException {
+    String classFile = ToolHelper.EXAMPLES_BUILD_DIR + "classes/trivial/Trivial.class";
+    D8Command command = D8Command.builder()
+            .addProgramFiles(Paths.get(classFile))
+            .build();
+    D8Output output = D8.run(command);
+    byte[] data = ByteStreams.toByteArray(output.getDexResources().get(0).getStream());
+    Marker marker = ExtractMarker.extractMarkerFromDexProgramData(data);
+    assert marker != null;
+    assert marker.getTool() == Tool.D8;
+    assert marker.getVersion().equals(Version.LABEL);
+  }
+}
diff --git a/tools/archive.py b/tools/archive.py
index 20d057c..8e7436b 100755
--- a/tools/archive.py
+++ b/tools/archive.py
@@ -65,10 +65,15 @@
 def Main():
   if not 'BUILDBOT_BUILDERNAME' in os.environ:
     raise Exception('You are not a bot, don\'t archive builds')
+  # Create maven release first which uses a build that exclude dependencies.
+  create_maven_release.main(["--out", utils.LIBS])
+
+  # Generate and copy the build that exclude dependencies.
+  gradle.RunGradleExcludeDeps([utils.R8])
+  shutil.copyfile(utils.R8_JAR, utils.R8_EXCLUDE_DEPS_JAR)
+
   # Ensure all archived artifacts has been built before archiving.
   gradle.RunGradle([utils.D8, utils.R8, utils.COMPATDX, utils.COMPATPROGUARD])
-  create_maven_release.main(['--jar', utils.R8_JAR, "--out", utils.LIBS])
-
   version = GetVersion()
   is_master = IsMaster(version)
   if is_master:
@@ -86,6 +91,7 @@
 
     for file in [utils.D8_JAR,
                  utils.R8_JAR,
+                 utils.R8_EXCLUDE_DEPS_JAR,
                  utils.COMPATDX_JAR,
                  utils.COMPATPROGUARD_JAR,
                  utils.MAVEN_ZIP]:
diff --git a/tools/create_maven_release.py b/tools/create_maven_release.py
index 85b558a..cc045a2 100755
--- a/tools/create_maven_release.py
+++ b/tools/create_maven_release.py
@@ -3,8 +3,9 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-import hashlib
 import argparse
+import gradle
+import hashlib
 from os import makedirs
 from os.path import join
 from shutil import copyfile, make_archive, rmtree
@@ -14,13 +15,13 @@
 import tempfile
 import utils
 
-LICENSETEMPLATE = Template(
+DEPENDENCYTEMPLATE = Template(
 """
-    <license>
-      <name>$name</name>
-      <url>$url</url>
-      <distribution>repo</distribution>
-    </license>""")
+    <dependency>
+        <groupId>$group</groupId>
+        <artifactId>$artifact</artifactId>
+        <version>$version</version>
+    </dependency>""")
 
 POMTEMPLATE = Template(
 """<project
@@ -42,8 +43,10 @@
       <name>BSD-3-Clause</name>
       <url>https://opensource.org/licenses/BSD-3-Clause</url>
       <distribution>repo</distribution>
-    </license>$library_licenses
+    </license>
   </licenses>
+  <dependencies>$dependencies
+  </dependencies>
   <developers>
     <developer>
       <name>The Android Open Source Project</name>
@@ -62,19 +65,19 @@
 
 def parse_options(argv):
   result = argparse.ArgumentParser()
-  result.add_argument('--jar', help='jar file to package')
   result.add_argument('--out', help='directory in which to put the output zip file')
   return result.parse_args(argv)
 
-def determine_version(jar):
-  cmd = []
-  cmd.append('java')
-  cmd.extend(['-jar', jar]);
-  cmd.append('--version')
-  output = subprocess.check_output(cmd)
-  version_string = output.split()[1]
-  assert version_string.startswith("v")
-  return version_string[1:]
+def determine_version():
+  version_file = join(
+      utils.SRC_ROOT, 'com', 'android', 'tools', 'r8', 'Version.java')
+  with open(version_file, 'r') as file:
+    for line in file:
+      if 'final String LABEL ' in line:
+        result = line[line.find('"v') + 2:]
+        result = result[:result.find('"')]
+        return result
+  raise Exception('Unable to determine version.')
 
 def generate_library_licenses():
   license_prefix = 'license: '
@@ -103,9 +106,76 @@
     result += LICENSETEMPLATE.substitute(name=name, url=url)
   return result
 
+
+# Generate the dependencies block for the pom file.
+#
+# We ask gradle to list all dependencies. In that output
+# we locate the runtimeClasspath block for 'main' which
+# looks something like:
+#
+# runtimeClasspath - Runtime classpath of source set 'main'.
+# +--- net.sf.jopt-simple:jopt-simple:4.6
+# +--- com.googlecode.json-simple:json-simple:1.1
+# +--- com.google.guava:guava:23.0
+# +--- it.unimi.dsi:fastutil:7.2.0
+# +--- org.ow2.asm:asm:6.0
+# +--- org.ow2.asm:asm-commons:6.0
+# |    \--- org.ow2.asm:asm-tree:6.0
+# |         \--- org.ow2.asm:asm:6.0
+# +--- org.ow2.asm:asm-tree:6.0 (*)
+# +--- org.ow2.asm:asm-analysis:6.0
+# |    \--- org.ow2.asm:asm-tree:6.0 (*)
+# \--- org.ow2.asm:asm-util:6.0
+#      \--- org.ow2.asm:asm-tree:6.0 (*)
+#
+# We filter out the repeats that are marked by '(*)'.
+#
+# For each remaining line, we remove the junk at the start
+# in chunks. As an example:
+#
+# '  |    \--- org.ow2.asm:asm-tree:6.0  '  --strip-->
+# '|    \--- org.ow2.asm:asm-tree:6.0'  -->
+# '\--- org.ow2.asm:asm-tree:6.0'  -->
+# 'org.ow2.asm:asm-tree:6.0'
+#
+# The end result is the dependency we are looking for:
+#
+# groupId: org.ow2.asm
+# artifact: asm-tree
+# version: 6.0
+def generate_dependencies():
+  dependencies = gradle.RunGradleGetOutput(['dependencies'])
+  dependency_lines = []
+  collect = False
+  for line in dependencies.splitlines():
+    if 'runtimeClasspath' in line and "'main'" in line:
+      collect = True
+      continue
+    if collect:
+      if not len(line) == 0:
+        if not '(*)' in line:
+          trimmed = line.strip()
+          while trimmed.find(' ') != -1:
+            trimmed = trimmed[trimmed.find(' ') + 1:].strip()
+          if not trimmed in dependency_lines:
+            dependency_lines.append(trimmed)
+      else:
+        break
+  result = ''
+  for dep in dependency_lines:
+    components = dep.split(':')
+    assert len(components) == 3
+    group = components[0]
+    artifact = components[1]
+    version = components[2]
+    result += DEPENDENCYTEMPLATE.substitute(
+        group=group, artifact=artifact, version=version)
+  return result
+
 def write_pom_file(version, pom_file):
-  library_licenses = generate_library_licenses()
-  version_pom = POMTEMPLATE.substitute(version=version, library_licenses=library_licenses)
+  dependencies = generate_dependencies()
+  version_pom = POMTEMPLATE.substitute(
+      version=version, dependencies=dependencies)
   with open(pom_file, 'w') as file:
     file.write(version_pom)
 
@@ -131,13 +201,14 @@
 
 def main(argv):
   options = parse_options(argv)
-  jar = options.jar
   outdir = options.out
-  if jar == None or outdir == None:
-    print 'Need to supply --jar and --out.'
+  if outdir == None:
+    print 'Need to supply output dir with --out.'
     exit(1)
+  # Build the R8 no deps artifact.
+  gradle.RunGradleExcludeDeps([utils.R8])
   # Create directory structure for this version.
-  version = determine_version(jar)
+  version = determine_version()
   with utils.TempDir() as tmp_dir:
     version_dir = join(
         tmp_dir, 'com', 'google', 'android', 'tools', 'r8', version, 'r8')
@@ -147,7 +218,7 @@
     write_pom_file(version, pom_file)
     # Copy the jar to the output.
     target_jar = join(version_dir, 'r8-' + version + '.jar')
-    copyfile(jar, target_jar)
+    copyfile(utils.R8_JAR, target_jar)
     # Create check sums.
     write_md5_for(target_jar)
     write_md5_for(pom_file)
diff --git a/tools/gradle.py b/tools/gradle.py
index 275c270..df80cc9 100755
--- a/tools/gradle.py
+++ b/tools/gradle.py
@@ -54,9 +54,12 @@
   else:
     print 'gradle.py: Shadow library present'
 
-def RunGradle(args, throw_on_failure=True):
+def EnsureDeps():
   EnsureGradle()
   EnsureShadow()
+
+def RunGradle(args, throw_on_failure=True):
+  EnsureDeps()
   cmd = [GRADLE]
   cmd.extend(args)
   utils.PrintCmd(cmd)
@@ -66,6 +69,19 @@
       raise
     return return_value
 
+def RunGradleExcludeDeps(args, throw_on_failure=True):
+  EnsureDeps()
+  args.append('-Pexclude_deps')
+  RunGradle(args, throw_on_failure)
+
+def RunGradleGetOutput(args):
+  EnsureDeps()
+  cmd = [GRADLE]
+  cmd.extend(args)
+  utils.PrintCmd(cmd)
+  with utils.ChangedWorkingDirectory(utils.REPO_ROOT):
+    return subprocess.check_output(cmd)
+
 def Main():
   RunGradle(sys.argv[1:])
 
diff --git a/tools/utils.py b/tools/utils.py
index 40a62b8..cf01d3b 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -20,6 +20,7 @@
 DEX_SEGMENTS_RESULT_PATTERN = re.compile('- ([^:]+): ([0-9]+)')
 LIBS = os.path.join(REPO_ROOT, 'build', 'libs')
 MAVEN_ZIP = os.path.join(LIBS, 'r8.zip')
+SRC_ROOT = os.path.join(REPO_ROOT, 'src', 'main', 'java')
 
 D8 = 'd8'
 R8 = 'r8'
@@ -28,6 +29,7 @@
 
 D8_JAR = os.path.join(LIBS, 'd8.jar')
 R8_JAR = os.path.join(LIBS, 'r8.jar')
+R8_EXCLUDE_DEPS_JAR = os.path.join(LIBS, 'r8-exclude-deps.jar')
 COMPATDX_JAR = os.path.join(LIBS, 'compatdx.jar')
 COMPATPROGUARD_JAR = os.path.join(LIBS, 'compatproguard.jar')