diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index fd5c29f..50f79dc 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -17,6 +17,8 @@
 import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.graph.GraphLense;
 import com.android.tools.r8.ir.conversion.IRConverter;
+import com.android.tools.r8.ir.optimize.EnumOrdinalMapCollector;
+import com.android.tools.r8.ir.optimize.SwitchMapCollector;
 import com.android.tools.r8.naming.Minifier;
 import com.android.tools.r8.naming.NamingLens;
 import com.android.tools.r8.optimize.BridgeMethodAnalysis;
@@ -36,6 +38,7 @@
 import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
 import com.android.tools.r8.shaking.SimpleClassMerger;
 import com.android.tools.r8.shaking.TreePruner;
+import com.android.tools.r8.shaking.protolite.ProtoLiteExtension;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.CfgPrinter;
 import com.android.tools.r8.utils.FileUtils;
@@ -241,6 +244,7 @@
         }
         rootSet = new RootSetBuilder(application, appInfo, options.keepRules).run(executorService);
         Enqueuer enqueuer = new Enqueuer(appInfo);
+        enqueuer.addExtension(new ProtoLiteExtension(appInfo));
         appInfo = enqueuer.traceApplication(rootSet, timing);
         if (options.printSeeds) {
           ByteArrayOutputStream bytes = new ByteArrayOutputStream();
@@ -270,8 +274,7 @@
 
       GraphLense graphLense = GraphLense.getIdentityLense();
 
-      if (appInfo.withLiveness() != null) {
-        // No-op until class merger is added.
+      if (appInfo.hasLiveness()) {
         graphLense = new MemberRebindingAnalysis(appInfo.withLiveness(), graphLense).run();
         // Class merging requires inlining.
         if (!options.skipClassMerging && options.inlineAccessors) {
@@ -282,6 +285,9 @@
         }
         appInfo = appInfo.withLiveness().prunedCopyFrom(application);
         appInfo = appInfo.withLiveness().rewrittenWithLense(graphLense);
+        // Collect switch maps and ordinals maps.
+        new SwitchMapCollector(appInfo.withLiveness(), options).run();
+        new EnumOrdinalMapCollector(appInfo.withLiveness(), options).run();
       }
 
       graphLense = new BridgeMethodAnalysis(graphLense, appInfo.withSubtyping()).run();
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 1f45dec..8d3d937 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -87,6 +87,7 @@
       minimalMainDex = value;
       return self();
     }
+
     /**
      * Add proguard configuration file resources.
      */
diff --git a/src/main/java/com/android/tools/r8/graph/DelegatingUseRegistry.java b/src/main/java/com/android/tools/r8/graph/DelegatingUseRegistry.java
new file mode 100644
index 0000000..0e28d3d
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/graph/DelegatingUseRegistry.java
@@ -0,0 +1,68 @@
+// 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.graph;
+
+public class DelegatingUseRegistry extends UseRegistry {
+    private final UseRegistry delegate;
+
+    public DelegatingUseRegistry(UseRegistry delegate) {
+      this.delegate = delegate;
+    }
+
+    @Override
+    public boolean registerInvokeVirtual(DexMethod method) {
+      return delegate.registerInvokeVirtual(method);
+    }
+
+    @Override
+    public boolean registerInvokeDirect(DexMethod method) {
+      return delegate.registerInvokeDirect(method);
+    }
+
+    @Override
+    public boolean registerInvokeStatic(DexMethod method) {
+      return delegate.registerInvokeStatic(method);
+    }
+
+    @Override
+    public boolean registerInvokeInterface(DexMethod method) {
+      return delegate.registerInvokeInterface(method);
+    }
+
+    @Override
+    public boolean registerInvokeSuper(DexMethod method) {
+      return delegate.registerInvokeSuper(method);
+    }
+
+    @Override
+    public boolean registerInstanceFieldWrite(DexField field) {
+      return delegate.registerInstanceFieldWrite(field);
+    }
+
+    @Override
+    public boolean registerInstanceFieldRead(DexField field) {
+      return delegate.registerInstanceFieldRead(field);
+    }
+
+    @Override
+    public boolean registerNewInstance(DexType type) {
+      return delegate.registerNewInstance(type);
+    }
+
+    @Override
+    public boolean registerStaticFieldRead(DexField field) {
+      return delegate.registerStaticFieldRead(field);
+    }
+
+    @Override
+    public boolean registerStaticFieldWrite(DexField field) {
+      return delegate.registerStaticFieldWrite(field);
+    }
+
+    @Override
+    public boolean registerTypeReference(DexType type) {
+      return delegate.registerTypeReference(type);
+    }
+
+}
diff --git a/src/main/java/com/android/tools/r8/graph/DexString.java b/src/main/java/com/android/tools/r8/graph/DexString.java
index 25416d9..e6914ec 100644
--- a/src/main/java/com/android/tools/r8/graph/DexString.java
+++ b/src/main/java/com/android/tools/r8/graph/DexString.java
@@ -321,4 +321,28 @@
     builder.append("]");
     return builder.toString();
   }
