/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
<!-- Test loading from web.xml-mapped JAR -->
enter TestSimpleTag simpletag1
invoking body i=0
foo
exit TestSimpleTag simpletag1
TestTag2.doStartTag() called here
TestTag2.doEndTag() called here

<!-- Test loading from autodeployed WEB-INF/lib/*.jar -->
TestTag3.doStartTag() called here
TestTag3.doEndTag() called here

<!-- Test loading from root-relative URL -->
TestTag2.doStartTag() called here
TestTag2.doEndTag() called here

<!-- Test loading from non-root-relative URL -->
TestTag2.doStartTag() called here
TestTag2.doEndTag() called here

<!-- Test loading from autodeployed .tld -->
Executed TestSimpleTag2
Executed TestSimpleTag3

<!-- Test loading from FreemarkerServlet "ClasspathTlds" -->
Executed TestSimpleTag2
Executed TestSimpleTag3

<!-- Test loading from "MetaInfTldSources", inherited from Jetty -->
a+b

<!-- Test loading from "MetaInfTldSources", set via init-param -->
Executed TestSimpleTag3
<table>
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>Maried</th></tr></thead>
<tbody>
<tr class="odd">
<td>Joe</td>
<td>30</td>
<td>true</td></tr>
<tr class="even">
<td>Fred</td>
<td>25</td>
<td>false</td></tr>
<tr class="odd">
<td>Emma</td>
<td>28</td>
<td>true</td></tr></tbody></table>

<!-- Test loading from mapped relative URL -->
Executed TestSimpleTag2
