@Override
  public void visitInnerClass(
      final String name, final String outerName, final String innerName, final int access) {
    if ((access & Opcodes.ACC_SYNTHETIC) != 0) return;
    if (!isCorrectName(innerName) || outerName == null) return;

    if ((getClassName(outerName) + "." + innerName).equals(myResult.getQualifiedName())) {
      // our result is inner class
      if (myParent instanceof PsiFileStub) {
        throw new OutOfOrderInnerClassException();
      }
    }

    if (!getClassName(outerName).equals(myResult.getQualifiedName())) return;

    final T innerSource = myInnersStrategy.findInnerClass(innerName, mySource);
    if (innerSource == null) return;

    final ClassReader reader = myInnersStrategy.readerForInnerClass(innerSource);
    if (reader == null) return;

    final StubBuildingVisitor<T> classVisitor =
        new StubBuildingVisitor<T>(innerSource, myInnersStrategy, myResult, access, innerName);
    reader.accept(classVisitor, ClassReader.SKIP_FRAMES);
  }
  @Override
  @Nullable
  public MethodVisitor visitMethod(
      final int access,
      final String name,
      final String desc,
      final String signature,
      final String[] exceptions) {
    // JLS 13.1 says: Any constructs introduced by the compiler that do not have a corresponding
    // construct in the source code
    // must be marked as synthetic, except for default constructors and the class initialization
    // method.
    // However Scala compiler erroneously generates ACC_BRIDGE instead of ACC_SYNTHETIC flag for
    // in-trait implementation delegation.
    // See IDEA-78649
    if ((access & Opcodes.ACC_SYNTHETIC) != 0) return null;

    if (SYNTHETIC_CLASS_INIT_METHOD.equals(name)) return null;

    boolean isDeprecated = (access & Opcodes.ACC_DEPRECATED) != 0;
    boolean isConstructor = SYNTHETIC_INIT_METHOD.equals(name);
    boolean isVarargs = (access & Opcodes.ACC_VARARGS) != 0;
    boolean isAnnotationMethod = myResult.isAnnotationType();

    if (!isConstructor && !isCorrectName(name)) return null;

    final byte flags =
        PsiMethodStubImpl.packFlags(
            isConstructor, isAnnotationMethod, isVarargs, isDeprecated, false);

    final String canonicalMethodName = isConstructor ? myResult.getName() : name;
    final List<String> args = new ArrayList<String>();
    final List<String> throwables = exceptions != null ? new ArrayList<String>() : null;

    final PsiMethodStubImpl stub =
        new PsiMethodStubImpl(myResult, StringRef.fromString(canonicalMethodName), flags, null);

    final PsiModifierListStub modList =
        new PsiModifierListStubImpl(stub, packMethodFlags(access, myResult.isInterface()));

    boolean parsedViaGenericSignature = false;
    String returnType;
    if (signature == null) {
      returnType = parseMethodViaDescription(desc, stub, args);
    } else {
      try {
        returnType = parseMethodViaGenericSignature(signature, stub, args, throwables);
        parsedViaGenericSignature = true;
      } catch (ClsFormatException e) {
        returnType = parseMethodViaDescription(desc, stub, args);
      }
    }

    stub.setReturnType(TypeInfo.fromString(returnType));

    final boolean isNonStaticInnerClassConstructor =
        isConstructor
            && !(myParent instanceof PsiFileStub)
            && (myModList.getModifiersMask() & Opcodes.ACC_STATIC) == 0;
    final boolean shouldSkipFirstParamForNonStaticInnerClassConstructor =
        !parsedViaGenericSignature && isNonStaticInnerClassConstructor;

    final PsiParameterListStubImpl parameterList = new PsiParameterListStubImpl(stub);
    final int paramCount = args.size();
    final PsiParameterStubImpl[] paramStubs = new PsiParameterStubImpl[paramCount];
    for (int i = 0; i < paramCount; i++) {
      if (shouldSkipFirstParamForNonStaticInnerClassConstructor && i == 0) continue;

      String arg = args.get(i);
      boolean isEllipsisParam = isVarargs && i == paramCount - 1;
      final TypeInfo typeInfo = TypeInfo.fromString(arg, isEllipsisParam);

      String paramName = i < parameterNames.length ? parameterNames[i] : "p" + (i + 1);
      PsiParameterStubImpl parameterStub =
          new PsiParameterStubImpl(parameterList, paramName, typeInfo, isEllipsisParam);
      paramStubs[i] = parameterStub;
      new PsiModifierListStubImpl(parameterStub, 0);
    }

    String[] thrownTypes = buildThrowsList(exceptions, throwables, parsedViaGenericSignature);
    newReferenceList(JavaStubElementTypes.THROWS_LIST, stub, thrownTypes);

    final int localVarIgnoreCount =
        (access & Opcodes.ACC_STATIC) != 0 ? 0 : isConstructor && myResult.isEnum() ? 3 : 1;
    final int paramIgnoreCount =
        isConstructor && myResult.isEnum() ? 2 : isNonStaticInnerClassConstructor ? 1 : 0;
    return new AnnotationParamCollectingVisitor(
        stub, modList, localVarIgnoreCount, paramIgnoreCount, paramCount, paramStubs);
  }