private static boolean isInConcatenationContext(PsiElement element) {
   final PsiElement parent = element.getParent();
   if (parent instanceof PsiPolyadicExpression) {
     final PsiPolyadicExpression parentExpression = (PsiPolyadicExpression) parent;
     final PsiType parentType = parentExpression.getType();
     if (parentType == null) {
       return false;
     }
     final String parentTypeText = parentType.getCanonicalText();
     return JAVA_LANG_STRING.equals(parentTypeText);
   } else if (parent instanceof PsiAssignmentExpression) {
     final PsiAssignmentExpression parentExpression = (PsiAssignmentExpression) parent;
     final IElementType tokenType = parentExpression.getOperationTokenType();
     if (!JavaTokenType.PLUSEQ.equals(tokenType)) {
       return false;
     }
     final PsiType parentType = parentExpression.getType();
     if (parentType == null) {
       return false;
     }
     final String parentTypeText = parentType.getCanonicalText();
     return JAVA_LANG_STRING.equals(parentTypeText);
   } else if (parent instanceof PsiExpressionList) {
     final PsiElement grandParent = parent.getParent();
     if (!(grandParent instanceof PsiMethodCallExpression)) {
       return false;
     }
     final PsiMethodCallExpression methodCall = (PsiMethodCallExpression) grandParent;
     final PsiReferenceExpression methodExpression = methodCall.getMethodExpression();
     final PsiExpression qualifierExpression = methodExpression.getQualifierExpression();
     final PsiType type;
     if (qualifierExpression == null) {
       // to use the intention inside the source of
       // String and StringBuffer
       type = methodExpression.getType();
     } else {
       type = qualifierExpression.getType();
     }
     if (type == null) {
       return false;
     }
     final String className = type.getCanonicalText();
     if (CommonClassNames.JAVA_LANG_STRING_BUFFER.equals(className)
         || CommonClassNames.JAVA_LANG_STRING_BUILDER.equals(className)) {
       @NonNls final String methodName = methodExpression.getReferenceName();
       if (!"append".equals(methodName) && !"insert".equals(methodName)) {
         return false;
       }
       final PsiElement method = methodExpression.resolve();
       return method != null;
     } else if (JAVA_LANG_STRING.equals(className)) {
       @NonNls final String methodName = methodExpression.getReferenceName();
       if (!"indexOf".equals(methodName)
           && !"lastIndexOf".equals(methodName)
           && !"replace".equals(methodName)) {
         return false;
       }
       final PsiElement method = methodExpression.resolve();
       return method != null;
     }
   }
   return false;
 }
  @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;

    // skip semi-synthetic enum methods
    boolean isEnum = myResult.isEnum();
    if (isEnum) {
      if ("values".equals(name) && desc.startsWith("()")) return null;
      if ("valueOf".equals(name) && desc.startsWith("(Ljava/lang/String;)")) 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);

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

    StringRef stringRef = StringRef.fromString(canonicalMethodName);
    int modifiersMask = packMethodFlags(access, myResult.isInterface());
    PsiMethodStubImpl stub =
        new PsiMethodStubImpl(
            myResult, stringRef, flags, signature, args, throwables, desc, modifiersMask);

    PsiModifierListStub modList =
        (PsiModifierListStub) stub.findChildStubByType(JavaStubElementTypes.MODIFIER_LIST);
    assert modList != null : stub;

    if (isEnum
        && isConstructor
        && signature == null
        && args.size() >= 2
        && JAVA_LANG_STRING.equals(args.get(0))
        && "int".equals(args.get(1))) {
      // exclude synthetic enum constructor parameters
      args = args.subList(2, args.size());
    }

    final boolean isNonStaticInnerClassConstructor =
        isConstructor
            && !(myParent instanceof PsiFileStub)
            && (myModList.getModifiersMask() & Opcodes.ACC_STATIC) == 0;
    boolean parsedViaGenericSignature = stub.isParsedViaGenericSignature();
    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);

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