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/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"));
+    });
+  }
+}