+
+  public boolean beginsWith(DexString prefix) {
+    if (content.length < prefix.content.length) {
+      return false;
+    }
+    for (int i = 0; i < prefix.content.length - 1; i++) {
+      if (content[i] != prefix.content[i]) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public boolean endsWith(DexString suffix) {
+    if (content.length < suffix.content.length) {
+      return false;
+    }
+    for (int i = content.length - suffix.content.length, j = 0; i < content.length; i++, j++) {
+      if (content[i] != suffix.content[j]) {
+        return false;
+      }
+    }
+    return true;
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/graph/DexType.java b/src/main/java/com/android/tools/r8/graph/DexType.java
index ac7d9ee..e06c0ad 100644
--- a/src/main/java/com/android/tools/r8/graph/DexType.java
+++ b/src/main/java/com/android/tools/r8/graph/DexType.java
@@ -139,6 +139,11 @@
 
   private boolean isSubtypeOfClass(DexType other, AppInfo appInfo) {
     DexType self = this;
+    if (other.hierarchyLevel == UNKNOWN_LEVEL) {
+      // We have no definition for this class, hence it is not part of the
+      // hierarchy.
+      return false;
+    }
     while (other.hierarchyLevel < self.hierarchyLevel) {
       DexClass holder = appInfo.definitionFor(self);
       assert holder != null && !holder.isInterface();
diff --git a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
index 5c9d171..5f1b33f 100644
--- a/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
+++ b/src/main/java/com/android/tools/r8/ir/code/BasicBlock.java
@@ -44,6 +44,12 @@
     return localsAtEntry;
   }
 
+  public void replaceLastInstruction(Instruction instruction) {
+    InstructionListIterator iterator = listIterator(getInstructions().size());
+    iterator.previous();
+    iterator.replaceCurrentInstruction(instruction);
+  }
+
   public enum ThrowingInfo {
     NO_THROW, CAN_THROW
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/DominatorTree.java b/src/main/java/com/android/tools/r8/ir/code/DominatorTree.java
index b5a7b75..9f28eea 100644
--- a/src/main/java/com/android/tools/r8/ir/code/DominatorTree.java
+++ b/src/main/java/com/android/tools/r8/ir/code/DominatorTree.java
@@ -87,6 +87,29 @@
     return dominator;
   }
 
+  /**
+   * Returns an iterator over all blocks dominated by dominator, including dominator itself.
+   */
+  public Iterable<BasicBlock> dominatedBlocks(BasicBlock domintator) {
+    return () -> new Iterator<BasicBlock>() {
+      private int current = domintator.getNumber();
+
+      @Override
+      public boolean hasNext() {
+        return dominatedBy(sorted[current], domintator);
+      }
+
+      @Override
+      public BasicBlock next() {
+        if (!hasNext()) {
+          return null;
+        } else {
+          return sorted[current++];
+        }
+      }
+    };
+  }
+
   public BasicBlock[] getSortedBlocks() {
     return sorted;
   }
diff --git a/src/main/java/com/android/tools/r8/ir/code/IRCode.java b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
index 7c37649..824d75c 100644
--- a/src/main/java/com/android/tools/r8/ir/code/IRCode.java
+++ b/src/main/java/com/android/tools/r8/ir/code/IRCode.java
@@ -390,4 +390,9 @@
   public final int getHighestBlockNumber() {
     return blocks.stream().max(Comparator.comparingInt(BasicBlock::getNumber)).get().getNumber();
   }
+
+  public Instruction createConstNull(Instruction from) {
+    Value newValue = createValue(from.outType());
+    return new ConstNumber(ConstType.fromMoveType(from.outType()), newValue, 0);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java b/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java
index 997b092..2cb8185 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstructionIterator.java
@@ -4,9 +4,7 @@
 
 package com.android.tools.r8.ir.code;
 
-import java.util.Iterator;
-
-public interface InstructionIterator extends Iterator<Instruction> {
+public interface InstructionIterator extends NextUntilIterator<Instruction> {
   /**
    * Replace the current instruction (aka the {@link Instruction} returned by the previous call to
    * {@link #next} with the passed in <code>newInstruction</code>.
diff --git a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
index bb88b64..431d338 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InstructionListIterator.java
@@ -10,7 +10,8 @@
 import java.util.ListIterator;
 import java.util.function.Predicate;
 
-public interface InstructionListIterator extends ListIterator<Instruction> {
+public interface InstructionListIterator extends ListIterator<Instruction>,
+    NextUntilIterator<Instruction> {
 
   /**
    * Peek the previous instruction.
diff --git a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
index cdc8644..6ccf1cc 100644
--- a/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
+++ b/src/main/java/com/android/tools/r8/ir/code/InvokeMethodWithReceiver.java
@@ -34,6 +34,9 @@
     return this;
   }
 
+  public Value getReceiver() {
+    return inValues.get(0);
+  }
 
   @Override
   public final InlineAction computeInlining(InliningOracle decider) {
diff --git a/src/main/java/com/android/tools/r8/ir/code/NextUntilIterator.java b/src/main/java/com/android/tools/r8/ir/code/NextUntilIterator.java
new file mode 100644
index 0000000..d15376e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/code/NextUntilIterator.java
@@ -0,0 +1,26 @@
+// 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.ir.code;
+
+import java.util.Iterator;
+import java.util.function.Predicate;
+
+public interface NextUntilIterator<T> extends Iterator<T> {
+
+  /**
+   * Continue to call {@link #next} while {@code predicate} tests {@code false}.
+   *
+   * @returns the item that matched the predicate or {@code null} if all items fail
+   * the predicate test
+   */
+  default T nextUntil(Predicate<T> predicate) {
+    while (hasNext()) {
+      T item = next();
+      if (predicate.test(item)) {
+        return item;
+      }
+    }
+    return null;
+  }
+}
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 e6b592d..8e613c0 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
@@ -32,6 +32,7 @@
 import com.android.tools.r8.ir.regalloc.LinearScanRegisterAllocator;
 import com.android.tools.r8.ir.regalloc.RegisterAllocator;
 import com.android.tools.r8.logging.Log;
+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;
@@ -64,9 +65,10 @@
   private final MemberValuePropagation memberValuePropagation;
   private final LensCodeRewriter lensCodeRewriter;
   private final Inliner inliner;
+  private final ProtoLitePruner protoLiteRewriter;
   private CallGraph callGraph;
-  private OptimizationFeedback ignoreOptimizationFeedback = new OptimizationFeedbackIgnore();
 
+  private OptimizationFeedback ignoreOptimizationFeedback = new OptimizationFeedbackIgnore();
   private DexString highestSortingString;
 
   private IRConverter(
@@ -94,16 +96,22 @@
         (enableDesugaring && enableInterfaceMethodDesugaring())
             ? new InterfaceMethodRewriter(this) : null;
     if (enableWholeProgramOptimizations) {
-      assert appInfo.withSubtyping() != null;
+      assert appInfo.hasSubtyping();
       this.inliner = new Inliner(appInfo.withSubtyping(), graphLense, options);
       this.outliner = new Outliner(appInfo, options);
       this.memberValuePropagation = new MemberValuePropagation(appInfo);
       this.lensCodeRewriter = new LensCodeRewriter(graphLense, appInfo.withSubtyping());
+      if (appInfo.hasLiveness()) {
+        this.protoLiteRewriter = new ProtoLitePruner(appInfo.withLiveness());
+      } else {
+        this.protoLiteRewriter = null;
+      }
     } else {
       this.inliner = null;
       this.outliner = null;
       this.memberValuePropagation = null;
       this.lensCodeRewriter = null;
+      this.protoLiteRewriter = null;
     }
   }
 
@@ -427,15 +435,20 @@
     printC1VisualizerHeader(method);
     printMethod(code, "Initial IR (SSA)");
 
-    if (lensCodeRewriter != null) {
-      lensCodeRewriter.rewrite(code, method);
-    } else {
-      assert graphLense.isIdentityLense();
+    if (!method.isProcessed()) {
+      if (protoLiteRewriter != null && protoLiteRewriter.appliesTo(method)) {
+        protoLiteRewriter.rewriteProtoLiteSpecialMethod(code, method);
+      }
+      if (lensCodeRewriter != null) {
+        lensCodeRewriter.rewrite(code, method);
+      } else {
+        assert graphLense.isIdentityLense();
+      }
     }
     if (memberValuePropagation != null) {
       memberValuePropagation.rewriteWithConstantValues(code);
     }
-    if (options.removeSwitchMaps) {
+    if (options.removeSwitchMaps && appInfo.hasLiveness()) {
       // TODO(zerny): Should we support removeSwitchMaps in debug mode? b/62936642
       assert !options.debug;
       codeRewriter.removeSwitchMaps(code);
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
index 14cd563..b1cdcbc 100644
--- a/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/optimize/CodeRewriter.java
@@ -9,12 +9,10 @@
 import com.android.tools.r8.graph.AppInfo;
 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.DexProto;
 import com.android.tools.r8.graph.DexType;
-import com.android.tools.r8.ir.code.ArrayGet;
 import com.android.tools.r8.ir.code.ArrayPut;
 import com.android.tools.r8.ir.code.BasicBlock;
 import com.android.tools.r8.ir.code.Binop;
@@ -32,7 +30,6 @@
 import com.android.tools.r8.ir.code.InstructionIterator;
 import com.android.tools.r8.ir.code.InstructionListIterator;
 import com.android.tools.r8.ir.code.Invoke;
-import com.android.tools.r8.ir.code.InvokeDirect;
 import com.android.tools.r8.ir.code.InvokeMethod;
 import com.android.tools.r8.ir.code.InvokeVirtual;
 import com.android.tools.r8.ir.code.MemberType;
@@ -47,6 +44,7 @@
 import com.android.tools.r8.ir.code.Switch;
 import com.android.tools.r8.ir.code.Value;
 import com.android.tools.r8.ir.conversion.OptimizationFeedback;
+import com.android.tools.r8.ir.optimize.SwitchUtils.EnumSwitchInfo;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.LongInterval;
 import com.google.common.base.Equivalence;
@@ -56,12 +54,8 @@
 import com.google.common.collect.ListMultimap;
 import it.unimi.dsi.fastutil.ints.Int2IntArrayMap;
 import it.unimi.dsi.fastutil.ints.Int2IntMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
-import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
 import it.unimi.dsi.fastutil.ints.IntArrayList;
 import it.unimi.dsi.fastutil.ints.IntList;
-import it.unimi.dsi.fastutil.objects.Reference2IntArrayMap;
-import it.unimi.dsi.fastutil.objects.Reference2IntMap;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.HashMap;
@@ -371,8 +365,6 @@
    *   ...
    * }
    * </pre></blockquote>
-   * See {@link #extractIndexMapFrom} and {@link #extractOrdinalsMapFor} for
-   * details of the companion class and ordinals computation.
    */
   public void removeSwitchMaps(IRCode code) {
     for (BasicBlock block : code.blocks) {
@@ -382,68 +374,38 @@
         // Pattern match a switch on a switch map as input.
         if (insn.isSwitch()) {
           Switch switchInsn = insn.asSwitch();
-          Instruction input = switchInsn.inValues().get(0).definition;
-          if (input == null || !input.isArrayGet()) {
-            continue;
-          }
-          ArrayGet arrayGet = input.asArrayGet();
-          Instruction index = arrayGet.index().definition;
-          if (index == null || !index.isInvokeVirtual()) {
-            continue;
-          }
-          InvokeVirtual ordinalInvoke = index.asInvokeVirtual();
-          DexMethod ordinalMethod = ordinalInvoke.getInvokedMethod();
-          DexClass enumClass = appInfo.definitionFor(ordinalMethod.holder);
-          if (enumClass == null
-              || (!enumClass.accessFlags.isEnum() && enumClass.type != dexItemFactory.enumType)
-              || ordinalMethod.name != dexItemFactory.ordinalMethodName
-              || ordinalMethod.proto.returnType != dexItemFactory.intType
-              || !ordinalMethod.proto.parameters.isEmpty()) {
-            continue;
-          }
-          Instruction array = arrayGet.array().definition;
-          if (array == null || !array.isStaticGet()) {
-            continue;
-          }
-          StaticGet staticGet = array.asStaticGet();
-          if (staticGet.getField().name.toSourceString().startsWith("$SwitchMap$")) {
-            Int2ReferenceMap<DexField> indexMap = extractIndexMapFrom(staticGet.getField());
-            if (indexMap == null || indexMap.isEmpty()) {
-              continue;
+          EnumSwitchInfo info = SwitchUtils
+              .analyzeSwitchOverEnum(switchInsn, appInfo.withLiveness());
+          if (info != null) {
+            Int2IntMap targetMap = new Int2IntArrayMap();
+            IntList keys = new IntArrayList(switchInsn.numberOfKeys());
+            for (int i = 0; i < switchInsn.numberOfKeys(); i++) {
+              assert switchInsn.targetBlockIndices()[i] != switchInsn.getFallthroughBlockIndex();
+              int key = info.ordinalsMap.getInt(info.indexMap.get(switchInsn.getKey(i)));
+              keys.add(key);
+              targetMap.put(key, switchInsn.targetBlockIndices()[i]);
             }
-            // Due to member rebinding, only the fields are certain to provide the actual enums
-            // class.
-            DexType switchMapHolder = indexMap.values().iterator().next().getHolder();
-            Reference2IntMap<DexField> ordinalsMap = extractOrdinalsMapFor(switchMapHolder);
-            if (ordinalsMap != null) {
-              Int2IntMap targetMap = new Int2IntArrayMap();
-              IntList keys = new IntArrayList(switchInsn.numberOfKeys());
-              for (int i = 0; i < switchInsn.numberOfKeys(); i++) {
-                assert switchInsn.targetBlockIndices()[i] != switchInsn.getFallthroughBlockIndex();
-                int key = ordinalsMap.getInt(indexMap.get(switchInsn.getKey(i)));
-                keys.add(key);
-                targetMap.put(key, switchInsn.targetBlockIndices()[i]);
-              }
-              keys.sort(Comparator.naturalOrder());
-              int[] targets = new int[keys.size()];
-              for (int i = 0; i < keys.size(); i++) {
-                targets[i] = targetMap.get(keys.getInt(i));
-              }
+            keys.sort(Comparator.naturalOrder());
+            int[] targets = new int[keys.size()];
+            for (int i = 0; i < keys.size(); i++) {
+              targets[i] = targetMap.get(keys.getInt(i));
+            }
 
-              Switch newSwitch = new Switch(ordinalInvoke.outValue(), keys.toIntArray(),
-                  targets, switchInsn.getFallthroughBlockIndex());
-              // Replace the switch itself.
-              it.replaceCurrentInstruction(newSwitch);
-              // If the original input to the switch is now unused, remove it too. It is not dead
-              // as it might have side-effects but we ignore these here.
-              if (arrayGet.outValue().numberOfUsers() == 0) {
-                arrayGet.inValues().forEach(v -> v.removeUser(arrayGet));
-                arrayGet.getBlock().removeInstruction(arrayGet);
-              }
-              if (staticGet.outValue().numberOfUsers() == 0) {
-                assert staticGet.inValues().isEmpty();
-                staticGet.getBlock().removeInstruction(staticGet);
-              }
+            Switch newSwitch = new Switch(info.ordinalInvoke.outValue(), keys.toIntArray(),
+                targets, switchInsn.getFallthroughBlockIndex());
+            // Replace the switch itself.
+            it.replaceCurrentInstruction(newSwitch);
+            // If the original input to the switch is now unused, remove it too. It is not dead
+            // as it might have side-effects but we ignore these here.
+            Instruction arrayGet = info.arrayGet;
+            if (arrayGet.outValue().numberOfUsers() == 0) {
+              arrayGet.inValues().forEach(v -> v.removeUser(arrayGet));
+              arrayGet.getBlock().removeInstruction(arrayGet);
+            }
+            Instruction staticGet = info.staticGet;
+            if (staticGet.outValue().numberOfUsers() == 0) {
+              assert staticGet.inValues().isEmpty();
+              staticGet.getBlock().removeInstruction(staticGet);
             }
           }
         }
@@ -451,156 +413,6 @@
     }
   }
 
-
-  /**
-   * Extracts the mapping from ordinal values to switch case constants.
-   * <p>
-   * This is done by pattern-matching on the class initializer of the synthetic switch map class.
-   * For a switch
-   *
-   * <blockquote><pre>
-   * switch (day) {
-   *   case WEDNESDAY:
-   *   case FRIDAY:
-   *     System.out.println("3 or 5");
-   *     break;
-   *   case SUNDAY:
-   *     System.out.println("7");
-   *     break;
-   *   default:
-   *     System.out.println("other");
-   * }
-   * </pre></blockquote>
-   *
-   * the generated companing class initializer will have the form
-   *
-   * <blockquote><pre>
-   * class Switches$1 {
-   *   static {
-   *   $SwitchMap$switchmaps$Days[Days.WEDNESDAY.ordinal()] = 1;
-   *   $SwitchMap$switchmaps$Days[Days.FRIDAY.ordinal()] = 2;
-   *   $SwitchMap$switchmaps$Days[Days.SUNDAY.ordinal()] = 3;
-   * }
-   * </pre></blockquote>
-   *
-   * Note that one map per class is generated, so the map might contain additional entries as used
-   * by other switches in the class.
-   */
-  private Int2ReferenceMap<DexField> extractIndexMapFrom(DexField field) {
-    DexClass clazz = appInfo.definitionFor(field.getHolder());
-    if (!clazz.accessFlags.isSynthetic()) {
-      return null;
-    }
-    DexEncodedMethod initializer = clazz.getClassInitializer();
-    if (initializer == null || initializer.getCode() == null) {
-      return null;
-    }
-    IRCode code = initializer.getCode().buildIR(initializer, new InternalOptions());
-    Int2ReferenceMap<DexField> switchMap = new Int2ReferenceArrayMap<>();
-    for (BasicBlock block : code.blocks) {
-      InstructionListIterator it = block.listIterator();
-      Instruction insn = it.nextUntil(i -> i.isStaticGet() && i.asStaticGet().getField() == field);
-      if (insn == null) {
-        continue;
-      }
-      for (Instruction use : insn.outValue().uniqueUsers()) {
-        if (use.isArrayPut()) {
-          Instruction index = use.asArrayPut().source().definition;
-          if (index == null || !index.isConstNumber()) {
-            return null;
-          }
-          int integerIndex = index.asConstNumber().getIntValue();
-          Instruction value = use.asArrayPut().index().definition;
-          if (value == null || !value.isInvokeVirtual()) {
-            return null;
-          }
-          InvokeVirtual invoke = value.asInvokeVirtual();
-          DexClass holder = appInfo.definitionFor(invoke.getInvokedMethod().holder);
-          if (holder == null ||
-              (!holder.accessFlags.isEnum() && holder.type != dexItemFactory.enumType)) {
-            return null;
-          }
-          Instruction enumGet = invoke.arguments().get(0).definition;
-          if (enumGet == null || !enumGet.isStaticGet()) {
-            return null;
-          }
-          DexField enumField = enumGet.asStaticGet().getField();
-          if (!appInfo.definitionFor(enumField.getHolder()).accessFlags.isEnum()) {
-            return null;
-          }
-          if (switchMap.put(integerIndex, enumField) != null) {
-            return null;
-          }
-        } else {
-          return null;
-        }
-      }
-    }
-    return switchMap;
-  }
-
-  /**
-   * Extracts the ordinal values for an Enum class from the classes static initializer.
-   * <p>
-   * An Enum class has a field for each value. In the class initializer, each field is initialized
-   * to a singleton object that represents the value. This code matches on the corresponding call
-   * to the constructor (instance initializer) and extracts the value of the second argument, which
-   * is the ordinal.
-   */
-  private Reference2IntMap<DexField> extractOrdinalsMapFor(DexType enumClass) {
-    DexClass clazz = appInfo.definitionFor(enumClass);
-    if (clazz == null || clazz.isLibraryClass()) {
-      // We have to keep binary compatibility in tact for libraries.
-      return null;
-    }
-    DexEncodedMethod initializer = clazz.getClassInitializer();
-    if (!clazz.accessFlags.isEnum() || initializer == null || initializer.getCode() == null) {
-      return null;
-    }
-    if (initializer.getCode().isDexCode()) {
-      // If the initializer have been optimized we cannot extract the ordinals map reliably.
-      return null;
-    }
-    IRCode code = initializer.getCode().buildIR(initializer, new InternalOptions());
-    Reference2IntMap<DexField> ordinalsMap = new Reference2IntArrayMap<>();
-    ordinalsMap.defaultReturnValue(-1);
-    InstructionIterator it = code.instructionIterator();
-    while (it.hasNext()) {
-      Instruction insn = it.next();
-      if (!insn.isStaticPut()) {
-        continue;
-      }
-      StaticPut staticPut = insn.asStaticPut();
-      if (staticPut.getField().type != enumClass) {
-        continue;
-      }
-      Instruction newInstance = staticPut.inValue().definition;
-      if (newInstance == null || !newInstance.isNewInstance()) {
-        continue;
-      }
-      Instruction ordinal = null;
-      for (Instruction ctorCall : newInstance.outValue().uniqueUsers()) {
-        if (!ctorCall.isInvokeDirect()) {
-          continue;
-        }
-        InvokeDirect invoke = ctorCall.asInvokeDirect();
-        if (!dexItemFactory.isConstructor(invoke.getInvokedMethod())
-            || invoke.arguments().size() < 3) {
-          continue;
-        }
-        ordinal = invoke.arguments().get(2).definition;
-        break;
-      }
-      if (ordinal == null || !ordinal.isConstNumber()) {
-        return null;
-      }
-      if (ordinalsMap.put(staticPut.getField(), ordinal.asConstNumber().getIntValue()) != -1) {
-        return null;
-      }
-    }
-    return ordinalsMap;
-  }
-
   /**
    * Rewrite all branch targets to the destination of trivial goto chains when possible.
    * Does not rewrite fallthrough targets as that would require block reordering and the
@@ -1287,7 +1099,7 @@
           }
         }
         assert theIf == block.exit();
-        replaceLastInstruction(block, new Goto());
+        block.replaceLastInstruction(new Goto());
         assert block.exit().isGoto();
         assert block.exit().asGoto().getTarget() == target;
       }
@@ -1310,7 +1122,7 @@
         int left = leftValue.getConstInstruction().asConstNumber().getIntValue();
         if (left == 0) {
           If ifz = new If(theIf.getType().forSwappedOperands(), rightValue);
-          replaceLastInstruction(block, ifz);
+          block.replaceLastInstruction(ifz);
           assert block.exit() == ifz;
         }
       } else {
@@ -1318,19 +1130,13 @@
         int right = rightValue.getConstInstruction().asConstNumber().getIntValue();
         if (right == 0) {
           If ifz = new If(theIf.getType(), leftValue);
-          replaceLastInstruction(block, ifz);
+          block.replaceLastInstruction(ifz);
           assert block.exit() == ifz;
         }
       }
     }
   }
 
-  private void replaceLastInstruction(BasicBlock block, Instruction instruction) {
-    InstructionListIterator iterator = block.listIterator(block.getInstructions().size());
-    iterator.previous();
-    iterator.replaceCurrentInstruction(instruction);
-  }
-
   public void rewriteLongCompareAndRequireNonNull(IRCode code, InternalOptions options) {
     if (options.canUseLongCompareAndObjectsNonNull()) {
       return;
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
new file mode 100644
index 0000000..b2ebecc
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/optimize/EnumOrdinalMapCollector.java
@@ -0,0 +1,102 @@
+// 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.ir.optimize;
+
+import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InstructionIterator;
+import com.android.tools.r8.ir.code.InvokeDirect;
+import com.android.tools.r8.ir.code.StaticPut;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
+import com.android.tools.r8.utils.InternalOptions;
+import it.unimi.dsi.fastutil.objects.Reference2IntArrayMap;
+import it.unimi.dsi.fastutil.objects.Reference2IntMap;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+/**
+ * Extracts the ordinal values for all Enum classes from their static initializer.
+ * <p>
+ * An Enum class has a field for each value. In the class initializer, each field is initialized
+ * to a singleton object that represents the value. This code matches on the corresponding call
+ * to the constructor (instance initializer) and extracts the value of the second argument, which
+ * is the ordinal.
+ */
+public class EnumOrdinalMapCollector {
+
+  private final AppInfoWithLiveness appInfo;
+  private final InternalOptions options;
+
+  private final Map<DexType, Reference2IntMap<DexField>> ordinalsMaps = new IdentityHashMap<>();
+
+  public EnumOrdinalMapCollector(AppInfoWithLiveness appInfo, InternalOptions options) {
+    this.appInfo = appInfo;
+    this.options = options;
+  }
+
+  public static Reference2IntMap<DexField> getOrdinalsMapFor(DexType enumClass,
+      AppInfoWithLiveness appInfo) {
+    Map<DexType, Reference2IntMap<DexField>> ordinalsMaps = appInfo
+        .getExtension(EnumOrdinalMapCollector.class, Collections.emptyMap());
+    return ordinalsMaps.get(enumClass);
+  }
+
+  public void run() {
+    appInfo.classes().forEach(this::processClasses);
+    if (!ordinalsMaps.isEmpty()) {
+      appInfo.setExtension(EnumOrdinalMapCollector.class, ordinalsMaps);
+    }
+  }
+
+  private void processClasses(DexProgramClass clazz) {
+    // Enum classes are flagged as such. Also, for library classes, the ordinals are not known.
+    if (!clazz.accessFlags.isEnum() || clazz.isLibraryClass() || !clazz.hasClassInitializer()) {
+      return;
+    }
+    DexEncodedMethod initializer = clazz.getClassInitializer();
+    IRCode code = initializer.getCode().buildIR(initializer, options);
+    Reference2IntMap<DexField> ordinalsMap = new Reference2IntArrayMap<>();
+    ordinalsMap.defaultReturnValue(-1);
+    InstructionIterator it = code.instructionIterator();
+    while (it.hasNext()) {
+      Instruction insn = it.next();
+      if (!insn.isStaticPut()) {
+        continue;
+      }
+      StaticPut staticPut = insn.asStaticPut();
+      if (staticPut.getField().type != clazz.type) {
+        continue;
+      }
+      Instruction newInstance = staticPut.inValue().definition;
+      if (newInstance == null || !newInstance.isNewInstance()) {
+        continue;
+      }
+      Instruction ordinal = null;
+      for (Instruction ctorCall : newInstance.outValue().uniqueUsers()) {
+        if (!ctorCall.isInvokeDirect()) {
+          continue;
+        }
+        InvokeDirect invoke = ctorCall.asInvokeDirect();
+        if (!appInfo.dexItemFactory.isConstructor(invoke.getInvokedMethod())
+            || invoke.arguments().size() < 3) {
+          continue;
+        }
+        ordinal = invoke.arguments().get(2).definition;
+        break;
+      }
+      if (ordinal == null || !ordinal.isConstNumber()) {
+        return;
+      }
+      if (ordinalsMap.put(staticPut.getField(), ordinal.asConstNumber().getIntValue()) != -1) {
+        return;
+      }
+    }
+    ordinalsMaps.put(clazz.type, ordinalsMap);
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
new file mode 100644
index 0000000..44f0759
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/optimize/SwitchMapCollector.java
@@ -0,0 +1,155 @@
+// 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.ir.optimize;
+
+import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexEncodedField;
+import com.android.tools.r8.graph.DexField;
+import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.graph.DexString;
+import com.android.tools.r8.graph.DexType;
+import com.android.tools.r8.ir.code.IRCode;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InstructionIterator;
+import com.android.tools.r8.ir.code.InvokeVirtual;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
+import com.android.tools.r8.utils.InternalOptions;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.IdentityHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+
+/**
+ * Extracts the mapping from ordinal values to switch case constants.
+ * <p>
+ * This is done by pattern-matching on the class initializer of the synthetic switch map class.
+ * For a switch
+ *
+ * <blockquote><pre>
+ * switch (day) {
+ *   case WEDNESDAY:
+ *   case FRIDAY:
+ *     System.out.println("3 or 5");
+ *     break;
+ *   case SUNDAY:
+ *     System.out.println("7");
+ *     break;
+ *   default:
+ *     System.out.println("other");
+ * }
+ * </pre></blockquote>
+ *
+ * the generated companing class initializer will have the form
+ *
+ * <blockquote><pre>
+ * class Switches$1 {
+ *   static {
+ *   $SwitchMap$switchmaps$Days[Days.WEDNESDAY.ordinal()] = 1;
+ *   $SwitchMap$switchmaps$Days[Days.FRIDAY.ordinal()] = 2;
+ *   $SwitchMap$switchmaps$Days[Days.SUNDAY.ordinal()] = 3;
+ * }
+ * </pre></blockquote>
+ *
+ * Note that one map per class is generated, so the map might contain additional entries as used
+ * by other switches in the class.
+ */
+public class SwitchMapCollector {
+
+  private final AppInfoWithLiveness appInfo;
+  private final InternalOptions options;
+  private final DexString switchMapPrefix;
+  private final DexType intArrayType;
+
+  private final Map<DexField, Int2ReferenceMap<DexField>> switchMaps = new IdentityHashMap<>();
+
+  public SwitchMapCollector(AppInfoWithLiveness appInfo, InternalOptions options) {
+    this.appInfo = appInfo;
+    this.options = options;
+    switchMapPrefix = appInfo.dexItemFactory.createString("$SwitchMap$");
+    intArrayType = appInfo.dexItemFactory.createType("[I");
+  }
+
+  public void run() {
+    appInfo.classes().forEach(this::processClasses);
+    if (!switchMaps.isEmpty()) {
+      appInfo.setExtension(SwitchMapCollector.class, switchMaps);
+    }
+  }
+
+  public static Int2ReferenceMap<DexField> getSwitchMapFor(DexField field,
+      AppInfoWithLiveness appInfo) {
+    Map<DexField, Int2ReferenceMap<DexField>> switchMaps = appInfo
+        .getExtension(SwitchMapCollector.class, Collections.emptyMap());
+    return switchMaps.get(field);
+  }
+
+  private void processClasses(DexProgramClass clazz) {
+    // Switchmap classes are synthetic and have a class initializer.
+    if (!clazz.accessFlags.isSynthetic() && !clazz.hasClassInitializer()) {
+      return;
+    }
+    List<DexEncodedField> switchMapFields = Arrays.stream(clazz.staticFields())
+        .filter(this::maybeIsSwitchMap).collect(Collectors.toList());
+    if (!switchMapFields.isEmpty()) {
+      IRCode initializer = clazz.getClassInitializer().buildIR(options);
+      switchMapFields.forEach(field -> extractSwitchMap(field, initializer));
+    }
+  }
+
+  private void extractSwitchMap(DexEncodedField encodedField, IRCode initializer) {
+    DexField field = encodedField.field;
+    Int2ReferenceMap<DexField> switchMap = new Int2ReferenceArrayMap<>();
+    InstructionIterator it = initializer.instructionIterator();
+    Instruction insn;
+    Predicate<Instruction> predicate = i -> i.isStaticGet() && i.asStaticGet().getField() == field;
+    while ((insn = it.nextUntil(predicate)) != null) {
+      for (Instruction use : insn.outValue().uniqueUsers()) {
+        if (use.isArrayPut()) {
+          Instruction index = use.asArrayPut().source().definition;
+          if (index == null || !index.isConstNumber()) {
+            return;
+          }
+          int integerIndex = index.asConstNumber().getIntValue();
+          Instruction value = use.asArrayPut().index().definition;
+          if (value == null || !value.isInvokeVirtual()) {
+            return;
+          }
+          InvokeVirtual invoke = value.asInvokeVirtual();
+          DexClass holder = appInfo.definitionFor(invoke.getInvokedMethod().holder);
+          if (holder == null ||
+              (!holder.accessFlags.isEnum() && holder.type != appInfo.dexItemFactory.enumType)) {
+            return;
+          }
+          Instruction enumGet = invoke.arguments().get(0).definition;
+          if (enumGet == null || !enumGet.isStaticGet()) {
+            return;
+          }
+          DexField enumField = enumGet.asStaticGet().getField();
+          if (!appInfo.definitionFor(enumField.getHolder()).accessFlags.isEnum()) {
+            return;
+          }
+          if (switchMap.put(integerIndex, enumField) != null) {
+            return;
+          }
+        } else {
+          return;
+        }
+      }
+    }
+    switchMaps.put(field, switchMap);
+  }
+
+  private boolean maybeIsSwitchMap(DexEncodedField dexEncodedField) {
+    // We are looking for synthetic fields of type int[].
+    DexField field = dexEncodedField.field;
+    return dexEncodedField.accessFlags.isSynthetic()
+        && field.name.beginsWith(switchMapPrefix)
+        && field.type == intArrayType;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/optimize/SwitchUtils.java b/src/main/java/com/android/tools/r8/ir/optimize/SwitchUtils.java
new file mode 100644
index 0000000..0c33561
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/optimize/SwitchUtils.java
@@ -0,0 +1,102 @@
+// 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.ir.optimize;
+
+import com.android.tools.r8.graph.DexClass;
+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.DexType;
+import com.android.tools.r8.ir.code.ArrayGet;
+import com.android.tools.r8.ir.code.Instruction;
+import com.android.tools.r8.ir.code.InvokeVirtual;
+import com.android.tools.r8.ir.code.StaticGet;
+import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
+import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
+import it.unimi.dsi.fastutil.objects.Reference2IntMap;
+
+public class SwitchUtils {
+
+  public static final class EnumSwitchInfo {
+    public final DexType enumClass;
+    public final Instruction ordinalInvoke;
+    public final Instruction arrayGet;
+    public final Instruction staticGet;
+    public final Int2ReferenceMap<DexField> indexMap;
+    public final Reference2IntMap ordinalsMap;
+
+    private EnumSwitchInfo(DexType enumClass,
+        Instruction ordinalInvoke,
+        Instruction arrayGet, Instruction staticGet,
+        Int2ReferenceMap<DexField> indexMap,
+        Reference2IntMap ordinalsMap) {
+      this.enumClass = enumClass;
+      this.ordinalInvoke = ordinalInvoke;
+      this.arrayGet = arrayGet;
+      this.staticGet = staticGet;
+      this.indexMap = indexMap;
+      this.ordinalsMap = ordinalsMap;
+    }
+  }
+
+  /**
+   * Looks for a switch statement over the enum companion class of the form
+   *
+   * <blockquote><pre>
+   * switch(CompanionClass.$switchmap$field[enumValue.ordinal()]) {
+   *   ...
+   * }
+   * </pre></blockquote>
+   *
+   * and extracts the components and the index and ordinal maps. See
+   * {@link EnumOrdinalMapCollector} and
+   * {@link SwitchMapCollector} for details.
+   */
+  public static EnumSwitchInfo analyzeSwitchOverEnum(Instruction switchInsn,
+      AppInfoWithLiveness appInfo) {
+    Instruction input = switchInsn.inValues().get(0).definition;
+    if (input == null || !input.isArrayGet()) {
+      return null;
+    }
+    ArrayGet arrayGet = input.asArrayGet();
+    Instruction index = arrayGet.index().definition;
+    if (index == null || !index.isInvokeVirtual()) {
+      return null;
+    }
+    InvokeVirtual ordinalInvoke = index.asInvokeVirtual();
+    DexMethod ordinalMethod = ordinalInvoke.getInvokedMethod();
+    DexClass enumClass = appInfo.definitionFor(ordinalMethod.holder);
+    DexItemFactory dexItemFactory = appInfo.dexItemFactory;
+    // After member rebinding, enumClass will be the actual java.lang.Enum class.
+    if (enumClass == null
+        || (!enumClass.accessFlags.isEnum() && enumClass.type != dexItemFactory.enumType)
+        || ordinalMethod.name != dexItemFactory.ordinalMethodName
+        || ordinalMethod.proto.returnType != dexItemFactory.intType
+        || !ordinalMethod.proto.parameters.isEmpty()) {
+      return null;
+    }
+    Instruction array = arrayGet.array().definition;
+    if (array == null || !array.isStaticGet()) {
+      return null;
+    }
+    StaticGet staticGet = array.asStaticGet();
+    Int2ReferenceMap<DexField> indexMap
+        = SwitchMapCollector.getSwitchMapFor(staticGet.getField(), appInfo);
+    if (indexMap == null || indexMap.isEmpty()) {
+      return null;
+    }
+    // Due to member rebinding, only the fields are certain to provide the actual enums
+    // class.
+    DexType enumTyoe = indexMap.values().iterator().next().getHolder();
+    Reference2IntMap ordinalsMap
+        = EnumOrdinalMapCollector.getOrdinalsMapFor(enumTyoe, appInfo);
+    if (ordinalsMap == null) {
+      return null;
+    }
+    return new EnumSwitchInfo(enumTyoe, ordinalInvoke, arrayGet, staticGet, indexMap,
+        ordinalsMap);
+  }
+
+
+}
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 b8fa85a..d25c4bc 100644
--- a/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
+++ b/src/main/java/com/android/tools/r8/shaking/Enqueuer.java
@@ -37,12 +37,14 @@
 import com.google.common.collect.Sets;
 import com.google.common.collect.Sets.SetView;
 import java.util.ArrayDeque;
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Deque;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.IdentityHashMap;
+import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Queue;
@@ -75,6 +77,9 @@
   private Map<DexType, Set<DexField>> staticFieldsRead = Maps.newIdentityHashMap();
   private Map<DexType, Set<DexField>> staticFieldsWritten = Maps.newIdentityHashMap();
 
+  private final List<SemanticsProvider> extensions = new ArrayList<>();
+  private final Map<Class, Object> extensionsState = new HashMap<>();
+
   /**
    * This map keeps a view of all virtual methods that are reachable from virtual invokes. A method
    * is reachable even if no live subtypes exist, so this is not sufficient for inclusion in the
@@ -152,6 +157,10 @@
     this.appInfo = appInfo;
   }
 
+  public void addExtension(SemanticsProvider extension) {
+    extensions.add(extension);
+  }
+
   private void enqueueRootItems(Map<DexItem, ProguardKeepRule> items) {
     workList.addAll(
         items.entrySet().stream().map(Action::forRootItem).collect(Collectors.toList()));
@@ -852,7 +861,21 @@
       for (DexAnnotationSet parameterAnnotation : method.parameterAnnotations.values) {
         processAnnotations(parameterAnnotation.annotations);
       }
-      method.registerReachableDefinitions(new UseRegistry(method));
+      boolean processed = false;
+      if (!extensions.isEmpty()) {
+        for (SemanticsProvider extension : extensions) {
+          if (extension.appliesTo(method)) {
+            assert extensions.stream().filter(e -> e.appliesTo(method)).count() == 1;
+            extensionsState.put(extension.getClass(),
+                extension.processMethod(method, new UseRegistry(method),
+                    extensionsState.get(extension.getClass())));
+            processed = true;
+          }
+        }
+      }
+      if (!processed) {
+        method.registerReachableDefinitions(new UseRegistry(method));
+      }
       // Add all dependent members to the workqueue.
       enqueueRootItems(rootSet.getDependentItems(method));
     }
@@ -1007,7 +1030,7 @@
      * Set of fields that belong to live classes and can be reached by invokes. These need to be
      * kept.
      */
-    final Set<DexField> liveFields;
+    public final Set<DexField> liveFields;
     /**
      * Set of all fields which may be touched by a get operation. This is actual field definitions.
      */
@@ -1060,6 +1083,10 @@
      * All items with assumevalues rule.
      */
     public final Map<DexItem, ProguardMemberRule> assumedValues;
+    /**
+     * Map from the class of an extension to the state it produced.
+     */
+    public final Map<Class, Object> extensions;
 
     private AppInfoWithLiveness(AppInfoWithSubtyping appInfo, Enqueuer enqueuer) {
       super(appInfo);
@@ -1081,6 +1108,7 @@
       this.staticInvokes = joinInvokedMethods(enqueuer.staticInvokes);
       this.noSideEffects = enqueuer.rootSet.noSideEffects;
       this.assumedValues = enqueuer.rootSet.assumedValues;
+      this.extensions = enqueuer.extensionsState;
       assert Sets.intersection(instanceFieldReads, staticFieldReads).size() == 0;
       assert Sets.intersection(instanceFieldWrites, staticFieldWrites).size() == 0;
     }
@@ -1106,6 +1134,7 @@
       this.superInvokes = previous.superInvokes;
       this.directInvokes = previous.directInvokes;
       this.staticInvokes = previous.staticInvokes;
+      this.extensions = previous.extensions;
       assert Sets.intersection(instanceFieldReads, staticFieldReads).size() == 0;
       assert Sets.intersection(instanceFieldWrites, staticFieldWrites).size() == 0;
     }
@@ -1131,6 +1160,7 @@
       this.superInvokes = rewriteItems(previous.superInvokes, lense::lookupMethod);
       this.directInvokes = rewriteItems(previous.directInvokes, lense::lookupMethod);
       this.staticInvokes = rewriteItems(previous.staticInvokes, lense::lookupMethod);
+      this.extensions = previous.extensions;
       assert Sets.intersection(instanceFieldReads, staticFieldReads).size() == 0;
       assert Sets.intersection(instanceFieldWrites, staticFieldWrites).size() == 0;
     }
@@ -1159,6 +1189,20 @@
       return builder.build();
     }
 
+    @SuppressWarnings("unchecked")
+    public <T> T getExtension(Class extension, T defaultValue) {
+      if (extensions.containsKey(extension)) {
+        return (T) extensions.get(extension);
+      } else {
+        return defaultValue;
+      }
+    }
+
+    public <T> void setExtension(Class extension, T value) {
+      assert !extensions.containsKey(extension);
+      extensions.put(extension, value);
+    }
+
     @Override
     public boolean hasLiveness() {
       return true;
@@ -1299,4 +1343,12 @@
       return false;
     }
   }
+
+  public interface SemanticsProvider {
+
+    boolean appliesTo(DexEncodedMethod method);
+
+    Object processMethod(DexEncodedMethod method,
+        com.android.tools.r8.graph.UseRegistry useRegistry, Object state);
+  }
 }
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
new file mode 100644
index 0000000..c2264f2
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteBase.java
@@ -0,0 +1,98 @@
+// 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
new file mode 100644
index 0000000..b217194
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLiteExtension.java
@@ -0,0 +1,208 @@
+// 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.shaking.Enqueuer.SemanticsProvider;
+import com.android.tools.r8.utils.MethodJavaSignatureEquivalence;
+import com.google.common.base.Equivalence;
+import com.google.common.base.Equivalence.Wrapper;
+import com.google.common.collect.Sets;
+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 implements SemanticsProvider {
+
+  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;
+  }
+
+  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);
+  }
+
+  @Override
+  @SuppressWarnings("unchecked")
+  public Object processMethod(DexEncodedMethod method, UseRegistry registry, Object state) {
+    return processMethod(method, registry, (Set<DexField>) state);
+  }
+
+  private Set<DexField> processMethod(DexEncodedMethod method, UseRegistry registry,
+      Set<DexField> state) {
+    if (state == null) {
+      state = Sets.newIdentityHashSet();
+    }
+    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.registerReachableDefinitions(
+          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.registerReachableDefinitions(new FilteringUseRegistry(registry, method.method.holder,
+          state));
+    }
+    return state;
+  }
+
+  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
new file mode 100644
index 0000000..8b0ac9e
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/shaking/protolite/ProtoLitePruner.java
@@ -0,0 +1,739 @@
+// 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.MoveType;
+import com.android.tools.r8.ir.code.Switch;
+import com.android.tools.r8.ir.code.Value;
+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.Set;
+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 AppInfoWithLiveness appInfo;
+
+  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 Set<DexField> seenFields;
+  private final DexMethod sizeMethod;
+
+  public ProtoLitePruner(AppInfoWithLiveness appInfo) {
+    super(appInfo);
+    this.appInfo = 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);
+
+    seenFields = appInfo.withLiveness()
+        .getExtension(ProtoLiteExtension.class, Collections.emptySet());
+  }
+
+  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");
+  }
+
+  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 seenFields.contains(correspondingField);
+  }
+
+  private boolean isDefinedAsNull(Value value) {
+    return value.definition != null && value.definition.isConstNumber()
+        && value.definition.asConstNumber().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 seenFields.contains(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().numberOfAllUsers() == 0)
+              && 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);
+    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);
+    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.liveFields.contains(field)) {
+                // Effectively inline the code that is normally inside these methods.
+                Value thisReference = invokeMethod.getReceiver();
+                Value newResult = code.createValue(MoveType.SINGLE);
+                invokeMethod.outValue().replaceUsers(newResult);
+                Value theList = code.createValue(MoveType.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;
+      if ((switchInstr = (Switch) it.nextUntil(Instruction::isSwitch)) != 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.getNormalSucessors());
+          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.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
new file mode 100644
index 0000000..9176378
--- /dev/null
+++ b/src/test/examples/enumproto/Enumproto.java
@@ -0,0 +1,66 @@
+// 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
new file mode 100644
index 0000000..0fa5695
--- /dev/null
+++ b/src/test/examples/enumproto/enum.proto
@@ -0,0 +1,25 @@
+// 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
new file mode 100644
index 0000000..a2731fb
--- /dev/null
+++ b/src/test/examples/enumproto/enum_three.proto
@@ -0,0 +1,25 @@
+// 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
new file mode 100644
index 0000000..088f88f
--- /dev/null
+++ b/src/test/examples/enumproto/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..fe1a535
--- /dev/null
+++ b/src/test/examples/nestedproto1/Nestedproto.java
@@ -0,0 +1,31 @@
+// Copyright (c) 2017, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+package 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
new file mode 100644
index 0000000..1c47672
--- /dev/null
+++ b/src/test/examples/nestedproto1/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..0d05749
--- /dev/null
+++ b/src/test/examples/nestedproto1/nested.proto
@@ -0,0 +1,24 @@
+// 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
new file mode 100644
index 0000000..59217de
--- /dev/null
+++ b/src/test/examples/nestedproto2/Nestedproto.java
@@ -0,0 +1,33 @@
+// 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
new file mode 100644
index 0000000..87c9218
--- /dev/null
+++ b/src/test/examples/nestedproto2/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..ac56f40
--- /dev/null
+++ b/src/test/examples/nestedproto2/nested.proto
@@ -0,0 +1,24 @@
+// 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
new file mode 100644
index 0000000..261705f
--- /dev/null
+++ b/src/test/examples/oneofproto/Oneofproto.java
@@ -0,0 +1,38 @@
+// 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
new file mode 100644
index 0000000..70f00f1
--- /dev/null
+++ b/src/test/examples/oneofproto/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..c5a67a1
--- /dev/null
+++ b/src/test/examples/oneofproto/oneof.proto
@@ -0,0 +1,17 @@
+// 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
new file mode 100644
index 0000000..d384173
--- /dev/null
+++ b/src/test/examples/protowithexts/withexts.proto
@@ -0,0 +1,19 @@
+// 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
new file mode 100644
index 0000000..280070d
--- /dev/null
+++ b/src/test/examples/repeatedproto/Repeatedproto.java
@@ -0,0 +1,22 @@
+// 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
new file mode 100644
index 0000000..3d02352
--- /dev/null
+++ b/src/test/examples/repeatedproto/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..7414e6f
--- /dev/null
+++ b/src/test/examples/repeatedproto/repeated.proto
@@ -0,0 +1,20 @@
+// 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
new file mode 100644
index 0000000..7da7881
--- /dev/null
+++ b/src/test/examples/repeatedproto/repeated_three.proto
@@ -0,0 +1,15 @@
+// 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
new file mode 100644
index 0000000..d07ce8d
--- /dev/null
+++ b/src/test/examples/simpleproto1/Simpleproto.java
@@ -0,0 +1,56 @@
+// 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
new file mode 100644
index 0000000..3c3c33f
--- /dev/null
+++ b/src/test/examples/simpleproto1/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..f4e1be4
--- /dev/null
+++ b/src/test/examples/simpleproto1/simple.proto
@@ -0,0 +1,14 @@
+// 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
new file mode 100644
index 0000000..f333d72
--- /dev/null
+++ b/src/test/examples/simpleproto2/Simpleproto.java
@@ -0,0 +1,30 @@
+// 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
new file mode 100644
index 0000000..8f9c93e
--- /dev/null
+++ b/src/test/examples/simpleproto2/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..b9173e9
--- /dev/null
+++ b/src/test/examples/simpleproto2/simple.proto
@@ -0,0 +1,14 @@
+// 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
new file mode 100644
index 0000000..2cdbae8
--- /dev/null
+++ b/src/test/examples/simpleproto3/Simpleproto.java
@@ -0,0 +1,65 @@
+// 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
new file mode 100644
index 0000000..186e9f8
--- /dev/null
+++ b/src/test/examples/simpleproto3/keep-rules.txt
@@ -0,0 +1,12 @@
+# 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
new file mode 100644
index 0000000..87512d1
--- /dev/null
+++ b/src/test/examples/simpleproto3/simple.proto
@@ -0,0 +1,14 @@
+// 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/internal/R8GMSCoreV10DeployJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
index afa437e..ca713fd 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10DeployJarVerificationTest.java
@@ -9,27 +9,22 @@
 import com.android.tools.r8.R8RunArtTestsTest.CompilerUnderTest;
 import com.android.tools.r8.shaking.ProguardRuleParserException;
 import com.android.tools.r8.utils.AndroidApp;
-import com.android.tools.r8.utils.InternalOptions;
 import java.io.IOException;
 import java.util.concurrent.ExecutionException;
 import org.junit.Test;
 
 public class R8GMSCoreV10DeployJarVerificationTest extends GMSCoreDeployJarVerificationTest {
 
-  private void configureDeterministic(InternalOptions options) {
-    options.removeSwitchMaps = false;
-  }
-
   @Test
   public void buildFromDeployJar()
       // TODO(tamaskenez): set hasReference = true when we have the noshrink file for V10
       throws ExecutionException, IOException, ProguardRuleParserException, CompilationException {
     AndroidApp app1 = buildFromDeployJar(
         CompilerUnderTest.R8, CompilationMode.RELEASE,
-        GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false, this::configureDeterministic);
+        GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false);
     AndroidApp app2 = buildFromDeployJar(
         CompilerUnderTest.R8, CompilationMode.RELEASE,
-        GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false, this::configureDeterministic);
+        GMSCoreCompilationTestBase.GMSCORE_V10_DIR, false);
 
     // Verify that the result of the two compilations was the same.
     assertIdenticalApplications(app1, app2);
diff --git a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
index 2640f13..766de9d 100644
--- a/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
+++ b/src/test/java/com/android/tools/r8/internal/R8GMSCoreV10TreeShakeJarVerificationTest.java
@@ -20,7 +20,6 @@
 
   private void configureDeterministic(InternalOptions options) {
     options.skipMinification = true;
-    options.removeSwitchMaps = false;
   }
 
   @Test
diff --git a/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java b/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java
index 646a481..4e8881a 100644
--- a/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java
+++ b/src/test/java/com/android/tools/r8/rewrite/switchmaps/RewriteSwitchMapsTest.java
@@ -13,7 +13,6 @@
 import java.nio.file.Paths;
 import java.util.concurrent.ExecutionException;
 import org.junit.Assert;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class RewriteSwitchMapsTest extends TestBase {
@@ -24,8 +23,6 @@
       "-keep class switchmaps.Switches { public static void main(...); } " +
           "-dontobfuscate";
 
-  // TODO(sgjesse): Re-enable this when the switch-map extraction has been fixed.
-  @Ignore
   @Test
   public void checkSwitchMapsRemoved()
       throws IOException, ProguardRuleParserException, ExecutionException, CompilationException {
diff --git a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
index 3435577..99be74a 100644
--- a/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/TreeShakingTest.java
@@ -372,6 +372,80 @@
         subclass.method("double", "anotherMethod", ImmutableList.of("double")).isPresent());
   }
 
+  private static void simpleproto1UnusedFieldIsGone(DexInspector inspector) {
+    ClassSubject protoClass = inspector.clazz("simpleproto1.GeneratedSimpleProto$Simple");
+    Assert.assertTrue(protoClass.isPresent());
+    Assert.assertFalse(protoClass.field("boolean", "other_").isPresent());
+  }
+
+  private static void simpleproto2UnusedFieldsAreGone(DexInspector 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());
+  }
+
+  private static void nestedproto1UnusedFieldsAreGone(DexInspector 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());
+  }
+
+  private static void nestedproto2UnusedFieldsAreGone(DexInspector 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());
+  }
+
+
+  private static void enumprotoUnusedFieldsAreGone(DexInspector 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());
+  }
+
+  private static void repeatedUnusedFieldsAreGone(DexInspector 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());
+  }
+
+  private static void oneofprotoUnusedFieldsAreGone(DexInspector 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());
+  }
+
   private static List<String> names =
       ImmutableList.of("pqr", "vw$", "abc", "def", "stu", "ghi", "jkl", "ea", "xyz_", "mno");
 
