public static boolean parseMasonMethod(
      PsiBuilder b, int l, IElementType closeToken, IElementType statementTokenType) {
    boolean r = false;

    PsiBuilder.Marker methodMarker = b.mark();
    b.advanceLexer();
    PsiBuilder.Marker subMarker = b.mark();
    if (PerlParserUtil.consumeToken(b, IDENTIFIER)) {
      subMarker.collapse(SUB);
      PerlParserImpl.method_signature(b, l);
      if (PerlParserUtil.consumeToken(b, MASON_TAG_CLOSER)) {
        PsiBuilder.Marker blockMarker = b.mark();
        PerlParserImpl.block_content(b, l);

        if (b.getTokenType() == closeToken) {
          blockMarker.done(BLOCK);
          blockMarker.setCustomEdgeTokenBinders(
              WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);
          b.advanceLexer();
          methodMarker.done(statementTokenType);
          r = true;
        }
      }
    }

    if (!r) {
      methodMarker.rollbackTo();
    }

    return r || recoverToGreedy(b, closeToken, "Error");
  }
  private static boolean parseAnnotatedSimpleStatement(
      PerlBuilder b, int l, IElementType keywordToken, IElementType statementToken) {
    PerlBuilder.Marker m = b.mark();
    PerlParserImpl.annotations(b, l);

    if (PerlParserUtil.consumeToken(b, keywordToken)) {
      if (PerlParserImpl.expr(b, l, -1)) {
        PerlParserUtil.parseStatementModifier(b, l);
        m.done(statementToken);
        return true;
      }
    }

    m.rollbackTo();
    return false;
  }
 private static boolean parseHasArgumentsSequenceContent(PerlBuilder b, int l) {
   PsiBuilder.Marker m = b.mark();
   if (parseHasAttributeDefinitions(b, l)
       && (PerlParserUtil.consumeToken(b, OPERATOR_COMMA)
           || PerlParserUtil.consumeToken(b, OPERATOR_COMMA_ARROW))
       && PerlParserImpl.expr(b, l, -1)) {
     m.drop();
     return true;
   }
   m.rollbackTo();
   return false;
 }
  private static boolean parseHas(PerlBuilder b, int l) {
    PerlBuilder.Marker m = b.mark();
    PerlParserImpl.annotations(b, l);

    if (PerlParserUtil.consumeToken(b, RESERVED_HAS) && parseHasArguments(b, l)) {
      PerlParserUtil.parseStatementModifier(b, l);
      m.done(MOOSE_STATEMENT_HAS);
      return true;
    }

    m.rollbackTo();
    return false;
  }
  protected static boolean parsePerlBlock(
      PsiBuilder b, int l, IElementType closeToken, IElementType blockToken) {
    b.advanceLexer();
    PsiBuilder.Marker abstractBlockMarker = b.mark();

    while (!b.eof() && b.getTokenType() != closeToken) {
      if (!PerlParserImpl.file_item(b, l)) {
        break;
      }
    }
    abstractBlockMarker.done(blockToken);
    abstractBlockMarker.setCustomEdgeTokenBinders(
        WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);
    return endOrRecover(b, closeToken);
  }
  private static boolean parseDefault(PerlBuilder b, int l) {
    PerlBuilder.Marker m = b.mark();

    IElementType tokenType = b.getTokenType();
    if (MOOSE_TOKEN_SET.contains(tokenType)) {
      b.advanceLexer();
      if (PerlParserImpl.expr(b, l, -1)) {
        PerlParserUtil.parseStatementModifier(b, l);
        m.done(RESERVED_TO_STATEMENT_MAP.get(tokenType));
        return true;
      }
    }

    m.rollbackTo();
    return false;
  }
  @Override
  public boolean parseStatement(PsiBuilder b, int l) {
    IElementType tokenType = b.getTokenType();

    boolean r = false;
    PsiBuilder.Marker m = b.mark();

    if (tokenType == MASON_BLOCK_OPENER) {
      PsiBuilder.Marker statementMarker = b.mark();
      b.advanceLexer();
      if (PerlParserImpl.expr(b, l, -1)) {
        // parseStatement filter
        if (PerlParserUtil.consumeToken(b, MASON_EXPR_FILTER_PIPE)) {
          while (b.getTokenType() == IDENTIFIER) {
            PsiBuilder.Marker fm = b.mark();
            b.advanceLexer();
            fm.collapse(SUB);
            fm.precede().done(METHOD);

            if (!PerlParserUtil.consumeToken(b, OPERATOR_COMMA)) {
              break;
            }
          }
        }
      }
      if (r = endOrRecover(b, MASON_BLOCK_CLOSER)) {
        statementMarker.done(STATEMENT);
      }
    }
    if (tokenType == MASON_CALL_OPENER) {
      PsiBuilder.Marker statementMarker = b.mark();
      b.advanceLexer();
      PerlParserImpl.expr(b, l, -1);
      if (r = endOrRecover(b, MASON_CALL_CLOSER)) {
        statementMarker.done(MASON_CALL_STATEMENT);
      }
    } else if (tokenType == MASON_CLASS_OPENER) {
      r = parsePerlBlock(b, l, MASON_CLASS_CLOSER);
    } else if (tokenType == MASON_INIT_OPENER) {
      r = parsePerlBlock(b, l, MASON_INIT_CLOSER);
    } else if (tokenType == MASON_PERL_OPENER) {
      r = parsePerlBlock(b, l, MASON_PERL_CLOSER);
    } else if (tokenType == MASON_FLAGS_OPENER) {
      b.advanceLexer();
      PsiBuilder.Marker statementMarker = b.mark();

      while (!b.eof() && b.getTokenType() != MASON_FLAGS_CLOSER) {
        if (!PerlParserImpl.expr(b, l, -1)) {
          break;
        }
      }
      statementMarker.done(MASON_FLAGS_STATEMENT);

      r = endOrRecover(b, MASON_FLAGS_CLOSER);
    } else if (tokenType == MASON_DOC_OPENER) {
      b.advanceLexer();
      PerlParserUtil.consumeToken(b, COMMENT_BLOCK);
      r = endOrRecover(b, MASON_DOC_CLOSER);
    } else if (tokenType == MASON_TEXT_OPENER) {
      b.advanceLexer();
      PsiBuilder.Marker stringMarker = b.mark();
      if (PerlParserUtil.consumeToken(b, STRING_CONTENT)) {
        stringMarker.done(MASON_TEXT_BLOCK);
      } else {
        stringMarker.drop();
      }
      r = endOrRecover(b, MASON_TEXT_CLOSER);
    } else if (tokenType == MASON_METHOD_OPENER) {
      r = parseMasonMethod(b, l, MASON_METHOD_CLOSER, MASON_METHOD_DEFINITION);
    } else if (tokenType == MASON_FILTER_OPENER) {
      r = parseMasonMethod(b, l, MASON_FILTER_CLOSER, MASON_FILTER_DEFINITION);
    } else if (tokenType == MASON_OVERRIDE_OPENER) {
      r = parseMasonMethod(b, l, MASON_OVERRIDE_CLOSER, MASON_OVERRIDE_DEFINITION);
    } else if (SIMPLE_MASON_NAMED_BLOCKS.contains(tokenType)) // simple named blocks
    {
      PsiBuilder.Marker statementMarker = b.mark();
      b.advanceLexer();
      IElementType closeToken = RESERVED_OPENER_TO_CLOSER_MAP.get(tokenType);

      if (PerlParserUtil.convertIdentifier(b, l, MASON_METHOD_MODIFIER_NAME)) {
        if (PerlParserUtil.consumeToken(b, MASON_TAG_CLOSER)) {
          PsiBuilder.Marker blockMarker = b.mark();
          PerlParserImpl.block_content(b, l);
          blockMarker.done(BLOCK);
          blockMarker.setCustomEdgeTokenBinders(
              WhitespacesBinders.GREEDY_LEFT_BINDER, WhitespacesBinders.GREEDY_RIGHT_BINDER);

          if (r = PerlParserUtil.consumeToken(b, closeToken)) {
            statementMarker.done(RESERVED_TO_STATEMENT_MAP.get(tokenType));
            statementMarker = null;
          }
        }
      }

      if (statementMarker != null) {
        statementMarker.drop();
      }

      r = r || recoverToGreedy(b, closeToken, "Error");
    }

    if (r) {
      m.drop();
    } else {
      m.rollbackTo();
    }

    return r || super.parseStatement(b, l);
  }
 private static boolean parseHasAttributeDefinitions(PerlBuilder b, int l) {
   IElementType currentWrapper = b.setStringWrapper(MOOSE_ATTRIBUTE);
   boolean r = PerlParserImpl.scalar_expr(b, l - 1);
   b.setStringWrapper(currentWrapper);
   return r;
 }