/*
 * 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
