diff --git a/src/main/java/com/android/tools/r8/D8CommandParser.java b/src/main/java/com/android/tools/r8/D8CommandParser.java
index 9e5d36a..93c0126 100644
--- a/src/main/java/com/android/tools/r8/D8CommandParser.java
+++ b/src/main/java/com/android/tools/r8/D8CommandParser.java
@@ -3,16 +3,79 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8;
 
+import static com.android.tools.r8.utils.FileUtils.isArchive;
+
 import com.android.tools.r8.errors.CompilationError;
 import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.origin.PathOrigin;
+import com.android.tools.r8.utils.ExceptionDiagnostic;
 import com.android.tools.r8.utils.FlagFile;
 import com.android.tools.r8.utils.StringDiagnostic;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
 
 public class D8CommandParser extends BaseCompilerCommandParser {
 
+  static class OrderedClassFileResourceProvider implements ClassFileResourceProvider {
+    static class Builder {
+      private final ImmutableList.Builder<ClassFileResourceProvider> builder =
+          ImmutableList.builder();
+      boolean empty = true;
+
+      OrderedClassFileResourceProvider build() {
+        return new OrderedClassFileResourceProvider(builder.build());
+      }
+
+      Builder addClassFileResourceProvider(ClassFileResourceProvider provider) {
+        builder.add(provider);
+        empty = false;
+        return this;
+      }
+
+      boolean isEmpty() {
+        return empty;
+      }
+    }
+
+    final List<ClassFileResourceProvider> providers;
+    final Set<String> descriptors = Sets.newHashSet();
+
+    private OrderedClassFileResourceProvider(ImmutableList<ClassFileResourceProvider> providers) {
+      this.providers = providers;
+      // Collect all descriptors that can be provided.
+      this.providers.forEach(provider -> this.descriptors.addAll(provider.getClassDescriptors()));
+    }
+
+    static Builder builder() {
+      return new Builder();
+    }
+
+    @Override
+    public Set<String> getClassDescriptors() {
+      return descriptors;
+    }
+
+    @Override
+    public ProgramResource getProgramResource(String descriptor) {
+      // Search the providers in order. Return the program resource from the first provider that
+      // can provide it.
+      for (ClassFileResourceProvider provider : providers) {
+        if (provider.getClassDescriptors().contains(descriptor)) {
+          return provider.getProgramResource(descriptor);
+        }
+      }
+      return null;
+    }
+  }
+
   public static void main(String[] args) throws CompilationFailedException {
     D8Command command = parse(args, Origin.root()).build();
     if (command.isPrintHelp()) {
@@ -76,6 +139,8 @@
     Path outputPath = null;
     OutputMode outputMode = null;
     boolean hasDefinedApiLevel = false;
+    OrderedClassFileResourceProvider.Builder classpathBuilder =
+        OrderedClassFileResourceProvider.builder();
     String[] expandedArgs = FlagFile.expandFlagFiles(args, builder);
     try {
       for (int i = 0; i < expandedArgs.length; i++) {
@@ -115,7 +180,22 @@
         } else if (arg.equals("--lib")) {
           builder.addLibraryFiles(Paths.get(expandedArgs[++i]));
         } else if (arg.equals("--classpath")) {
-          builder.addClasspathFiles(Paths.get(expandedArgs[++i]));
+          Path file = Paths.get(expandedArgs[++i]);
+          try {
+            if (!Files.exists(file)) {
+              throw new NoSuchFileException(file.toString());
+            }
+            if (isArchive(file)) {
+              classpathBuilder.addClassFileResourceProvider(new ArchiveClassFileProvider(file));
+            } else if (Files.isDirectory(file)) {
+              classpathBuilder.addClassFileResourceProvider(
+                  DirectoryClassFileProvider.fromDirectory(file));
+            } else {
+              throw new CompilationError("Unsupported classpath file type", new PathOrigin(file));
+            }
+          } catch (IOException e) {
+            builder.error(new ExceptionDiagnostic(e, new PathOrigin(file)));
+          }
         } else if (arg.equals("--main-dex-list")) {
           builder.addMainDexListFiles(Paths.get(expandedArgs[++i]));
         } else if (arg.equals("--optimize-multidex-for-linearalloc")) {
@@ -140,6 +220,9 @@
           builder.addProgramFiles(Paths.get(arg));
         }
       }
+      if (!classpathBuilder.isEmpty()) {
+        builder.addClasspathResourceProvider(classpathBuilder.build());
+      }
       if (compilationMode != null) {
         builder.setMode(compilationMode);
       }
diff --git a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
index 56e381b..e3ec746 100644
--- a/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
+++ b/src/main/java/com/android/tools/r8/naming/ClassNameMinifier.java
@@ -8,9 +8,11 @@
 import static com.android.tools.r8.utils.DescriptorUtils.getPackageBinaryNameFromJavaType;
 
 import com.android.tools.r8.graph.DexAnnotation;
+import com.android.tools.r8.graph.DexAnnotationSet;
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexEncodedField;
 import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexItem;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexProto;
 import com.android.tools.r8.graph.DexString;
@@ -18,16 +20,20 @@
 import com.android.tools.r8.graph.InnerClassAttribute;
 import com.android.tools.r8.naming.signature.GenericSignatureAction;
 import com.android.tools.r8.naming.signature.GenericSignatureParser;
+import com.android.tools.r8.origin.Origin;
 import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
 import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
+import com.android.tools.r8.utils.Reporter;
+import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.StringUtils;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+import java.lang.reflect.GenericSignatureFormatError;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -40,6 +46,7 @@
 
   private final AppInfoWithLiveness appInfo;
   private final RootSet rootSet;
+  private final Reporter reporter;
   private final PackageObfuscationMode packageObfuscationMode;
   private final boolean isAccessModificationAllowed;
   private final Set<String> noObfuscationPrefixes = Sets.newHashSet();
@@ -66,6 +73,7 @@
       InternalOptions options) {
     this.appInfo = appInfo;
     this.rootSet = rootSet;
+    this.reporter = options.reporter;
     this.packageObfuscationMode = options.proguardConfiguration.getPackageObfuscationMode();
     this.isAccessModificationAllowed = options.proguardConfiguration.isAccessModificationAllowed();
     this.packageDictionary = options.proguardConfiguration.getPackageObfuscationDictionary();
@@ -152,27 +160,75 @@
     }
   }
 
+  private void parseError(DexItem item, Origin origin, GenericSignatureFormatError e) {
+    StringBuilder message = new StringBuilder("Invalid class signature for ");
+    if (item instanceof DexClass) {
+      message.append("class ");
+      message.append(((DexClass) item).getType().toSourceString());
+    } else if (item instanceof DexEncodedField) {
+      message.append("field ");
+      message.append(item.toSourceString());
+    } else {
+      assert item instanceof DexEncodedMethod;
+      message.append("method ");
+      message.append(item.toSourceString());
+    }
+    message.append(".\n");
+    message.append(e.getMessage());
+    reporter.warning(new StringDiagnostic(message.toString(), origin));
+  }
+
   private void renameTypesInGenericSignatures() {
     for (DexClass clazz : appInfo.classes()) {
-      rewriteGenericSignatures(clazz.annotations.annotations,
-          genericSignatureParser::parseClassSignature);
+      clazz.annotations = rewriteGenericSignatures(clazz.annotations,
+          genericSignatureParser::parseClassSignature,
+          e -> parseError(clazz, clazz.getOrigin(), e));
       clazz.forEachField(field -> rewriteGenericSignatures(
-          field.annotations.annotations, genericSignatureParser::parseFieldSignature));
+          field.annotations, genericSignatureParser::parseFieldSignature,
+          e -> parseError(field, clazz.getOrigin(), e)));
       clazz.forEachMethod(method -> rewriteGenericSignatures(
-          method.annotations.annotations, genericSignatureParser::parseMethodSignature));
+          method.annotations, genericSignatureParser::parseMethodSignature,
+          e -> parseError(method, clazz.getOrigin(), e)));
     }
   }
 
