public static boolean isFunctionReference(
      PsiElement psiElement, int wantIndex, String... funcName) {

    PsiElement variableContext = psiElement.getContext();
    if (!(variableContext instanceof ParameterList)) {
      return false;
    }

    ParameterList parameterList = (ParameterList) variableContext;
    PsiElement context = parameterList.getContext();
    if (!(context instanceof FunctionReference)) {
      return false;
    }

    FunctionReference methodReference = (FunctionReference) context;
    String name = methodReference.getName();

    if (name == null || !Arrays.asList(funcName).contains(name)) {
      return false;
    }

    ParameterBag currentIndex = getCurrentParameterIndex(psiElement);
    if (currentIndex == null) {
      return false;
    }

    return !(wantIndex >= 0 && currentIndex.getIndex() != wantIndex);
  }
  public static void apply(
      final String functionName,
      @NotNull final FunctionReference reference,
      final String modifiers,
      final String pattern,
      @NotNull final ProblemsHolder holder) {
    if (reference.getParameters().length >= 2 && !StringUtil.isEmpty(pattern)) {
      Matcher regexMatcher = regexTextSearch.matcher(pattern);
      if (regexMatcher.find()) {
        final boolean ignoreCase = !StringUtil.isEmpty(modifiers) && modifiers.indexOf('i') >= 0;
        final boolean startWith = !StringUtil.isEmpty(regexMatcher.group(1));

        /* analyse if pattern is the one strategy targeting */
        String strProblemDescription = null;
        if (functionName.equals("preg_match") && startWith) {
          strProblemDescription = ignoreCase ? strProblemStartIgnoreCase : strProblemStartTreatCase;
        }
        if (functionName.equals("preg_match") && !startWith) {
          strProblemDescription =
              ignoreCase ? strProblemContainsIgnoreCase : strProblemContainsTreatCase;
        }
        if (functionName.equals("preg_replace") && !startWith) {
          strProblemDescription =
              ignoreCase ? strProblemReplaceIgnoreCase : strProblemReplaceTreatCase;
        }

        if (null != strProblemDescription) {
          String strError = strProblemDescription.replace("%t%", regexMatcher.group(2));
          holder.registerProblem(
              reference, strError, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
        }
      }
    }
  }
  @Nullable
  public static String getReferenceSignature(
      FunctionReference functionReference, char trimKey, int equalParameterCount) {

    String refSignature = functionReference.getSignature();
    if (StringUtil.isEmpty(refSignature)) {
      return null;
    }

    PsiElement[] parameters = functionReference.getParameters();
    if (parameters.length != equalParameterCount) {
      return null;
    }

    PsiElement parameter = parameters[0];

    // we already have a string value
    if ((parameter instanceof StringLiteralExpression)) {
      String param = ((StringLiteralExpression) parameter).getContents();
      if (StringUtil.isNotEmpty(param)) {
        return refSignature + trimKey + param;
      }

      return null;
    }

    // whitelist here; we can also provide some more but think of performance
    // Service::NAME, $this->name and Entity::CLASS;
    if (parameter instanceof PhpReference
        && (parameter instanceof ClassConstantReference || parameter instanceof FieldReference)) {
      String signature = ((PhpReference) parameter).getSignature();
      if (StringUtil.isNotEmpty(signature)) {
        return refSignature + trimKey + signature;
      }

      return null;
    }

    return null;
  }