/*
 * 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.
 */
<html>
<head>
<title>FreeMarker: Exception Test</title>
</head>
<body>

<p>A simple test follows:</p>

<p>Hello, world! <br />
<!-- Template Error: Couldn't get value of variable test: Couldn't read string value of test: freemarker.template.TemplateModelException: Throwing from ExceptionModel!
	at freemarker.test.templatesuite.models.ExceptionModel.getAsString(ExceptionModel.java:42)
	at freemarker.template.expression.Variable.getValue(Variable.java:69)
	at freemarker.template.instruction.VariableInstruction.process(VariableInstruction.java:55)
	at freemarker.template.compiler.TemplateArrayList.process(TemplateArrayList.java:69)
	at freemarker.template.Template.process(Template.java:226)
	at freemarker.test.TestException2.runTest(TestException2.java:83)
	at junit.framework.TestCase.runBare(TestCase.java:140)
	at junit.framework.TestResult$1.protect(TestResult.java:106)
	at junit.framework.TestResult.runProtected(TestResult.java:124)
	at junit.framework.TestResult.run(TestResult.java:109)
	at junit.framework.TestCase.run(TestCase.java:131)
	at junit.framework.TestSuite.runTest(TestSuite.java:173)
	at junit.framework.TestSuite.run(TestSuite.java:168)
	at junit.swingui.TestRunner$17.run(TestRunner.java:644)
 -->
</p>

</body>
</html>