You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 10:13:15 UTC

[sling-org-apache-sling-scripting-thymeleaf] 04/50: SLING-5075 upgrade Thymeleaf to 3.0

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.scripting.thymeleaf-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-scripting-thymeleaf.git

commit a1cd3cbf80372f389501232aa9f4f5326314a164
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Sep 29 14:13:44 2015 +0000

    SLING-5075 upgrade Thymeleaf to 3.0
    
    * use Thymeleaf 3.0.0.ALPHA03 and adjust dependencies
    * refactor and use new Thymeleaf APIs
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/contrib/scripting/thymeleaf@1705867 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md                                          |   6 +-
 pom.xml                                            |  35 +--
 .../thymeleaf/SlingTemplateModeHandler.java        |  30 ---
 ...AttrProcessor.java => DefaultSlingContext.java} |  27 ++-
 .../internal/NonCachingTemplateResolver.java       | 129 +++++++----
 .../internal/ResourceBundleMessageResolver.java    |  14 +-
 .../thymeleaf/internal/SlingResourceResolver.java  |  38 +++-
 .../thymeleaf/internal/SlingWebContext.java        | 124 ----------
 .../thymeleaf/internal/ThymeleafScriptEngine.java  |  11 +-
 .../internal/ThymeleafScriptEngineFactory.java     |  15 +-
 .../thymeleaf/internal/dialect/SlingDialect.java   |  47 ++--
 .../scripting/thymeleaf/internal/dom/NodeUtil.java |  34 ---
 ...va => SlingAddSelectorsAttributeProcessor.java} |  21 +-
 ...or.java => SlingHtmlAttributeTagProcessor.java} |  26 +--
 ...java => SlingIncludeAttributeTagProcessor.java} |  91 ++++----
 .../SlingLocalVariableAttributeTagProcessor.java   |  50 ++++
 ...lingReplaceSelectorsAttributeTagProcessor.java} |  21 +-
 ...> SlingReplaceSuffixAttributeTagProcessor.java} |  21 +-
 ...=> SlingResourceTypeAttributeTagProcessor.java} |  21 +-
 ....java => SlingUnwrapAttributeTagProcessor.java} |  21 +-
 .../attr/SlingNodePropertyAttrProcessor.java       |  52 -----
 .../processor/attr/SlingUnwrapAttrProcessor.java   |  43 ----
 .../AbstractTemplateModeHandler.java               | 110 ---------
 .../Html5TemplateModeHandler.java                  |  64 ------
 .../LegacyHtml5TemplateModeHandler.java            |  64 ------
 .../ValidatingXhtmlTemplateModeHandler.java        |  64 ------
 .../ValidatingXmlTemplateModeHandler.java          |  64 ------
 .../XhtmlTemplateModeHandler.java                  |  64 ------
 .../XmlTemplateModeHandler.java                    |  64 ------
 .../html/AbstractHtmlTemplateParser.java           | 253 ---------------------
 .../OSGI-INF/metatype/metatype.properties          |  35 ++-
 31 files changed, 351 insertions(+), 1308 deletions(-)

