@Nullable
  public static String getMethodParameterAt(@NotNull ParameterList parameterList, int index) {
    PsiElement[] parameters = parameterList.getParameters();

    if (parameters.length < index + 1) {
      return null;
    }

    return getMethodParameter(parameters[index]);
  }
  @Nullable
  public static ParameterBag getCurrentParameterIndex(PsiElement psiElement) {

    if (!(psiElement.getContext() instanceof ParameterList)) {
      return null;
    }

    ParameterList parameterList = (ParameterList) psiElement.getContext();
    if (!(parameterList.getContext() instanceof ParameterListOwner)) {
      return null;
    }

    return getCurrentParameterIndex(parameterList.getParameters(), psiElement);
  }
  @Nullable
  public static PsiElement getMethodParameterPsiElementAt(
      @Nullable ParameterList parameterList, int index) {

    if (parameterList == null) {
      return null;
    }

    PsiElement[] parameters = parameterList.getParameters();

    if (parameters.length < index + 1) {
      return null;
    }

    return parameters[index];
  }
  /**
   * Extract type hint from method parameter
   *
   * <p>function foo(\FooClass $class)
   */
  @Nullable
  public static String getMethodParameterTypeHint(@NotNull Method method) {
    ParameterList childOfType = PsiTreeUtil.getChildOfType(method, ParameterList.class);
    if (childOfType == null) {
      return null;
    }

    PsiElement[] parameters = childOfType.getParameters();
    if (parameters.length == 0) {
      return null;
    }

    ClassReference classReference = PsiTreeUtil.getChildOfType(parameters[0], ClassReference.class);
    if (classReference == null) {
      return null;
    }

    String fqn = classReference.getFQN();
    if (fqn == null) {
      return null;
    }

    return fqn;
  }