@Nullable
  public AnnotationDescriptor resolveAnnotation(
      @NotNull JavaAnnotation javaAnnotation, @NotNull PostponedTasks postponedTasks) {
    final AnnotationDescriptor annotation = new AnnotationDescriptor();
    FqName fqName = javaAnnotation.getFqName();
    if (fqName == null) {
      return null;
    }

    // Don't process internal jet annotations and jetbrains NotNull annotations
    if (fqName.asString().startsWith("jet.runtime.typeinfo.")
        || fqName.equals(JETBRAINS_NOT_NULL_ANNOTATION)
        || fqName.equals(JvmAnnotationNames.KOTLIN_CLASS)
        || fqName.equals(JvmAnnotationNames.KOTLIN_PACKAGE)) {
      return null;
    }

    AnnotationDescriptor mappedClassDescriptor =
        JavaToKotlinClassMap.getInstance().mapToAnnotationClass(fqName);
    if (mappedClassDescriptor != null) {
      return mappedClassDescriptor;
    }

    final ClassDescriptor annotationClass =
        classResolver.resolveClass(fqName, INCLUDE_KOTLIN_SOURCES, postponedTasks);
    if (annotationClass == null) {
      return null;
    }

    postponedTasks.addTask(
        new Runnable() {
          @Override
          public void run() {
            annotation.setAnnotationType(annotationClass.getDefaultType());
          }
        });

    for (JavaAnnotationArgument argument : javaAnnotation.getArguments()) {
      CompileTimeConstant value =
          argumentResolver.resolveAnnotationArgument(fqName, argument, postponedTasks);
      if (value == null) continue;

      Name name = argument.getName();
      ValueParameterDescriptor descriptor =
          DescriptorResolverUtils.getAnnotationParameterByName(
              name == null ? DEFAULT_ANNOTATION_MEMBER_NAME : name, annotationClass);
      if (descriptor != null) {
        annotation.setValueArgument(descriptor, value);
      }
    }

    return annotation;
  }
  public JvmFunctionImplTypes(@NotNull ReflectionTypes reflectionTypes) {
    this.reflectionTypes = reflectionTypes;

    ModuleDescriptor fakeModule =
        new ModuleDescriptorImpl(
            Name.special("<fake module for functions impl>"),
            Collections.<ImportPath>emptyList(),
            JavaToKotlinClassMap.getInstance());

    PackageFragmentDescriptor kotlinJvmInternal =
        new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.jvm.internal"));
    PackageFragmentDescriptor kotlinReflectJvmInternal =
        new MutablePackageFragmentDescriptor(fakeModule, new FqName("kotlin.reflect.jvm.internal"));

    this.functionImpl = createClass(kotlinJvmInternal, "FunctionImpl", "out R");
    this.extensionFunctionImpl =
        createClass(kotlinJvmInternal, "ExtensionFunctionImpl", "in T", "out R");
    this.kFunctionImpl = createClass(kotlinReflectJvmInternal, "KFunctionImpl", "out R");
    this.kExtensionFunctionImpl =
        createClass(kotlinReflectJvmInternal, "KExtensionFunctionImpl", "in T", "out R");
    this.kMemberFunctionImpl =
        createClass(kotlinReflectJvmInternal, "KMemberFunctionImpl", "in T", "out R");
  }