/*
   * whenCondition
   *   : expression
   *   : ("in" | "!in") expression
   *   : ("is" | "!is") isRHS
   *   ;
   */
  private void parseWhenCondition() {
    PsiBuilder.Marker condition = mark();
    myBuilder.disableNewlines();
    if (at(IN_KEYWORD) || at(NOT_IN)) {
      PsiBuilder.Marker mark = mark();
      advance(); // IN_KEYWORD or NOT_IN
      mark.done(OPERATION_REFERENCE);

      if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
        error("Expecting an element");
      } else {
        parseExpression();
      }
      condition.done(WHEN_CONDITION_IN_RANGE);
    } else if (at(IS_KEYWORD) || at(NOT_IS)) {
      advance(); // IS_KEYWORD or NOT_IS

      if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
        error("Expecting a type");
      } else {
        myJetParsing.parseTypeRef();
      }
      condition.done(WHEN_CONDITION_IS_PATTERN);
    } else {
      if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_ARROW)) {
        error("Expecting an expression, is-condition or in-condition");
      } else {
        parseExpression();
      }
      condition.done(WHEN_CONDITION_EXPRESSION);
    }
    myBuilder.restoreNewlinesState();
  }
  /*
   * "this" ("<" type ">")? label?
   */
  private void parseSuperExpression() {
    assert _at(SUPER_KEYWORD);
    PsiBuilder.Marker mark = mark();

    PsiBuilder.Marker superReference = mark();
    advance(); // SUPER_KEYWORD
    superReference.done(REFERENCE_EXPRESSION);

    if (at(LT)) {
      // This may be "super < foo" or "super<foo>", thus the backtracking
      PsiBuilder.Marker supertype = mark();

      myBuilder.disableNewlines();
      advance(); // LT

      myJetParsing.parseTypeRef();

      if (at(GT)) {
        advance(); // GT
        supertype.drop();
      } else {
        supertype.rollbackTo();
      }
      myBuilder.restoreNewlinesState();
    }
    parseLabelReferenceWithNoWhitespace();

    mark.done(SUPER_EXPRESSION);
  }
  /*
   * SimpleName{,}
   */
  private void parseFunctionLiteralShorthandParameterList() {
    PsiBuilder.Marker parameterList = mark();

    while (!eof()) {
      PsiBuilder.Marker parameter = mark();

      //            int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new
      // At(IDENTIFIER), new AtOffset(doubleArrowPos)));
      //            createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST,
      // false);

      if (at(COLON)) {
        error("Expecting parameter name");
      } else {
        expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
      }

      if (at(COLON)) {
        advance(); // COLON
        myJetParsing.parseTypeRef(TokenSet.create(ARROW, COMMA));
      }
      parameter.done(VALUE_PARAMETER);

      if (at(ARROW)) {
        break;
      } else if (at(COMMA)) {
        advance(); // COMMA
      } else {
        error("Expecting '->' or ','");
        break;
      }
    }

    parameterList.done(VALUE_PARAMETER_LIST);
  }
  /*
   * for
   *   : "for" "(" annotations ("val" | "var")? (multipleVariableDeclarations | variableDeclarationEntry) "in" expression ")" expression
   *   ;
   *
   *   TODO: empty loop body (at the end of the block)?
   */
  private void parseFor() {
    assert _at(FOR_KEYWORD);

    PsiBuilder.Marker loop = mark();

    advance(); // FOR_KEYWORD

    if (expect(LPAR, "Expecting '(' to open a loop range", EXPRESSION_FIRST)) {
      myBuilder.disableNewlines();

      if (!at(RPAR)) {
        PsiBuilder.Marker parameter = mark();

        if (!at(IN_KEYWORD)) {
          myJetParsing.parseModifierList(DEFAULT, TokenSet.create(IN_KEYWORD, RPAR, COLON));
        }

        if (at(VAL_KEYWORD) || at(VAR_KEYWORD)) advance(); // VAL_KEYWORD or VAR_KEYWORD

        if (at(LPAR)) {
          myJetParsing.parseMultiDeclarationName(TokenSet.create(IN_KEYWORD, LBRACE));
          parameter.done(DESTRUCTURING_DECLARATION);
        } else {
          expect(IDENTIFIER, "Expecting a variable name", TokenSet.create(COLON, IN_KEYWORD));

          if (at(COLON)) {
            advance(); // COLON
            myJetParsing.parseTypeRef(TokenSet.create(IN_KEYWORD));
          }
          parameter.done(VALUE_PARAMETER);
        }

        if (expect(IN_KEYWORD, "Expecting 'in'", TokenSet.create(LPAR, LBRACE, RPAR))) {
          PsiBuilder.Marker range = mark();
          parseExpression();
          range.done(LOOP_RANGE);
        }
      } else {
        error("Expecting a variable name");
      }

      expectNoAdvance(RPAR, "Expecting ')'");
      myBuilder.restoreNewlinesState();
    }

    parseControlStructureBody();

    loop.done(FOR);
  }