-  private void rewriteGenericSignatures(DexAnnotation[] annotations, Consumer<String> parser) {
-    for (int i = 0; i < annotations.length; i++) {
-      DexAnnotation annotation = annotations[i];
+  private DexAnnotationSet rewriteGenericSignatures(
+      DexAnnotationSet annotations,
+      Consumer<String> parser,
+      Consumer<GenericSignatureFormatError> parseError) {
+    // There can be no more than one signature annotation in an annotation set.
+    final int VALID = -1;
+    int invalid = VALID;
+    for (int i = 0; i < annotations.annotations.length && invalid == VALID; i++) {
+      DexAnnotation annotation = annotations.annotations[i];
       if (DexAnnotation.isSignatureAnnotation(annotation, appInfo.dexItemFactory)) {
-        parser.accept(DexAnnotation.getSignature(annotation));
-        annotations[i] = DexAnnotation.createSignatureAnnotation(
-            genericSignatureRewriter.getRenamedSignature(),
-            appInfo.dexItemFactory);
+        try {
+          parser.accept(DexAnnotation.getSignature(annotation));
+          annotations.annotations[i] = DexAnnotation.createSignatureAnnotation(
+              genericSignatureRewriter.getRenamedSignature(),
+              appInfo.dexItemFactory);
+        } catch (GenericSignatureFormatError e) {
+          parseError.accept(e);
+          invalid = i;
+        }
       }
     }
+
+    // Return the rewritten signatures if it was valid and could be rewritten.
+    if (invalid == VALID) {
+      return annotations;
+    }
+    // Remove invalid signature if found.
+    DexAnnotation[] prunedAnnotations =
+        new DexAnnotation[annotations.annotations.length - 1];
+    int dest = 0;
+    for (int i = 0; i < annotations.annotations.length; i++) {
+      if (i != invalid) {
+        prunedAnnotations[dest++] = annotations.annotations[i];
+      }
+    }
+    assert dest == prunedAnnotations.length;
+    return new DexAnnotationSet(prunedAnnotations);
   }
 
   /**
@@ -453,7 +509,6 @@
       String renamed =
           getClassBinaryNameFromDescriptor(
               renaming.getOrDefault(type, type.descriptor).toString());
-      assert renamed.startsWith(enclosingRenamedBinaryName + Minifier.INNER_CLASS_SEPARATOR);
       String outName = renamed.substring(enclosingRenamedBinaryName.length() + 1);
       renamedSignature.append(outName);
       return type;
diff --git a/src/test/java/com/android/tools/r8/D8CommandTest.java b/src/test/java/com/android/tools/r8/D8CommandTest.java
index 1b846a5..0c278f7 100644
--- a/src/test/java/com/android/tools/r8/D8CommandTest.java
+++ b/src/test/java/com/android/tools/r8/D8CommandTest.java
@@ -6,13 +6,13 @@
 import static com.android.tools.r8.R8CommandTest.getOutputPath;
 import static com.android.tools.r8.ToolHelper.EXAMPLES_BUILD_DIR;
 import static com.android.tools.r8.utils.FileUtils.JAR_EXTENSION;
-import static java.nio.file.StandardOpenOption.CREATE_NEW;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertTrue;
 
 import com.android.sdklib.AndroidVersion;
+import com.android.tools.r8.D8CommandParser.OrderedClassFileResourceProvider;
 import com.android.tools.r8.ToolHelper.ProcessResult;
 import com.android.tools.r8.dex.Marker;
 import com.android.tools.r8.dex.Marker.Tool;
@@ -24,7 +24,6 @@
 import com.google.common.collect.ImmutableList;
 import java.io.IOException;
 import java.nio.file.Files;
-import java.nio.file.OpenOption;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.List;
@@ -263,13 +262,37 @@
         tmpClassesDir.toString());
     AndroidApp inputApp = ToolHelper.getApp(command);
     assertEquals(1, inputApp.getClasspathResourceProviders().size());
+    OrderedClassFileResourceProvider classpathProvider =
+        (OrderedClassFileResourceProvider) inputApp.getClasspathResourceProviders().get(0);
+    assertEquals(1, classpathProvider.providers.size());
     assertTrue(Files.isSameFile(tmpClassesDir,
-        ((DirectoryClassFileProvider) inputApp.getClasspathResourceProviders().get(0)).getRoot()));
+        ((DirectoryClassFileProvider) classpathProvider.providers.get(0)).getRoot()));
     assertEquals(1, inputApp.getLibraryResourceProviders().size());
     assertTrue(Files.isSameFile(tmpClassesDir,
         ((DirectoryClassFileProvider) inputApp.getLibraryResourceProviders().get(0)).getRoot()));
   }
 
+  @Test
+  public void folderClasspathMultiple() throws Throwable {
+    Path inputFile =
+        Paths.get(ToolHelper.EXAMPLES_ANDROID_N_BUILD_DIR, "interfacemethods" + JAR_EXTENSION);
+    Path tmpClassesDir1 = temp.newFolder().toPath();
+    Path tmpClassesDir2 = temp.newFolder().toPath();
+    ZipUtils.unzip(inputFile.toString(), tmpClassesDir1.toFile());
+    ZipUtils.unzip(inputFile.toString(), tmpClassesDir2.toFile());
+    D8Command command = parse("--classpath", tmpClassesDir1.toString(), "--classpath",
+        tmpClassesDir2.toString());
+    AndroidApp inputApp = ToolHelper.getApp(command);
+    assertEquals(1, inputApp.getClasspathResourceProviders().size());
+    OrderedClassFileResourceProvider classpathProvider =
+        (OrderedClassFileResourceProvider) inputApp.getClasspathResourceProviders().get(0);
+    assertEquals(2, classpathProvider.providers.size());
+    assertTrue(Files.isSameFile(tmpClassesDir1,
+        ((DirectoryClassFileProvider) classpathProvider.providers.get(0)).getRoot()));
+    assertTrue(Files.isSameFile(tmpClassesDir2,
+        ((DirectoryClassFileProvider) classpathProvider.providers.get(1)).getRoot()));
+  }
+
   @Test(expected = CompilationFailedException.class)
   public void classFolderProgram() throws Throwable {
     Path inputFile =
diff --git a/src/test/java/com/android/tools/r8/OrderedClassFileResourceProviderTest.java b/src/test/java/com/android/tools/r8/OrderedClassFileResourceProviderTest.java
new file mode 100644
index 0000000..dc497c4
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/OrderedClassFileResourceProviderTest.java
@@ -0,0 +1,113 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8;
+
+import static org.junit.Assert.assertEquals;
+
+import com.android.tools.r8.D8CommandParser.OrderedClassFileResourceProvider;
+import com.android.tools.r8.origin.Origin;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Set;
+import org.junit.Test;
+
+public class OrderedClassFileResourceProviderTest extends TestBase {
+  class SimpleClassFileResourceProvider implements ClassFileResourceProvider {
+
+    private final Set<String> descriptors;
+    private final ProgramResource fixedProgramResource;
+
+    SimpleClassFileResourceProvider(int id, Set<String> descriptors) {
+      this.descriptors = descriptors;
+      this.fixedProgramResource = new SimpleProgramResource(id);
+    }
+
+    @Override
+    public Set<String> getClassDescriptors() {
+      return descriptors;
+    }
+
+    @Override
+    public ProgramResource getProgramResource(String descriptor) {
+      return fixedProgramResource;
+    }
+  }
+
+  class SimpleProgramResource implements ProgramResource {
+
+    private final Origin origin;
+
+    SimpleProgramResource(int id) {
+      origin = new SimpleOrigin(id);
+    }
+
+    @Override
+    public Kind getKind() {
+      return null;
+    }
+
+    @Override
+    public InputStream getByteStream() throws ResourceException {
+      return null;
+    }
+
+    @Override
+    public Set<String> getClassDescriptors() {
+      return null;
+    }
+
+    @Override
+    public Origin getOrigin() {
+      return origin;
+    }
+  }
+
+  public class SimpleOrigin extends Origin {
+
+    private final int id;
+
+    private SimpleOrigin(int index) {
+      super(root());
+      this.id = index;
+    }
+
+    int getId() {
+      return id;
+    }
+
+    @Override
+    public String part() {
+      return "Test";
+    }
+  }
+
+  @Test
+  public void test() {
+    OrderedClassFileResourceProvider.Builder builder = OrderedClassFileResourceProvider.builder();
+    builder.addClassFileResourceProvider(new SimpleClassFileResourceProvider(1, ImmutableSet.of(
+        "L/a/a/a", "L/a/a/b", "L/a/a/c"
+    )));
+    builder.addClassFileResourceProvider(new SimpleClassFileResourceProvider(2, ImmutableSet.of(
+        "L/a/a/b", "L/a/a/c", "L/a/a/d"
+        )));
+    ClassFileResourceProvider provider = builder.build();
+    assertEquals(
+        ImmutableSet.of("L/a/a/a", "L/a/a/b", "L/a/a/c", "L/a/a/d"),
+        provider.getClassDescriptors());
+
+    Map<String, Integer> expectations = ImmutableMap.of(
+        "L/a/a/a", 1,
+        "L/a/a/b", 1,
+        "L/a/a/c", 1,
+        "L/a/a/d", 2
+    );
+    expectations.forEach((descriptor, id) ->
+        assertEquals(
+            (int) id,
+            ((SimpleOrigin) provider.getProgramResource(descriptor).getOrigin()).getId()));
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java b/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
index 751ac83..1d1604b 100644
--- a/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
+++ b/src/test/java/com/android/tools/r8/naming/GenericSignatureParserTest.java
@@ -82,7 +82,7 @@
     parseSimpleError(
         GenericSignatureParser::parseClassSignature,
         e -> assertTrue(e.getMessage().startsWith("Expected L at position 1")));
-    // TODO(sgjesse): The position 2 reported here is onr off.
+    // TODO(sgjesse): The position 2 reported here is one off.
     parseSimpleError(
         GenericSignatureParser::parseFieldSignature,
         e -> assertTrue(e.getMessage().startsWith("Expected L, [ or T at position 2")));
@@ -104,7 +104,7 @@
           fail("Succesfully parsed " + signature.substring(0, i) + " (position " + i +")");
         }
       } catch (GenericSignatureFormatError e) {
-        assertTrue("" + i + " Was: " + e.getMessage(), e.getMessage().contains("at position " + (i + 1)));
+        assertTrue(e.getMessage().contains("at position " + (i + 1)));
       }
     }
   }
diff --git a/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
new file mode 100644
index 0000000..68cd36f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/naming/MinifierClassSignatureTest.java
@@ -0,0 +1,496 @@
+// Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.naming;
+
+import static com.android.tools.r8.utils.DexInspectorMatchers.isPresent;
+import static com.android.tools.r8.utils.DexInspectorMatchers.isRenamed;
+import static org.hamcrest.CoreMatchers.not;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertThat;
+import static org.objectweb.asm.Opcodes.ACC_FINAL;
+import static org.objectweb.asm.Opcodes.ACC_SUPER;
+import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
+import static org.objectweb.asm.Opcodes.ALOAD;
+import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static org.objectweb.asm.Opcodes.PUTFIELD;
+import static org.objectweb.asm.Opcodes.RETURN;
+import static org.objectweb.asm.Opcodes.V1_8;
+
+import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DiagnosticsChecker;
+import com.android.tools.r8.R8Command;
+import com.android.tools.r8.StringConsumer;
+import com.android.tools.r8.TestBase;
+import com.android.tools.r8.ToolHelper;
+import com.android.tools.r8.graph.invokesuper.Consumer;
+import com.android.tools.r8.origin.Origin;
+import com.android.tools.r8.utils.DexInspector;
+import com.android.tools.r8.utils.DexInspector.ClassSubject;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableMap;
+import org.junit.Test;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.FieldVisitor;
+import org.objectweb.asm.MethodVisitor;
+
+public class MinifierClassSignatureTest extends TestBase {
+  /*
+
+  class Simple {
+  }
+  class Base<T> {
+  }
+  class Outer<T> {
+    class Inner {
+      class InnerInner {
+      }
+      class ExtendsInnerInner extends InnerInner {
+      }
+    }
+    class ExtendsInner extends Inner {
+    }
+  }
+
+  */
+
+  String baseSignature = "<T:Ljava/lang/Object;>Ljava/lang/Object;";
+  String outerSignature = "<T:Ljava/lang/Object;>Ljava/lang/Object;";
+  String extendsInnerSignature = "LOuter<TT;>.Inner;";
+  String extendsInnerInnerSignature = "LOuter<TT;>.Inner.InnerInner;";
+
+  private byte[] dumpSimple(String classSignature) throws Exception {
+
+    ClassWriter cw = new ClassWriter(0);
+    MethodVisitor mv;
+
+    String signature = classSignature;
+    cw.visit(V1_8, ACC_SUPER, "Simple", signature, "java/lang/Object", null);
+
+    {
+      mv = cw.visitMethod(0, "<init>", "()V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private byte[] dumpBase(String classSignature) throws Exception {
+
+    final String javacClassSignature = baseSignature;
+    ClassWriter cw = new ClassWriter(0);
+    MethodVisitor mv;
+
+    String signature = classSignature != null ? classSignature : javacClassSignature;
+    cw.visit(V1_8, ACC_SUPER, "Base", signature, "java/lang/Object", null);
+
+    {
+      mv = cw.visitMethod(0, "<init>", "()V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+
+  private byte[] dumpOuter(String classSignature) {
+
+    final String javacClassSignature = outerSignature;
+    ClassWriter cw = new ClassWriter(0);
+    MethodVisitor mv;
+
+    String signature = classSignature != null ? classSignature : javacClassSignature;
+    cw.visit(V1_8, ACC_SUPER, "Outer", signature, "java/lang/Object", null);
+
+    cw.visitInnerClass("Outer$ExtendsInner", "Outer", "ExtendsInner", 0);
+
+    cw.visitInnerClass("Outer$Inner", "Outer", "Inner", 0);
+
+    {
+      mv = cw.visitMethod(0, "<init>", "()V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(1, 1);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private byte[] dumpInner(String classSignature) {
+
+    final String javacClassSignature = null;
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+
+    String signature = classSignature != null ? classSignature : javacClassSignature;
+    cw.visit(V1_8, ACC_SUPER, "Outer$Inner", signature, "java/lang/Object", null);
+
+    cw.visitInnerClass("Outer$Inner", "Outer", "Inner", 0);
+
+    cw.visitInnerClass("Outer$Inner$ExtendsInnerInner", "Outer$Inner", "ExtendsInnerInner", 0);
+
+    cw.visitInnerClass("Outer$Inner$InnerInner", "Outer$Inner", "InnerInner", 0);
+
+    {
+      fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "LOuter;", null, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "(LOuter;)V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitFieldInsn(PUTFIELD, "Outer$Inner", "this$0", "LOuter;");
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 2);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private byte[] dumpExtendsInner(String classSignature) throws Exception {
+
+    final String javacClassSignature = extendsInnerSignature;
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+
+    String signature = classSignature != null ? classSignature : javacClassSignature;
+    cw.visit(V1_8, ACC_SUPER, "Outer$ExtendsInner", signature, "Outer$Inner", null);
+
+    cw.visitInnerClass("Outer$Inner", "Outer", "Inner", 0);
+
+    cw.visitInnerClass("Outer$ExtendsInner", "Outer", "ExtendsInner", 0);
+
+    {
+      fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$0", "LOuter;", null, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "(LOuter;)V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitFieldInsn(PUTFIELD, "Outer$ExtendsInner", "this$0", "LOuter;");
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitMethodInsn(INVOKESPECIAL, "Outer$Inner", "<init>", "(LOuter;)V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 2);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private byte[] dumpInnerInner(String classSignature) throws Exception {
+
+    final String javacClassSignature = null;
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+
+    String signature = classSignature != null ? classSignature : javacClassSignature;
+    cw.visit(V1_8, ACC_SUPER, "Outer$Inner$InnerInner", signature, "java/lang/Object", null);
+
+    cw.visitInnerClass("Outer$Inner", "Outer", "Inner", 0);
+
+    cw.visitInnerClass("Outer$Inner$InnerInner", "Outer$Inner", "InnerInner", 0);
+
+    {
+      fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$1", "LOuter$Inner;", null, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "(LOuter$Inner;)V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitFieldInsn(PUTFIELD, "Outer$Inner$InnerInner", "this$1", "LOuter$Inner;");
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 2);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  private byte[] dumpExtendsInnerInner(String classSignature) throws Exception {
+
+    final String javacClassSignature = extendsInnerInnerSignature;
+    ClassWriter cw = new ClassWriter(0);
+    FieldVisitor fv;
+    MethodVisitor mv;
+
+    String signature = classSignature != null ? classSignature : javacClassSignature;
+    cw.visit(V1_8, ACC_SUPER, "Outer$Inner$ExtendsInnerInner", signature, "Outer$Inner$InnerInner",
+        null);
+
+    cw.visitInnerClass("Outer$Inner", "Outer", "Inner", 0);
+
+    cw.visitInnerClass("Outer$Inner$InnerInner", "Outer$Inner", "InnerInner", 0);
+
+    cw.visitInnerClass("Outer$Inner$ExtendsInnerInner", "Outer$Inner", "ExtendsInnerInner", 0);
+
+    {
+      fv = cw.visitField(ACC_FINAL + ACC_SYNTHETIC, "this$1", "LOuter$Inner;", null, null);
+      fv.visitEnd();
+    }
+    {
+      mv = cw.visitMethod(0, "<init>", "(LOuter$Inner;)V", null, null);
+      mv.visitCode();
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitFieldInsn(PUTFIELD, "Outer$Inner$ExtendsInnerInner", "this$1", "LOuter$Inner;");
+      mv.visitVarInsn(ALOAD, 0);
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitMethodInsn(INVOKESPECIAL, "Outer$Inner$InnerInner", "<init>", "(LOuter$Inner;)V",
+          false);
+      mv.visitInsn(RETURN);
+      mv.visitMaxs(2, 2);
+      mv.visitEnd();
+    }
+    cw.visitEnd();
+
+    return cw.toByteArray();
+  }
+
+  public void runTest(
+      ImmutableMap<String, String> signatures,
+      Consumer<DiagnosticsChecker> diagnostics,
+      Consumer<DexInspector> inspect)
+      throws Exception {
+    DiagnosticsChecker checker = new DiagnosticsChecker();
+    DexInspector inspector = new DexInspector(
+      ToolHelper.runR8(R8Command.builder(checker)
+          .addClassProgramData(dumpSimple(signatures.get("Simple")), Origin.unknown())
+          .addClassProgramData(dumpBase(signatures.get("Base")), Origin.unknown())
+          .addClassProgramData(dumpOuter(signatures.get("Outer")), Origin.unknown())
+          .addClassProgramData(dumpInner(signatures.get("Outer$Inner")), Origin.unknown())
+          .addClassProgramData(
+              dumpExtendsInner(signatures.get("Outer$ExtendsInner")), Origin.unknown())
+          .addClassProgramData(
+              dumpInnerInner(signatures.get("Outer$Inner$InnerInner")), Origin.unknown())
+          .addClassProgramData(
+              dumpExtendsInnerInner(
+                  signatures.get("Outer$Inner$ExtendsInnerInner")), Origin.unknown())
+          .addProguardConfiguration(ImmutableList.of(
+              "-keepattributes InnerClasses,EnclosingMethod,Signature",
+              "-keep,allowobfuscation class **"
+          ), Origin.unknown())
+          .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+          .setProguardMapConsumer(StringConsumer.emptyConsumer())
+          .build()));
+    // All classes are kept, and renamed.
+    assertThat(inspector.clazz("Simple"), isRenamed());
+    assertThat(inspector.clazz("Base"), isRenamed());
+    assertThat(inspector.clazz("Outer"), isRenamed());
+    assertThat(inspector.clazz("Outer$Inner"), isRenamed());
+    assertThat(inspector.clazz("Outer$ExtendsInner"), isRenamed());
+    assertThat(inspector.clazz("Outer$Inner$InnerInner"), isRenamed());
+    assertThat(inspector.clazz("Outer$Inner$ExtendsInnerInner"), isRenamed());
+
+    // Test that classes with have their original signature if the default was provided.
+    if (!signatures.containsKey("Simple")) {
+      assertNull(inspector.clazz("Simple").getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("Base")) {
+      assertEquals(baseSignature, inspector.clazz("Base").getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("Outer")) {
+      assertEquals(outerSignature, inspector.clazz("Outer").getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("Outer$Inner")) {
+      assertNull(inspector.clazz("Outer$Inner").getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("Outer$ExtendsInner")) {
+      assertEquals(extendsInnerSignature,
+          inspector.clazz("Outer$ExtendsInner").getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("Outer$Inner$InnerInner")) {
+      assertNull(inspector.clazz("Outer$Inner$InnerInner").getOriginalSignatureAttribute());
+    }
+    if (!signatures.containsKey("Outer$Inner$ExtendsInnerInner")) {
+      assertEquals(extendsInnerInnerSignature,
+          inspector.clazz("Outer$Inner$ExtendsInnerInner").getOriginalSignatureAttribute());
+    }
+
+    diagnostics.accept(checker);
+    inspect.accept(inspector);
+  }
+
+  private void testSingleClass(String name, String signature,
+      Consumer<DiagnosticsChecker> diagnostics,
+      Consumer<DexInspector> inspector)
+      throws Exception {
+    ImmutableMap<String, String> signatures = ImmutableMap.of(name, signature);
+    runTest(signatures, diagnostics, inspector);
+  }
+
+  private void isOriginUnknown(Origin origin) {
+    assertSame(Origin.unknown(), origin);
+  }
+
+  private void noWarnings(DiagnosticsChecker checker) {
+    assertEquals(0, checker.warnings.size());
+  }
+
+  private void noInspection(DexInspector inspector) {
+  }
+
+  private void noSignatureAttribute(ClassSubject clazz) {
+    assertNull(clazz.getFinalSignatureAttribute());
+    assertNull(clazz.getOriginalSignatureAttribute());
+  }
+
+  @Test
+  public void originalJavacSignatures() throws Exception {
+    // Test using the signatures generated by javac.
+    runTest(ImmutableMap.of(), this::noWarnings, this::noInspection);
+  }
+
+  @Test
+  public void classSignature_empty() throws Exception {
+    testSingleClass("Outer", "", this::noWarnings, inspector -> {
+      ClassSubject outer = inspector.clazz("Outer");
+      assertNull(outer.getFinalSignatureAttribute());
+      assertNull(outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureOuter_valid() throws Exception {
+    // class Outer<T extends Simple> extends Base<T>
+    String signature = "<T:LSimple;>LBase<TT;>;";
+    testSingleClass("Outer", signature, this::noWarnings, inspector -> {
+      ClassSubject outer = inspector.clazz("Outer");
+      ClassSubject simple = inspector.clazz("Simple");
+      ClassSubject base = inspector.clazz("Base");
+      String baseDescriptorWithoutSemicolon =
+          base.getFinalDescriptor().substring(0, base.getFinalDescriptor().length() - 1);
+      String minifiedSignature =
+          "<T:" +  simple.getFinalDescriptor() + ">" + baseDescriptorWithoutSemicolon + "<TT;>;";
+      assertEquals(minifiedSignature, outer.getFinalSignatureAttribute());
+      assertEquals(signature, outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureExtendsInner_valid() throws Exception {
+    String signature = "LOuter<TT;>.Inner;";
+    testSingleClass("Outer$ExtendsInner", signature, this::noWarnings, inspector -> {
+      ClassSubject extendsInner = inspector.clazz("Outer$ExtendsInner");
+      ClassSubject outer = inspector.clazz("Outer");
+      ClassSubject inner = inspector.clazz("Outer$Inner");
+      String outerDescriptorWithoutSemicolon =
+          outer.getFinalDescriptor().substring(0, outer.getFinalDescriptor().length() - 1);
+      String innerFinalDescriptor = inner.getFinalDescriptor();
+      String innerLastPart =
+          innerFinalDescriptor.substring(innerFinalDescriptor.indexOf("$") + 1);
+      String minifiedSignature = outerDescriptorWithoutSemicolon + "<TT;>." + innerLastPart;
+      assertEquals(minifiedSignature, extendsInner.getFinalSignatureAttribute());
+      assertEquals(signature, extendsInner.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureOuter_classNotFound() throws Exception {
+    String signature = "<T:LNotFound;>LNotFound;";
+    testSingleClass("Outer", signature, this::noWarnings, inspector -> {
+      assertThat(inspector.clazz("NotFound"), not(isPresent()));
+      ClassSubject outer = inspector.clazz("Outer");
+      assertEquals(signature, outer.getOriginalSignatureAttribute());
+    });
+  }
+
+  @Test
+  public void classSignatureOuter_invalid() throws Exception {
+    testSingleClass("Outer", "X", diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid class signature for class Outer", "Expected L at position 1");
+    }, inspector -> noSignatureAttribute(inspector.clazz("Outer")));
+  }
+
+  @Test
+  public void classSignatureOuter_invalidEnd() throws Exception {
+    testSingleClass("Outer", "<L", diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid class signature for class Outer", "Unexpected end of signature at position 3");
+    }, inspector -> noSignatureAttribute(inspector.clazz("Outer")));
+  }
+
+  @Test
+  public void classSignatureExtendsInner_invalid() throws Exception {
+    testSingleClass("Outer$ExtendsInner", "X", diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid class signature for class Outer$ExtendsInner", "Expected L at position 1");
+    }, inspector -> noSignatureAttribute(inspector.clazz("Outer$ExtendsInner")));
+  }
+
+  @Test
+  public void classSignatureExtendsInnerInner_invalid() throws Exception {
+    testSingleClass("Outer$Inner$ExtendsInnerInner", "X", diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid class signature for class Outer$Inner$ExtendsInnerInner",
+          "Expected L at position 1");
+    }, inspector -> noSignatureAttribute(inspector.clazz("Outer$Inner$ExtendsInnerInner")));
+  }
+
+  @Test
+  public void multipleWarnings() throws Exception {
+    runTest(ImmutableMap.of(
+        "Outer", "X",
+        "Outer$ExtendsInner", "X",
+        "Outer$Inner$ExtendsInnerInner", "X"), diagnostics -> {
+      assertEquals(3, diagnostics.warnings.size());
+    }, inspector -> {
+      noSignatureAttribute(inspector.clazz("Outer"));
+      noSignatureAttribute(inspector.clazz("Outer$ExtendsInner"));
+      noSignatureAttribute(inspector.clazz("Outer$Inner$ExtendsInnerInner"));
+    });
+  }
+  @Test
+  public void regress80029761() throws Exception {
+    String signature = "LOuter<TT;>.com/example/Inner;";
+    testSingleClass("Outer$ExtendsInner", signature, diagnostics -> {
+      assertEquals(1, diagnostics.warnings.size());
+      DiagnosticsChecker.checkDiagnostic(diagnostics.warnings.get(0), this::isOriginUnknown,
+          "Invalid class signature for class Outer$ExtendsInner", "Expected ; at position 16");
+    }, inspector -> {
+      noSignatureAttribute(inspector.clazz("Outer$ExtendsInner"));
+    });
+  }
+}