@@ -557,7 +631,15 @@
             "assumevalues5",
             "annotationremoval",
             "memberrebinding2",
-            "memberrebinding3");
+            "memberrebinding3",
+            "simpleproto1",
+            "simpleproto2",
+            "simpleproto3",
+            "nestedproto1",
+            "nestedproto2",
+            "enumproto",
+            "repeatedproto",
+            "oneofproto");
 
     // Keys can be the name of the test or the name of the test followed by a colon and the name
     // of the keep file.
@@ -614,6 +696,20 @@
     inspections
         .put("annotationremoval:keep-rules-keep-innerannotation.txt",
             TreeShakingTest::annotationRemovalHasAllInnerClassAnnotations);
+    inspections
+        .put("simpleproto1:keep-rules.txt", TreeShakingTest::simpleproto1UnusedFieldIsGone);
+    inspections
+        .put("simpleproto2:keep-rules.txt", TreeShakingTest::simpleproto2UnusedFieldsAreGone);
+    inspections
+        .put("nestedproto1:keep-rules.txt", TreeShakingTest::nestedproto1UnusedFieldsAreGone);
+    inspections
+        .put("nestedproto2:keep-rules.txt", TreeShakingTest::nestedproto2UnusedFieldsAreGone);
+    inspections
+        .put("enumproto:keep-rules.txt", TreeShakingTest::enumprotoUnusedFieldsAreGone);
+    inspections
+        .put("repeatedproto:keep-rules.txt", TreeShakingTest::repeatedUnusedFieldsAreGone);
+    inspections
+        .put("oneofproto:keep-rules.txt", TreeShakingTest::oneofprotoUnusedFieldsAreGone);
 
     // Keys can be the name of the test or the name of the test followed by a colon and the name
     // of the keep file.
@@ -779,7 +875,7 @@
           Collections.singletonList(generated.toString()), mainClass, extraArtArgs, null);
       outputComparator.accept(output1, output2);
     } else {
-      ToolHelper.checkArtOutputIdentical(Collections.singletonList(originalDex),
+      String output = ToolHelper.checkArtOutputIdentical(Collections.singletonList(originalDex),
           Collections.singletonList(generated.toString()), mainClass,
           extraArtArgs, null);
     }