diff --git a/README.md b/README.md
index 8078cf6..43afc3b 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,7 @@ scripting engine for [_Thymeleaf_](http://www.thymeleaf.org) templates
 Features
 --------
 
-* out of the box support for _legacy_ HTML5 through embedded _NekoHTML_
-* runtime configurable `TemplateModeHandler`s for _XML_, _VALIDXML_, _XHTML_, _VALIDXHTML_, _HTML5_ and _LEGACYHTML5_
+* simple non-caching `TemplateResolver` supporting `PatternSpec` configurations for all template modes (`HTML`, `XML`, `TEXT`, `JAVASCRIPT`, `CSS`) 
 * `ResourceResolver` backed by Sling's `ResourceResolver`
 * `MessageResolver` backed by `ResourceBundleProvider` from `org.apache.sling.i18n`
 * `SlingDialect`
@@ -20,8 +19,6 @@ For running Sling Scripting Thymeleaf with Sling's Launchpad some dependencies n
     mvn:org.apache.sling/org.apache.sling.i18n/2.2.10
     mvn:org.javassist/javassist/3.18.2-GA
     mvn:commons-io/commons-io/2.4
-    mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xerces/2.11.0_1
-    mvn:org.apache.servicemix.bundles/org.apache.servicemix.bundles.xmlresolver/1.2_5
 
 There is a feature for Karaf:
 
@@ -33,3 +30,4 @@ relevant Thymeleaf issues
 
 * [Create OSGi bundle](https://github.com/thymeleaf/thymeleaf/issues/32)
 * [Remove initialize() steps in extension points](https://github.com/thymeleaf/thymeleaf/issues/54)
+* [keep (custom) IContext accessible](https://github.com/thymeleaf/thymeleaf/issues/388)
diff --git a/pom.xml b/pom.xml
index e4a03c0..c7539fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -29,7 +29,7 @@
   </parent>
 
   <artifactId>org.apache.sling.scripting.thymeleaf</artifactId>
-  <version>0.0.7-SNAPSHOT</version>
+  <version>0.1.7-SNAPSHOT</version>
   <packaging>bundle</packaging>
 
   <name>Apache Sling Scripting Thymeleaf</name>
@@ -38,6 +38,10 @@
   <properties>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    <org.thymeleaf.version>3.0.0.ALPHA03</org.thymeleaf.version>
+    <org.attoparser.version>2.0.0.BETA3</org.attoparser.version>
+    <org.unbescape.version>1.1.1.RELEASE</org.unbescape.version>
+    <ognl.version>3.1</ognl.version>
   </properties>
 
   <scm>
@@ -119,33 +123,27 @@
     <dependency>
       <groupId>org.thymeleaf</groupId>
       <artifactId>thymeleaf</artifactId>
-      <version>2.1.4.RELEASE</version>
+      <version>${org.thymeleaf.version}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>org.unbescape</groupId>
-      <artifactId>unbescape</artifactId>
-      <version>1.1.0.RELEASE</version>
+      <groupId>org.attoparser</groupId>
+      <artifactId>attoparser</artifactId>
+      <version>${org.attoparser.version}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
-      <groupId>net.sourceforge.nekohtml</groupId>
-      <artifactId>nekohtml</artifactId>
-      <version>1.9.21</version>
+      <groupId>org.unbescape</groupId>
+      <artifactId>unbescape</artifactId>
+      <version>${org.unbescape.version}</version>
       <scope>compile</scope>
     </dependency>
     <dependency>
       <groupId>ognl</groupId>
       <artifactId>ognl</artifactId>
-      <version>3.0.8</version>
+      <version>${ognl.version}</version>
       <scope>compile</scope>
     </dependency>
-    <dependency>
-      <groupId>xerces</groupId>
-      <artifactId>xercesImpl</artifactId>
-      <version>2.11.0</version>
-      <scope>provided</scope>
-    </dependency>
     <!-- logging -->
     <dependency>
       <groupId>org.slf4j</groupId>
@@ -174,7 +172,10 @@
           <instructions>
             <Export-Package>
               org.apache.sling.scripting.thymeleaf,
-              org.thymeleaf.*;version="2.1.4.RELEASE"
+              org.thymeleaf.*;version=${org.thymeleaf.version},
+              org.attoparser.*;version=${org.attoparser.version},
+              org.unbescape.*;version=${org.unbescape.version},
+              ognl.*;version=${ognl.version}
             </Export-Package>
             <Import-Package>
               org.apache.commons.io.input;version="1.4.9999",
@@ -184,7 +185,7 @@
               *
             </DynamicImport-Package>
             <Embed-Dependency>
-              *;scope=compile;inline=true;inline=!**/AbstractHtmlTemplateParser*.class
+              *;scope=compile;inline=true
             </Embed-Dependency>
             <ScriptEngine-Name>${project.name}</ScriptEngine-Name>
             <ScriptEngine-Version>${project.version}</ScriptEngine-Version>
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/SlingTemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/SlingTemplateModeHandler.java
deleted file mode 100644
index 66a1c3c..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/SlingTemplateModeHandler.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf;
-
-import aQute.bnd.annotation.ProviderType;
-import org.thymeleaf.PatternSpec;
-import org.thymeleaf.templatemode.ITemplateModeHandler;
-
-@ProviderType
-public interface SlingTemplateModeHandler extends ITemplateModeHandler {
-
-    PatternSpec getPatternSpec();
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/DefaultSlingContext.java
similarity index 54%
copy from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java
copy to src/main/java/org/apache/sling/scripting/thymeleaf/internal/DefaultSlingContext.java
index b28dc0d..a8b6ac4 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/DefaultSlingContext.java
@@ -16,28 +16,27 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal;
 
-public final class SlingResourceTypeAttrProcessor extends SlingNodePropertyAttrProcessor {
+import java.util.Locale;
+import java.util.Map;
 
-    public static final int ATTR_PRECEDENCE = 99;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.scripting.thymeleaf.SlingContext;
+import org.thymeleaf.context.AbstractContext;
 
-    public static final String ATTR_NAME = "resourceType";
+public final class DefaultSlingContext extends AbstractContext implements SlingContext {
 
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
+    private final ResourceResolver resourceResolver;
 
-    public SlingResourceTypeAttrProcessor() {
-        super(ATTR_NAME);
+    public DefaultSlingContext(final ResourceResolver resourceResolver, final Locale locale, final Map<String, Object> variables) {
+        super(locale, variables);
+        this.resourceResolver = resourceResolver;
     }
 
     @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
-    }
-
-    @Override
-    protected String getNodePropertyName() {
-        return NODE_PROPERTY_NAME;
+    public ResourceResolver getResourceResolver() {
+        return resourceResolver;
     }
 
 }
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java
index 67a6fc0..aeda2a1 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/NonCachingTemplateResolver.java
@@ -18,8 +18,9 @@
  */
 package org.apache.sling.scripting.thymeleaf.internal;
 
+import java.util.Collections;
 import java.util.Dictionary;
-import java.util.LinkedHashSet;
+import java.util.HashSet;
 import java.util.Set;
 
 import org.apache.felix.scr.annotations.Activate;
@@ -28,22 +29,23 @@ import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Modified;
 import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.PropertyUnbounded;
 import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.apache.felix.scr.annotations.ReferencePolicy;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.scripting.thymeleaf.SlingTemplateModeHandler;
 import org.osgi.framework.Constants;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.thymeleaf.TemplateProcessingParameters;
+import org.thymeleaf.IEngineConfiguration;
+import org.thymeleaf.cache.ICacheEntryValidity;
+import org.thymeleaf.cache.NonCacheableCacheEntryValidity;
+import org.thymeleaf.context.IContext;
 import org.thymeleaf.resourceresolver.IResourceResolver;
-import org.thymeleaf.templateresolver.ITemplateResolutionValidity;
+import org.thymeleaf.templatemode.TemplateMode;
 import org.thymeleaf.templateresolver.ITemplateResolver;
-import org.thymeleaf.templateresolver.NonCacheableTemplateResolutionValidity;
 import org.thymeleaf.templateresolver.TemplateResolution;
+import org.thymeleaf.util.PatternSpec;
 
 @Component(
     label = "Apache Sling Scripting Thymeleaf “Non-Caching Template Resolver”",
@@ -53,17 +55,20 @@ import org.thymeleaf.templateresolver.TemplateResolution;
 )
 @Service
 @Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "non-caching template resolver for Sling Scripting Thymeleaf")
+    @Property(
+        name = Constants.SERVICE_VENDOR,
+        value = "The Apache Software Foundation"
+    ),
+    @Property(
+        name = Constants.SERVICE_DESCRIPTION,
+        value = "non-caching template resolver for Sling Scripting Thymeleaf"
+    )
 })
 public class NonCachingTemplateResolver implements ITemplateResolver {
 
     @Reference
     private IResourceResolver resourceResolver;
 
-    @Reference(referenceInterface = SlingTemplateModeHandler.class, cardinality = ReferenceCardinality.MANDATORY_MULTIPLE, policy = ReferencePolicy.DYNAMIC)
-    private final Set<SlingTemplateModeHandler> templateModeHandlers = new LinkedHashSet<SlingTemplateModeHandler>();
-
     private Integer order;
 
     public static final int DEFAULT_ORDER = 0;
@@ -78,6 +83,31 @@ public class NonCachingTemplateResolver implements ITemplateResolver {
     @Property(value = DEFAULT_ENCODING)
     public static final String ENCODING_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.encoding";
 
+    private final PatternSpec htmlPatternSpec = new PatternSpec();
+
+    @Property(unbounded = PropertyUnbounded.ARRAY)
+    public static final String HTML_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.htmlPatterns";
+
+    private final PatternSpec xmlPatternSpec = new PatternSpec();
+
+    @Property(unbounded = PropertyUnbounded.ARRAY)
+    public static final String XML_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.xmlPatterns";
+
+    private final PatternSpec textPatternSpec = new PatternSpec();
+
+    @Property(unbounded = PropertyUnbounded.ARRAY)
+    public static final String TEXT_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.textPatterns";
+
+    private final PatternSpec javascriptPatternSpec = new PatternSpec();
+
+    @Property(unbounded = PropertyUnbounded.ARRAY)
+    public static final String JAVASCRIPT_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.javascriptPatterns";
+
+    private final PatternSpec cssPatternSpec = new PatternSpec();
+
+    @Property(unbounded = PropertyUnbounded.ARRAY)
+    public static final String CSS_PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.cssPatterns";
+
     private final Logger logger = LoggerFactory.getLogger(NonCachingTemplateResolver.class);
 
     public NonCachingTemplateResolver() {
@@ -100,20 +130,31 @@ public class NonCachingTemplateResolver implements ITemplateResolver {
         logger.debug("deactivate");
     }
 
-    protected synchronized void bindTemplateModeHandlers(final SlingTemplateModeHandler templateModeHandler) {
-        logger.debug("binding template mode handler '{}'", templateModeHandler.getTemplateModeName());
-        templateModeHandlers.add(templateModeHandler);
-    }
-
-    protected synchronized void unbindTemplateModeHandlers(final SlingTemplateModeHandler templateModeHandler) {
-        logger.debug("unbinding template mode handler '{}'", templateModeHandler.getTemplateModeName());
-        templateModeHandlers.remove(templateModeHandler);
-    }
-
     private void configure(final ComponentContext componentContext) {
         final Dictionary properties = componentContext.getProperties();
         order = PropertiesUtil.toInteger(properties.get(ORDER_PARAMETER), DEFAULT_ORDER);
         encoding = PropertiesUtil.toString(properties.get(ENCODING_PARAMETER), DEFAULT_ENCODING);
+        // HTML
+        final String[] htmlPatterns = PropertiesUtil.toStringArray(properties.get(HTML_PATTERNS_PARAMETER), new String[]{});
+        setPatterns(htmlPatterns, htmlPatternSpec);
+        // XML
+        final String[] xmlPatterns = PropertiesUtil.toStringArray(properties.get(XML_PATTERNS_PARAMETER), new String[]{});
+        setPatterns(xmlPatterns, htmlPatternSpec);
+        // TEXT
+        final String[] textPatterns = PropertiesUtil.toStringArray(properties.get(TEXT_PATTERNS_PARAMETER), new String[]{});
+        setPatterns(textPatterns, textPatternSpec);
+        // JAVASCRIPT
+        final String[] javascriptPatterns = PropertiesUtil.toStringArray(properties.get(JAVASCRIPT_PATTERNS_PARAMETER), new String[]{});
+        setPatterns(javascriptPatterns, javascriptPatternSpec);
+        // CSS
+        final String[] cssPatterns = PropertiesUtil.toStringArray(properties.get(CSS_PATTERNS_PARAMETER), new String[]{});
+        setPatterns(cssPatterns, cssPatternSpec);
+    }
+
+    private void setPatterns(final String[] strings, final PatternSpec patternSpec) {
+        final Set<String> set = new HashSet<String>();
+        Collections.addAll(set, strings);
+        patternSpec.setPatterns(set);
     }
 
     @Override
@@ -127,27 +168,35 @@ public class NonCachingTemplateResolver implements ITemplateResolver {
     }
 
     @Override
-    public TemplateResolution resolveTemplate(TemplateProcessingParameters templateProcessingParameters) {
-        final String templateName = templateProcessingParameters.getTemplateName();
-        final String resourceName = templateName; // TODO
+    public TemplateResolution resolveTemplate(final IEngineConfiguration configuration, final IContext context, final String templateName) {
+        final String resourceName = templateName;
         final String characterEncoding = encoding;
-        final String templateMode = computeTemplateMode(templateName);
-        final ITemplateResolutionValidity validity = new NonCacheableTemplateResolutionValidity();
-        return new TemplateResolution(templateName, resourceName, resourceResolver, characterEncoding, templateMode, validity);
-    }
-
-    @Override
-    public void initialize() {
+        final TemplateMode templateMode = computeTemplateMode(templateName);
+        final ICacheEntryValidity cacheEntryValidity = new NonCacheableCacheEntryValidity();
+        if (templateMode != null) {
+            logger.debug("using template mode '{}' for template '{}'", templateMode, templateName);
+            return new TemplateResolution(templateName, resourceName, resourceResolver, characterEncoding, templateMode, cacheEntryValidity);
+        } else {
+            logger.warn("no template mode for template '{}'", templateName);
+            return null; // will fail at caller
+        }
     }
 
-    protected String computeTemplateMode(final String templateName) {
-        for (final SlingTemplateModeHandler templateModeHandler : templateModeHandlers) {
-            final String templateMode = templateModeHandler.getTemplateModeName();
-            logger.debug("template mode handler '{}' with patterns {}", templateMode, templateModeHandler.getPatternSpec().getPatterns());
-            if (templateModeHandler.getPatternSpec().matches(templateName)) {
-                logger.debug("using template mode '{}' for template '{}'", templateMode, templateName);
-                return templateMode;
-            }
+    private TemplateMode computeTemplateMode(final String templateName) {
+        if (htmlPatternSpec.matches(templateName)) {
+            return TemplateMode.HTML;
+        }
+        if (xmlPatternSpec.matches(templateName)) {
+            return TemplateMode.XML;
+        }
+        if (textPatternSpec.matches(templateName)) {
+            return TemplateMode.TEXT;
+        }
+        if (javascriptPatternSpec.matches(templateName)) {
+            return TemplateMode.JAVASCRIPT;
+        }
+        if (cssPatternSpec.matches(templateName)) {
+            return TemplateMode.CSS;
         }
         return null;
     }
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java
index 7b023a4..69e028c 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ResourceBundleMessageResolver.java
@@ -37,8 +37,7 @@ import org.osgi.framework.Constants;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.thymeleaf.Arguments;
-import org.thymeleaf.context.IContext;
+import org.thymeleaf.context.ITemplateProcessingContext;
 import org.thymeleaf.messageresolver.IMessageResolver;
 import org.thymeleaf.messageresolver.MessageResolution;
 
@@ -105,10 +104,9 @@ public class ResourceBundleMessageResolver implements IMessageResolver {
     }
 
     @Override
-    public MessageResolution resolveMessage(final Arguments arguments, final String key, final Object[] messageParameters) {
-        logger.debug("arguments: {}, key: {}, message parameters: {}", arguments, key, messageParameters);
-        final IContext context = arguments.getContext();
-        final Locale locale = context.getLocale();
+    public MessageResolution resolveMessage(final ITemplateProcessingContext processingContext, final String key, final Object[] messageParameters) {
+        logger.debug("processingContext: {}, key: {}, message parameters: {}", processingContext, key, messageParameters);
+        final Locale locale = processingContext.getLocale();
         final ResourceBundle resourceBundle = resourceBundleProvider.getResourceBundle(locale);
         final String string = resourceBundle.getString(key);
         final MessageFormat messageFormat = new MessageFormat(string, locale);
@@ -116,8 +114,4 @@ public class ResourceBundleMessageResolver implements IMessageResolver {
         return new MessageResolution(message);
     }
 
-    @Override
-    public void initialize() {
-    }
-
 }
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java
index 53aea06..bf5bb14 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingResourceResolver.java
@@ -18,19 +18,25 @@
  */
 package org.apache.sling.scripting.thymeleaf.internal;
 
+import java.io.IOException;
 import java.io.InputStream;
 
+import org.apache.commons.io.IOUtils;
 import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.scripting.SlingScriptConstants;
 import org.apache.sling.scripting.thymeleaf.SlingContext;
 import org.osgi.framework.Constants;
-import org.thymeleaf.TemplateProcessingParameters;
+import org.thymeleaf.IEngineConfiguration;
 import org.thymeleaf.context.IContext;
+import org.thymeleaf.context.IWebVariablesMap;
 import org.thymeleaf.exceptions.TemplateProcessingException;
+import org.thymeleaf.resource.CharArrayResource;
+import org.thymeleaf.resource.IResource;
 import org.thymeleaf.resourceresolver.IResourceResolver;
 import org.thymeleaf.util.Validate;
 
@@ -57,18 +63,32 @@ public class SlingResourceResolver implements IResourceResolver {
     }
 
     @Override
-    public InputStream getResourceAsStream(final TemplateProcessingParameters templateProcessingParameters, final String resourceName) {
-
-        Validate.notNull(templateProcessingParameters, "Template Processing Parameters cannot be null");
-
-        final IContext context = templateProcessingParameters.getContext();
+    public IResource resolveResource(final IEngineConfiguration engineConfiguration, final IContext context, final String resourceName, final String characterEncoding) {
+        Validate.notNull(context, "context cannot be null");
+        Validate.notNull(context, "resource name cannot be null");
         if (context instanceof SlingContext) {
             final SlingContext slingContext = (SlingContext) context;
             final ResourceResolver resourceResolver = slingContext.getResourceResolver();
-            final Resource resource = resourceResolver.getResource(resourceName);
-            return resource.adaptTo(InputStream.class);
+            return resolveResource(resourceResolver, resourceName);
+        } else if (context instanceof IWebVariablesMap) { // TODO Thymeleaf #388
+            final IWebVariablesMap webVariablesMap = (IWebVariablesMap) context;
+            final ResourceResolver resourceResolver = (ResourceResolver) webVariablesMap.getVariable(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER);
+            return resolveResource(resourceResolver, resourceName);
         } else {
-            throw new TemplateProcessingException("Cannot handle context: " + context.getClass().getName());
+            final String message = String.format("Cannot handle context: %s", context.getClass().getName());
+            throw new TemplateProcessingException(message);
+        }
+    }
+
+    private IResource resolveResource(final ResourceResolver resourceResolver, final String resourceName) {
+        final Resource resource = resourceResolver.getResource(resourceName);
+        final InputStream inputStream = resource.adaptTo(InputStream.class);
+        try {
+            final char[] content = IOUtils.toCharArray(inputStream);
+            return new CharArrayResource(resourceName, content);
+        } catch (IOException e) {
+            final String message = String.format("Cannot read from resource '%s'", resourceName);
+            throw new TemplateProcessingException(message, e);
         }
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingWebContext.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingWebContext.java
deleted file mode 100644
index 88cbf49..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/SlingWebContext.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal;
-
-import java.util.Calendar;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.ServletContext;
-import javax.servlet.http.HttpSession;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.resource.ResourceResolver;
-import org.apache.sling.scripting.thymeleaf.SlingContext;
-import org.thymeleaf.context.AbstractContext;
-import org.thymeleaf.context.IWebContext;
-import org.thymeleaf.context.VariablesMap;
-import org.thymeleaf.context.WebContextExecutionInfo;
-import org.thymeleaf.util.Validate;
-
-public final class SlingWebContext implements SlingContext, IWebContext {
-
-    private final SlingHttpServletRequest servletRequest;
-
-    private final SlingHttpServletResponse servletResponse;
-
-    private final ServletContext servletContext;
-
-    private final ResourceResolver resourceResolver;
-
-    private final Locale locale;
-
-    private final VariablesMap<String, Object> variables = new VariablesMap<String, Object>();
-
-    public SlingWebContext(final SlingHttpServletRequest servletRequest, final SlingHttpServletResponse servletResponse, final ServletContext servletContext, final ResourceResolver resourceResolver, final Locale locale, final Map<String, ?> variables) {
-        this.servletRequest = servletRequest;
-        this.servletResponse = servletResponse;
-        this.servletContext = servletContext;
-        this.resourceResolver = resourceResolver;
-        this.locale = locale;
-        this.variables.putAll(variables);
-    }
-
-    @Override
-    public SlingHttpServletRequest getHttpServletRequest() {
-        return servletRequest;
-    }
-
-    @Override
-    public SlingHttpServletResponse getHttpServletResponse() {
-        return servletResponse;
-    }
-
-    @Override
-    public HttpSession getHttpSession() {
-        return servletRequest.getSession(false);
-    }
-
-    @Override
-    public ServletContext getServletContext() {
-        return servletContext;
-    }
-
-    @Override
-    public ResourceResolver getResourceResolver() {
-        return resourceResolver;
-    }
-
-    @Override
-    public Locale getLocale() {
-        return locale;
-    }
-
-    @Override
-    public VariablesMap<String, Object> getVariables() {
-        return variables;
-    }
-
-    @Override
-    public VariablesMap<String, String[]> getRequestParameters() {
-        throw new UnsupportedOperationException("Deprecated method is not supported.");
-    }
-
-    @Override
-    public VariablesMap<String, Object> getRequestAttributes() {
-        throw new UnsupportedOperationException("Deprecated method is not supported.");
-    }
-
-    @Override
-    public VariablesMap<String, Object> getSessionAttributes() {
-        throw new UnsupportedOperationException("Deprecated method is not supported.");
-    }
-
-    @Override
-    public VariablesMap<String, Object> getApplicationAttributes() {
-        throw new UnsupportedOperationException("Deprecated method is not supported.");
-    }
-
-    @Override
-    public void addContextExecutionInfo(String templateName) {
-        Validate.notEmpty(templateName, "Template name cannot be null or empty");
-        final Calendar now = Calendar.getInstance();
-        final WebContextExecutionInfo webContextExecutionInfo = new WebContextExecutionInfo(templateName, now);
-        variables.put(AbstractContext.EXEC_INFO_VARIABLE_NAME, webContextExecutionInfo);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java
index 055e80e..05ae90b 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngine.java
@@ -25,10 +25,7 @@ import java.util.Locale;
 import javax.script.Bindings;
 import javax.script.ScriptContext;
 import javax.script.ScriptException;
-import javax.servlet.ServletContext;
 
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.scripting.SlingBindings;
 import org.apache.sling.api.scripting.SlingScriptConstants;
@@ -58,10 +55,6 @@ public final class ThymeleafScriptEngine extends AbstractSlingScriptEngine {
             throw new ScriptException("SlingScriptHelper missing from bindings");
         }
 
-        final SlingHttpServletRequest request = helper.getRequest();
-        final SlingHttpServletResponse response = helper.getResponse();
-        final ServletContext servletContext = null; // only used by Thymeleaf's ServletContextResourceResolver
-
         ResourceResolver resourceResolver = (ResourceResolver) scriptContext.getAttribute(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER, SlingScriptConstants.SLING_SCOPE);
         if (resourceResolver == null) {
             resourceResolver = helper.getScript().getScriptResource().getResourceResolver();
@@ -71,8 +64,10 @@ public final class ThymeleafScriptEngine extends AbstractSlingScriptEngine {
         final String scriptName = helper.getScript().getScriptResource().getPath();
         final Writer writer = scriptContext.getWriter();
 
+        bindings.put(SlingScriptConstants.ATTR_SCRIPT_RESOURCE_RESOLVER, resourceResolver); // TODO #388
+
         try {
-            final IContext context = new SlingWebContext(request, response, servletContext, resourceResolver, locale, bindings);
+            final IContext context = new DefaultSlingContext(resourceResolver, locale, bindings);
             thymeleafScriptEngineFactory.getTemplateEngine().process(scriptName, context, writer);
         } catch (Exception e) {
             logger.error("Failure rendering Thymeleaf template '{}': {}", scriptName, e.getMessage());
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java
index 776ade3..a374d22 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/ThymeleafScriptEngineFactory.java
@@ -42,6 +42,7 @@ import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.thymeleaf.TemplateEngine;
+import org.thymeleaf.Thymeleaf;
 import org.thymeleaf.dialect.IDialect;
 import org.thymeleaf.messageresolver.IMessageResolver;
 import org.thymeleaf.standard.StandardDialect;
@@ -137,13 +138,13 @@ public final class ThymeleafScriptEngineFactory extends AbstractScriptEngineFact
     }
 
     protected synchronized void bindDialects(final IDialect dialect) {
-        logger.debug("binding a dialect for prefix '{}'", dialect.getPrefix());
+        logger.debug("binding dialect '{}'", dialect.getName());
         dialects.add(dialect);
         configureTemplateEngine();
     }
 
     protected synchronized void unbindDialects(final IDialect dialect) {
-        logger.debug("unbinding a dialect for prefix '{}'", dialect.getPrefix());
+        logger.debug("unbinding dialect '{}'", dialect.getName());
         dialects.remove(dialect);
         configureTemplateEngine();
     }
@@ -164,9 +165,7 @@ public final class ThymeleafScriptEngineFactory extends AbstractScriptEngineFact
     // the configuration of the Thymeleaf TemplateEngine is static and we need to recreate on modification
     private synchronized void configureTemplateEngine() {
         logger.info("configure template engine");
-        if (templateEngine == null || templateEngine.isInitialized()) {
-            templateEngine = new TemplateEngine();
-        }
+        final TemplateEngine templateEngine = new TemplateEngine();
         if (templateResolvers.size() > 0) {
             templateEngine.setTemplateResolvers(templateResolvers);
         }
@@ -178,6 +177,10 @@ public final class ThymeleafScriptEngineFactory extends AbstractScriptEngineFact
             final IDialect standardDialect = new StandardDialect();
             templateEngine.addDialect(standardDialect);
         }
+        // TODO
+        // final ICacheManager cacheManager = null;
+        // templateEngine.setCacheManager(cacheManager);
+        this.templateEngine = templateEngine;
     }
 
     @Override
@@ -187,7 +190,7 @@ public final class ThymeleafScriptEngineFactory extends AbstractScriptEngineFact
 
     @Override
     public String getLanguageVersion() {
-        return "2.1"; // TODO get version from Thymeleaf
+        return Thymeleaf.VERSION;
     }
 
     @Override
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java
index 8adbd90..1ffe8bd 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dialect/SlingDialect.java
@@ -25,14 +25,14 @@ import org.apache.felix.scr.annotations.Component;
 import org.apache.felix.scr.annotations.Properties;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.scripting.thymeleaf.internal.processor.attr.SlingAddSelectorsAttrProcessor;
-import org.apache.sling.scripting.thymeleaf.internal.processor.attr.SlingIncludeAttrProcessor;
-import org.apache.sling.scripting.thymeleaf.internal.processor.attr.SlingReplaceSelectorsAttrProcessor;
-import org.apache.sling.scripting.thymeleaf.internal.processor.attr.SlingReplaceSuffixAttrProcessor;
-import org.apache.sling.scripting.thymeleaf.internal.processor.attr.SlingResourceTypeAttrProcessor;
-import org.apache.sling.scripting.thymeleaf.internal.processor.attr.SlingUnwrapAttrProcessor;
+import org.apache.sling.scripting.thymeleaf.internal.processor.SlingAddSelectorsAttributeProcessor;
+import org.apache.sling.scripting.thymeleaf.internal.processor.SlingIncludeAttributeTagProcessor;
+import org.apache.sling.scripting.thymeleaf.internal.processor.SlingReplaceSelectorsAttributeTagProcessor;
+import org.apache.sling.scripting.thymeleaf.internal.processor.SlingReplaceSuffixAttributeTagProcessor;
+import org.apache.sling.scripting.thymeleaf.internal.processor.SlingResourceTypeAttributeTagProcessor;
+import org.apache.sling.scripting.thymeleaf.internal.processor.SlingUnwrapAttributeTagProcessor;
 import org.osgi.framework.Constants;
-import org.thymeleaf.dialect.AbstractDialect;
+import org.thymeleaf.dialect.AbstractProcessorDialect;
 import org.thymeleaf.processor.IProcessor;
 
 @Component(
@@ -40,27 +40,34 @@ import org.thymeleaf.processor.IProcessor;
 )
 @Service
 @Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "Sling dialect for Sling Scripting Thymeleaf")
+    @Property(
+        name = Constants.SERVICE_VENDOR,
+        value = "The Apache Software Foundation"
+    ),
+    @Property(
+        name = Constants.SERVICE_DESCRIPTION,
+        value = "Sling dialect for Sling Scripting Thymeleaf"
+    )
 })
-public final class SlingDialect extends AbstractDialect {
+public final class SlingDialect extends AbstractProcessorDialect {
+
+    public static final String NAME = "Sling";
 
     public static final String PREFIX = "sling";
 
-    @Override
-    public String getPrefix() {
-        return PREFIX;
+    public SlingDialect() {
+        super(NAME, PREFIX, 0);
     }
 
     @Override
-    public Set<IProcessor> getProcessors() {
+    public Set<IProcessor> getProcessors(final String prefix) {
         final Set<IProcessor> processors = new HashSet<IProcessor>();
-        processors.add(new SlingAddSelectorsAttrProcessor());
-        processors.add(new SlingIncludeAttrProcessor());
-        processors.add(new SlingReplaceSelectorsAttrProcessor());
-        processors.add(new SlingReplaceSuffixAttrProcessor());
-        processors.add(new SlingResourceTypeAttrProcessor());
-        processors.add(new SlingUnwrapAttrProcessor());
+        processors.add(new SlingAddSelectorsAttributeProcessor(this, prefix));
+        processors.add(new SlingIncludeAttributeTagProcessor(this, prefix));
+        processors.add(new SlingReplaceSelectorsAttributeTagProcessor(this, prefix));
+        processors.add(new SlingReplaceSuffixAttributeTagProcessor(this, prefix));
+        processors.add(new SlingResourceTypeAttributeTagProcessor(this, prefix));
+        processors.add(new SlingUnwrapAttributeTagProcessor(this, prefix));
         return processors;
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dom/NodeUtil.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dom/NodeUtil.java
deleted file mode 100644
index 6a29738..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/dom/NodeUtil.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.dom;
-
-import org.thymeleaf.dom.Node;
-
-public final class NodeUtil {
-
-    public static <T> T getNodeProperty(final Node node, final String name, final Class<T> clazz) {
-        final Object nodeProperty = node.getNodeProperty(name);
-        try {
-            return clazz.cast(nodeProperty);
-        } catch (ClassCastException e) {
-            return null;
-        }
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingAddSelectorsAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingAddSelectorsAttributeProcessor.java
similarity index 59%
copy from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingAddSelectorsAttrProcessor.java
copy to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingAddSelectorsAttributeProcessor.java
index 3538976..c63df81 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingAddSelectorsAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingAddSelectorsAttributeProcessor.java
@@ -16,27 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
-public final class SlingAddSelectorsAttrProcessor extends SlingNodePropertyAttrProcessor {
+import org.thymeleaf.dialect.IProcessorDialect;
 
-    public static final int ATTR_PRECEDENCE = 99;
+public final class SlingAddSelectorsAttributeProcessor extends SlingLocalVariableAttributeTagProcessor {
 
-    public static final String ATTR_NAME = "addSelectors";
+    public static final int ATTRIBUTE_PRECEDENCE = 99;
 
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
+    public static final String ATTRIBUTE_NAME = "addSelectors";
 
-    public SlingAddSelectorsAttrProcessor() {
-        super(ATTR_NAME);
-    }
+    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME);
 
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
+    public SlingAddSelectorsAttributeProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) {
+        super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE);
     }
 
     @Override
-    protected String getNodePropertyName() {
+    protected String getLocalVariableName() {
         return NODE_PROPERTY_NAME;
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingAddSelectorsAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingHtmlAttributeTagProcessor.java
similarity index 55%
rename from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingAddSelectorsAttrProcessor.java
rename to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingHtmlAttributeTagProcessor.java
index 3538976..3491477 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingAddSelectorsAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingHtmlAttributeTagProcessor.java
@@ -16,28 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
-public final class SlingAddSelectorsAttrProcessor extends SlingNodePropertyAttrProcessor {
+import org.thymeleaf.dialect.IProcessorDialect;
+import org.thymeleaf.processor.element.AbstractAttributeTagProcessor;
+import org.thymeleaf.templatemode.TemplateMode;
 
-    public static final int ATTR_PRECEDENCE = 99;
+public abstract class SlingHtmlAttributeTagProcessor extends AbstractAttributeTagProcessor {
 
-    public static final String ATTR_NAME = "addSelectors";
-
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
-
-    public SlingAddSelectorsAttrProcessor() {
-        super(ATTR_NAME);
-    }
-
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
-    }
-
-    @Override
-    protected String getNodePropertyName() {
-        return NODE_PROPERTY_NAME;
+    public SlingHtmlAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix, final String attributeName, final int precedence, final boolean removeAttribute) {
+        super(processorDialect, TemplateMode.HTML, dialectPrefix, null, false, attributeName, false, precedence, removeAttribute);
     }
 
 }
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingIncludeAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java
similarity index 65%
rename from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingIncludeAttrProcessor.java
rename to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java
index 1cbcee6..304afb7 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingIncludeAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingIncludeAttributeTagProcessor.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
 import java.io.IOException;
 
@@ -30,51 +30,46 @@ import org.apache.sling.api.resource.Resource;
 import org.apache.sling.api.resource.ResourceUtil;
 import org.apache.sling.api.resource.SyntheticResource;
 import org.apache.sling.scripting.core.servlet.CaptureResponseWrapper;
-import org.apache.sling.scripting.thymeleaf.internal.SlingWebContext;
-import org.apache.sling.scripting.thymeleaf.internal.dom.NodeUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.thymeleaf.Arguments;
-import org.thymeleaf.Configuration;
-import org.thymeleaf.context.IContext;
-import org.thymeleaf.dom.Element;
-import org.thymeleaf.dom.Macro;
-import org.thymeleaf.processor.ProcessorResult;
-import org.thymeleaf.processor.attr.AbstractAttrProcessor;
+import org.thymeleaf.IEngineConfiguration;
+import org.thymeleaf.context.ITemplateProcessingContext;
+import org.thymeleaf.context.IVariablesMap;
+import org.thymeleaf.context.IWebVariablesMap;
+import org.thymeleaf.dialect.IProcessorDialect;
+import org.thymeleaf.engine.AttributeName;
+import org.thymeleaf.model.IProcessableElementTag;
+import org.thymeleaf.processor.element.IElementTagStructureHandler;
 import org.thymeleaf.standard.expression.IStandardExpression;
 import org.thymeleaf.standard.expression.IStandardExpressionParser;
 import org.thymeleaf.standard.expression.StandardExpressions;
 
-public class SlingIncludeAttrProcessor extends AbstractAttrProcessor {
+public class SlingIncludeAttributeTagProcessor extends SlingHtmlAttributeTagProcessor {
 
-    public static final int ATTR_PRECEDENCE = 100;
+    public static final int ATTRIBUTE_PRECEDENCE = 100;
 
-    public static final String ATTR_NAME = "include";
+    public static final String ATTRIBUTE_NAME = "include";
 
-    private final Logger logger = LoggerFactory.getLogger(SlingIncludeAttrProcessor.class);
+    private final Logger logger = LoggerFactory.getLogger(SlingIncludeAttributeTagProcessor.class);
 
-    public SlingIncludeAttrProcessor() {
-        super(ATTR_NAME);
+    public SlingIncludeAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) {
+        super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE, true);
     }
 
     @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
-    }
+    protected void doProcess(final ITemplateProcessingContext processingContext, final IProcessableElementTag tag, final AttributeName attributeName, final String attributeValue, final String tagTemplateName, final int tagLine, final int tagCol, final IElementTagStructureHandler elementTagStructureHandler) {
+        // final IContext context = arguments.getTemplateProcessingParameters().getContext();
+        // if (context instanceof SlingWebContext) {
+        try {
+            final IWebVariablesMap webVariablesMap = (IWebVariablesMap) processingContext.getVariables();
+            final SlingHttpServletRequest slingHttpServletRequest = (SlingHttpServletRequest) webVariablesMap.getRequest();
+            final SlingHttpServletResponse slingHttpServletResponse = (SlingHttpServletResponse) webVariablesMap.getResponse();
+
+            final IEngineConfiguration configuration = processingContext.getConfiguration();
+            final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
+            final IStandardExpression expression = expressionParser.parseExpression(processingContext, attributeValue);
+            final Object include = expression.execute(processingContext);
 
-    @Override
-    protected ProcessorResult processAttribute(final Arguments arguments, final Element element, final String attributeName) {
-        final IContext context = arguments.getTemplateProcessingParameters().getContext();
-        if (context instanceof SlingWebContext) {
-            final SlingWebContext slingWebContext = (SlingWebContext) context;
-            final SlingHttpServletRequest slingHttpServletRequest = slingWebContext.getHttpServletRequest();
-            final SlingHttpServletResponse slingHttpServletResponse = slingWebContext.getHttpServletResponse();
-            // resource or path to include
-            final Configuration configuration = arguments.getConfiguration();
-            final String attributeValue = element.getAttributeValue(attributeName);
-            final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
-            final IStandardExpression expression = parser.parseExpression(configuration, arguments, attributeValue);
-            final Object include = expression.execute(configuration, arguments);
             String path = null;
             if (include instanceof String) {
                 path = (String) include;
@@ -84,30 +79,29 @@ public class SlingIncludeAttrProcessor extends AbstractAttrProcessor {
                 resource = (Resource) include;
             }
             // request dispatcher options
-            final RequestDispatcherOptions requestDispatcherOptions = prepareRequestDispatcherOptions(element);
+            final RequestDispatcherOptions requestDispatcherOptions = prepareRequestDispatcherOptions(webVariablesMap);
             // dispatch
             final String content = dispatch(resource, path, slingHttpServletRequest, slingHttpServletResponse, requestDispatcherOptions);
             // cleanup
-            element.removeAttribute(attributeName);
-            element.clearChildren();
+            tag.getAttributes().removeAttribute(attributeName);
+            // element.clearChildren();
             // add output
-            final Macro macro = new Macro(content);
-            element.addChild(macro);
-            final Boolean unwrap = NodeUtil.getNodeProperty(element, SlingUnwrapAttrProcessor.NODE_PROPERTY_NAME, Boolean.class);
+            final Boolean unwrap = (Boolean) webVariablesMap.getVariable(SlingUnwrapAttributeTagProcessor.NODE_PROPERTY_NAME);
             if (unwrap != null && unwrap) {
-                element.getParent().extractChild(element);
+                elementTagStructureHandler.replaceWith(content, false);
+            } else {
+                elementTagStructureHandler.setBody(content, false);
             }
-        } else {
-            throw new RuntimeException("Context is not an instance of SlingWebContext, unable to process include attribute");
+        } catch (Exception e) {
+            throw new RuntimeException("unable to process include attribute", e);
         }
-        return ProcessorResult.OK;
     }
 
-    protected RequestDispatcherOptions prepareRequestDispatcherOptions(final Element element) {
-        final String resourceType = NodeUtil.getNodeProperty(element, SlingResourceTypeAttrProcessor.NODE_PROPERTY_NAME, String.class);
-        final String replaceSelectors = NodeUtil.getNodeProperty(element, SlingReplaceSelectorsAttrProcessor.NODE_PROPERTY_NAME, String.class);
-        final String addSelectors = NodeUtil.getNodeProperty(element, SlingAddSelectorsAttrProcessor.NODE_PROPERTY_NAME, String.class);
-        final String replaceSuffix = NodeUtil.getNodeProperty(element, SlingReplaceSuffixAttrProcessor.NODE_PROPERTY_NAME, String.class);
+    protected RequestDispatcherOptions prepareRequestDispatcherOptions(final IVariablesMap variablesMap) {
+        final String resourceType = (String) variablesMap.getVariable(SlingResourceTypeAttributeTagProcessor.NODE_PROPERTY_NAME);
+        final String replaceSelectors = (String) variablesMap.getVariable(SlingReplaceSelectorsAttributeTagProcessor.NODE_PROPERTY_NAME);
+        final String addSelectors = (String) variablesMap.getVariable(SlingAddSelectorsAttributeProcessor.NODE_PROPERTY_NAME);
+        final String replaceSuffix = (String) variablesMap.getVariable(SlingReplaceSuffixAttributeTagProcessor.NODE_PROPERTY_NAME);
         final RequestDispatcherOptions options = new RequestDispatcherOptions();
         options.setForceResourceType(resourceType);
         options.setReplaceSelectors(replaceSelectors);
@@ -117,14 +111,13 @@ public class SlingIncludeAttrProcessor extends AbstractAttrProcessor {
     }
 
     /**
-     * @see "org.apache.sling.scripting.jsp.taglib.IncludeTagHandler"
-     *
      * @param resource the resource to include
      * @param path the path to include
      * @param slingHttpServletRequest the current request
      * @param slingHttpServletResponse the current response
      * @param requestDispatcherOptions the options for the request dispatcher
      * @return the character response from the include call to request dispatcher
+     * @see "org.apache.sling.scripting.jsp.taglib.IncludeTagHandler"
      */
     protected String dispatch(Resource resource, String path, final SlingHttpServletRequest slingHttpServletRequest, final SlingHttpServletResponse slingHttpServletResponse, final RequestDispatcherOptions requestDispatcherOptions) {
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingLocalVariableAttributeTagProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingLocalVariableAttributeTagProcessor.java
new file mode 100644
index 0000000..867719a
--- /dev/null
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingLocalVariableAttributeTagProcessor.java
@@ -0,0 +1,50 @@
+/*
+ * 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 org.apache.sling.scripting.thymeleaf.internal.processor;
+
+import org.thymeleaf.IEngineConfiguration;
+import org.thymeleaf.context.ITemplateProcessingContext;
+import org.thymeleaf.dialect.IProcessorDialect;
+import org.thymeleaf.engine.AttributeName;
+import org.thymeleaf.model.IProcessableElementTag;
+import org.thymeleaf.processor.element.IElementTagStructureHandler;
+import org.thymeleaf.standard.expression.IStandardExpression;
+import org.thymeleaf.standard.expression.IStandardExpressionParser;
+import org.thymeleaf.standard.expression.StandardExpressions;
+
+public abstract class SlingLocalVariableAttributeTagProcessor extends SlingHtmlAttributeTagProcessor {
+
+    public static final String LOCAL_VARIABLE_PREFIX = "sling";
+
+    public SlingLocalVariableAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix, final String attributeName, final int precedence) {
+        super(processorDialect, dialectPrefix, attributeName, precedence, true);
+    }
+
+    protected abstract String getLocalVariableName();
+
+    @Override
+    protected void doProcess(final ITemplateProcessingContext templateProcessingContext, final IProcessableElementTag processableElementTag, final AttributeName attributeName, final String attributeValue, final String attributeTemplateName, final int attributeLine, final int attributeCol, final IElementTagStructureHandler structureHandler) {
+        final IEngineConfiguration configuration = templateProcessingContext.getConfiguration();
+        final IStandardExpressionParser expressionParser = StandardExpressions.getExpressionParser(configuration);
+        final IStandardExpression expression = expressionParser.parseExpression(templateProcessingContext, attributeValue);
+        final Object result = expression.execute(templateProcessingContext);
+        structureHandler.setLocalVariable(getLocalVariableName(), result);
+    }
+
+}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSelectorsAttributeTagProcessor.java
similarity index 58%
copy from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java
copy to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSelectorsAttributeTagProcessor.java
index b28dc0d..dec3409 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSelectorsAttributeTagProcessor.java
@@ -16,27 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
-public final class SlingResourceTypeAttrProcessor extends SlingNodePropertyAttrProcessor {
+import org.thymeleaf.dialect.IProcessorDialect;
 
-    public static final int ATTR_PRECEDENCE = 99;
+public final class SlingReplaceSelectorsAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor {
 
-    public static final String ATTR_NAME = "resourceType";
+    public static final int ATTRIBUTE_PRECEDENCE = 99;
 
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
+    public static final String ATTRIBUTE_NAME = "replaceSelectors";
 
-    public SlingResourceTypeAttrProcessor() {
-        super(ATTR_NAME);
-    }
+    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME);
 
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
+    public SlingReplaceSelectorsAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) {
+        super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE);
     }
 
     @Override
-    protected String getNodePropertyName() {
+    protected String getLocalVariableName() {
         return NODE_PROPERTY_NAME;
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingReplaceSelectorsAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSuffixAttributeTagProcessor.java
similarity index 59%
rename from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingReplaceSelectorsAttrProcessor.java
rename to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSuffixAttributeTagProcessor.java
index 3bc6429..1d7ae66 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingReplaceSelectorsAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingReplaceSuffixAttributeTagProcessor.java
@@ -16,27 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
-public final class SlingReplaceSelectorsAttrProcessor extends SlingNodePropertyAttrProcessor {
+import org.thymeleaf.dialect.IProcessorDialect;
 
-    public static final int ATTR_PRECEDENCE = 99;
+public final class SlingReplaceSuffixAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor {
 
-    public static final String ATTR_NAME = "replaceSelectors";
+    public static final int ATTRIBUTE_PRECEDENCE = 99;
 
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
+    public static final String ATTRIBUTE_NAME = "replaceSuffix";
 
-    public SlingReplaceSelectorsAttrProcessor() {
-        super(ATTR_NAME);
-    }
+    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME);
 
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
+    public SlingReplaceSuffixAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) {
+        super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE);
     }
 
     @Override
-    protected String getNodePropertyName() {
+    protected String getLocalVariableName() {
         return NODE_PROPERTY_NAME;
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingReplaceSuffixAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingResourceTypeAttributeTagProcessor.java
similarity index 59%
rename from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingReplaceSuffixAttrProcessor.java
rename to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingResourceTypeAttributeTagProcessor.java
index ed7f4d6..589e9fa 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingReplaceSuffixAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingResourceTypeAttributeTagProcessor.java
@@ -16,27 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
-public final class SlingReplaceSuffixAttrProcessor extends SlingNodePropertyAttrProcessor {
+import org.thymeleaf.dialect.IProcessorDialect;
 
-    public static final int ATTR_PRECEDENCE = 99;
+public final class SlingResourceTypeAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor {
 
-    public static final String ATTR_NAME = "replaceSuffix";
+    public static final int ATTRIBUTE_PRECEDENCE = 99;
 
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
+    public static final String ATTRIBUTE_NAME = "resourceType";
 
-    public SlingReplaceSuffixAttrProcessor() {
-        super(ATTR_NAME);
-    }
+    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME);
 
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
+    public SlingResourceTypeAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) {
+        super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE);
     }
 
     @Override
-    protected String getNodePropertyName() {
+    protected String getLocalVariableName() {
         return NODE_PROPERTY_NAME;
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingUnwrapAttributeTagProcessor.java
similarity index 60%
rename from src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java
rename to src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingUnwrapAttributeTagProcessor.java
index b28dc0d..ee0e0dc 100644
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingResourceTypeAttrProcessor.java
+++ b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/SlingUnwrapAttributeTagProcessor.java
@@ -16,27 +16,24 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.scripting.thymeleaf.internal.processor.attr;
+package org.apache.sling.scripting.thymeleaf.internal.processor;
 
-public final class SlingResourceTypeAttrProcessor extends SlingNodePropertyAttrProcessor {
+import org.thymeleaf.dialect.IProcessorDialect;
 
-    public static final int ATTR_PRECEDENCE = 99;
+public final class SlingUnwrapAttributeTagProcessor extends SlingLocalVariableAttributeTagProcessor {
 
-    public static final String ATTR_NAME = "resourceType";
+    public static final int ATTRIBUTE_PRECEDENCE = 99;
 
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
+    public static final String ATTRIBUTE_NAME = "unwrap";
 
-    public SlingResourceTypeAttrProcessor() {
-        super(ATTR_NAME);
-    }
+    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", LOCAL_VARIABLE_PREFIX, ATTRIBUTE_NAME);
 
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
+    public SlingUnwrapAttributeTagProcessor(final IProcessorDialect processorDialect, final String dialectPrefix) {
+        super(processorDialect, dialectPrefix, ATTRIBUTE_NAME, ATTRIBUTE_PRECEDENCE);
     }
 
     @Override
-    protected String getNodePropertyName() {
+    protected String getLocalVariableName() {
         return NODE_PROPERTY_NAME;
     }
 
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingNodePropertyAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingNodePropertyAttrProcessor.java
deleted file mode 100644
index 317d123..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingNodePropertyAttrProcessor.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.processor.attr;
-
-import org.thymeleaf.Arguments;
-import org.thymeleaf.Configuration;
-import org.thymeleaf.dom.Element;
-import org.thymeleaf.processor.ProcessorResult;
-import org.thymeleaf.processor.attr.AbstractAttrProcessor;
-import org.thymeleaf.standard.expression.IStandardExpression;
-import org.thymeleaf.standard.expression.IStandardExpressionParser;
-import org.thymeleaf.standard.expression.StandardExpressions;
-
-public abstract class SlingNodePropertyAttrProcessor extends AbstractAttrProcessor {
-
-    public static final String PREFIX = "sling";
-
-    public SlingNodePropertyAttrProcessor(final String attributeName) {
-        super(attributeName);
-    }
-
-    protected abstract String getNodePropertyName();
-
-    @Override
-    protected ProcessorResult processAttribute(final Arguments arguments, final Element element, final String attributeName) {
-        final Configuration configuration = arguments.getConfiguration();
-        final String attributeValue = element.getAttributeValue(attributeName);
-        final IStandardExpressionParser parser = StandardExpressions.getExpressionParser(configuration);
-        final IStandardExpression expression = parser.parseExpression(configuration, arguments, attributeValue);
-        final Object result = expression.execute(configuration, arguments);
-        element.setNodeProperty(getNodePropertyName(), result);
-        element.removeAttribute(attributeName);
-        return ProcessorResult.OK;
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingUnwrapAttrProcessor.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingUnwrapAttrProcessor.java
deleted file mode 100644
index a27c5f3..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/processor/attr/SlingUnwrapAttrProcessor.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.processor.attr;
-
-public final class SlingUnwrapAttrProcessor extends SlingNodePropertyAttrProcessor {
-
-    public static final int ATTR_PRECEDENCE = 99;
-
-    public static final String ATTR_NAME = "unwrap";
-
-    public static final String NODE_PROPERTY_NAME = String.format("%s.%s", PREFIX, ATTR_NAME);
-
-    public SlingUnwrapAttrProcessor() {
-        super(ATTR_NAME);
-    }
-
-    @Override
-    public int getPrecedence() {
-        return ATTR_PRECEDENCE;
-    }
-
-    @Override
-    protected String getNodePropertyName() {
-        return NODE_PROPERTY_NAME;
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/AbstractTemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/AbstractTemplateModeHandler.java
deleted file mode 100644
index f20d8ac..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/AbstractTemplateModeHandler.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.sling.scripting.thymeleaf.SlingTemplateModeHandler;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.thymeleaf.PatternSpec;
-import org.thymeleaf.templateparser.ITemplateParser;
-import org.thymeleaf.templatewriter.ITemplateWriter;
-
-public abstract class AbstractTemplateModeHandler implements SlingTemplateModeHandler {
-
-    private final String templateModeName;
-
-    private final ITemplateParser templateParser;
-
-    private final ITemplateWriter templateWriter;
-
-    private PatternSpec patternSpec;
-
-    // see StandardTemplateModeHandlers#MAX_PARSERS_POOL_SIZE
-    private static final int MAX_PARSERS_POOL_SIZE = 24;
-
-    private final Logger logger = LoggerFactory.getLogger(AbstractTemplateModeHandler.class);
-
-    protected AbstractTemplateModeHandler(final String templateModeName, final ITemplateParser templateParser, final ITemplateWriter templateWriter) {
-        this.templateModeName = templateModeName;
-        this.templateParser = templateParser;
-        this.templateWriter = templateWriter;
-    }
-
-    @Activate
-    protected void activate(final ComponentContext componentContext) {
-        logger.debug("activate");
-        configure(componentContext);
-    }
-
-    @Modified
-    protected void modified(final ComponentContext componentContext) {
-        logger.debug("modified");
-        configure(componentContext);
-    }
-
-    @Deactivate
-    protected void deactivate(final ComponentContext componentContext) {
-        logger.debug("deactivate");
-    }
-
-    protected abstract void configure(final ComponentContext componentContext);
-
-    protected void configurePatternSpec(final String[] strings) {
-        final Set<String> set = new HashSet<String>();
-        Collections.addAll(set, strings);
-        final PatternSpec patternSpec = new PatternSpec(); // isInitialized() is private, so create a new PatternSpec
-        patternSpec.setPatterns(set);
-        this.patternSpec = patternSpec;
-    }
-
-    @Override
-    public String getTemplateModeName() {
-        return templateModeName;
-    }
-
-    @Override
-    public ITemplateParser getTemplateParser() {
-        return templateParser;
-    }
-
-    @Override
-    public ITemplateWriter getTemplateWriter() {
-        return templateWriter;
-    }
-
-    @Override
-    public PatternSpec getPatternSpec() {
-        return patternSpec;
-    }
-
-    // see StandardTemplateModeHandlers
-    protected static int poolSize() {
-        final int availableProcessors = Runtime.getRuntime().availableProcessors();
-        return Math.min((availableProcessors <= 2 ? availableProcessors : availableProcessors - 1), MAX_PARSERS_POOL_SIZE);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/Html5TemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/Html5TemplateModeHandler.java
deleted file mode 100644
index fd68c1d..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/Html5TemplateModeHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Dictionary;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
-import org.thymeleaf.templateparser.xmlsax.XhtmlAndHtml5NonValidatingSAXTemplateParser;
-import org.thymeleaf.templatewriter.XhtmlHtml5TemplateWriter;
-
-@Component(
-    label = "Apache Sling Scripting Thymeleaf “HTML5 Template Mode Handler”",
-    description = "HTML5 template mode handler for Sling Scripting Thymeleaf",
-    immediate = true,
-    metatype = true,
-    policy = ConfigurationPolicy.REQUIRE
-)
-@Service
-@Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "HTML5 template mode handler for Sling Scripting Thymeleaf")
-})
-public class Html5TemplateModeHandler extends AbstractTemplateModeHandler {
-
-    public static final String TEMPLATE_MODE_NAME = "HTML5";
-
-    @Property(unbounded = PropertyUnbounded.ARRAY)
-    public static final String PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.Html5TemplateModeHandler.patterns";
-
-    public Html5TemplateModeHandler() {
-        super(TEMPLATE_MODE_NAME, new XhtmlAndHtml5NonValidatingSAXTemplateParser(poolSize()), new XhtmlHtml5TemplateWriter());
-    }
-
-    protected void configure(final ComponentContext componentContext) {
-        final Dictionary properties = componentContext.getProperties();
-        final String[] strings = PropertiesUtil.toStringArray(properties.get(PATTERNS_PARAMETER), new String[]{});
-        configurePatternSpec(strings);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/LegacyHtml5TemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/LegacyHtml5TemplateModeHandler.java
deleted file mode 100644
index dc92716..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/LegacyHtml5TemplateModeHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Dictionary;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
-import org.thymeleaf.templateparser.html.LegacyHtml5TemplateParser;
-import org.thymeleaf.templatewriter.XmlTemplateWriter;
-
-@Component(
-    label = "Apache Sling Scripting Thymeleaf “Legacy HTML5 Template Mode Handler”",
-    description = "legacy HTML5 template mode handler for Sling Scripting Thymeleaf",
-    immediate = true,
-    metatype = true,
-    policy = ConfigurationPolicy.REQUIRE
-)
-@Service
-@Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "legacy HTML5 template mode handler for Sling Scripting Thymeleaf")
-})
-public class LegacyHtml5TemplateModeHandler extends AbstractTemplateModeHandler {
-
-    public static final String TEMPLATE_MODE_NAME = "LEGACYHTML5";
-
-    @Property(unbounded = PropertyUnbounded.ARRAY)
-    public static final String PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.LegacyHtml5TemplateModeHandler.patterns";
-
-    public LegacyHtml5TemplateModeHandler() {
-        super(TEMPLATE_MODE_NAME, new LegacyHtml5TemplateParser(TEMPLATE_MODE_NAME, poolSize()), new XmlTemplateWriter());
-    }
-
-    protected void configure(final ComponentContext componentContext) {
-        final Dictionary properties = componentContext.getProperties();
-        final String[] strings = PropertiesUtil.toStringArray(properties.get(PATTERNS_PARAMETER), new String[]{});
-        configurePatternSpec(strings);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/ValidatingXhtmlTemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/ValidatingXhtmlTemplateModeHandler.java
deleted file mode 100644
index 8c4bc59..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/ValidatingXhtmlTemplateModeHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Dictionary;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
-import org.thymeleaf.templateparser.xmlsax.XhtmlAndHtml5NonValidatingSAXTemplateParser;
-import org.thymeleaf.templatewriter.XhtmlHtml5TemplateWriter;
-
-@Component(
-    label = "Apache Sling Scripting Thymeleaf “Validating XHTML Template Mode Handler”",
-    description = "validating XHTML template mode handler for Sling Scripting Thymeleaf",
-    immediate = true,
-    metatype = true,
-    policy = ConfigurationPolicy.REQUIRE
-)
-@Service
-@Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "validating XHTML template mode handler for Sling Scripting Thymeleaf")
-})
-public class ValidatingXhtmlTemplateModeHandler extends AbstractTemplateModeHandler {
-
-    public static final String TEMPLATE_MODE_NAME = "VALIDXHTML";
-
-    @Property(unbounded = PropertyUnbounded.ARRAY)
-    public static final String PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.ValidatingXhtmlTemplateModeHandler.patterns";
-
-    public ValidatingXhtmlTemplateModeHandler() {
-        super(TEMPLATE_MODE_NAME, new XhtmlAndHtml5NonValidatingSAXTemplateParser(poolSize()), new XhtmlHtml5TemplateWriter());
-    }
-
-    protected void configure(final ComponentContext componentContext) {
-        final Dictionary properties = componentContext.getProperties();
-        final String[] strings = PropertiesUtil.toStringArray(properties.get(PATTERNS_PARAMETER), new String[]{});
-        configurePatternSpec(strings);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/ValidatingXmlTemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/ValidatingXmlTemplateModeHandler.java
deleted file mode 100644
index c92fe86..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/ValidatingXmlTemplateModeHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Dictionary;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
-import org.thymeleaf.templateparser.xmlsax.XmlValidatingSAXTemplateParser;
-import org.thymeleaf.templatewriter.XmlTemplateWriter;
-
-@Component(
-    label = "Apache Sling Scripting Thymeleaf “Validating XML Template Mode Handler”",
-    description = "validating XML template mode handler for Sling Scripting Thymeleaf",
-    immediate = true,
-    metatype = true,
-    policy = ConfigurationPolicy.REQUIRE
-)
-@Service
-@Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "validating XML template mode handler for Sling Scripting Thymeleaf")
-})
-public class ValidatingXmlTemplateModeHandler extends AbstractTemplateModeHandler {
-
-    public static final String TEMPLATE_MODE_NAME = "VALIDXML";
-
-    @Property(unbounded = PropertyUnbounded.ARRAY)
-    public static final String PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.ValidatingXmlTemplateModeHandler.patterns";
-
-    public ValidatingXmlTemplateModeHandler() {
-        super(TEMPLATE_MODE_NAME, new XmlValidatingSAXTemplateParser(poolSize()), new XmlTemplateWriter());
-    }
-
-    protected void configure(final ComponentContext componentContext) {
-        final Dictionary properties = componentContext.getProperties();
-        final String[] strings = PropertiesUtil.toStringArray(properties.get(PATTERNS_PARAMETER), new String[]{});
-        configurePatternSpec(strings);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/XhtmlTemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/XhtmlTemplateModeHandler.java
deleted file mode 100644
index 9d0cd2f..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/XhtmlTemplateModeHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Dictionary;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
-import org.thymeleaf.templateparser.xmlsax.XhtmlAndHtml5NonValidatingSAXTemplateParser;
-import org.thymeleaf.templatewriter.XhtmlHtml5TemplateWriter;
-
-@Component(
-    label = "Apache Sling Scripting Thymeleaf “XHTML Template Mode Handler”",
-    description = "XHTML template mode handler for Sling Scripting Thymeleaf",
-    immediate = true,
-    metatype = true,
-    policy = ConfigurationPolicy.REQUIRE
-)
-@Service
-@Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "XHTML template mode handler for Sling Scripting Thymeleaf")
-})
-public class XhtmlTemplateModeHandler extends AbstractTemplateModeHandler {
-
-    public static final String TEMPLATE_MODE_NAME = "XHTML";
-
-    @Property(unbounded = PropertyUnbounded.ARRAY)
-    public static final String PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.XhtmlTemplateModeHandler.patterns";
-
-    public XhtmlTemplateModeHandler() {
-        super(TEMPLATE_MODE_NAME, new XhtmlAndHtml5NonValidatingSAXTemplateParser(poolSize()), new XhtmlHtml5TemplateWriter());
-    }
-
-    protected void configure(final ComponentContext componentContext) {
-        final Dictionary properties = componentContext.getProperties();
-        final String[] strings = PropertiesUtil.toStringArray(properties.get(PATTERNS_PARAMETER), new String[]{});
-        configurePatternSpec(strings);
-    }
-
-}
diff --git a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/XmlTemplateModeHandler.java b/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/XmlTemplateModeHandler.java
deleted file mode 100644
index d55c8a9..0000000
--- a/src/main/java/org/apache/sling/scripting/thymeleaf/internal/templatemodehandler/XmlTemplateModeHandler.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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 org.apache.sling.scripting.thymeleaf.internal.templatemodehandler;
-
-import java.util.Dictionary;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.ConfigurationPolicy;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.PropertyUnbounded;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.osgi.framework.Constants;
-import org.osgi.service.component.ComponentContext;
-import org.thymeleaf.templateparser.xmlsax.XmlNonValidatingSAXTemplateParser;
-import org.thymeleaf.templatewriter.XmlTemplateWriter;
-
-@Component(
-    label = "Apache Sling Scripting Thymeleaf “XML Template Mode Handler”",
-    description = "XML template mode handler for Sling Scripting Thymeleaf",
-    immediate = true,
-    metatype = true,
-    policy = ConfigurationPolicy.REQUIRE
-)
-@Service
-@Properties({
-    @Property(name = Constants.SERVICE_VENDOR, value = "The Apache Software Foundation"),
-    @Property(name = Constants.SERVICE_DESCRIPTION, value = "XML template mode handler for Sling Scripting Thymeleaf")
-})
-public class XmlTemplateModeHandler extends AbstractTemplateModeHandler {
-
-    public static final String TEMPLATE_MODE_NAME = "XML";
-
-    @Property(unbounded = PropertyUnbounded.ARRAY)
-    public static final String PATTERNS_PARAMETER = "org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.XmlTemplateModeHandler.patterns";
-
-    public XmlTemplateModeHandler() {
-        super(TEMPLATE_MODE_NAME, new XmlNonValidatingSAXTemplateParser(poolSize()), new XmlTemplateWriter());
-    }
-
-    protected void configure(final ComponentContext componentContext) {
-        final Dictionary properties = componentContext.getProperties();
-        final String[] strings = PropertiesUtil.toStringArray(properties.get(PATTERNS_PARAMETER), new String[]{});
-        configurePatternSpec(strings);
-    }
-
-}
diff --git a/src/main/java/org/thymeleaf/templateparser/html/AbstractHtmlTemplateParser.java b/src/main/java/org/thymeleaf/templateparser/html/AbstractHtmlTemplateParser.java
deleted file mode 100755
index d4a4ddd..0000000
--- a/src/main/java/org/thymeleaf/templateparser/html/AbstractHtmlTemplateParser.java
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * =============================================================================
- *
- *   Copyright (c) 2011-2014, The THYMELEAF team (http://www.thymeleaf.org)
- *
- *   Licensed 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 org.thymeleaf.templateparser.html;
-
-import java.io.Reader;
-import java.io.StringReader;
-import java.util.List;
-
-import org.apache.xerces.parsers.DOMParser;
-import org.cyberneko.html.HTMLConfiguration;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.thymeleaf.Configuration;
-import org.thymeleaf.dom.Document;
-import org.thymeleaf.dom.Node;
-import org.thymeleaf.exceptions.ConfigurationException;
-import org.thymeleaf.exceptions.TemplateInputException;
-import org.thymeleaf.exceptions.TemplateProcessingException;
-import org.thymeleaf.templateparser.EntityResolver;
-import org.thymeleaf.templateparser.ErrorHandler;
-import org.thymeleaf.templateparser.ITemplateParser;
-import org.thymeleaf.templateparser.TemplatePreprocessingReader;
-import org.thymeleaf.util.ResourcePool;
-import org.thymeleaf.util.StandardDOMTranslator;
-import org.xml.sax.InputSource;
-
-// NOTE: This is a slightly modified class. The nasty class loader stuff is removed to not break on OSGi.
-
-/**
- * <p>
- *   Document parser implementation for non-XML HTML documents.
- * </p>
- *
- * @since 2.0.0
- *
- * @author Daniel Fern&aacute;ndez
- */
-public abstract class AbstractHtmlTemplateParser implements ITemplateParser {
-
-    private static final int BUFFER_SIZE = 8192;
-
-    private final String templateModeName;
-    private final NekoBasedHtmlParser parser;
-
-
-    protected AbstractHtmlTemplateParser(final String templateModeName, final int poolSize) {
-        this.templateModeName = templateModeName;
-        parser = new NekoBasedHtmlParser(poolSize);
-    }
-
-
-
-
-
-    public final Document parseTemplate(final Configuration configuration, final String documentName, final Reader reader) {
-        return this.parser.parseTemplate(configuration, documentName, getTemplatePreprocessingReader(reader));
-    }
-
-
-
-
-    public final List<Node> parseFragment(final Configuration configuration, final String fragment) {
-        final String wrappedFragment = wrapFragment(fragment);
-        final Document document =
-                parseTemplate(
-                        configuration,
-                        null, // documentName
-                        new StringReader(wrappedFragment));
-        return unwrapFragment(document);
-    }
-
-
-    protected abstract String wrapFragment(final String fragment);
-    protected abstract List<Node> unwrapFragment(final Document document);
-
-
-
-
-
-    /*
-     * This is defined in a class apart so that the classloader does not always try to load
-     * neko and xerces classes that might not be in the classpath.
-     */
-    private static class NekoBasedHtmlParser {
-
-
-        private final Logger logger = LoggerFactory.getLogger(this.getClass());
-        // The org.apache.xerces.parsers.DOMParser is not used here as a type
-        // parameter to avoid the class loader to try to load this xerces class
-        // (and fail) before we control the error at the constructor.
-        private final ResourcePool<Object> pool;
-        private boolean canResetParsers = true;
-
-
-        private NekoBasedHtmlParser(final int poolSize) {
-            super();
-            this.pool = new ResourcePool<Object>(new HtmlTemplateParserFactory(), poolSize);
-        }
-
-
-
-
-        public final Document parseTemplate(final Configuration configuration, final String documentName,
-                final TemplatePreprocessingReader templateReader) {
-
-            final DOMParser domParser = (DOMParser) this.pool.allocate();
-
-            try {
-
-                domParser.setErrorHandler(ErrorHandler.INSTANCE);
-                domParser.setEntityResolver(new EntityResolver(configuration));
-
-                domParser.parse(new InputSource(templateReader));
-                final org.w3c.dom.Document domDocument = domParser.getDocument();
-
-                if (this.canResetParsers) {
-                    try {
-                        /*
-                         * Reset the parser so that it can be used again.
-                         */
-                        domParser.reset();
-                    } catch (final UnsupportedOperationException ignored) {
-                        if (this.logger.isWarnEnabled()) {
-                            this.logger.warn(
-                                    "[THYMELEAF] The HTML Parser implementation being used (\"{}\") does not implement " +
-                                        "the \"reset\" operation. This will force Thymeleaf to re-create parser instances " +
-                                        "each time they are needed for parsing templates, which is more costly. Enabling template " +
-                                        "cache is recommended, and also using a parser library which implements \"reset\" such as " +
-                                        "nekoHTML version 1.9.15 or newer.",
-                                    domParser.getClass().getName());
-                        }
-                        this.canResetParsers = false;
-                    }
-                }
-
-                return StandardDOMTranslator.translateDocument(domDocument, documentName, templateReader.getDocTypeClause());
-
-            } catch (final TemplateProcessingException e) {
-                throw e;
-            } catch (final Exception e) {
-                throw new TemplateInputException("Exception parsing document", e);
-            } finally {
-
-                if (templateReader != null) {
-                    try {
-                        templateReader.close();
-                    } catch (final Exception ignored) {
-                        // ignored
-                    }
-                }
-
-                if (this.canResetParsers) {
-                    this.pool.release(domParser);
-                } else {
-                    this.pool.discardAndReplace(domParser);
-                }
-
-            }
-        }
-
-
-    }
-
-
-
-    static class HtmlTemplateParserFactory implements ResourcePool.IResourceFactory<Object> {
-
-        HtmlTemplateParserFactory() {
-            super();
-        }
-
-
-        public Object createResource() {
-
-            try {
-
-                final HTMLConfiguration config = new HTMLConfiguration();
-
-                config.setFeature("http://xml.org/sax/features/namespaces", false);
-                config.setFeature("http://cyberneko.org/html/features/override-doctype", true);
-                config.setFeature("http://cyberneko.org/html/features/scanner/cdata-sections", true);
-
-                // Avoids the inclusion of <HTML><BODY>, etc. around template fragments. Tag balancing will only
-                // be performed inside the fragments' root nodes.
-                config.setFeature("http://cyberneko.org/html/features/balance-tags/document-fragment", true);
-
-                config.setProperty("http://cyberneko.org/html/properties/doctype/pubid", "");
-                config.setProperty("http://cyberneko.org/html/properties/doctype/sysid", "");
-                config.setProperty("http://cyberneko.org/html/properties/names/elems", "match");
-                config.setProperty("http://cyberneko.org/html/properties/names/attrs", "no-change");
-
-                return new DOMParser(config);
-
-            } catch(final Exception e) {
-                throw new ConfigurationException(
-                    "Error while creating nekoHTML-based parser for " +
-                    "LEGACYHTML5 template modes.", e);
-            }
-
-        }
-
-
-    }
-
-
-
-
-    /**
-     *
-     * @return the result
-     * @since 2.0.11
-     */
-    protected boolean shouldAddThymeleafRootToParser() {
-        return false;
-    }
-
-
-
-    /**
-     *
-     * @param reader reader
-     * @return the result
-     * @since 2.0.11
-     */
-    protected TemplatePreprocessingReader getTemplatePreprocessingReader(final Reader reader) {
-        if (reader instanceof TemplatePreprocessingReader) {
-            final TemplatePreprocessingReader templatePreprocessingReader = (TemplatePreprocessingReader) reader;
-            return new TemplatePreprocessingReader(
-                    templatePreprocessingReader.getInnerReader(), BUFFER_SIZE, shouldAddThymeleafRootToParser());
-        }
-        return new TemplatePreprocessingReader(reader, BUFFER_SIZE, shouldAddThymeleafRootToParser());
-    }
-
-
-
-}
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index b649d08..17f23e4 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -37,30 +37,21 @@ org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.order.d
 org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.encoding.name = encoding
 org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.encoding.description = encoding for reading templates
 
-# ResourceBundleMessageResolver
-org.apache.sling.scripting.thymeleaf.internal.ResourceBundleMessageResolver.order.name = order
-org.apache.sling.scripting.thymeleaf.internal.ResourceBundleMessageResolver.order.description = property for ordering message resolvers inside the Thymeleaf template engine
-
-# XmlTemplateModeHandler
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.XmlTemplateModeHandler.patterns.name = patterns
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.XmlTemplateModeHandler.patterns.description = the template patterns (regular expressions) this service should handle (e.g. /apps/sling/*.xml - NOTE: extension needs to be enabled for this script engine)
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.htmlPatterns.name = patterns for Template Mode HTML
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.htmlPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode HTML (e.g. /apps/sling/*.html - NOTE: extension needs to be enabled for this script engine)
 
-# ValidatingXmlTemplateModeHandler
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.ValidatingXmlTemplateModeHandler.patterns.name = patterns
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.ValidatingXmlTemplateModeHandler.patterns.description = the template patterns (regular expressions) this service should handle (e.g. /apps/sling/*.xml - NOTE: extension needs to be enabled for this script engine)
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.xmlPatterns.name = patterns for Template Mode XML
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.xmlPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode XML (e.g. /apps/sling/*.xml - NOTE: extension needs to be enabled for this script engine)
 
-# XhtmlTemplateModeHandler
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.XhtmlTemplateModeHandler.patterns.name = patterns
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.XhtmlTemplateModeHandler.patterns.description = the template patterns (regular expressions) this service should handle (e.g. /apps/sling/*.xhtml - NOTE: extension needs to be enabled for this script engine)
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.textPatterns.name = patterns for Template Mode TEXT
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.textPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode TEXT (e.g. /apps/sling/*.txt - NOTE: extension needs to be enabled for this script engine)
 
-# ValidatingXhtmlTemplateModeHandler
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.ValidatingXhtmlTemplateModeHandler.patterns.name = patterns
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.ValidatingXhtmlTemplateModeHandler.patterns.description = the template patterns (regular expressions) this service should handle (e.g. /apps/sling/*.xhtml - NOTE: extension needs to be enabled for this script engine)
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.javascriptPatterns.name = patterns for Template Mode JAVASCRIPT
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.javascriptPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode JAVASCRIPT (e.g. /apps/sling/*.js - NOTE: extension needs to be enabled for this script engine)
 
-# Html5TemplateModeHandler
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.Html5TemplateModeHandler.patterns.name = patterns
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.Html5TemplateModeHandler.patterns.description = the template patterns (regular expressions) this service should handle (e.g. /apps/sling/*.html) - NOTE: extension needs to be enabled for this script engine)
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.cssPatterns.name = patterns for Template Mode CSS
+org.apache.sling.scripting.thymeleaf.internal.NonCachingTemplateResolver.cssPatterns.description = the template patterns (regular expressions) which should be handled by Template Mode CSS (e.g. /apps/sling/*.css) - NOTE: extension needs to be enabled for this script engine)
 
-# LegacyHtml5TemplateModeHandler
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.LegacyHtml5TemplateModeHandler.patterns.name = patterns
-org.apache.sling.scripting.thymeleaf.internal.templatemodehandler.LegacyHtml5TemplateModeHandler.patterns.description = the template patterns (regular expressions) this service should handle (e.g. /apps/sling/*.html) - NOTE: extension needs to be enabled for this script engine)
+# ResourceBundleMessageResolver
+org.apache.sling.scripting.thymeleaf.internal.ResourceBundleMessageResolver.order.name = order
+org.apache.sling.scripting.thymeleaf.internal.ResourceBundleMessageResolver.order.description = property for ordering message resolvers inside the Thymeleaf template engine

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.