/*
 * 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.
 */
package freemarker.ext.servlet;

import static freemarker.ext.servlet.FreemarkerServlet.*;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

import java.io.IOException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.Locale;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;

import freemarker.cache.ConditionalTemplateConfigurationFactory;
import freemarker.cache.FileNameGlobMatcher;
import freemarker.cache.FirstMatchTemplateConfigurationFactory;
import freemarker.cache.StringTemplateLoader;
import freemarker.cache.TemplateLoader;
import freemarker.core.Environment;
import freemarker.core.TemplateConfiguration;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class FreemarkerServletTest {

    private static final String OUTPUT_FORMAT_HEADER_FTL = "outputFormatHeader.ftl";
    private static final String CONTENT_TYPE_ATTR_FTL = "contentTypeAttr.ftl";
    private static final String CONTENT_TYPE_ATTR_WITH_CHARSET_FTL = "contentTypeAttrWithCharset.ftl";
    private static final String FOO_FTL = "foo.ftl";
    private static final String FOO_SRC_UTF8_FTL = "foo-src-utf8.ftl";
    private static final String FOO_OUT_UTF8_FTL = "foo-out-utf8.ftl";
    private static final String STD_OUTPUT_FORMAT_HTML_FTL = "stdOutputFormatHTML.ftl";
    private static final String STD_OUTPUT_FORMAT_XML_FTL = "stdOutputFormatXML.ftl";
    private static final String STD_OUTPUT_FORMAT_XHTML_FTL = "stdOutputFormatXHTML.ftl";
    private static final String STD_OUTPUT_FORMAT_JAVA_SCRIPT_FTL = "stdOutputFormatJavaScript.ftl";
    private static final String STD_OUTPUT_FORMAT_JSON_FTL = "stdOutputFormatJSON.ftl";
    private static final String STD_OUTPUT_FORMAT_CSS_FTL = "stdOutputFormatCSS.ftl";
    private static final String STD_OUTPUT_FORMAT_PLAIN_TEXT_FTL = "stdOutputFormatPlainText.ftl";
    private static final String STD_OUTPUT_FORMAT_RTF_FTL = "stdOutputFormatRTF.ftl";

    private static final Locale DEFAULT_LOCALE = Locale.US;
    private static final String CFG_DEFAULT_ENCODING = "US-ASCII";
    /** According to the Servlet Specification */
    private static final String SERVLET_RESPONSE_DEFAULT_CHARSET = "ISO-8859-1";
    private static final String DEFAULT_CONTENT_TYPE = "text/html";

    private MockServletContext servletContext;

    @Before
    public void setUp() throws Exception {
        servletContext = new MockServletContext();
        servletContext.setContextPath("/");
    }

    @Test
    public void testContentTypeInitParams() throws Exception {
        // Default is INIT_PARAM_VALUE_ALWAYS, hence null is the same:
        for (String overrideCT : new String[] { null, INIT_PARAM_VALUE_ALWAYS }) {
            assertResponseContentTypeEquals(
                    DEFAULT_CONTENT_TYPE + "; charset=UTF-8", // <- expected
                    null, overrideCT, // <- init-params
                    FOO_FTL, null); // <- request
            assertResponseContentTypeEquals(
                    "text/css; charset=UTF-8", // <- expected
                    "text/css", overrideCT, // <- init-params
                    FOO_FTL, null); // <- request
            assertResponseContentTypeEquals(
                    DEFAULT_CONTENT_TYPE + "; charset=UTF-8", // <- expected
                    null, overrideCT, // <- init-params
                    FOO_FTL, "application/json"); // <- request
            assertResponseContentTypeEquals(
                    "text/css; charset=UTF-8", // <- expected
                    "text/css", overrideCT, // <- init-params
                    FOO_FTL, "application/json"); // <- request
            assertResponseContentTypeEquals(
                    "text/plain", // <- expected
                    null, overrideCT, // <- init-params
                    CONTENT_TYPE_ATTR_FTL, "application/json"); // <- request
            assertResponseContentTypeEquals(
                    "text/plain; charset=UTF-8", // <- expected
                    null, overrideCT, // <- init-params
                    OUTPUT_FORMAT_HEADER_FTL, "application/json"); // <- request
        }

        assertResponseContentTypeEquals(
                DEFAULT_CONTENT_TYPE + "; charset=UTF-8", // <- expected
                null, INIT_PARAM_VALUE_WHEN_TEMPLATE_HAS_MIME_TYPE, // <- init-params
                FOO_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "text/css; charset=UTF-8", // <- expected
                "text/css", INIT_PARAM_VALUE_WHEN_TEMPLATE_HAS_MIME_TYPE, // <- init-params
                FOO_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/json", // <- expected
                null, INIT_PARAM_VALUE_WHEN_TEMPLATE_HAS_MIME_TYPE, // <- init-params
                FOO_FTL, "application/json"); // <- request
        assertResponseContentTypeEquals(
                "application/json", // <- expected
                "text/css", INIT_PARAM_VALUE_WHEN_TEMPLATE_HAS_MIME_TYPE, // <- init-params
                FOO_FTL, "application/json"); // <- request
        assertResponseContentTypeEquals(
                "text/plain", // <- expected
                null, INIT_PARAM_VALUE_WHEN_TEMPLATE_HAS_MIME_TYPE, // <- init-params
                CONTENT_TYPE_ATTR_FTL, "application/json"); // <- request
        assertResponseContentTypeEquals(
                "text/plain; charset=UTF-8", // <- expected
                null, INIT_PARAM_VALUE_WHEN_TEMPLATE_HAS_MIME_TYPE, // <- init-params
                OUTPUT_FORMAT_HEADER_FTL, "application/json"); // <- request

        assertResponseContentTypeEquals(
                DEFAULT_CONTENT_TYPE + "; charset=UTF-8", // <- expected
                null, INIT_PARAM_VALUE_NEVER, // <- init-params
                FOO_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "text/css; charset=UTF-8", // <- expected
                "text/css", INIT_PARAM_VALUE_NEVER, // <- init-params
                FOO_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/json", // <- expected
                null, INIT_PARAM_VALUE_NEVER, // <- init-params
                FOO_FTL, "application/json"); // <- request
        assertResponseContentTypeEquals(
                "application/json", // <- expected
                "text/css", INIT_PARAM_VALUE_NEVER, // <- init-params
                FOO_FTL, "application/json"); // <- request
        assertResponseContentTypeEquals(
                "application/json", // <- expected
                null, INIT_PARAM_VALUE_NEVER, // <- init-params
                CONTENT_TYPE_ATTR_FTL, "application/json"); // <- request
        assertResponseContentTypeEquals(
                "application/json", // <- expected
                null, INIT_PARAM_VALUE_NEVER, // <- init-params
                OUTPUT_FORMAT_HEADER_FTL, "application/json"); // <- request
    }

    @Test
    public void testStandardContentType() throws Exception {
        assertResponseContentTypeEquals(
                "text/html; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_HTML_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/xhtml+xml; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_XHTML_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/xml; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_XML_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/javascript; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_JAVA_SCRIPT_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/json; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_JSON_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "text/css; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_CSS_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "text/plain; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_PLAIN_TEXT_FTL, null); // <- request
        assertResponseContentTypeEquals(
                "application/rtf; charset=UTF-8", // <- expected
                null, null, // <- init-params
                STD_OUTPUT_FORMAT_RTF_FTL, null); // <- request
    }
    
    @Test
    public void testResponseLocaleInitParams() throws Exception {
        assertTemplateLocaleEquals(
                DEFAULT_LOCALE, // <- expected template locale
                null, // <- request locale
                null, // <- init-param
                FOO_FTL);
        assertTemplateLocaleEquals(
                DEFAULT_LOCALE, // <- expected template locale
                Locale.FRENCH, // <- request locale
                null, // <- init-param
                FOO_FTL);
        assertTemplateLocaleEquals(
                DEFAULT_LOCALE, // <- expected template locale
                Locale.FRENCH, // <- request locale
                INIT_PARAM_VALUE_ALWAYS, // <- init-param
                FOO_FTL);
        assertTemplateLocaleEquals(
                DEFAULT_LOCALE, // <- expected template locale
                null, // <- request locale
                INIT_PARAM_VALUE_NEVER, // <- init-param
                FOO_FTL);
        assertTemplateLocaleEquals(
                Locale.FRENCH, // <- expected template locale
                Locale.FRENCH, // <- request locale
                INIT_PARAM_VALUE_NEVER, // <- init-param
                FOO_FTL);
    }

    @Test
    public void testResponseOutputCharsetInitParam() throws Exception {
        for (String initParamValue : new String[] { null, FreemarkerServlet.INIT_PARAM_VALUE_LEGACY }) {
            // Legacy mode is not aware of the outputEncoding, thus it doesn't set it:
            assertOutputEncodingEquals(
                    CFG_DEFAULT_ENCODING, // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    FOO_FTL);
            assertOutputEncodingEquals(
                    CFG_DEFAULT_ENCODING, // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    FOO_FTL);
            // Legacy mode follows the source encoding of the template:
            assertOutputEncodingEquals(
                    "UTF-8", // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    FOO_SRC_UTF8_FTL);
            // Legacy mode doesn't deal with outputEncoding, but it's inherited by the Environment from the Template:
            assertOutputEncodingEquals(
                    CFG_DEFAULT_ENCODING, // <- expected response.characterEncoding
                    "UTF-8", // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    FOO_OUT_UTF8_FTL);
            // Charset in content type is the strongest:
            assertOutputEncodingEquals(
                    "ISO-8859-2", // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    "text/html; charset=ISO-8859-2", // ContentType init-param
                    FOO_FTL);
            assertOutputEncodingEquals(
                    "ISO-8859-2", // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    "text/html; charset=ISO-8859-2", // ContentType init-param
                    FOO_SRC_UTF8_FTL);
            assertOutputEncodingEquals(
                    "UTF-8", // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    CONTENT_TYPE_ATTR_WITH_CHARSET_FTL);
            assertOutputEncodingEquals(
                    "UTF-8", // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    initParamValue, // <- init-param
                    "text/html; charset=ISO-8859-2", // ContentType init-param
                    CONTENT_TYPE_ATTR_WITH_CHARSET_FTL);
        }
        
        // Non-legacy mode always keeps env.outputEncoding in sync. with the Servlet response encoding:
        assertOutputEncodingEquals(
                CFG_DEFAULT_ENCODING, // <- expected response.characterEncoding
                CFG_DEFAULT_ENCODING, // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FROM_TEMPLATE, // <- init-param
                FOO_FTL);
        // Non-legacy mode considers the template-specific outputEncoding:
        assertOutputEncodingEquals(
                "UTF-8", // <- expected response.characterEncoding
                "UTF-8", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FROM_TEMPLATE, // <- init-param
                FOO_OUT_UTF8_FTL);
        // Non-legacy mode uses the template source encoding as a fallback for outputEncoding:
        assertOutputEncodingEquals(
                "UTF-8", // <- expected response.characterEncoding
                "UTF-8", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FROM_TEMPLATE, // <- init-param
                FOO_SRC_UTF8_FTL);
        // Not allowed to specify the charset in the contentType init-param: 
        try {
            assertOutputEncodingEquals(
                    null, // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    FreemarkerServlet.INIT_PARAM_VALUE_FROM_TEMPLATE, // <- init-param
                    "text/html; charset=ISO-8859-2", // ContentType init-param
                    FOO_FTL);
            fail();
        } catch (ServletException e) {
            assertThat(e.getCause().getCause().getMessage(), containsString(FreemarkerServlet.INIT_PARAM_VALUE_LEGACY));
        }
        // But the legacy content_type template attribute can still set the output charset:
        assertOutputEncodingEquals(
                "UTF-8", // <- expected response.characterEncoding
                "UTF-8", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FROM_TEMPLATE, // <- init-param
                CONTENT_TYPE_ATTR_WITH_CHARSET_FTL);
        
        // Do not set mode:
        assertOutputEncodingEquals(
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected response.characterEncoding
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_DO_NOT_SET, // <- init-param
                FOO_FTL);
        assertOutputEncodingEquals(
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected response.characterEncoding
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_DO_NOT_SET, // <- init-param
                FOO_SRC_UTF8_FTL);
        assertOutputEncodingEquals(
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected response.characterEncoding
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_DO_NOT_SET, // <- init-param
                FOO_OUT_UTF8_FTL);
        // Not allowed to specify the charset in the contentType init-param: 
        try {
            assertOutputEncodingEquals(
                    SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected response.characterEncoding
                    SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected env.outputEncoding
                    FreemarkerServlet.INIT_PARAM_VALUE_DO_NOT_SET, // <- init-param
                    "text/html; charset=ISO-8859-2", // ContentType init-param
                    FOO_FTL);
            fail();
        } catch (ServletException e) {
            assertThat(e.getCause().getCause().getMessage(), containsString(FreemarkerServlet.INIT_PARAM_VALUE_LEGACY));
        }
        // The legacy content_type template attribute can still specify an output charset, though it will be ignored:
        assertOutputEncodingEquals(
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected response.characterEncoding
                SERVLET_RESPONSE_DEFAULT_CHARSET, // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_DO_NOT_SET, // <- init-param
                CONTENT_TYPE_ATTR_WITH_CHARSET_FTL);
        
        // Forced mode:
        assertOutputEncodingEquals(
                "UTF-16LE", // <- expected response.characterEncoding
                "UTF-16LE", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
                FOO_FTL);
        assertOutputEncodingEquals(
                "UTF-16LE", // <- expected response.characterEncoding
                "UTF-16LE", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
                FOO_SRC_UTF8_FTL);
        assertOutputEncodingEquals(
                "UTF-16LE", // <- expected response.characterEncoding
                "UTF-16LE", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
                FOO_OUT_UTF8_FTL);
        try {
            assertOutputEncodingEquals(
                    null, // <- expected response.characterEncoding
                    null, // <- expected env.outputEncoding
                    FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "noSuchCharset", // <- init-param
                    FOO_FTL);
            fail();
        } catch (ServletException e) {
            assertThat(e.getCause().getCause(), instanceOf(UnsupportedCharsetException.class));
        }
        // Not allowed to specify the charset in the contentType init-param: 
        try {
            assertOutputEncodingEquals(
                    "UTF-16LE", // <- expected response.characterEncoding
                    "UTF-16LE", // <- expected env.outputEncoding
                    FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
                    "text/html; charset=ISO-8859-2", // ContentType init-param
                    FOO_FTL);
            fail();
        } catch (ServletException e) {
            assertThat(e.getCause().getCause().getMessage(), containsString(FreemarkerServlet.INIT_PARAM_VALUE_LEGACY));
        }
        // The legacy content_type template attribute can still specify an output charset, though it will be overridden:
        assertOutputEncodingEquals(
                "UTF-16LE", // <- expected response.characterEncoding
                "UTF-16LE", // <- expected env.outputEncoding
                FreemarkerServlet.INIT_PARAM_VALUE_FORCE_PREFIX + "UTF-16LE", // <- init-param
                CONTENT_TYPE_ATTR_WITH_CHARSET_FTL);
    }

    private void assertResponseContentTypeEquals(
            String exptectContentType,
            String ctInitParam, String overrideCTInitParam,
            String templateName, String responseCT)
                    throws ServletException, IOException {
        MockHttpServletRequest request = createMockHttpServletRequest(servletContext, templateName, null);

        MockHttpServletResponse response = new MockHttpServletResponse();
        if (responseCT != null) {
            response.setContentType(responseCT);
            assertEquals(responseCT, response.getContentType());
        } else {
            assertNull(response.getContentType());
        }

        MockServletConfig servletConfig = new MockServletConfig(servletContext);
        servletConfig.addInitParameter(Configuration.DEFAULT_ENCODING_KEY, "UTF-8");
        if (ctInitParam != null) {
            servletConfig.addInitParameter(INIT_PARAM_CONTENT_TYPE, ctInitParam);
        }
        if (overrideCTInitParam != null) {
            servletConfig.addInitParameter(INIT_PARAM_OVERRIDE_RESPONSE_CONTENT_TYPE, overrideCTInitParam);
        }

        TestFreemarkerServlet freemarkerServlet = new TestFreemarkerServlet();
        try {
            freemarkerServlet.init(servletConfig);

            freemarkerServlet.doGet(request, response);

            assertEquals(HttpServletResponse.SC_OK, response.getStatus());
            assertEquals(exptectContentType, response.getContentType());
        } finally {
            freemarkerServlet.destroy();
        }
    }

    private void assertTemplateLocaleEquals(
            Locale exptectLocale,
            Locale requestLocale,
            String overrideResponseLocaleInitParam,
            String templateName)
                    throws ServletException, IOException {
        MockHttpServletRequest request = createMockHttpServletRequest(servletContext, templateName, requestLocale);
        MockHttpServletResponse response = new MockHttpServletResponse();

        MockServletConfig servletConfig = new MockServletConfig(servletContext);

        if (overrideResponseLocaleInitParam != null) {
            servletConfig.addInitParameter(INIT_PARAM_OVERRIDE_RESPONSE_LOCALE, overrideResponseLocaleInitParam);
        }

        TestFreemarkerServlet freemarkerServlet = new TestFreemarkerServlet();

        try {
            freemarkerServlet.init(servletConfig);
            freemarkerServlet.doGet(request, response);

            assertEquals(HttpServletResponse.SC_OK, response.getStatus());
            assertEquals(exptectLocale, freemarkerServlet.lastLocale);
            assertEquals(freemarkerServlet.lastLocale, freemarkerServlet.lastMainTemplate.getLocale());
        } finally {
            freemarkerServlet.destroy();
        }
    }

    private void assertOutputEncodingEquals(
            String exptectRespCharacterEncoding,
            String exptectEnvOutputEncoding,
            String responseCharacterEncodingInitParam,
            String templateName) throws ServletException, IOException {
        assertOutputEncodingEquals(
                exptectRespCharacterEncoding, exptectEnvOutputEncoding,
                responseCharacterEncodingInitParam, null,
                templateName);
    }
    
    private void assertOutputEncodingEquals(
            String exptectRespCharacterEncoding,
            String exptectEnvOutputEncoding,
            String responseCharacterEncodingInitParam,
            String contentTypeInitParam,
            String templateName)
                    throws ServletException, IOException {
        MockHttpServletRequest request = createMockHttpServletRequest(servletContext, templateName, null);
        MockHttpServletResponse response = new MockHttpServletResponse();

        MockServletConfig servletConfig = new MockServletConfig(servletContext);

        if (responseCharacterEncodingInitParam != null) {
            servletConfig.addInitParameter(INIT_PARAM_RESPONSE_CHARACTER_ENCODING, responseCharacterEncodingInitParam);
        }
        
        if (contentTypeInitParam != null) {
            servletConfig.addInitParameter(INIT_PARAM_CONTENT_TYPE, contentTypeInitParam);
        }

        TestFreemarkerServlet freemarkerServlet = new TestFreemarkerServlet();

        try {
            freemarkerServlet.init(servletConfig);
            freemarkerServlet.doGet(request, response);

            assertEquals(HttpServletResponse.SC_OK, response.getStatus());
            assertEquals(exptectEnvOutputEncoding, freemarkerServlet.lastOutputEncoding);
            assertEquals(exptectRespCharacterEncoding, response.getCharacterEncoding());
        } finally {
            freemarkerServlet.destroy();
        }
    }

    private MockHttpServletRequest createMockHttpServletRequest(final ServletContext servletContext,
            final String pathInfo, final Locale requestLocale) {
        MockHttpServletRequest servletRequest = new MockHttpServletRequest(servletContext) {

            @Override
            public Locale getLocale() {
                return requestLocale;
            }
        };

        servletRequest.setServerName("localhost");
        servletRequest.setServerPort(8080);
        servletRequest.setContextPath("");
        servletRequest.setRequestURI(pathInfo);
        servletRequest.setPathInfo(pathInfo);

        return servletRequest;
    }

    static class TestFreemarkerServlet extends FreemarkerServlet {

        private Template lastMainTemplate;
        private Locale lastLocale;
        private String lastOutputEncoding;

        @Override
        protected Configuration createConfiguration() {
            Configuration cfg = super.createConfiguration();
            // Needed for the TemplateConfiguration that sets outputEncoding:
            cfg.setIncompatibleImprovements(Configuration.VERSION_2_3_22);

            // Set a test runner environment independent default locale:
            cfg.setLocale(DEFAULT_LOCALE);
            cfg.setDefaultEncoding(CFG_DEFAULT_ENCODING);

            {
                TemplateConfiguration outUtf8TC = new TemplateConfiguration();
                outUtf8TC.setOutputEncoding("UTF-8");
                
                TemplateConfiguration srcUtf8TC = new TemplateConfiguration();
                srcUtf8TC.setEncoding("UTF-8");
                
                cfg.setTemplateConfigurations(
                        new FirstMatchTemplateConfigurationFactory(
                                new ConditionalTemplateConfigurationFactory(
                                        new FileNameGlobMatcher(FOO_SRC_UTF8_FTL), srcUtf8TC),
                                new ConditionalTemplateConfigurationFactory(
                                        new FileNameGlobMatcher(FOO_OUT_UTF8_FTL), outUtf8TC)
                        )
                        .allowNoMatch(true)
                );
            }

            return cfg;
        }

        @Override
        protected TemplateLoader createTemplateLoader(String templatePath) throws IOException {
            // Override default template loader
            if (templatePath.equals("class://")) {
                StringTemplateLoader tl = new StringTemplateLoader();
                
                tl.putTemplate(FOO_FTL, "foo");
                tl.putTemplate(FOO_SRC_UTF8_FTL, "foo");
                tl.putTemplate(FOO_OUT_UTF8_FTL, "foo");
                tl.putTemplate(CONTENT_TYPE_ATTR_FTL, "<#ftl attributes={ 'content_type': 'text/plain' }>foo");
                tl.putTemplate(CONTENT_TYPE_ATTR_WITH_CHARSET_FTL, "<#ftl attributes={ 'content_type': 'text/plain; charset=UTF-8' }>foo");
                tl.putTemplate(OUTPUT_FORMAT_HEADER_FTL, "<#ftl outputFormat='plainText'>foo");
                
                tl.putTemplate(STD_OUTPUT_FORMAT_HTML_FTL, "<#ftl outputFormat='HTML'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_XHTML_FTL, "<#ftl outputFormat='XHTML'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_XML_FTL, "<#ftl outputFormat='XML'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_JAVA_SCRIPT_FTL, "<#ftl outputFormat='JavaScript'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_JSON_FTL, "<#ftl outputFormat='JSON'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_CSS_FTL, "<#ftl outputFormat='CSS'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_PLAIN_TEXT_FTL, "<#ftl outputFormat='plainText'>");
                tl.putTemplate(STD_OUTPUT_FORMAT_RTF_FTL, "<#ftl outputFormat='RTF'>");
                
                return tl;
            } else {
                return super.createTemplateLoader(templatePath);
            }
        }

        @Override
        protected void processEnvironment(Environment env, HttpServletRequest request, HttpServletResponse response)
                throws TemplateException, IOException {
            lastMainTemplate = env.getMainTemplate();
            lastLocale = env.getLocale();
            lastOutputEncoding = env.getOutputEncoding();
            super.processEnvironment(env, request, response);
        }

    }

}