private static @NotNull TypeInfo parseClassOrTypeVariableElementToTypeInfo(@NotNull CharIterator signature, TypeInfoProvider mapping)
    throws ClsFormatException {
    char variance = parseVariance(signature);
    if (variance == '*') {
      return new TypeInfo.SimpleTypeInfo(TypeKind.WILDCARD);
    }

    int dimensions = parseDimensions(signature);

    TypeInfo info = parseTypeWithoutVarianceToTypeInfo(signature, mapping);
    if (info == null) {
      throw new ClsFormatException("Unable to parse signature: " + signature);
    }

    while (dimensions > 0) {
      dimensions--;
      info = info.arrayOf();
    }

    switch (variance) {
      case VARIANCE_NONE:
        return info;
      case VARIANCE_EXTENDS:
        return new TypeInfo.DerivedTypeInfo(TypeKind.EXTENDS, info);
      case VARIANCE_SUPER:
        return new TypeInfo.DerivedTypeInfo(TypeKind.SUPER, info);
      default:
        throw new ClsFormatException("Unable to parse signature: " + signature);
    }
  }
private static @NotNull TypeInfo parseClassOrTypeVariableElementToTypeInfo(@NotNull CharIterator signature, TypeInfoProvider mapping)