@Test
void testComplexTemplate() {

  StringBuilder stringBuilder = new StringBuilder();
  stringBuilder
      .append("text before for loop followed by blank line\n")
      .append("{% for item in items %}\n")
      .append("{% if item.itemType equals \"ITEM_TYPE1\" -%}\n")
      .append("Item 1\n")
      .append("{% elseif item.itemType equals \"ITEM_TYPE2\" -%}\n")
      .append("Item 2\n")
      .append("{%- endif -%}")
      .append("{% endfor -%}")
      .append("text after for loop preceded by blank line");
  Loader<String> loader = new StringLoader();
  Reader templateReader = loader.getReader(stringBuilder.toString());
  TokenStream tokenStream = this.lexer.tokenize(templateReader, this.TEMPLATE_NAME);
  int i = 0;
  assertThat(tokenStream.peek(i).getType()).isEqualTo(Type.TEXT);
  assertThat(tokenStream.peek(i++).getValue()).isEqualTo("text before for loop followed by blank line\n");
  assertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_START);
  assertThat(tokenStream.peek(i++).getValue()).isNull();
  assertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
  assertThat(tokenStream.peek(i++).getValue()).isEqualTo("for");
  assertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
  assertThat(tokenStream.peek(i++).getValue()).isEqualTo("item");
  assertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
  assertThat(tokenStream.peek(i++).getValue()).isEqualTo("in");
  assertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
  assertThat(tokenStream.peek(i++).getValue()).isEqualTo("items");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_END);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("%}");
/ note that the new line character included as part of a TEXT token
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.TEXT);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("\n");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_START);
ssertThat(tokenStream.peek(i++).getValue()).isNull(); 
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("if");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("item");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.PUNCTUATION);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo(".");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("itemType");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.OPERATOR);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("equals");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.STRING);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("ITEM_TYPE1");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_END);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("%}"); 
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.TEXT);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("Item 1\n");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_START);
ssertThat(tokenStream.peek(i++).getValue()).isNull(); 
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("elseif");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("item");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.PUNCTUATION);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo(".");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("itemType");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.OPERATOR);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("equals");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.STRING);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("ITEM_TYPE2");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_END);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("%}");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.TEXT);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("Item 2");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_START);
ssertThat(tokenStream.peek(i++).getValue()).isNull(); 
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("endif");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_END);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("%}");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_START);
ssertThat(tokenStream.peek(i++).getValue()).isNull(); 
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.NAME);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("endfor");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EXECUTE_END);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("%}");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.TEXT);
ssertThat(tokenStream.peek(i++).getValue()).isEqualTo("text after for loop preceded by blank line");
ssertThat(tokenStream.peek(i).getType()).isEqualTo(Type.EOF);
ssertThat(tokenStream.peek(i++).getValue()).isNull(); 
}