private static @NotNull TypeInfo parseParameterizedClassRefSignatureToTypeInfo(CharIterator signature, TypeInfoProvider mapping)
    throws ClsFormatException {
    signature.next();
    int start = signature.pos();
    boolean hasSpace = false;
    while (true) {
      switch (signature.current()) {
        case ';': {
          String jvmName = signature.substring(start);
          if (hasSpace) {
            jvmName = jvmName.replace(" ", "");
          }
          TypeInfo type = mapping.toTypeInfo(jvmName);
          signature.next();
          return type;
        }
        case CharIterator.DONE:
          throw new ClsFormatException("Malformed signature: " + signature);
        case '<': {
          String jvmName = signature.substring(start);
          if (hasSpace) {
            jvmName = jvmName.replace(" ", "");
          }
          TypeInfo.RefTypeInfo type = mapping.toTypeInfo(jvmName);
          signature.next();
          List<TypeInfo> components = new ArrayList<>();
          do {
            components.add(parseClassOrTypeVariableElementToTypeInfo(signature, mapping));
          }
          while (signature.current() != '>');
          type = type.withComponents(components);
          signature.next();
          switch (signature.current()) {
            case ';':
              signature.next();
              return type;
            case '.':
              TypeInfo inner = parseParameterizedClassRefSignatureToTypeInfo(signature, mapping);
              if (!(inner instanceof TypeInfo.RefTypeInfo)) {
                throw new ClsFormatException("Malformed signature: " + signature);
              }
              return ((TypeInfo.RefTypeInfo)inner).withOuter(type);
            default:
              throw new ClsFormatException("Malformed signature: " + signature);
          }
        }
        case ' ':
          hasSpace = true;
          break;
        default:
      }
      signature.next();
    }
  }
private static @NotNull TypeInfo parseParameterizedClassRefSignatureToTypeInfo(CharIterator signature, TypeInfoProvider mapping)