diff --git a/build.gradle b/build.gradle
index e49bbb5..f42501a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -20,7 +20,6 @@
     junitVersion = '4.12'
     kotlinVersion = '1.2.30'
     kotlinExtMetadataJVMVersion = '0.0.3'
-    protobufVersion = '3.0.0'
     smaliVersion = '2.2b4'
 }
 
@@ -65,7 +64,6 @@
         }
     }
     dependencies {
-        classpath 'com.google.protobuf:protobuf-gradle-plugin:0.8.1'
         classpath 'com.cookpad.android.licensetools:license-tools-plugin:0.23.0'
         classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
         classpath "net.ltgt.gradle:gradle-errorprone-plugin:0.0.13"
@@ -83,7 +81,6 @@
 
 apply plugin: 'java'
 apply plugin: 'idea'
-apply plugin: 'com.google.protobuf'
 apply plugin: 'com.cookpad.android.licensetools'
 apply plugin: 'net.ltgt.errorprone-base'
 apply plugin: "net.ltgt.apt"
@@ -151,12 +148,7 @@
     }
     examples {
         java {
-            srcDirs = ['src/test/examples', 'build/generated/source/proto/examples/javalite/' ]
-        }
-        proto {
-            srcDirs = [
-                    'src/test/examples',
-            ]
+            srcDirs = ['src/test/examples']
         }
         output.resourcesDir = 'build/classes/examples'
     }
@@ -252,9 +244,7 @@
     examplesAndroidPCompile group: 'org.ow2.asm', name: 'asm', version: asmVersion
     // Import Guava for @Nullable annotation
     examplesCompile "com.google.guava:guava:$guavaVersion"
-    examplesCompile "com.google.protobuf:protobuf-lite:$protobufVersion"
     examplesCompileOnly "com.google.auto.value:auto-value:$autoValueVersion"
-    examplesRuntime "com.google.protobuf:protobuf-lite:$protobufVersion"
     supportLibs "com.android.support:support-v4:$androidSupportVersion"
     supportLibs "junit:junit:$junitVersion"
     supportLibs "com.android.support.test.espresso:espresso-core:$espressoVersion"
@@ -271,29 +261,6 @@
     licensesYaml = file('LIBRARY-LICENSE')
 }
 
-protobuf {
-    protoc {
-        // Download from repositories
-        artifact = "com.google.protobuf:protoc:$protobufVersion"
-    }
-    plugins {
-        javalite {
-            artifact = "com.google.protobuf:protoc-gen-javalite:$protobufVersion"
-        }
-    }
-    generateProtoTasks {
-        all().each { task ->
-            task.builtins {
-                // Disable the java code generator, as we want javalite only.
-                remove java
-            }
-            task.plugins {
-                javalite {}
-            }
-        }
-    }
-}
-
 def osString = OperatingSystem.current().isLinux() ? "linux" :
         OperatingSystem.current().isMacOsX() ? "mac" : "windows"
 
