/** new FooClass() */
  @Nullable
  private static PhpClass getNewExpressionPhpClass(@NotNull NewExpression newExpression) {
    ClassReference classReference = newExpression.getClassReference();
    if (classReference != null) {
      String fqn = classReference.getFQN();
      if (fqn != null) {
        return PhpElementsUtil.getClass(newExpression.getProject(), fqn);
      }
    }

    return null;
  }
  /** finishView, buildView: $this->vars */
  public static Set<String> getFormViewVars(Project project, String... formTypeNames) {

    Set<String> stringSet = new HashSet<String>();

    ArrayList<PhpClass> phpClasses = new ArrayList<PhpClass>();

    // attach core form phpclass
    // @TODO: add formtype itself
    PhpClass coreForm = FormUtil.getFormTypeToClass(project, "form");
    if (coreForm != null) {
      phpClasses.add(coreForm);
    }

    // for extension can also provide vars
    for (Map.Entry<String, String> entry :
        FormOptionsUtil.getFormExtensionKeys(project, formTypeNames).entrySet()) {
      PhpClass phpClass = PhpElementsUtil.getClassInterface(project, entry.getValue());
      if (phpClass != null) {
        phpClasses.add(phpClass);
      }
    }

    for (PhpClass phpClass : phpClasses) {
      for (String stringMethod : new String[] {"finishView", "buildView"}) {
        Method method = PhpElementsUtil.getClassMethod(phpClass, stringMethod);
        if (method != null) {

          // self method
          getMethodVars(stringSet, method);

          // allow parent::
          // @TODO: provide global util method
          for (ClassReference classReference :
              PsiTreeUtil.collectElementsOfType(method, ClassReference.class)) {
            if ("parent".equals(classReference.getName())) {
              PsiElement methodReference = classReference.getContext();
              if (methodReference instanceof MethodReference) {
                PsiElement parentMethod = ((MethodReference) methodReference).resolve();
                if (parentMethod instanceof Method) {
                  getMethodVars(stringSet, (Method) parentMethod);
                }
              }
            }
          }
        }
      }
    }

    return stringSet;
  }
  /**
   * 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;
  }