private void checkTokenOrder(final AbstractToken token,
                                     final List<TokenType> consumedTokens) {

            final TokenType tokenType = token.getTokenType();

            final Set<TokenType> keywordsRequiredBefore = TokenType.getKeywordsRequiredBefore(tokenType);

            for (final TokenType requiredType : keywordsRequiredBefore) {
                if (!consumedTokens.contains(requiredType)) {
                    throw new TokenException(token,
                            "Required token " + requiredType + " before " + tokenType);
                }
            }

            final Set<TokenType> keywordsValidBefore = TokenType.getKeywordsValidBefore(tokenType);

            for (final TokenType consumedType : consumedTokens) {
                if (!keywordsValidBefore.contains(consumedType)) {
                    throw new TokenException(token,
                            "Unexpected token " + tokenType + " after " + consumedType);
                }
            }
        }
@param isLenient Ignores any additional child tokens found. This is to support getting just
                 the data source from a partially written query, which is likely to not be
                 a valid query. For example, you may type
                 <pre>{@code from View sel}</pre> and at this point do code completion on 'sel'
                 so if this method is called it will treat 'sel as an extra child.
stroom-query/stroom-query-common/src/main/java/stroom/query/language/SearchRequestFactory.java