@NotNull
  private static MethodInferenceData infer(PsiMethodImpl method) {
    InferenceMode mode = getInferenceMode(method);
    if (mode == InferenceMode.DISABLED ||
        mode == InferenceMode.PARAMETERS && method.getParameterList().isEmpty()) {
      return MethodInferenceData.UNKNOWN;
    }

    MethodData data = ContractInferenceIndexKt.getIndexedData(method);
    if (data == null) return MethodInferenceData.UNKNOWN;
    BitSet notNullParameters = data.getNotNullParameters();
    if (mode == InferenceMode.PARAMETERS) {
      // Infer parameters nullability only (for unstable methods)
      return notNullParameters.isEmpty() ? MethodInferenceData.UNKNOWN :
             new MethodInferenceData(Mutability.UNKNOWN, Nullability.UNKNOWN, Collections.emptyList(),
                                     MutationSignature.unknown(), notNullParameters);
    }

    Nullability nullability = findNullability(method, data);
    Mutability mutability = findMutability(method, data);
    MutationSignature signature = findMutationSignature(method, data);

    IntPredicate isNotNullParameter = i -> {
      PsiParameter[] parameters = method.getParameterList().getParameters();
      NullableNotNullManager manager = NullableNotNullManager.getInstance(method.getProject());
      NullabilityAnnotationInfo parameterInfo = manager.findExplicitNullability(parameters[i]);
      return parameterInfo != null ? parameterInfo.getNullability() == Nullability.NOT_NULL : notNullParameters.get(i);
    };
    List<StandardMethodContract> contracts = findContracts(method, data, nullability, isNotNullParameter);
    if (nullability == Nullability.NULLABLE && ContainerUtil.find(contracts, c -> c.getReturnValue().isNull()) != null) {
      nullability = Nullability.UNKNOWN;
    }

    return new MethodInferenceData(mutability, nullability, contracts, signature, notNullParameters);
  }
@NotNull
  private static MethodInferenceData infer(PsiMethodImpl method)