@Override
  public void visitExpressionStatement(@NotNull PsiExpressionStatement expressionStatement) {
    super.visitExpressionStatement(expressionStatement);

    final CompiledPattern pattern = myCompilingVisitor.getContext().getPattern();
    final PsiElement child = expressionStatement.getLastChild();
    final PsiElement parent = expressionStatement.getParent();
    if (!(child instanceof PsiJavaToken) && !(child instanceof PsiComment) && parent instanceof PsiCodeFragment) {
      // search for expression or symbol
      final PsiElement reference = expressionStatement.getFirstChild();
      final MatchingHandler referenceHandler = pattern.getHandler(reference);

      if (referenceHandler instanceof SubstitutionHandler substitutionHandler &&
          substitutionHandler.findPredicate(ExprTypePredicate.class) == null &&
          reference instanceof PsiReferenceExpression) {
        // symbol
        pattern.setHandler(expressionStatement, referenceHandler);
        referenceHandler.setFilter(SymbolNodeFilter.getInstance());

        myCompilingVisitor.setHandler(expressionStatement, new SymbolHandler(substitutionHandler));
      }
      else if (reference instanceof PsiLiteralExpression) {
        final MatchingHandler handler = new ExpressionHandler();
        myCompilingVisitor.setHandler(expressionStatement, handler);
        handler.setFilter(ConstantFilter.getInstance());
      }
      else {
        // just expression
        final MatchingHandler handler = new ExpressionHandler();
        myCompilingVisitor.setHandler(expressionStatement, handler);

        handler.setFilter(ExpressionFilter.getInstance());
      }
    }
    else {
      if (expressionStatement.getExpression() instanceof PsiReferenceExpression && pattern.isRealTypedVar(expressionStatement)) {
        // search for statement
        final MatchingHandler handler = pattern.getHandler(expressionStatement);
        if (handler instanceof SubstitutionHandler substitutionHandler) {
          if (parent instanceof PsiForStatement forStatement &&
              (forStatement.getInitialization() == expressionStatement ||
               forStatement.getUpdate() == expressionStatement)) {
            substitutionHandler.setFilter(e -> e instanceof PsiExpression || e instanceof PsiExpressionListStatement ||
                                               e instanceof PsiDeclarationStatement || e instanceof PsiEmptyStatement);
          }
          else {
            substitutionHandler.setFilter(new StatementFilter());
            substitutionHandler.setMatchHandler(new StatementHandler());
          }
        }
      }
    }
  }
@Override
  public void visitExpressionStatement(@NotNull PsiExpressionStatement expressionStatement)