KeywordCallState determineInitialKeywordCallState(KeywordCallState initialKeywordCallState) {
    /*
     * in this particular case, we need to do lookahead to see if we have zero or more direct variable references,
     * followed by a variable reference suffixed with an equal sign. If this is the case, those variables will be
     * considered as lvalues and the following argument as a keyword.
     */

    KeywordCallState keywordCallState = scanLine(initialKeywordCallState, line, argOff);
    if (!keywordCallState.isUndetermined()) {
      return keywordCallState;
    }

    outer:
    for (int lineIdx = lineIterator.nextIndex(); lineIdx < lines.size(); ++lineIdx) {
      RobotLine nextLine = lines.get(lineIdx);
      LineType type = nextLine.type;
      switch (type) {
        case COMMENT_LINE:
          continue;
        case CONTINUATION_LINE:
          {
            int nextLineArgOff = determineContinuationLineArgOff(nextLine);
            keywordCallState = scanLine(keywordCallState, nextLine, nextLineArgOff);
            if (!keywordCallState.isUndetermined()) {
              return keywordCallState;
            }
            break;
          }
        default:
          break outer;
      }
    }
    // no equal sign found so..
    return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT
        ? KeywordCallState.KEYWORD_NOT_FOR_NOINDENT
        : KeywordCallState.KEYWORD;
  }
 private KeywordCallState scanLine(
     KeywordCallState initialKeywordCallState, RobotLine scanLine, int scanOff) {
   assert initialKeywordCallState.isUndetermined();
   for (; scanOff < scanLine.arguments.size(); ++scanOff) {
     ParsedString parsedString = scanLine.arguments.get(scanOff);
     if (parsedString.isEmpty()) {
       if (initialKeywordCallState == KeywordCallState.UNDETERMINED) {
         // no variables yet
         continue;
       } else {
         // no equal sign found before first non-variable parameter
         return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT
             ? KeywordCallState.KEYWORD_NOT_FOR_NOINDENT
             : KeywordCallState.KEYWORD;
       }
     }
     String arg = parsedString.getValue();
     switch (arg.charAt(0)) {
       case '$':
       case '@':
         // TODO ensure it's a proper lvalue
         initialKeywordCallState = KeywordCallState.UNDETERMINED_GOTVARIABLE;
         break;
       default:
         // non-variable and no prior lvalue indication, so..
         return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT
             ? KeywordCallState.KEYWORD_NOT_FOR_NOINDENT
             : KeywordCallState.KEYWORD;
     }
     if (arg.endsWith("=")) {
       return initialKeywordCallState == KeywordCallState.UNDETERMINED_NOT_FOR_NOINDENT
           ? KeywordCallState.LVALUE_NOINDENT
           : KeywordCallState.LVALUE;
     }
   }
   return initialKeywordCallState;
 }
 /**
  * Before this is called the first time, keywordSequence_keywordCallState must be initialized to
  * either UNDETERMINED, UNDETERMINED_NOINDENT, KEYWORD_NOINDENT, KEYWORD_NOT_FOR_NOINDENT
  *
  * @param templatesEnabled whether the template flags {@link #globalTemplateAtLine} and {@link
  *     #localTemplateAtLine} affect keyword calls during this invocation
  */
 private void parseKeywordCall(boolean templatesEnabled) {
   if (keywordSequence_keywordCallState.isUndetermined()) {
     keywordSequence_keywordCallState =
         determineInitialKeywordCallState(keywordSequence_keywordCallState);
   }
   switch (keywordSequence_keywordCallState) {
     case LVALUE_NOINDENT:
     case LVALUE:
       {
         ParsedString variable = line.arguments.get(argOff);
         if (!variable.isEmpty()
             || keywordSequence_keywordCallState == KeywordCallState.LVALUE_NOINDENT) {
           variable.setType(ArgumentType.KEYWORD_LVALUE);
           if (variable.getValue().endsWith("=")) {
             keywordSequence_keywordCallState = KeywordCallState.KEYWORD_NOT_FOR_NOINDENT;
           }
         }
         prepareNextToken();
         return;
       }
     case KEYWORD_NOT_FOR_NOINDENT:
     case KEYWORD:
       {
         ParsedString keyword = line.arguments.get(argOff);
         if (!keyword.isEmpty()
             || keywordSequence_keywordCallState == KeywordCallState.KEYWORD_NOT_FOR_NOINDENT) {
           if (keyword.getValue().equals(":FOR")
               && keywordSequence_keywordCallState != KeywordCallState.KEYWORD_NOT_FOR_NOINDENT) {
             keyword.setType(ArgumentType.FOR_PART);
             keywordSequence_keywordCallState = KeywordCallState.FOR_VARS;
           } else {
             if (templatesEnabled && isTemplateActive()) {
               keyword.setType(ArgumentType.KEYWORD_ARG);
               // TODO support "Run Keyword If" etc as template keyword
               keywordSequence_keywordArgPos = KEYWORD_ARG_POS_NONE;
             } else if (NONE_STR.equals(keyword.getValue())) {
               // TODO verify what is this branch about
               keyword.setType(ArgumentType.SETTING_VAL);
               keywordSequence_keywordArgPos = KEYWORD_ARG_POS_NONE;
             } else {
               keyword.setType(ArgumentType.KEYWORD_CALL);
               setUpKeywordArgPos(keyword);
             }
             keywordSequence_keywordCallState = KeywordCallState.KEYWORD_ARGS;
           }
         }
         prepareNextToken();
         return;
       }
     case FOR_VARS:
       {
         ParsedString arg = line.arguments.get(argOff);
         String argVal = arg.getValue();
         if (argVal.equals("IN") || argVal.equals("IN RANGE")) {
           arg.setType(ArgumentType.FOR_PART);
           keywordSequence_keywordCallState = KeywordCallState.FOR_ARGS;
           prepareNextToken();
           return;
         }
         arg.setType(ArgumentType.KEYWORD_LVALUE);
         prepareNextToken();
         return;
       }
     case FOR_ARGS:
       {
         setArgTypesToEol(ArgumentType.KEYWORD_ARG);
         prepareNextLine();
         return;
       }
     case KEYWORD_ARGS:
       {
         ParsedString arg = line.arguments.get(argOff);
         boolean isKeyword;
         switch (keywordSequence_keywordArgPos) {
           case KEYWORD_ARG_POS_NONE:
             isKeyword = false;
             break;
           case KEYWORD_ARG_POS_ALL:
             isKeyword = true;
             break;
           default:
             isKeyword = keywordSequence_currentArgPos++ == keywordSequence_keywordArgPos;
             if (isKeyword) {
               setUpKeywordArgPos(arg);
             }
             break;
         }
         if (isKeyword) {
           arg.setType(ArgumentType.KEYWORD_CALL_DYNAMIC);
         } else {
           arg.setType(ArgumentType.KEYWORD_ARG);
         }
         prepareNextToken();
         return;
       }
     default:
       throw new RuntimeException();
   }
 }