@@ -759,7 +726,6 @@
 task buildExampleJars {
     dependsOn downloadProguard
     def examplesDir = file("src/test/examples")
-    def protoSourceDir = file("build/generated/source/proto/examples/javalite")
     def proguardScript
     if (OperatingSystem.current().isWindows()) {
         proguardScript = "third_party/proguard/proguard5.2.1/bin/proguard.bat"
@@ -782,9 +748,8 @@
     }
 
     task "compile_examples"(type: JavaCompile) {
-        dependsOn "generateExamplesProto"
         dependsOn "copy_examples_resources"
-        source examplesDir, protoSourceDir
+        source examplesDir
         include "**/*.java"
         destinationDir = file("build/test/examples/classes")
         classpath = sourceSets.examples.compileClasspath
@@ -792,8 +757,8 @@
         targetCompatibility = JavaVersion.VERSION_1_7
         options.compilerArgs = ["-g:source,lines", "-Xlint:none"]
     }
-    task "compile_examples_debuginfo_all"(type: JavaCompile, dependsOn: "generateExamplesProto") {
-        source examplesDir, protoSourceDir
+    task "compile_examples_debuginfo_all"(type: JavaCompile) {
+        source examplesDir
         include "**/*.java"
         destinationDir = file("build/test/examples/classes_debuginfo_all")
         classpath = sourceSets.examples.compileClasspath
@@ -801,8 +766,8 @@
         targetCompatibility = JavaVersion.VERSION_1_7
         options.compilerArgs = ["-g", "-Xlint:none"]
     }
-    task "compile_examples_debuginfo_none"(type: JavaCompile, dependsOn: "generateExamplesProto") {
-        source examplesDir, protoSourceDir
+    task "compile_examples_debuginfo_none"(type: JavaCompile) {
+        source examplesDir
         include "**/*.java"
         destinationDir = file("build/test/examples/classes_debuginfo_none")
         classpath = sourceSets.examples.compileClasspath
@@ -819,13 +784,6 @@
         dependsOn "jar_example_${name}_debuginfo_none"
         dependsOn "extractExamplesRuntime"
         def runtimeDependencies = copySpec { }
-        if (!fileTree(dir: dir, include: '**/*.proto').empty) {
-            // If we have any proto use, we have to include those classes and the runtime.
-            runtimeDependencies = copySpec {
-                from "$buildDir/runtime/examples/"
-                include "com/google/protobuf/**/*.class"
-            }
-        }
         // The "throwing" test verifies debugging/stack info on the post-proguarded output.
         def proguardConfigPath = "${dir}/proguard.cfg"
         if (new File(proguardConfigPath).exists()) {
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index b1622ba..6de196e 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -46,7 +46,6 @@
 import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
 import com.android.tools.r8.shaking.TreePruner;
 import com.android.tools.r8.shaking.VerticalClassMerger;
-import com.android.tools.r8.shaking.protolite.ProtoLiteExtension;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.CfgPrinter;
@@ -289,18 +288,14 @@
                     options.proguardConfiguration.getRules(),
                     options)
                 .run(executorService);
-        ProtoLiteExtension protoLiteExtension =
-            options.forceProguardCompatibility
-                ? null
-                : new ProtoLiteExtension(appView.getAppInfo());
+
         Enqueuer enqueuer =
             new Enqueuer(
                 appView.getAppInfo(),
                 appView.getGraphLense(),
                 options,
                 options.forceProguardCompatibility,
-                compatibility,
-                protoLiteExtension);
+                compatibility);
         appView.setAppInfo(enqueuer.traceApplication(rootSet, executorService, timing));
         if (options.proguardConfiguration.isPrintSeeds()) {
           ByteArrayOutputStream bytes = new ByteArrayOutputStream();
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index ca4652c..fb67255 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -58,7 +58,6 @@
 import com.android.tools.r8.kotlin.KotlinInfo;
 import com.android.tools.r8.logging.Log;
 import com.android.tools.r8.naming.IdentifierNameStringMarker;
-import com.android.tools.r8.shaking.protolite.ProtoLitePruner;
 import com.android.tools.r8.utils.CfgPrinter;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
@@ -109,7 +108,6 @@
   private final LensCodeRewriter lensCodeRewriter;
   private final NonNullTracker nonNullTracker;
   private final Inliner inliner;
-  private final ProtoLitePruner protoLiteRewriter;
   private final IdentifierNameStringMarker identifierNameStringMarker;
   private final Devirtualizer devirtualizer;
   private final CovariantReturnTypeAnnotationTransformer covariantReturnTypeAnnotationTransformer;
@@ -165,9 +163,6 @@
               new MemberValuePropagation(appInfo.withLiveness()) : null;
       this.lensCodeRewriter = new LensCodeRewriter(graphLense, appInfo.withSubtyping());
       if (appInfo.hasLiveness()) {
-        // When disabling the pruner here, also disable the ProtoLiteExtension in R8.java.
-        this.protoLiteRewriter =
-            options.forceProguardCompatibility ? null : new ProtoLitePruner(appInfo.withLiveness());
         if (!appInfo.withLiveness().identifierNameStrings.isEmpty() && options.enableMinification) {
           this.identifierNameStringMarker =
               new IdentifierNameStringMarker(appInfo.withLiveness(), options);
@@ -177,7 +172,6 @@
         this.devirtualizer =
             options.enableDevirtualization ? new Devirtualizer(appInfo.withLiveness()) : null;
       } else {
-        this.protoLiteRewriter = null;
         this.identifierNameStringMarker = null;
         this.devirtualizer = null;
       }
@@ -187,7 +181,6 @@
       this.outliner = null;
       this.memberValuePropagation = null;
       this.lensCodeRewriter = null;
-      this.protoLiteRewriter = null;
       this.identifierNameStringMarker = null;
       this.devirtualizer = null;
     }
@@ -743,9 +736,6 @@
     }
 
     if (!method.isProcessed()) {
-      if (protoLiteRewriter != null && protoLiteRewriter.appliesTo(method)) {
-        protoLiteRewriter.rewriteProtoLiteSpecialMethod(code, method);
-      }
       if (lensCodeRewriter != null) {
         lensCodeRewriter.rewrite(code, method);
       } else {
diff --git a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
index 97456ec..13308e5 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -44,7 +44,6 @@
 import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.RootSetBuilder.ConsequentRootSet;
 import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
-import com.android.tools.r8.shaking.protolite.ProtoLiteExtension;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.Timing;
@@ -116,8 +115,6 @@
       Maps.newIdentityHashMap();
   private final Set<DexCallSite> callSites = Sets.newIdentityHashSet();
 
-  private final ProtoLiteExtension protoLiteExtension;
-  private final Set<DexField> protoLiteFields = Sets.newIdentityHashSet();
   private final Set<DexReference> identifierNameStrings = Sets.newIdentityHashSet();
 
   /**
@@ -228,7 +225,7 @@
       GraphLense graphLense,
       InternalOptions options,
       boolean forceProguardCompatibility) {
-    this(appInfo, graphLense, options, forceProguardCompatibility, null, null);
+    this(appInfo, graphLense, options, forceProguardCompatibility, null);
   }
 
   public Enqueuer(
@@ -236,13 +233,11 @@
       GraphLense graphLense,
       InternalOptions options,
       boolean forceProguardCompatibility,
-      ProguardConfiguration.Builder compatibility,
-      ProtoLiteExtension protoLiteExtension) {
+      ProguardConfiguration.Builder compatibility) {
     this.appInfo = appInfo;
     this.graphLense = graphLense;
     this.compatibility = compatibility;
     this.options = options;
-    this.protoLiteExtension = protoLiteExtension;
     this.forceProguardCompatibility = forceProguardCompatibility;
   }
 
@@ -1378,11 +1373,7 @@
       markParameterAndReturnTypesAsLive(method);
       processAnnotations(method.annotations.annotations);
       method.parameterAnnotationsList.forEachAnnotation(this::processAnnotation);
-      if (protoLiteExtension != null && protoLiteExtension.appliesTo(method)) {
-        protoLiteExtension.processMethod(method, new UseRegistry(method), protoLiteFields);
-      } else {
-        method.registerCodeReferences(new UseRegistry(method));
-      }
+      method.registerCodeReferences(new UseRegistry(method));
       // Add all dependent members to the workqueue.
       enqueueRootItems(rootSet.getDependentItems(method));
     }
@@ -1711,11 +1702,6 @@
      */
     public final Object2BooleanMap<DexReference> identifierNameStrings;
     /**
-     * Set of fields that have been identified as proto-lite fields by the
-     * {@link ProtoLiteExtension}.
-     */
-    final Set<DexField> protoLiteFields;
-    /**
      * A set of types that have been removed by the {@link TreePruner}.
      */
     final Set<DexType> prunedTypes;
@@ -1770,7 +1756,6 @@
       this.neverInline = enqueuer.rootSet.neverInline;
       this.identifierNameStrings = joinIdentifierNameStrings(
           enqueuer.rootSet.identifierNameStrings, enqueuer.identifierNameStrings);
-      this.protoLiteFields = enqueuer.protoLiteFields;
       this.prunedTypes = Collections.emptySet();
       this.switchMaps = Collections.emptyMap();
       this.ordinalsMaps = Collections.emptyMap();
@@ -1808,7 +1793,6 @@
       this.staticInvokes = previous.staticInvokes;
       this.callSites = previous.callSites;
       this.brokenSuperInvokes = previous.brokenSuperInvokes;
-      this.protoLiteFields = previous.protoLiteFields;
       this.alwaysInline = previous.alwaysInline;
       this.forceInline = previous.forceInline;
       this.neverInline = previous.neverInline;
@@ -1872,7 +1856,6 @@
               .collect(Collectors.toList()));
       this.switchMaps = previous.switchMaps;
       this.ordinalsMaps = rewriteKeys(previous.ordinalsMaps, lense::lookupType);
-      this.protoLiteFields = previous.protoLiteFields;
       // Sanity check sets after rewriting.
       assert Sets.intersection(instanceFieldReads.keySet(), staticFieldReads.keySet()).isEmpty();
       assert Sets.intersection(instanceFieldWrites.keySet(), staticFieldWrites.keySet()).isEmpty();
@@ -1905,7 +1888,6 @@
       this.staticInvokes = previous.staticInvokes;
       this.callSites = previous.callSites;
       this.brokenSuperInvokes = previous.brokenSuperInvokes;
-      this.protoLiteFields = previous.protoLiteFields;
       this.alwaysInline = previous.alwaysInline;
       this.forceInline = previous.forceInline;
       this.neverInline = previous.neverInline;
@@ -2027,10 +2009,6 @@
       return pinnedItems.contains(reference);
     }
 
-    public boolean isProtoLiteField(DexField field) {
-      return protoLiteFields.contains(field);
-    }
-
     public Iterable<DexReference> getPinnedItems() {
       return pinnedItems;
     }
diff --git a/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteBase.java b/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteBase.java
deleted file mode 100644
index c2264f2..0000000
--- a/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteBase.java
+++ /dev/null
@@ -1,98 +0,0 @@
-// 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.shaking.protolite;
-
-import com.android.tools.r8.graph.AppInfoWithSubtyping;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
-
-/**
- * Contains common definitions used by the {@link ProtoLiteExtension} for tree shaking and the
- * corresponding {@link ProtoLitePruner} code rewriting.
- */
-abstract class ProtoLiteBase {
-
-  static final int GETTER_NAME_PREFIX_LENGTH = 3;
-  static final int COUNT_POSTFIX_LENGTH = 5;
-
-  final AppInfoWithSubtyping appInfo;
-
-  final DexType messageType;
-  final DexString dynamicMethodName;
-  final DexString writeToMethodName;
-  final DexString getSerializedSizeMethodName;
-  final DexString constructorMethodName;
-  final DexString setterNamePrefix;
-  final DexString getterNamePrefix;
-  final DexString bitFieldPrefix;
-  final DexString underscore;
-
-  ProtoLiteBase(AppInfoWithSubtyping appInfo) {
-    this.appInfo = appInfo;
-    DexItemFactory factory = appInfo.dexItemFactory;
-    this.messageType = factory.createType("Lcom/google/protobuf/GeneratedMessageLite;");
-    this.dynamicMethodName = factory.createString("dynamicMethod");
-    this.writeToMethodName = factory.createString("writeTo");
-    this.getSerializedSizeMethodName = factory.createString("getSerializedSize");
-    this.constructorMethodName = factory.constructorMethodName;
-    this.setterNamePrefix = factory.createString("set");
-    this.getterNamePrefix = factory.createString("get");
-    this.bitFieldPrefix = factory.createString("bitField");
-    this.underscore = factory.createString("_");
-    assert getterNamePrefix.size == GETTER_NAME_PREFIX_LENGTH;
-  }
-
-  /**
-   * Returns true of the given method is a setter on a message class that does need processing
-   * by this phase of proto lite shaking.
-   * <p>
-   * False positives are ok.
-   */
-  abstract boolean isSetterThatNeedsProcessing(DexEncodedMethod method);
-
-  DexField getterToField(DexMethod getter) {
-    return getterToField(getter, 0);
-  }
-
-  DexField getterToField(DexMethod getter, int postfixLength) {
-    String getterName = getter.name.toString();
-    assert getterName.length() > GETTER_NAME_PREFIX_LENGTH + postfixLength;
-    String fieldName = Character.toLowerCase(getterName.charAt(GETTER_NAME_PREFIX_LENGTH))
-        + getterName.substring(GETTER_NAME_PREFIX_LENGTH + 1, getterName.length() - postfixLength)
-        + "_";
-    DexItemFactory factory = appInfo.dexItemFactory;
-    return factory
-        .createField(getter.holder, getter.proto.returnType, factory.createString(fieldName));
-  }
-
-  boolean hasSingleIntArgument(DexMethod method) {
-    return method.getArity() == 1
-        && method.proto.parameters.values[0] == appInfo.dexItemFactory.intType;
-  }
-
-  public boolean appliesTo(DexEncodedMethod method) {
-    if (!method.method.holder.isSubtypeOf(messageType, appInfo)) {
-      return false;
-    }
-    DexClass clazz = appInfo.definitionFor(method.method.holder);
-    // We only care for the actual leaf classes that implement a specific proto.
-    if (!clazz.accessFlags.isFinal()) {
-      return false;
-    }
-    DexString methodName = method.method.name;
-    // We could be even more precise here and check for the signature. However, there is only
-    // one of each method generated.
-    return methodName == dynamicMethodName
-        || methodName == writeToMethodName
-        || methodName == getSerializedSizeMethodName
-        || methodName == constructorMethodName
-        || isSetterThatNeedsProcessing(method);
-  }
-
-}
diff --git a/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteExtension.java b/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteExtension.java
deleted file mode 100644
index c4dee58..0000000
--- a/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteExtension.java
+++ /dev/null
@@ -1,198 +0,0 @@
-// 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.shaking.protolite;
-
-import com.android.tools.r8.graph.AppInfoWithSubtyping;
-import com.android.tools.r8.graph.DelegatingUseRegistry;
-import com.android.tools.r8.graph.DexClass;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.graph.UseRegistry;
-import com.android.tools.r8.utils.MethodJavaSignatureEquivalence;
-import com.google.common.base.Equivalence;
-import com.google.common.base.Equivalence.Wrapper;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Extends the tree shaker with special treatment for ProtoLite generated classes.
- * <p>
- * The goal is to remove unused fields from proto classes. To achieve this, we filter the
- * dependency processing of certain methods of ProtoLite classes. Read/write references to
- * fields or corresponding getters are ignored. If the fields or getters are not used otherwise
- * in the program, they will be pruned even though they are referenced from the processed
- * ProtoLite class.
- * <p>
- * The companion code rewriter in {@link ProtoLitePruner} then fixes up the code and removes
- * references to these dead fields and getters in a semantics preserving way. For proto2, the
- * fields are turned into unknown fields and hence are preserved over the wire. For proto3, the
- * fields are removed and, as with unknown fields in proto3, their data is lost on retransmission.
- * <p>
- * We have to process the following three methods specially:
- * <dl>
- *   <dt>dynamicMethod</dt>
- *   <dd>implements most proto operations, like merging, comparing, etc</dd>
- *   <dt>writeTo</dt>
- *   <dd>performs the actual write operations</dd>
- *   <dt>getSerializedSize</dt>
- *   <dd>implements computing the serialized size of a proto, very similar to writeTo</dd>
- * </dl>
- * As they access all fields of a proto, regardless of whether they are used, we have to mask
- * their accesses to ensure actually dead fields are not made live.
- * <p>
- * We also have to treat setters specially. While their code does not need to be rewritten, we
- * need to ensure that the fields they write are actually kept and marked as live. We achieve
- * this by also marking them read.
- */
-public class ProtoLiteExtension extends ProtoLiteBase {
-
-  private final Equivalence<DexMethod> equivalence = MethodJavaSignatureEquivalence.get();
-  /**
-   * Set of all methods directly defined on the GeneratedMessageLite class. Used to filter
-   * getters from other methods that begin with get.
-   */
-  private final Set<Wrapper<DexMethod>> methodsOnMessageType;
-
-  private final DexString caseGetterSuffix;
-  private final DexString caseFieldSuffix;
-
-  public ProtoLiteExtension(AppInfoWithSubtyping appInfo) {
-    super(appInfo);
-    DexItemFactory factory = appInfo.dexItemFactory;
-    this.methodsOnMessageType = computeMethodsOnMessageType();
-    this.caseGetterSuffix = factory.createString("Case");
-    this.caseFieldSuffix = factory.createString("Case_");
-  }
-
-  private Set<Wrapper<DexMethod>> computeMethodsOnMessageType() {
-    DexClass messageClass = appInfo.definitionFor(messageType);
-    if (messageClass == null) {
-      return Collections.emptySet();
-    }
-    Set<Wrapper<DexMethod>> superMethods = new HashSet<>();
-    messageClass.forEachMethod(method -> superMethods.add(equivalence.wrap(method.method)));
-    return superMethods;
-  }
-
-  @Override
-  boolean isSetterThatNeedsProcessing(DexEncodedMethod method) {
-    return method.accessFlags.isPrivate()
-        && method.method.name.beginsWith(setterNamePrefix)
-        && !methodsOnMessageType.contains(equivalence.wrap(method.method));
-  }
-
-  private boolean isGetter(DexMethod method, DexType instanceType) {
-    return method.holder == instanceType
-        && (method.proto.parameters.isEmpty() || hasSingleIntArgument(method))
-        && method.name.beginsWith(getterNamePrefix)
-        && !method.name.endsWith(caseGetterSuffix)
-        && !methodsOnMessageType.contains(equivalence.wrap(method));
-  }
-
-  private boolean isProtoField(DexField field, DexType instanceType) {
-    if (field.getHolder() != instanceType) {
-      return false;
-    }
-    // All instance fields that end with _ are proto fields. For proto2, there are also the
-    // bitField<n>_ fields that are used to store presence information. We process those normally.
-    // Likewise, the XXXCase_ fields for oneOfs.
-    DexString name = field.name;
-    return name.endsWith(underscore)
-        && !name.beginsWith(bitFieldPrefix)
-        && !name.endsWith(caseFieldSuffix);
-  }
-
-  public void processMethod(DexEncodedMethod method, UseRegistry registry,
-      Set<DexField> protoLiteFields) {
-    assert protoLiteFields != null;
-    if (isSetterThatNeedsProcessing(method)) {
-      // If a field is accessed by a live setter, the field is live as it has to be written to the
-      // serialized stream for this proto. As we mask all reads in the writing code and normally
-      // remove fields that are only written but never read, we have to mark fields used in setters
-      // as read and written.
-      method.registerCodeReferences(
-          new FieldWriteImpliesReadUseRegistry(registry, method.method.holder));
-    } else {
-      // Filter all getters and field accesses in these methods. We do not want fields to become
-      // live just due to being referenced in a special method. The pruning phase will remove
-      // all references to dead fields in the code later.
-      method.registerCodeReferences(new FilteringUseRegistry(registry, method.method.holder,
-          protoLiteFields));
-    }
-  }
-
-  private class FieldWriteImpliesReadUseRegistry extends DelegatingUseRegistry {
-
-    private final DexType instanceType;
-
-    FieldWriteImpliesReadUseRegistry(UseRegistry delegate,
-        DexType instanceType) {
-      super(delegate);
-      this.instanceType = instanceType;
-    }
-
-    @Override
-    public boolean registerInstanceFieldWrite(DexField field) {
-      if (isProtoField(field, instanceType)) {
-        super.registerInstanceFieldRead(field);
-      }
-      return super.registerInstanceFieldWrite(field);
-    }
-  }
-
-  private class FilteringUseRegistry extends DelegatingUseRegistry {
-
-    private final DexType instanceType;
-    private final Set<DexField> registerField;
-
-    private FilteringUseRegistry(UseRegistry delegate,
-        DexType instanceType, Set<DexField> registerField) {
-      super(delegate);
-      this.instanceType = instanceType;
-      this.registerField = registerField;
-    }
-
-    @Override
-    public boolean registerInstanceFieldWrite(DexField field) {
-      if (isProtoField(field, instanceType)) {
-        registerField.add(field);
-        return false;
-      }
-      return super.registerInstanceFieldWrite(field);
-    }
-
-    @Override
-    public boolean registerInstanceFieldRead(DexField field) {
-      if (isProtoField(field, instanceType)) {
-        registerField.add(field);
-        return false;
-      }
-      return super.registerInstanceFieldRead(field);
-    }
-
-    @Override
-    public boolean registerInvokeVirtual(DexMethod method) {
-      if (isGetter(method, instanceType)) {
-        // Try whether this is a getXXX method.
-        DexField field = getterToField(method);
-        if (isProtoField(field, instanceType)) {
-          registerField.add(field);
-          return false;
-        }
-        // Try whether this is a getXXXCount method.
-        field = getterToField(method, COUNT_POSTFIX_LENGTH);
-        if (isProtoField(field, instanceType)) {
-          registerField.add(field);
-          return false;
-        }
-      }
-      return super.registerInvokeVirtual(method);
-    }
-  }
-}
diff --git a/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLitePruner.java b/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLitePruner.java
deleted file mode 100644
index c37102c..0000000
--- a/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLitePruner.java
+++ /dev/null
@@ -1,735 +0,0 @@
-// 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.shaking.protolite;
-
-import com.android.tools.r8.errors.CompilationError;
-import com.android.tools.r8.errors.Unreachable;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexField;
-import com.android.tools.r8.graph.DexItemFactory;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexString;
-import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.code.BasicBlock;
-import com.android.tools.r8.ir.code.DominatorTree;
-import com.android.tools.r8.ir.code.IRCode;
-import com.android.tools.r8.ir.code.InstanceGet;
-import com.android.tools.r8.ir.code.InstancePut;
-import com.android.tools.r8.ir.code.Instruction;
-import com.android.tools.r8.ir.code.InstructionIterator;
-import com.android.tools.r8.ir.code.InstructionListIterator;
-import com.android.tools.r8.ir.code.InvokeInterface;
-import com.android.tools.r8.ir.code.InvokeMethod;
-import com.android.tools.r8.ir.code.InvokeMethodWithReceiver;
-import com.android.tools.r8.ir.code.InvokeStatic;
-import com.android.tools.r8.ir.code.MemberType;
-import com.android.tools.r8.ir.code.Switch;
-import com.android.tools.r8.ir.code.Value;
-import com.android.tools.r8.ir.code.ValueType;
-import com.android.tools.r8.ir.optimize.SwitchUtils;
-import com.android.tools.r8.ir.optimize.SwitchUtils.EnumSwitchInfo;
-import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import it.unimi.dsi.fastutil.ints.IntArrayList;
-import it.unimi.dsi.fastutil.ints.IntList;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.BiPredicate;
-
-/**
- * Implements the second phase of proto lite tree shaking.
- * <p>
- * In the pruner pass, we remove all references to the now dead fields from the methods that
- * were treated specially during tree shaking using the {@link ProtoLiteExtension}.
- * <p>
- * For proto2 code, we aim to keep presence information for fields alive and move the values of
- * dead fields to the unknown fields storage. For proto3, as it has no concept of passing on
- * unknown fields, dead fields are completely removed. In particular, reading a proto and writing
- * it again might loose data.
- */
-public class ProtoLitePruner extends ProtoLiteBase {
-
-  private final DexType visitorType;
-
-  private final DexType methodEnumType;
-  private final DexType codedOutputStreamType;
-  private final DexType protobufListType;
-  private final DexType listType;
-
-  private final DexString visitTag;
-  private final DexString mergeTag;
-  private final DexString isInitializedTag;
-  private final DexString makeImmutabkeTag;
-  private final DexString computeMethodPrefix;
-  private final DexString writeMethodPrefix;
-  private final DexString isInitializedMethodName;
-
-  private final DexString makeImmutableMethodName;
-  private final DexString sizeMethodName;
-  private final DexMethod sizeMethod;
-
-  public ProtoLitePruner(AppInfoWithLiveness appInfo) {
-    super(appInfo);
-    DexItemFactory factory = appInfo.dexItemFactory;
-    this.visitorType = factory.createType("Lcom/google/protobuf/GeneratedMessageLite$Visitor;");
-    this.methodEnumType = factory
-        .createType("Lcom/google/protobuf/GeneratedMessageLite$MethodToInvoke;");
-    this.codedOutputStreamType = factory.createType("Lcom/google/protobuf/CodedOutputStream;");
-    this.protobufListType = factory.createType("Lcom/google/protobuf/Internal$ProtobufList;");
-    this.listType = factory.createType("Ljava/util/List;");
-    this.visitTag = factory.createString("VISIT");
-    this.mergeTag = factory.createString("MERGE_FROM_STREAM");
-    this.isInitializedTag = factory.createString("IS_INITIALIZED");
-    this.makeImmutabkeTag = factory.createString("MAKE_IMMUTABLE");
-    this.computeMethodPrefix = factory.createString("compute");
-    this.writeMethodPrefix = factory.createString("write");
-    this.sizeMethodName = factory.createString("size");
-    this.isInitializedMethodName = factory.createString("isInitialized");
-    this.makeImmutableMethodName = factory.createString("makeImmutable");
-    this.sizeMethod = factory.createMethod(listType,
-        factory.createProto(factory.intType), sizeMethodName);
-  }
-
-  private boolean isPresenceField(DexField field, DexType instanceType) {
-    if (field.getHolder() != instanceType) {
-      return false;
-    }
-    // Proto2 uses fields named bitField<n>_ fields to store presence information.
-    String fieldName = field.name.toString();
-    return fieldName.endsWith("_")
-        && fieldName.startsWith("bitField");
-  }
-
-  @Override
-  boolean isSetterThatNeedsProcessing(DexEncodedMethod method) {
-    // The pruner does not need to process setters, so this method always returns false.
-    return false;
-  }
-
-  private boolean isGetter(DexMethod method) {
-    return isGetterHelper(method, 0);
-  }
-
-  private boolean isCountGetter(DexMethod method) {
-    return isGetterHelper(method, COUNT_POSTFIX_LENGTH);
-  }
-
-  private boolean isGetterHelper(DexMethod method, int postFixLength) {
-    if (!method.name.beginsWith(getterNamePrefix)
-        || !(method.proto.parameters.isEmpty() || hasSingleIntArgument(method))
-        || (method.holder == messageType)
-        || !method.holder.isSubtypeOf(messageType, appInfo)
-        || method.name.size <= GETTER_NAME_PREFIX_LENGTH + postFixLength) {
-      return false;
-    }
-    DexField correspondingField = getterToField(method, postFixLength);
-    return isProtoField(correspondingField);
-  }
-
-  private boolean isDefinedAsNull(Value value) {
-    return value.definition != null && value.isZero();
-  }
-
-  private boolean isComputeSizeMethod(DexMethod invokedMethod) {
-    return invokedMethod.holder == codedOutputStreamType
-        && invokedMethod.name.beginsWith(computeMethodPrefix);
-  }
-
-  private boolean isWriteMethod(DexMethod invokedMethod) {
-    return invokedMethod.holder == codedOutputStreamType
-        && invokedMethod.name.beginsWith(writeMethodPrefix);
-  }
-
-  private boolean isProtoField(DexField field) {
-    return appInfo.withLiveness().isProtoLiteField(field);
-  }
-
-  public void rewriteProtoLiteSpecialMethod(IRCode code, DexEncodedMethod method) {
-    DexString methodName = method.method.name;
-    if (methodName == dynamicMethodName) {
-      rewriteDynamicMethod(code, method);
-    } else if ((methodName == writeToMethodName) || (methodName == getSerializedSizeMethodName)) {
-      rewriteSizeOrWriteMethod(code);
-    } else if (methodName == constructorMethodName) {
-      rewriteConstructor(code);
-    } else {
-      throw new Unreachable();
-    }
-  }
-
-  /**
-   * For protos with repeated fields, the constructor may contain field initialization code like
-   *
-   * <pre>
-   * private Repeated() {
-   *  repeated_ = com.google.protobuf.GeneratedMessageLite.emptyProtobufList();
-   *  other_ = emptyBooleanList();
-   *  sub_ = emptyProtobufList();
-   * }
-   * </pre>
-   *
-   * which this rewriting removes.
-   */
-  private void rewriteConstructor(IRCode code) {
-    boolean wasRewritten;
-    do {
-      wasRewritten = false;
-      InstructionIterator it = code.instructionIterator();
-      while (it.hasNext()) {
-        Instruction insn = it.next();
-        if (insn.isInstancePut() && isDeadProtoField(insn.asInstancePut().getField())) {
-          // Remove initializations of dead fields.
-          it.remove();
-          wasRewritten = true;
-        } else if (insn.isInvokeStatic()) {
-          // Remove now unneeded constructor calls.
-          InvokeStatic invokeStatic = insn.asInvokeStatic();
-          DexMethod invokedMethod = invokeStatic.getInvokedMethod();
-          if ((!invokeStatic.outValue().isUsed())
-              && invokedMethod.proto.returnType.isSubtypeOf(protobufListType, appInfo)) {
-            it.remove();
-          }
-        }
-      }
-    } while (wasRewritten);
-  }
-
-
-  /**
-   * The writeTo and getSerializedSize methods of a generated proto access all fields. We have to
-   * remove the accesses to dead fields. The actual code of these methods varies to quite some
-   * degree depending on the types of the fields. For example
-   *
-   * <pre>
-   * public void writeTo(com.google.protobuf.CodedOutputStream output) throws java.io.IOException {
-   *   if (((bitField0_ & 0x00000001) == 0x00000001)) {
-   *     output.writeInt32(1, id_);
-   *   }
-   *   if (((bitField0_ & 0x00000002) == 0x00000002)) {
-   *     output.writeMessage(2, getInner());
-   *   }
-   *   for (int i = 0; i < repeated_.size(); i++) {
-   *     output.writeString(3, repeated_.get(i));
-   *   }
-   *   for (int i = 0; i < other_.size(); i++) {
-   *     output.writeBool(4, other_.getBoolean(i));
-   *   }
-   *   for (int i = 0; i < sub_.size(); i++) {
-   *     output.writeMessage(5, sub_.get(i));
-   *   }
-   *   unknownFields.writeTo(output);
-   * }
-   * </pre>
-   *
-   * We look for direct field accesses (id_, repeated_, etc. above) and getters (getInner) and
-   * rewrite those to null/0. We also rewrite all uses of the results, like the size() and
-   * write methods above.
-   */
-  private void rewriteSizeOrWriteMethod(IRCode code) {
-    boolean wasRewritten;
-    do {
-      wasRewritten = false;
-      InstructionIterator it = code.instructionIterator();
-      while (it.hasNext()) {
-        Instruction insn = it.next();
-        if (insn.isInstanceGet()) {
-          DexField field = insn.asInstanceGet().getField();
-          if (isDeadProtoField(field)) {
-            // Rewrite deads field access to corresponding 0.
-            it.replaceCurrentInstruction(code.createConstNull(insn.asInstanceGet()));
-            wasRewritten = true;
-          }
-        } else if (insn.isInvokeMethodWithReceiver()) {
-          InvokeMethodWithReceiver invokeMethod = insn.asInvokeMethodWithReceiver();
-          DexMethod invokedMethod = invokeMethod.getInvokedMethod();
-          if (isDeadProtoGetter(invokedMethod)) {
-            // Rewrite dead getters.
-            it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-            wasRewritten = true;
-          } else if (invokedMethod.name == sizeMethodName
-              && invokedMethod.holder.isSubtypeOf(listType, appInfo)) {
-            Value receiver = invokeMethod.getReceiver();
-            if (isDefinedAsNull(receiver)) {
-              // Rewrite size() methods with null receiver.
-              it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-            }
-          } else if (invokedMethod.name == getterNamePrefix
-              && invokedMethod.holder.isSubtypeOf(listType, appInfo)) {
-            Value receiver = invokeMethod.getReceiver();
-            if (isDefinedAsNull(receiver)) {
-              // Rewrite get(x) methods with null receiver.
-              it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-              wasRewritten = true;
-            }
-          } else if (isWriteMethod(invokedMethod)) {
-            Value lastArg = Iterables.getLast(invokeMethod.inValues());
-            if (isDefinedAsNull(lastArg)) {
-              it.remove();
-            }
-          }
-        } else if (insn.isInvokeMethod()) {
-          InvokeMethod invokeMethod = insn.asInvokeMethod();
-          DexMethod invokedMethod = invokeMethod.getInvokedMethod();
-          if (isComputeSizeMethod(invokedMethod)) {
-            Value lastArg = Iterables.getLast(invokeMethod.inValues());
-            if (isDefinedAsNull(lastArg)) {
-              // This is a computeSize method on a constant null. The field was dead.
-              assert (invokeMethod.outValue() != null);
-              it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-              wasRewritten = true;
-            }
-          }
-        }
-      }
-    } while (wasRewritten);
-  }
-
-  /**
-   * The dyanmicMethod code is actually a collection of various methods contained in one.
-   * It uses a switch statement over an enum to identify which actual operation is performed.
-   * We need to rewrite all cases that might access dead fields. These are
-   * <dl>
-   * <dt>IS_INITIALIZED</dt>
-   * <dd>See {@link #rewriteIsInitializedCase}.</dd>
-   * <dt>MAKE_IMMUTABLE</dt>
-   * <dd>See {@link #rewriteMakeImmutableCase}.</dd>
-   * <dt>VISIT</dt>
-   * <dd>See {@link #rewriteVisitCase}.</dd>
-   * <dt>MERGE_FROM_STREAM</dt>
-   * <dd>See {@link #rewriteMergeCase}.</dd>
-   * </dl>
-   */
-  private void rewriteDynamicMethod(IRCode code, DexEncodedMethod method) {
-    // This method contains a switch and we are interested in some of the cases only.
-    InstructionIterator iterator = code.instructionIterator();
-    Instruction matchingInstr = iterator.nextUntil(Instruction::isSwitch);
-    if (matchingInstr == null) {
-      throw new CompilationError("dynamicMethod in protoLite without switch.");
-    }
-    Switch switchInstr = matchingInstr.asSwitch();
-    EnumSwitchInfo info = SwitchUtils.analyzeSwitchOverEnum(switchInstr, appInfo.withLiveness());
-    if (info == null || info.enumClass != methodEnumType) {
-      throw new CompilationError("Malformed switch in dynamicMethod of proto lite.");
-    }
-    BasicBlock initializedCase = null;
-    BasicBlock visitCase = null;
-    BasicBlock mergeCase = null;
-    BasicBlock makeImmutableCase = null;
-    for (int keyIdx = 0; keyIdx < switchInstr.numberOfKeys(); keyIdx++) {
-      int key = switchInstr.getKey(keyIdx);
-      DexField label = info.indexMap.get(key);
-      assert label != null;
-      if (label.name == visitTag) {
-        assert visitCase == null;
-        visitCase = switchInstr.targetBlock(keyIdx);
-      } else if (label.name == mergeTag) {
-        assert mergeCase == null;
-        mergeCase = switchInstr.targetBlock(keyIdx);
-      } else if (label.name == isInitializedTag) {
-        assert initializedCase == null;
-        initializedCase = switchInstr.targetBlock(keyIdx);
-      } else if (label.name == makeImmutabkeTag) {
-        assert makeImmutableCase == null;
-        makeImmutableCase = switchInstr.targetBlock(keyIdx);
-      }
-    }
-    DexType instanceType = method.method.getHolder();
-    rewriteIsInitializedCase(initializedCase, instanceType, code);
-    assert code.isConsistentSSA();
-    rewriteMakeImmutableCase(makeImmutableCase, code);
-    assert code.isConsistentSSA();
-    rewriteVisitCase(visitCase, code);
-    assert code.isConsistentSSA();
-    rewriteMergeCase(mergeCase, instanceType, code);
-    // Rewriting of the merge case changes branching structure and adds more blocks that target
-    // the fallthrough label. This can introduce critical edges. Therefore, we split critical
-    // edges to maintain our edge-split form.
-    code.splitCriticalEdges();
-    assert code.isConsistentSSA();
-  }
-
-  /**
-   * In the presence of repeated fields, the MAKE_IMMUTABLE case will contain code of the form
-   *
-   * <pre>
-   * case MAKE_IMMUTABLE: {
-   *   repeated_.makeImmutable();
-   *   other_.makeImmutable();
-   *   sub_.makeImmutable();
-   *   return null;
-   * }
-   * </pre>
-   *
-   * For dead fields, we remove the field access and the call to makeImmutable.
-   */
-  private void rewriteMakeImmutableCase(BasicBlock switchCase, IRCode code) {
-    DominatorTree dom = new DominatorTree(code);
-    boolean wasRewritten;
-    do {
-      wasRewritten = false;
-      for (BasicBlock current : dom.dominatedBlocks(switchCase)) {
-        InstructionIterator it = current.iterator();
-        while (it.hasNext()) {
-          Instruction insn = it.next();
-          if (insn.isInstanceGet() && isDeadProtoField(insn.asInstanceGet().getField())) {
-            it.replaceCurrentInstruction(code.createConstNull(insn));
-            wasRewritten = true;
-          } else if (insn.isInvokeMethodWithReceiver()) {
-            InvokeMethodWithReceiver invokeMethod = insn.asInvokeMethodWithReceiver();
-            DexMethod invokedMethod = invokeMethod.getInvokedMethod();
-            if (isDeadProtoGetter(invokedMethod)) {
-              it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-              wasRewritten = true;
-            } else if (invokedMethod.name == makeImmutableMethodName
-                && invokedMethod.getHolder().isSubtypeOf(protobufListType, appInfo)) {
-              Value receiver = invokeMethod.getReceiver();
-              if (isDefinedAsNull(receiver)) {
-                it.remove();
-              }
-            }
-          }
-        }
-      }
-    } while (wasRewritten);
-  }
-
-  /**
-   * The IS_INITIALIZED case also has a high degree of variability depending on the type of fields.
-   * Common code looks as follows
-   *
-   * <pre>
-   * case IS_INITIALIZED: {
-   *   byte isInitialized = memoizedIsInitialized;
-   *   if (isInitialized == 1) return DEFAULT_INSTANCE;
-   *   if (isInitialized == 0) return null;
-   *
-   *   boolean shouldMemoize = ((Boolean) arg0).booleanValue();
-   *   if (!hasId()) {
-   *     if (shouldMemoize) {
-   *       memoizedIsInitialized = 0;
-   *     }
-   *     return null;
-   *   }
-   *   for (int i = 0; i < getSubCount(); i++) {
-   *     if (!getSub(i).isInitialized()) {
-   *       if (shouldMemoize) {
-   *         memoizedIsInitialized = 0;
-   *       }
-   *       return null;
-   *     }
-   *   }
-   *   if (shouldMemoize) memoizedIsInitialized = 1;
-   *   return DEFAULT_INSTANCE;
-   * }
-   * </pre>
-   *
-   * We remove all the accesses of dead fields and getters. We also replace secondary invokes
-   * (like getSubCount or isInitialized) with conservative default values (e.g. 0, true).
-   * <p>
-   * We also rewrite getXXXCount methods on live fields, as accesses to those methods was filtered
-   * during tree shaking. In place of those methods, we inline their definition.
-   */
-  private void rewriteIsInitializedCase(BasicBlock switchCase, DexType instanceType,
-      IRCode code) {
-    DominatorTree dom = new DominatorTree(code);
-    boolean wasRewritten;
-    do {
-      wasRewritten = false;
-      for (BasicBlock current : dom.dominatedBlocks(switchCase)) {
-        InstructionIterator it = current.iterator();
-        while (it.hasNext()) {
-          Instruction insn = it.next();
-          if (insn.isInvokeMethodWithReceiver()) {
-            InvokeMethodWithReceiver invokeMethod = insn.asInvokeMethodWithReceiver();
-            DexMethod invokedMethod = invokeMethod.getInvokedMethod();
-            if (isDeadProtoGetter(invokedMethod)) {
-              it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-              wasRewritten = true;
-            } else if (invokedMethod.name == isInitializedMethodName
-                && invokedMethod.getHolder().isSubtypeOf(messageType, appInfo)) {
-              Value receiver = invokeMethod.getReceiver();
-              if (isDefinedAsNull(receiver)) {
-                // We cannot compute initialization state for nested messages and repeated
-                // messages that have been removed or moved to unknown fields. Just return
-                // true.
-                it.replaceCurrentInstruction(code.createTrue());
-                wasRewritten = true;
-              }
-            } else if (isCountGetter(invokedMethod)) {
-              // We have to rewrite these as a precaution, as they might be dead due to
-              // tree shaking ignoring them.
-              DexField field = getterToField(invokedMethod, 5);
-              if (appInfo.withLiveness().liveFields.contains(field)) {
-                // Effectively inline the code that is normally inside these methods.
-                Value thisReference = invokeMethod.getReceiver();
-                Value newResult = code.createValue(ValueType.INT);
-                invokeMethod.outValue().replaceUsers(newResult);
-                Value theList = code.createValue(ValueType.OBJECT);
-                it.replaceCurrentInstruction(
-                    new InstanceGet(MemberType.OBJECT, theList, thisReference, field));
-                it.add(new InvokeInterface(sizeMethod, newResult, Collections.emptyList()));
-              } else {
-                // The field is dead, so its count is always 0.
-                it.replaceCurrentInstruction(code.createConstNull(invokeMethod));
-              }
-            }
-          }
-        }
-      }
-    } while (wasRewritten);
-  }
-
-  private InstancePut findProtoFieldWrite(BasicBlock block, DexType instanceType,
-      BiPredicate<DexField, DexType> filter, DominatorTree dom) {
-    for (BasicBlock current : dom.dominatedBlocks(block)) {
-      InstructionIterator insns = current.iterator();
-      InstancePut instancePut = (InstancePut) insns.nextUntil(Instruction::isInstancePut);
-      if (instancePut != null && filter.test(instancePut.getField(), instanceType)) {
-        return instancePut;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * For the merge case, we typically see code that contains a switch over the field tags. The inner
-   * switch has the form
-   *
-   * <pre>
-   * switch (tag) {
-   *   case 0:
-   *     done = true;
-   *     break;
-   *   default: {
-   *     if (!parseUnknownField(tag, input)) {
-   *       done = true;
-   *     }
-   *     break;
-   *   }
-   *   case 8: {
-   *     bitField0_ |= 0x00000001;
-   *     id_ = input.readInt32();
-   *     break;
-   *   }
-   *   case 18: {
-   *     nestedproto2.GeneratedNestedProto.NestedOne.Builder subBuilder = null;
-   *     if (((bitField0_ & 0x00000002) == 0x00000002)) {
-   *       subBuilder = inner_.toBuilder();
-   *     }
-   *     inner_ = input.readMessage(nestedproto2.GeneratedNestedProto.NestedOne.parser(),
-   *         extensionRegistry);
-   *     if (subBuilder != null) {
-   *       subBuilder.mergeFrom(inner_);
-   *       inner_ = subBuilder.buildPartial();
-   *     }
-   *     bitField0_ |= 0x00000002;
-   *     break;
-   *   }
-   *   case 24: {
-   *     if (!other_.isModifiable()) {
-   *       other_ =
-   *           com.google.protobuf.GeneratedMessageLite.mutableCopy(other_);
-   *     }
-   *     other_.addBoolean(input.readBool());
-   *     break;
-   *   }
-   *   case 26: {
-   *     int length = input.readRawVarint32();
-   *     int limit = input.pushLimit(length);
-   *     if (!other_.isModifiable() && input.getBytesUntilLimit() > 0) {
-   *       final int currentSize = other_.size();
-   *       other_ = other_.mutableCopyWithCapacity(
-   *       currentSize + (length/1));
-   *     }
-   *     while (input.getBytesUntilLimit() > 0) {
-   *       other_.addBoolean(input.readBool());
-   *     }
-   *     input.popLimit(limit);
-   *     break;
-   *   }
-   * }
-   * </pre>
-   *
-   * The general approach here is to identify the field that is processed by a case and, if
-   * the field is dead, remove the entire case.
-   * <p>
-   * We slightly complicate the rewriting by also checking whether the block computes a
-   * presence bitfield (bitField0_ above). If so, we move that computation to a new block that
-   * continues to the default case. This ensures that presence is recorded correctly, yet the
-   * field is moved to the unknownFields collection, if such exists.
-   */
-  private void rewriteMergeCase(BasicBlock caseBlock, DexType instanceType,
-      IRCode code) {
-    // We are looking for a switch statement over the input tag. Just traverse all blocks until
-    // we find it.
-    List<BasicBlock> deadBlocks = new ArrayList<>();
-    DominatorTree dom = new DominatorTree(code);
-    for (BasicBlock current : dom.dominatedBlocks(caseBlock)) {
-      InstructionIterator it = current.iterator();
-      Switch switchInstr = (Switch) it.nextUntil(Instruction::isSwitch);
-      if (switchInstr != null) {
-        int nextBlock = code.getHighestBlockNumber() + 1;
-        IntList liveKeys = new IntArrayList(switchInstr.numberOfKeys());
-        List<BasicBlock> liveBlocks = new ArrayList<>(switchInstr.numberOfKeys());
-        boolean needsCleanup = false;
-        // Filter out all the cases that contain writes to dead fields.
-        for (int keyIdx = 0; keyIdx < switchInstr.numberOfKeys(); keyIdx++) {
-          BasicBlock targetBlock = switchInstr.targetBlock(keyIdx);
-          InstancePut instancePut =
-              findProtoFieldWrite(targetBlock, instanceType, (field, holder) -> isProtoField(field),
-                  dom);
-          if (instancePut == null
-              || appInfo.withLiveness().liveFields.contains(instancePut.getField())) {
-            // This is a live case. Keep it.
-            liveKeys.add(switchInstr.getKey(keyIdx));
-            liveBlocks.add(targetBlock);
-          } else {
-            // We cannot just remove this entire switch case if there is some computation here
-            // for whether the field is present. We check this by searching for a write to
-            // the bitField<xxx>_ fields. If such write exists, we move the corresponding
-            // instructions to the first block in the switch.
-            //TODO(herhut): Only do this if the written field has a live hasMethod.
-            InstancePut bitFieldUpdate = findProtoFieldWrite(targetBlock, instanceType,
-                this::isPresenceField, dom);
-            if (bitFieldUpdate != null) {
-              BasicBlock newBlock = BasicBlock.createGotoBlock(nextBlock++);
-              newBlock.link(switchInstr.fallthroughBlock());
-              // Copy over the computation of the field;
-              moveInstructionTo(newBlock.listIterator(), bitFieldUpdate, dom, targetBlock);
-              switchInstr.getBlock().link(newBlock);
-              liveKeys.add(switchInstr.getKey(keyIdx));
-              liveBlocks.add(newBlock);
-              code.blocks.add(newBlock);
-            }
-            needsCleanup = true;
-          }
-        }
-        if (needsCleanup) {
-          DominatorTree updatedTree = new DominatorTree(code);
-          BasicBlock fallThrough = switchInstr.fallthroughBlock();
-          List<BasicBlock> successors = ImmutableList.copyOf(current.getNormalSuccessors());
-          for (BasicBlock successor : successors) {
-            if (successor != fallThrough && !liveBlocks.contains(successor)) {
-              deadBlocks.addAll(current.unlink(successor, updatedTree));
-            }
-          }
-          int[] blockIndices = new int[liveBlocks.size()];
-          for (int i = 0; i < liveBlocks.size(); i++) {
-            blockIndices[i] = current.getSuccessors().indexOf(liveBlocks.get(i));
-          }
-          Switch newSwitch = new Switch(switchInstr.inValues().get(0), liveKeys.toIntArray(),
-              blockIndices, current.getSuccessors().indexOf(fallThrough));
-          it.replaceCurrentInstruction(newSwitch);
-        }
-        break;
-      }
-    }
-    code.removeBlocks(deadBlocks);
-  }
-
-  //TODO(herhut): This should really be a copy with a value substitution map.
-  private void moveInstructionTo(InstructionListIterator iterator, Instruction insn,
-      DominatorTree dom,
-      BasicBlock dominator) {
-    for (Value value : insn.inValues()) {
-      Instruction input = value.definition;
-      // We do not support phis.
-      assert input != null;
-      if (dom.dominatedBy(input.getBlock(), dominator)) {
-        // And no shared instructions.
-        assert input.outValue().numberOfUsers() == 1;
-        moveInstructionTo(iterator, input, dom, dominator);
-      }
-    }
-    insn.getBlock().removeInstruction(insn);
-    iterator.add(insn);
-  }
-
-  private boolean isDeadProtoField(DexField field) {
-    return isProtoField(field) && !appInfo.withLiveness().liveFields.contains(field);
-  }
-
-  private boolean isDeadProtoGetter(DexMethod method) {
-    return isGetter(method) && isDeadProtoField(getterToField(method));
-  }
-
-  private boolean isVisitOfDeadField(Instruction instruction) {
-    if (!instruction.isInvokeMethod()) {
-      return false;
-    }
-    InvokeMethod invokeMethod = instruction.asInvokeMethod();
-    if (invokeMethod.getInvokedMethod().getHolder() == visitorType
-        && invokeMethod.getInvokedMethod().getArity() >= 2) {
-      Instruction secondArg = invokeMethod.inValues().get(2).definition;
-      return secondArg.isConstNumber();
-    }
-    return false;
-  }
-
-  /**
-   * The visit case has typically the form
-   *
-   * <pre>
-   * case VISIT: {
-   *   Visitor visitor = (Visitor) arg0;
-   *   repeatedproto.GeneratedRepeatedProto.Repeated other =
-   *       (repeatedproto.GeneratedRepeatedProto.Repeated) arg1;
-   *   id_ = visitor.visitInt(
-   *       hasId(), id_,
-   *       other.hasId(), other.id_);
-   *   repeated_= visitor.visitList(repeated_, other.repeated_);
-   *   inner_ = visitor.visitMessage(inner_, other.inner_);
-   *   if (visitor == com.google.protobuf.GeneratedMessageLite.MergeFromVisitor.INSTANCE) {
-   *     bitField0_ |= other.bitField0_;
-   *   }
-   *   return this;
-   * }
-   * </pre>
-   *
-   * We remove all writes and reads to dead fields and correspondign secondary instructions, like
-   * the visitXXX methods.
-   * <p>
-   * Note that the invoked hasMethods are benign, as the only access the bitFieldXXX_ fields, which
-   * we currently do not remove. Inlining will likely remove the methods.
-   */
-  private void rewriteVisitCase(BasicBlock switchCase, IRCode code) {
-    DominatorTree dom = new DominatorTree(code);
-    boolean wasRewritten;
-    do {
-      wasRewritten = false;
-      for (BasicBlock target : dom.dominatedBlocks(switchCase)) {
-        InstructionIterator it = target.iterator();
-        while (it.hasNext()) {
-          Instruction insn = it.next();
-          if (insn.isInstanceGet()) {
-            InstanceGet instanceGet = insn.asInstanceGet();
-            if (isDeadProtoField(instanceGet.getField())) {
-              it.replaceCurrentInstruction(code.createConstNull(instanceGet));
-              wasRewritten = true;
-            }
-          } else if (insn.isInstancePut()) {
-            if (isDeadProtoField(insn.asInstancePut().getField())) {
-              it.remove();
-            }
-          } else if (isVisitOfDeadField(insn)) {
-            it.replaceCurrentInstruction(code.createConstNull(insn));
-          } else if (insn.isCheckCast()) {
-            // The call to visitXXX is a generic method invoke, so it will be followed by a check
-            // cast to fix up the type. As the result is no longer needed once we are done, we can
-            // remove the cast. This removes a potential last reference to an inner message class.
-            // TODO(herhut): We should have a generic dead cast removal.
-            Value inValue = insn.inValues().get(0);
-            if (isDefinedAsNull(inValue)) {
-              insn.outValue().replaceUsers(inValue);
-              it.remove();
-            }
-          }
-
-        }
-      }
-    } while (wasRewritten);
-  }
-}
diff --git a/src/test/examples/enumproto/Enumproto.java b/src/test/examples/enumproto/Enumproto.java
deleted file mode 100644
index 9176378..0000000
--- a/src/test/examples/enumproto/Enumproto.java
+++ /dev/null
@@ -1,66 +0,0 @@
-// 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 enumproto;
-
-
-import enumproto.GeneratedEnumProto.Enum;
-import enumproto.three.GeneratedEnumProto.EnumThree;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-
-public class Enumproto {
-
-  private static final byte[] WITH_ALL_FIELDS = new byte[]{6, 8, 42, 16, 2, 24, 3};
-  private static final byte[] WITH_DEFAULT_FOR_ENUM = new byte[]{2, 8, 42};
-
-
-  public static void main(String... args) throws IOException {
-    readProtoAndPrintDaEnum(WITH_ALL_FIELDS);
-    readProtoAndPrintDaEnum(WITH_DEFAULT_FOR_ENUM);
-    readProtoThreeAndPrintDaEnum(WITH_ALL_FIELDS);
-    readProtoThreeAndPrintDaEnum(WITH_DEFAULT_FOR_ENUM);
-    roundTrip(WITH_ALL_FIELDS);
-    roundTrip(WITH_DEFAULT_FOR_ENUM);
-    roundTripThree(WITH_ALL_FIELDS);
-    roundTripThree(WITH_DEFAULT_FOR_ENUM);
-  }
-
-  private static void readProtoAndPrintDaEnum(byte[] bytes) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(bytes);
-    Enum.Builder builder = Enum.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Enum buffer = builder.build();
-    System.out.println(buffer.getEnum());
-  }
-
-  private static void readProtoThreeAndPrintDaEnum(byte[] bytes) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(bytes);
-    EnumThree.Builder builder = EnumThree.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    EnumThree buffer = builder.build();
-    System.out.println(buffer.getEnum());
-  }
-
-  private static void roundTrip(byte[] bytes) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(bytes);
-    Enum.Builder builder = Enum.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Enum buffer = builder.build();
-    ByteArrayOutputStream output = new ByteArrayOutputStream();
-    buffer.writeDelimitedTo(output);
-    readProtoAndPrintDaEnum(output.toByteArray());
-  }
-
-  private static void roundTripThree(byte[] bytes) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(bytes);
-    EnumThree.Builder builder = EnumThree.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    EnumThree buffer = builder.build();
-    ByteArrayOutputStream output = new ByteArrayOutputStream();
-    buffer.writeDelimitedTo(output);
-    readProtoThreeAndPrintDaEnum(output.toByteArray());
-  }
-
-}
diff --git a/src/test/examples/enumproto/enum.proto b/src/test/examples/enumproto/enum.proto
deleted file mode 100644
index 0fa5695..0000000
--- a/src/test/examples/enumproto/enum.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-// 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.
-syntax = "proto2";
-package enumproto;
-
-option java_outer_classname = "GeneratedEnumProto";
-
-message Enum {
-  required int32 id = 1;
-  enum DaEnum {
-    UNKOWN = 0;
-    KNOWN = 1;
-    BELIEF = 2;
-  }
-  optional DaEnum enum = 2;
-  enum OtherEnum {
-    BLACK = 0;
-    RED = 1;
-    GREEN = 2;
-    OKALALALA = 3;
-  }
-  optional OtherEnum other = 3;
-}
-
diff --git a/src/test/examples/enumproto/enum_three.proto b/src/test/examples/enumproto/enum_three.proto
deleted file mode 100644
index a2731fb..0000000
--- a/src/test/examples/enumproto/enum_three.proto
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto3";
-package enumproto.three;
-
-option java_outer_classname = "GeneratedEnumProto";
-
-message EnumThree {
-  int32 id = 1;
-  enum DaEnum {
-    UNKOWN = 0;
-    KNOWN = 1;
-    BELIEF = 2;
-  }
-  DaEnum enum = 2;
-  enum OtherEnum {
-    BLACK = 0;
-    RED = 1;
-    GREEN = 2;
-    OKALALALA = 3;
-  }
-  OtherEnum other = 3;
-}
-
diff --git a/src/test/examples/enumproto/keep-rules.txt b/src/test/examples/enumproto/keep-rules.txt
deleted file mode 100644
index 088f88f..0000000
--- a/src/test/examples/enumproto/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class enumproto.Enumproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/nestedproto1/Nestedproto.java b/src/test/examples/nestedproto1/Nestedproto.java
deleted file mode 100644
index fe1a535..0000000
--- a/src/test/examples/nestedproto1/Nestedproto.java
+++ /dev/null
@@ -1,31 +0,0 @@
-// 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 nestedproto1;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import nestedproto1.GeneratedNestedProto.Outer;
-
-public class Nestedproto {
-
-  private static final byte[] NESTED_MESSAGE_WITH_BOTH = new byte[] {25, 8, 42, 18, 12, 8, 1, 18, 8,
-      105, 110, 110, 101, 114, 79, 110, 101, 26, 7, 8, 2, 21, 0, 0, -10, 66};
-
-  private static final byte[] NESTED_MESSAGE_WITH_ONE = new byte[]{16, 8, 42, 18, 12, 8, 1, 18, 8,
-      105,
-      110, 110, 101, 114, 79, 110, 101};
-
-  public static void main(String... args) throws IOException {
-    testWith(NESTED_MESSAGE_WITH_BOTH);
-    testWith(NESTED_MESSAGE_WITH_ONE);
-  }
-
-  public static void testWith(byte[] data) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(data);
-    Outer.Builder builder = Outer.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Outer outer = builder.build();
-    System.out.println(outer.getInner().getOther());
-  }
-}
diff --git a/src/test/examples/nestedproto1/keep-rules.txt b/src/test/examples/nestedproto1/keep-rules.txt
deleted file mode 100644
index 1c47672..0000000
--- a/src/test/examples/nestedproto1/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class nestedproto1.Nestedproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/nestedproto1/nested.proto b/src/test/examples/nestedproto1/nested.proto
deleted file mode 100644
index 0d05749..0000000
--- a/src/test/examples/nestedproto1/nested.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package nestedproto1;
-
-option java_outer_classname = "GeneratedNestedProto";
-
-message NestedOne {
-  required int32 id = 1;
-  optional string other = 2;
-}
-
-message NestedTwo {
-  required int32 id = 1;
-  optional float other = 2;
-}
-
-message Outer {
-  required int32 id = 1;
-  required NestedOne inner = 2;
-  optional NestedTwo inner2 = 3;
-}
-
diff --git a/src/test/examples/nestedproto2/Nestedproto.java b/src/test/examples/nestedproto2/Nestedproto.java
deleted file mode 100644
index 59217de..0000000
--- a/src/test/examples/nestedproto2/Nestedproto.java
+++ /dev/null
@@ -1,33 +0,0 @@
-// 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 nestedproto2;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import nestedproto2.GeneratedNestedProto.Outer;
-
-public class Nestedproto {
-
-  private static final byte[] NESTED_MESSAGE_WITH_BOTH = new byte[]{25, 8, 42, 18, 12, 8, 1, 18, 8,
-      105, 110, 110, 101, 114, 79, 110, 101, 26, 7, 8, 2, 21, 0, 0, -10, 66};
-
-  private static final byte[] NESTED_MESSAGE_WITH_ONE = new byte[]{16, 8, 42, 18, 12, 8, 1, 18, 8,
-      105,
-      110, 110, 101, 114, 79, 110, 101};
-
-  // Test that all fields remain when roundtripping with removed fields.
-  public static void main(String... args) throws IOException {
-    testWith(NESTED_MESSAGE_WITH_BOTH);
-    testWith(NESTED_MESSAGE_WITH_ONE);
-  }
-
-  private static void testWith(byte[] data) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(data);
-    Outer.Builder builder = Outer.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    builder.setId(1982);
-    Outer outer = builder.build();
-    outer.writeTo(System.out);
-  }
-}
diff --git a/src/test/examples/nestedproto2/keep-rules.txt b/src/test/examples/nestedproto2/keep-rules.txt
deleted file mode 100644
index 87c9218..0000000
--- a/src/test/examples/nestedproto2/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class nestedproto2.Nestedproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/nestedproto2/nested.proto b/src/test/examples/nestedproto2/nested.proto
deleted file mode 100644
index ac56f40..0000000
--- a/src/test/examples/nestedproto2/nested.proto
+++ /dev/null
@@ -1,24 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package nestedproto2;
-
-option java_outer_classname = "GeneratedNestedProto";
-
-message NestedOne {
-  required int32 id = 1;
-  optional string other = 2;
-}
-
-message NestedTwo {
-  required int32 id = 1;
-  optional float other = 2;
-}
-
-message Outer {
-  required int32 id = 1;
-  required NestedOne inner = 2;
-  optional NestedTwo inner2 = 3;
-}
-
diff --git a/src/test/examples/oneofproto/Oneofproto.java b/src/test/examples/oneofproto/Oneofproto.java
deleted file mode 100644
index 261705f..0000000
--- a/src/test/examples/oneofproto/Oneofproto.java
+++ /dev/null
@@ -1,38 +0,0 @@
-// 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 oneofproto;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import oneofproto.GeneratedOneOfProto.Oneof;
-
-public class Oneofproto {
-
-  private static final byte[] WITH_BOOL_FIELD = new byte[]{4, 8, 42, 24, 1};
-  private static final byte[] WITH_FLOAT_FIELD = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
-  private static final byte[] WITH_STRING_FIELD = new byte[]{9, 8, 42, 34, 5, 104, 101, 108, 108,
-      111};
-  private static final byte[] WITH_NO_FIELD = new byte[]{2, 8, 42};
-
-
-  public static void main(String... args) throws IOException {
-    roundTrip(WITH_BOOL_FIELD);
-    roundTrip(WITH_FLOAT_FIELD);
-    roundTrip(WITH_STRING_FIELD);
-    roundTrip(WITH_NO_FIELD);
-  }
-
-  private static void roundTrip(byte[] data) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(data);
-    Oneof.Builder builder = Oneof.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Oneof oneof = builder.build();
-    ByteArrayOutputStream output = new ByteArrayOutputStream();
-    oneof.writeDelimitedTo(output);
-    System.out.println(Arrays.toString(output.toByteArray()));
-  }
-
-}
diff --git a/src/test/examples/oneofproto/keep-rules.txt b/src/test/examples/oneofproto/keep-rules.txt
deleted file mode 100644
index 70f00f1..0000000
--- a/src/test/examples/oneofproto/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class oneofproto.Oneofproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/oneofproto/oneof.proto b/src/test/examples/oneofproto/oneof.proto
deleted file mode 100644
index c5a67a1..0000000
--- a/src/test/examples/oneofproto/oneof.proto
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package oneofproto;
-
-option java_outer_classname = "GeneratedOneOfProto";
-
-message Oneof {
-  required int32 id = 1;
-  oneof otherfields {
-    float floatField = 2;
-    bool boolField = 3;
-    string stringField = 4;
-  }
-}
-
diff --git a/src/test/examples/protowithexts/withexts.proto b/src/test/examples/protowithexts/withexts.proto
deleted file mode 100644
index d384173..0000000
--- a/src/test/examples/protowithexts/withexts.proto
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package protowithexts;
-
-option java_outer_classname = "GeneratedProtoWithExts";
-
-message Simple {
-  required int32 id = 1;
-
-  optional int32 other = 2;
-
-  extensions 10 to 19;
-}
-
-extend Simple {
-  optional string extra = 10;
-}
diff --git a/src/test/examples/repeatedproto/Repeatedproto.java b/src/test/examples/repeatedproto/Repeatedproto.java
deleted file mode 100644
index 280070d..0000000
--- a/src/test/examples/repeatedproto/Repeatedproto.java
+++ /dev/null
@@ -1,22 +0,0 @@
-// 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 repeatedproto;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import repeatedproto.GeneratedRepeatedProto.Repeated;
-
-public class Repeatedproto {
-
-  private static final byte[] WITH_ALL_FIELDS = new byte[]{29, 8, 123, 18, 3, 111, 110, 101, 18, 3,
-      116, 119, 111, 18, 5, 116, 104, 114, 101, 101, 24, 1, 34, 2, 8, 42, 34, 2, 8, 42};
-
-  public static void main(String... args) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(WITH_ALL_FIELDS);
-    Repeated.Builder builder = Repeated.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Repeated repeated = builder.build();
-    System.out.println(repeated.getRepeatedList());
-  }
-}
diff --git a/src/test/examples/repeatedproto/keep-rules.txt b/src/test/examples/repeatedproto/keep-rules.txt
deleted file mode 100644
index 3d02352..0000000
--- a/src/test/examples/repeatedproto/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class repeatedproto.Repeatedproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/repeatedproto/repeated.proto b/src/test/examples/repeatedproto/repeated.proto
deleted file mode 100644
index 7414e6f..0000000
--- a/src/test/examples/repeatedproto/repeated.proto
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package repeatedproto;
-
-option java_outer_classname = "GeneratedRepeatedProto";
-
-message Repeated {
-  required int32 id = 1;
-  repeated string repeated = 2;
-  repeated bool other = 3;
-
-  message Sub {
-    required int32 value = 1;
-  }
-
-  repeated Sub sub = 4;
-}
-
diff --git a/src/test/examples/repeatedproto/repeated_three.proto b/src/test/examples/repeatedproto/repeated_three.proto
deleted file mode 100644
index 7da7881..0000000
--- a/src/test/examples/repeatedproto/repeated_three.proto
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto3";
-package repeatedproto.three;
-
-option java_outer_classname = "GeneratedRepeatedProto";
-
-
-message RepeatedThree {
-  int32 id = 1;
-  repeated string repeated = 2;
-  repeated bool other = 3;
-}
-
diff --git a/src/test/examples/simpleproto1/Simpleproto.java b/src/test/examples/simpleproto1/Simpleproto.java
deleted file mode 100644
index d07ce8d..0000000
--- a/src/test/examples/simpleproto1/Simpleproto.java
+++ /dev/null
@@ -1,56 +0,0 @@
-// 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 simpleproto1;
-
-import com.google.protobuf.UninitializedMessageException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import simpleproto1.GeneratedSimpleProto.Simple;
-
-public class Simpleproto {
-
-  private static final byte[] WITH_REQUIRED_FIELDS = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
-  private static final byte[] WITH_MISSING_FIELD = new byte[]{2, 8, 42};
-
-
-  public static void main(String... args) throws IOException {
-    readProtoWithAllReqFields();
-    partialBuildFails();
-    partialReadFails();
-  }
-
-  private static void partialBuildFails() {
-    Simple.Builder builder = Simple.newBuilder();
-    builder.setId(32);
-    try {
-      builder.build();
-    } catch (UninitializedMessageException e) {
-      System.out.println("got exception");
-    }
-  }
-
-  private static void partialReadFails() throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(WITH_MISSING_FIELD);
-    Simple.Builder builder = Simple.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    try {
-      builder.build();
-    } catch (UninitializedMessageException e) {
-      System.out.println("got exception");
-    }
-  }
-
-  private static void readProtoWithAllReqFields() throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(WITH_REQUIRED_FIELDS);
-    Simple.Builder builder = Simple.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Simple simple = builder.build();
-    ByteArrayOutputStream output = new ByteArrayOutputStream(WITH_REQUIRED_FIELDS.length);
-    simple.writeDelimitedTo(output);
-    System.out.println(Arrays.toString(output.toByteArray()));
-    System.out.println(Arrays.equals(WITH_REQUIRED_FIELDS, output.toByteArray()));
-  }
-}
diff --git a/src/test/examples/simpleproto1/keep-rules.txt b/src/test/examples/simpleproto1/keep-rules.txt
deleted file mode 100644
index 3c3c33f..0000000
--- a/src/test/examples/simpleproto1/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class simpleproto1.Simpleproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/simpleproto1/simple.proto b/src/test/examples/simpleproto1/simple.proto
deleted file mode 100644
index f4e1be4..0000000
--- a/src/test/examples/simpleproto1/simple.proto
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package simpleproto1;
-
-option java_outer_classname = "GeneratedSimpleProto";
-
-message Simple {
-  required int32 id = 1;
-  required float unusedRequired = 2;
-  optional bool other = 3;
-}
-
diff --git a/src/test/examples/simpleproto2/Simpleproto.java b/src/test/examples/simpleproto2/Simpleproto.java
deleted file mode 100644
index f333d72..0000000
--- a/src/test/examples/simpleproto2/Simpleproto.java
+++ /dev/null
@@ -1,30 +0,0 @@
-// 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 simpleproto2;
-
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import simpleproto2.GeneratedSimpleProto.Simple;
-
-/**
- * A class that only uses a has method but otherwise ignores the value of a field.
- */
-public class Simpleproto {
-
-  private static final byte[] WITHOUT_HASME_FIELD = new byte[]{2, 8, 42};
-  private static final byte[] WITH_HASME_FIELD = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
-
-  public static void main(String... args) throws IOException {
-    testHasWorks(WITHOUT_HASME_FIELD, false);
-    testHasWorks(WITH_HASME_FIELD, true);
-  }
-
-  private static void testHasWorks(byte[] msg, boolean expected) throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(msg);
-    Simple.Builder builder = Simple.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Simple simple = builder.build();
-    System.out.println("Expected " + expected + " and got " + simple.hasHasMe());
-  }
-}
diff --git a/src/test/examples/simpleproto2/keep-rules.txt b/src/test/examples/simpleproto2/keep-rules.txt
deleted file mode 100644
index 8f9c93e..0000000
--- a/src/test/examples/simpleproto2/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class simpleproto2.Simpleproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/simpleproto2/simple.proto b/src/test/examples/simpleproto2/simple.proto
deleted file mode 100644
index b9173e9..0000000
--- a/src/test/examples/simpleproto2/simple.proto
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto2";
-package simpleproto2;
-
-option java_outer_classname = "GeneratedSimpleProto";
-
-message Simple {
-  required int32 id = 1;
-  optional float hasMe = 2;
-  optional int32 other = 3;
-}
-
diff --git a/src/test/examples/simpleproto3/Simpleproto.java b/src/test/examples/simpleproto3/Simpleproto.java
deleted file mode 100644
index 2cdbae8..0000000
--- a/src/test/examples/simpleproto3/Simpleproto.java
+++ /dev/null
@@ -1,65 +0,0 @@
-// 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 simpleproto3;
-
-import com.google.protobuf.UninitializedMessageException;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import simpleproto3.GeneratedSimpleProto.Simple;
-
-public class Simpleproto {
-
-  private static final byte[] WITH_REQUIRED_FIELDS = new byte[]{7, 8, 42, 21, 0, 0, -10, 66};
-  private static final byte[] WITH_MISSING_FIELD = new byte[]{2, 8, 42};
-
-
-  public static void main(String... args) throws IOException {
-    readProtoWithAllReqFields();
-    partialBuildFails();
-    partialReadFails();
-  }
-
-  private static void partialBuildFails() {
-    Simple.Builder builder = Simple.newBuilder();
-    builder.setId(32);
-    try {
-      builder.build();
-    } catch (UninitializedMessageException e) {
-      System.out.println("got exception");
-    }
-  }
-
-  private static void partialReadFails() throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(WITH_MISSING_FIELD);
-    Simple.Builder builder = Simple.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    try {
-      builder.build();
-    } catch (UninitializedMessageException e) {
-      System.out.println("got exception");
-    }
-  }
-
-  private static void readProtoWithAllReqFields() throws IOException {
-    ByteArrayInputStream input = new ByteArrayInputStream(WITH_REQUIRED_FIELDS);
-    Simple.Builder builder = Simple.newBuilder();
-    builder.mergeDelimitedFrom(input);
-    Simple simple = builder.build();
-    ByteArrayOutputStream output = new ByteArrayOutputStream(WITH_REQUIRED_FIELDS.length);
-    simple.writeDelimitedTo(output);
-    System.out.println(isContained(WITH_REQUIRED_FIELDS, output.toByteArray()));
-  }
-
-  // After shaking, the serialized proto will no longer contain fields that are not referenced.
-  private static boolean isContained(byte[] fullBytes, byte[] reducedBytes) {
-    int j = 1;
-    for (int i = 1; i < fullBytes.length && j < reducedBytes.length; i++) {
-      if (fullBytes[i] == reducedBytes[j]) {
-        j++;
-      }
-    }
-    return j == reducedBytes.length;
-  }
-}
diff --git a/src/test/examples/simpleproto3/keep-rules.txt b/src/test/examples/simpleproto3/keep-rules.txt
deleted file mode 100644
index 186e9f8..0000000
--- a/src/test/examples/simpleproto3/keep-rules.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-# 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.
-
-# Keep the application entry point. Get rid of everything that is not
-# reachable from there.
--keep public class simpleproto3.Simpleproto {
-  public static void main(...);
-}
-
-# allow access modification to enable minification
--allowaccessmodification
diff --git a/src/test/examples/simpleproto3/simple.proto b/src/test/examples/simpleproto3/simple.proto
deleted file mode 100644
index 87512d1..0000000
--- a/src/test/examples/simpleproto3/simple.proto
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) 2016, 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.
-syntax = "proto3";
-package simpleproto3;
-
-option java_outer_classname = "GeneratedSimpleProto";
-
-message Simple {
-  int32 id = 1;
-  float unusedRequired = 2;
-  bool other = 3;
-}
-
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingEnumprotoTest.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingEnumprotoTest.java
deleted file mode 100644
index 7f211db..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingEnumprotoTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingEnumprotoTest extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingEnumprotoTest(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/enumproto", "enumproto.Enumproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingEnumprotoTest::enumprotoUnusedFieldsAreGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/enumproto/keep-rules.txt"));
-  }
-
-  private static void enumprotoUnusedFieldsAreGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("enumproto.GeneratedEnumProto$Enum");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertFalse(protoClass.field("int", "id_").isPresent());
-    Assert.assertTrue(protoClass.field("int", "enum_").isPresent());
-    Assert.assertFalse(protoClass.field("int", "other_").isPresent());
-    ClassSubject protoThreeClass = inspector.clazz("enumproto.three.GeneratedEnumProto$EnumThree");
-    Assert.assertTrue(protoThreeClass.isPresent());
-    Assert.assertFalse(protoThreeClass.field("int", "id_").isPresent());
-    Assert.assertTrue(protoThreeClass.field("int", "enum_").isPresent());
-    Assert.assertFalse(protoThreeClass.field("int", "other_").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingNestedproto1Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingNestedproto1Test.java
deleted file mode 100644
index 16b5f59..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingNestedproto1Test.java
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingNestedproto1Test extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingNestedproto1Test(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/nestedproto1", "nestedproto1.Nestedproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingNestedproto1Test::nestedproto1UnusedFieldsAreGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/nestedproto1/keep-rules.txt"));
-  }
-
-  private static void nestedproto1UnusedFieldsAreGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("nestedproto1.GeneratedNestedProto$Outer");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertFalse(protoClass.field("int", "id_").isPresent());
-    Assert.assertTrue(
-        protoClass.field("nestedproto1.GeneratedNestedProto$NestedOne", "inner_").isPresent());
-    Assert.assertFalse(
-        protoClass.field("nestedproto1.GeneratedNestedProto$NestedTwo", "inner2_").isPresent());
-    ClassSubject nestedOne = inspector.clazz("nestedproto1.GeneratedNestedProto$NestedOne");
-    Assert.assertTrue(nestedOne.isPresent());
-    Assert.assertTrue(nestedOne.field("java.lang.String", "other_").isPresent());
-    Assert.assertFalse(nestedOne.field("int", "id_").isPresent());
-    Assert.assertFalse(inspector.clazz("nestedproto1.GeneratedNestedProto$NestedTwo").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingNestedproto2Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingNestedproto2Test.java
deleted file mode 100644
index a679810..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingNestedproto2Test.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingNestedproto2Test extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingNestedproto2Test(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/nestedproto2", "nestedproto2.Nestedproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingNestedproto2Test::nestedproto2UnusedFieldsAreGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/nestedproto2/keep-rules.txt"));
-  }
-
-  private static void nestedproto2UnusedFieldsAreGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("nestedproto2.GeneratedNestedProto$Outer");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertTrue(protoClass.field("int", "id_").isPresent());
-    Assert.assertFalse(
-        protoClass.field("nestedproto2.GeneratedNestedProto$NestedOne", "inner_").isPresent());
-    Assert.assertFalse(
-        protoClass.field("nestedproto2.GeneratedNestedProto$NestedTwo", "inner2_").isPresent());
-    Assert.assertFalse(inspector.clazz("nestedproto2.GeneratedNestedProto$NestedOne").isPresent());
-    Assert.assertFalse(inspector.clazz("nestedproto2.GeneratedNestedProto$NestedTwo").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingOneofprotoTest.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingOneofprotoTest.java
deleted file mode 100644
index e38258c..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingOneofprotoTest.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingOneofprotoTest extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingOneofprotoTest(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/oneofproto", "oneofproto.Oneofproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingOneofprotoTest::oneofprotoUnusedFieldsAreGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/oneofproto/keep-rules.txt"));
-  }
-
-  private static void oneofprotoUnusedFieldsAreGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("oneofproto.GeneratedOneOfProto$Oneof");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertFalse(protoClass.field("int", "id_").isPresent());
-    Assert.assertFalse(protoClass.field("Object", "otherfields_").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingRepeatedprotoTest.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingRepeatedprotoTest.java
deleted file mode 100644
index 923cf34..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingRepeatedprotoTest.java
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingRepeatedprotoTest extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingRepeatedprotoTest(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/repeatedproto", "repeatedproto.Repeatedproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingRepeatedprotoTest::repeatedUnusedFieldsAreGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/repeatedproto/keep-rules.txt"));
-  }
-
-  private static void repeatedUnusedFieldsAreGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("repeatedproto.GeneratedRepeatedProto$Repeated");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertFalse(protoClass.field("int", "id_").isPresent());
-    Assert.assertTrue(
-        protoClass.field("com.google.protobuf.Internal$ProtobufList", "repeated_").isPresent());
-    Assert.assertFalse(
-        protoClass.field("com.google.protobuf.Internal$ProtobufList", "sub_").isPresent());
-    Assert.assertFalse(
-        protoClass.field("com.google.protobuf.Internal$BooleanList", "other_").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto1Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto1Test.java
deleted file mode 100644
index 64e3839..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto1Test.java
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingSimpleproto1Test extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingSimpleproto1Test(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/simpleproto1", "simpleproto1.Simpleproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingSimpleproto1Test::simpleproto1UnusedFieldIsGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/simpleproto1/keep-rules.txt"));
-  }
-
-  private static void simpleproto1UnusedFieldIsGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("simpleproto1.GeneratedSimpleProto$Simple");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertFalse(protoClass.field("boolean", "other_").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto2Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto2Test.java
deleted file mode 100644
index 5304dae..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto2Test.java
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.android.tools.r8.utils.codeinspector.ClassSubject;
-import com.android.tools.r8.utils.codeinspector.CodeInspector;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingSimpleproto2Test extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingSimpleproto2Test(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/simpleproto2", "simpleproto2.Simpleproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(
-        TreeShakingSimpleproto2Test::simpleproto2UnusedFieldsAreGone,
-        null,
-        null,
-        ImmutableList.of("src/test/examples/simpleproto2/keep-rules.txt"));
-  }
-
-  private static void simpleproto2UnusedFieldsAreGone(CodeInspector inspector) {
-    ClassSubject protoClass = inspector.clazz("simpleproto2.GeneratedSimpleProto$Simple");
-    Assert.assertTrue(protoClass.isPresent());
-    Assert.assertFalse(protoClass.field("int", "id_").isPresent());
-    Assert.assertFalse(protoClass.field("float", "hasMe_").isPresent());
-    Assert.assertFalse(protoClass.field("int", "other_").isPresent());
-  }
-}
diff --git a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto3Test.java b/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto3Test.java
deleted file mode 100644
index 896517a..0000000
--- a/src/test/java/com/android/tools/r8/shaking/examples/TreeShakingSimpleproto3Test.java
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright (c) 2018, 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.shaking.examples;
-
-import com.android.tools.r8.TestBase.MinifyMode;
-import com.android.tools.r8.shaking.TreeShakingTest;
-import com.google.common.collect.ImmutableList;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-
-@RunWith(Parameterized.class)
-public class TreeShakingSimpleproto3Test extends TreeShakingTest {
-
-  @Parameters(name = "mode:{0}-{1} minify:{2}")
-  public static Collection<Object[]> data() {
-    List<Object[]> parameters = new ArrayList<>();
-    for (MinifyMode minify : MinifyMode.values()) {
-      parameters.add(new Object[] {Frontend.JAR, Backend.CF, minify});
-      parameters.add(new Object[] {Frontend.JAR, Backend.DEX, minify});
-      parameters.add(new Object[] {Frontend.DEX, Backend.DEX, minify});
-    }
-    return parameters;
-  }
-
-  public TreeShakingSimpleproto3Test(Frontend frontend, Backend backend, MinifyMode minify) {
-    super("examples/simpleproto3", "simpleproto3.Simpleproto", frontend, backend, minify);
-  }
-
-  @Test
-  public void test() throws Exception {
-    runTest(null, null, null, ImmutableList.of("src/test/examples/simpleproto3/keep-rules.txt"));
-  }
-}
