public static @NotNull List<Pair<PsiModifierListOwner, PsiType>> getMembersWithAllowedValues(@NotNull PsiElement pos) {
    Set<Pair<PsiModifierListOwner, PsiType>> result = new HashSet<>();
    if (IN_METHOD_CALL_ARGUMENT.accepts(pos)) {
      PsiCall call = PsiTreeUtil.getParentOfType(pos, PsiCall.class);
      if (call == null) return Collections.emptyList();

      PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(call.getProject()).getResolveHelper();
      JavaResolveResult[] methods = getMethodCandidates(call, resolveHelper);
      for (JavaResolveResult resolveResult : methods) {
        PsiElement element = resolveResult.getElement();
        if (!(element instanceof PsiMethod method)) return Collections.emptyList();
        if (!resolveHelper.isAccessible(method, call, null)) continue;
        PsiElement argument = pos;
        while (!(argument.getContext() instanceof PsiExpressionList list)) argument = argument.getContext();
        int i = ArrayUtil.indexOf(list.getExpressions(), argument);
        if (i == -1) continue;
        PsiParameter[] params = method.getParameterList().getParameters();
        PsiParameter parameter;
        PsiType parameterType;
        if (method.isVarArgs() && i >= params.length - 1) {
          parameter = ArrayUtil.getLastElement(params);
          parameterType = ((PsiEllipsisType)parameter.getType()).getComponentType();
        }
        else if (i < params.length) {
          parameter = params[i];
          parameterType = parameter.getType();
        }
        else {
          continue;
        }
        result.add(Pair.create(parameter, parameterType));
      }
    }
    else if (IN_BINARY_COMPARISON.accepts(pos)) {
      PsiPolyadicExpression exp = PsiTreeUtil.getParentOfType(pos, PsiPolyadicExpression.class);
      if (exp != null && (exp.getOperationTokenType() == JavaTokenType.EQEQ || exp.getOperationTokenType() == JavaTokenType.NE)) {
        for (PsiExpression operand : exp.getOperands()) {
          PsiModifierListOwner resolved = resolveExpression(operand);
          if (resolved != null) {
            result.add(Pair.create(resolved, operand.getType()));
            // if something interesting assigned to this variable, e.g. magic method, suggest its magic too
            MagicConstantInspection.processValuesFlownTo(operand, pos.getContainingFile(), pos.getManager(), expression -> {
              PsiModifierListOwner assigned = resolveExpression(expression);
              if (assigned != null) {
                result.add(Pair.create(assigned, operand.getType()));
              }
              return true;
            });
          }
        }
      }
    }
    else if (IN_ASSIGNMENT.accepts(pos)) {
      PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(pos, PsiAssignmentExpression.class);
      PsiExpression l = assignment == null ? null : assignment.getLExpression();
      PsiModifierListOwner resolved = resolveExpression(l);
      if (resolved != null && PsiTreeUtil.isAncestor(assignment.getRExpression(), pos, false)) {
        result.add(Pair.create(resolved, l.getType()));
      }
    }
    else if (IN_VARIABLE.accepts(pos)) {
      PsiVariable variable = PsiTreeUtil.getParentOfType(pos, PsiVariable.class);
      result.add(Pair.create(variable, variable.getType()));
    }
    else if (IN_RETURN.accepts(pos)) {
      PsiReturnStatement statement = PsiTreeUtil.getParentOfType(pos, PsiReturnStatement.class);
      PsiExpression l = statement == null ? null : statement.getReturnValue();
      PsiElement element = PsiTreeUtil.getParentOfType(l, PsiMethod.class, PsiLambdaExpression.class);
      if (element instanceof PsiMethod) {
        result.add(Pair.create((PsiModifierListOwner)element, ((PsiMethod)element).getReturnType()));
      }
      else if (element instanceof PsiLambdaExpression) {
        final PsiType interfaceType = ((PsiLambdaExpression)element).getFunctionalInterfaceType();
        final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(interfaceType);
        if (interfaceMethod != null) {
          result.add(Pair.create(interfaceMethod, LambdaUtil.getFunctionalInterfaceReturnType(interfaceType)));
        }
      }
    }
    else if (IN_ANNOTATION_INITIALIZER.accepts(pos)) {
      PsiNameValuePair pair = (PsiNameValuePair)pos.getParent().getParent();
      if (pair.getValue() instanceof PsiExpression) {
        PsiReference ref = pair.getReference();
        PsiMethod method = ref == null ? null : (PsiMethod)ref.resolve();
        if (method != null) {
          result.add(Pair.create(method, method.getReturnType()));
        }
      }
    }
    return new ArrayList<>(result);
  }
public static @NotNull List<Pair<PsiModifierListOwner, PsiType>> getMembersWithAllowedValues(@NotNull PsiElement pos)