/** {@inheritDoc} */
  @Override
  protected void parse(WordParser wordParser, boolean tolerant) {

    // Parse state field
    if (tolerant) {
      stateFieldExpression = parse(wordParser, UpdateItemStateFieldPathExpressionBNF.ID, tolerant);
    } else {
      stateFieldExpression = new StateFieldPathExpression(this, wordParser.word());
      stateFieldExpression.parse(wordParser, tolerant);
    }

    hasSpaceAfterStateFieldPathExpression = wordParser.skipLeadingWhitespace() > 0;

    // Parse '='
    hasEqualSign = wordParser.startsWith(EQUAL);

    if (hasEqualSign) {
      wordParser.moveForward(1);
      hasSpaceAfterEqualSign = wordParser.skipLeadingWhitespace() > 0;
      if (stateFieldExpression != null) {
        hasSpaceAfterStateFieldPathExpression = true;
      }
    }

    // Parse new value
    newValue = parse(wordParser, NewValueBNF.ID, tolerant);

    if (!hasSpaceAfterEqualSign && (newValue != null)) {
      hasSpaceAfterEqualSign = true;
    }
  }
  /** {@inheritDoc} */
  @Override
  protected void parse(WordParser wordParser, boolean tolerant) {

    // Parse 'NOT'
    if (wordParser.startsWithIgnoreCase('N')) {
      notIdentifier = wordParser.moveForward(NOT);
      wordParser.skipLeadingWhitespace();
    }

    // Parse 'BETWEEN'
    betweenIdentifier = wordParser.moveForward(BETWEEN);
    hasSpaceAfterBetween = (wordParser.skipLeadingWhitespace() > 0);

    // Parse lower bound expression
    lowerBoundExpression = parse(wordParser, InternalBetweenExpressionBNF.ID, tolerant);

    if (lowerBoundExpression != null) {
      hasSpaceAfterLowerBound = (wordParser.skipLeadingWhitespace() > 0);
    }

    // Parse 'AND'
    if (!tolerant || wordParser.startsWithIdentifier(AND)) {
      andIdentifier = wordParser.moveForward(AND);
      hasSpaceAfterAnd = (wordParser.skipLeadingWhitespace() > 0);
    }

    // Parse upper bound expression
    upperBoundExpression = parse(wordParser, InternalBetweenExpressionBNF.ID, tolerant);
  }
  /**
   * Determines whether the JPQL fragment is an expression of the form <code>&lt;IDENTIFIER&gt;(
   * </code>.
   *
   * @param wordParser The text to parse based on the current position of the cursor
   * @param identifier The identifier to verify if it's for an expression or for possibly for a
   *     variable name
   * @return <code>true</code> if the identifier is followed by '('; <code>false</code> otherwise
   */
  public static boolean isFunctionExpression(WordParser wordParser, String identifier) {

    // Skip the identifier
    int count = identifier.length();
    wordParser.moveForward(identifier);

    // Check to see if ( is following the identifier
    int whitespace = wordParser.skipLeadingWhitespace();
    boolean function = wordParser.startsWith('(');

    // Revert the changes
    wordParser.moveBackward(count + whitespace);

    return function;
  }
 /** {@inheritDoc} */
 @Override
 protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {
   return wordParser.character() == RIGHT_PARENTHESIS
       || word.equalsIgnoreCase(AND)
       || word.equalsIgnoreCase(THEN)
       || word.equalsIgnoreCase(ELSE)
       || super.isParsingComplete(wordParser, word, expression);
 }
 /** {@inheritDoc} */
 @Override
 protected void parse(WordParser wordParser, boolean tolerant) {
   wordParser.moveForward(getText());
 }