@Override
  public void visitNewExpression(@NotNull PsiNewExpression expression) {
    final PsiExpression other = getExpression(PsiExpression.class, expression);
    final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
    if (other instanceof PsiArrayInitializerExpression &&
        other.getParent() instanceof PsiVariable &&
        areZeroLiterals(expression.getArrayDimensions())
    ) {
      final MatchContext matchContext = myMatchingVisitor.getMatchContext();
      final CompiledPattern pattern = matchContext.getPattern();
      final boolean isTypedVar = pattern.isTypedVar(classReference);
      if (isTypedVar && !myMatchingVisitor.setResult(myMatchingVisitor.matchOptionally(classReference, null))) {
        return;
      }
      final PsiType otherType = other.getType();
      final MatchingHandler handler;
      if (classReference != null && (handler = pattern.getHandler(classReference)) instanceof SubstitutionHandler && otherType != null) {
        final SubstitutionHandler substitutionHandler = (SubstitutionHandler)handler;
        final MatchPredicate predicate = substitutionHandler.getPredicate();
        if (predicate != null) {
          final PsiElementFactory factory = JavaPsiFacade.getElementFactory(other.getProject());
          final PsiTypeElement otherTypeElement = factory.createTypeElement(otherType.getDeepComponentType());
          myMatchingVisitor.setResult(predicate.match(otherTypeElement, matchContext));
        }
      }
      else {
        final PsiType type = expression.getType();
        myMatchingVisitor.setResult(type != null && type.equals(otherType));
      }
      if (myMatchingVisitor.getResult()) {
        final PsiArrayInitializerExpression initializer = expression.getArrayInitializer();
        if (initializer != null) {
          myMatchingVisitor.setResult(myMatchingVisitor.matchSons(initializer, other));
        }
        else {
          myMatchingVisitor.setResult(((PsiArrayInitializerExpression)other).getInitializers().length == 0);
        }
      }
      return;
    }

    if (!myMatchingVisitor.setResult(other instanceof PsiNewExpression)) {
      return;
    }
    final PsiNewExpression new2 = (PsiNewExpression)other;

    final PsiJavaCodeReferenceElement otherClassReference = new2.getClassReference();
    if (classReference != null) {
      if (otherClassReference != null) {
        if (myMatchingVisitor.setResult(myMatchingVisitor.matchOptionally(classReference, otherClassReference))) {
          matchArrayOrArguments(expression, new2);
        }
        return;
      }
      else {
        // match array of primitive by new 'T();
        final PsiKeyword newKeyword = PsiTreeUtil.getChildOfType(new2, PsiKeyword.class);
        final PsiKeyword typeKeyword = PsiTreeUtil.getNextSiblingOfType(newKeyword, PsiKeyword.class);

        if (typeKeyword != null ) {
          if (myMatchingVisitor.setResult(myMatchingVisitor.matchOptionally(classReference, typeKeyword))) {
            matchArrayOrArguments(expression, new2);
          }
          return;
        }
      }
    }

    final PsiAnonymousClass anonymousClass = expression.getAnonymousClass();
    if (classReference == otherClassReference) {
      //myMatchingVisitor.setResult(myMatchingVisitor.matchSons(expression, new2));
      if (anonymousClass != null) { // anonymous class
        myMatchingVisitor.setResult(matchTypeParameters(expression, new2) &&
                                    myMatchingVisitor.matchSons(expression.getArgumentList(), new2.getArgumentList()) &&
                                    myMatchingVisitor.match(anonymousClass, new2.getAnonymousClass()));
      }
      else { // array of primitive type
        final PsiType type1 = expression.getType();
        final PsiType type2 = new2.getType();
        if (myMatchingVisitor.setResult(type1 != null && type2 != null && type1.getDeepComponentType() == type2.getDeepComponentType())) {
          matchArrayOrArguments(expression, new2);
        }
      }
    }
    else if (anonymousClass == null && classReference != null && new2.getAnonymousClass() != null) {
      // allow matching anonymous class without pattern
      myMatchingVisitor.setResult(myMatchingVisitor.match(classReference, new2.getAnonymousClass().getBaseClassReference()) &&
                                  myMatchingVisitor.matchSons(expression.getArgumentList(), new2.getArgumentList()) &&
                                  matchTypeParameters(expression, new2));
    }
    else {
      myMatchingVisitor.setResult(false);
    }
  }
@Override
  public void visitNewExpression(@NotNull PsiNewExpression expression)