Merge pull request #688 from JCgH4164838Gh792C124B5/localS2_62_ExecWaitCleanup

[WW-5312] Attempt to fix ExecuteAndWaitInterceptor inconsistent processing
diff --git a/apps/rest-showcase/src/main/resources/struts.xml b/apps/rest-showcase/src/main/resources/struts.xml
index b451518..5a49e0e 100644
--- a/apps/rest-showcase/src/main/resources/struts.xml
+++ b/apps/rest-showcase/src/main/resources/struts.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 
 <struts>
diff --git a/apps/showcase/src/main/resources/struts-actionchaining.xml b/apps/showcase/src/main/resources/struts-actionchaining.xml
index 2b187dd..4f39940 100644
--- a/apps/showcase/src/main/resources/struts-actionchaining.xml
+++ b/apps/showcase/src/main/resources/struts-actionchaining.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 	<package name="actionchaining" extends="struts-default" namespace="/actionchaining">
diff --git a/apps/showcase/src/main/resources/struts-async.xml b/apps/showcase/src/main/resources/struts-async.xml
index 0921e68..178a14d 100644
--- a/apps/showcase/src/main/resources/struts-async.xml
+++ b/apps/showcase/src/main/resources/struts-async.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="async" extends="json-default" namespace="/async">
diff --git a/apps/showcase/src/main/resources/struts-conversion.xml b/apps/showcase/src/main/resources/struts-conversion.xml
index 4c4c165..873c070 100644
--- a/apps/showcase/src/main/resources/struts-conversion.xml
+++ b/apps/showcase/src/main/resources/struts-conversion.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 	<package name="conversion" namespace="/conversion" extends="struts-default">
diff --git a/apps/showcase/src/main/resources/struts-dispatcher.xml b/apps/showcase/src/main/resources/struts-dispatcher.xml
index 7051b1f..9d9ea24 100644
--- a/apps/showcase/src/main/resources/struts-dispatcher.xml
+++ b/apps/showcase/src/main/resources/struts-dispatcher.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="dispatcher" extends="struts-default" namespace="/dispatcher">
diff --git a/apps/showcase/src/main/resources/struts-filedownload.xml b/apps/showcase/src/main/resources/struts-filedownload.xml
index 335777b..5a8b5ae 100644
--- a/apps/showcase/src/main/resources/struts-filedownload.xml
+++ b/apps/showcase/src/main/resources/struts-filedownload.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 	<package name="filedownload" extends="struts-default" namespace="/filedownload">
diff --git a/apps/showcase/src/main/resources/struts-fileupload.xml b/apps/showcase/src/main/resources/struts-fileupload.xml
index 4efcad8..5b500b7 100644
--- a/apps/showcase/src/main/resources/struts-fileupload.xml
+++ b/apps/showcase/src/main/resources/struts-fileupload.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 	<package name="fileupload" extends="struts-default" namespace="/fileupload">
diff --git a/apps/showcase/src/main/resources/struts-freemarker.xml b/apps/showcase/src/main/resources/struts-freemarker.xml
index c0de0a9..e4dd3f1 100644
--- a/apps/showcase/src/main/resources/struts-freemarker.xml
+++ b/apps/showcase/src/main/resources/struts-freemarker.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="freemarker" namespace="/freemarker" extends="struts-default">
diff --git a/apps/showcase/src/main/resources/struts-hangman.xml b/apps/showcase/src/main/resources/struts-hangman.xml
index d81f4b3..510b4e7 100644
--- a/apps/showcase/src/main/resources/struts-hangman.xml
+++ b/apps/showcase/src/main/resources/struts-hangman.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 	<package name="hangman" extends="struts-default" namespace="/hangman">
diff --git a/apps/showcase/src/main/resources/struts-interactive.xml b/apps/showcase/src/main/resources/struts-interactive.xml
index cda563d..c057a39 100644
--- a/apps/showcase/src/main/resources/struts-interactive.xml
+++ b/apps/showcase/src/main/resources/struts-interactive.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="interactive" namespace="/interactive" extends="struts-default">
diff --git a/apps/showcase/src/main/resources/struts-model-driven.xml b/apps/showcase/src/main/resources/struts-model-driven.xml
index da01d92..2183c20 100644
--- a/apps/showcase/src/main/resources/struts-model-driven.xml
+++ b/apps/showcase/src/main/resources/struts-model-driven.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 	<package name="modelDriven" extends="struts-default" namespace="/modelDriven">
diff --git a/apps/showcase/src/main/resources/struts-person.xml b/apps/showcase/src/main/resources/struts-person.xml
index a150088..0a97104 100644
--- a/apps/showcase/src/main/resources/struts-person.xml
+++ b/apps/showcase/src/main/resources/struts-person.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <!-- START SNIPPET: xworkSample -->
 
diff --git a/apps/showcase/src/main/resources/struts-tags-non-ui.xml b/apps/showcase/src/main/resources/struts-tags-non-ui.xml
index f445da0..c6a2ee3 100644
--- a/apps/showcase/src/main/resources/struts-tags-non-ui.xml
+++ b/apps/showcase/src/main/resources/struts-tags-non-ui.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/apps/showcase/src/main/resources/struts-tags-ui.xml b/apps/showcase/src/main/resources/struts-tags-ui.xml
index 1055678..0580d5b 100644
--- a/apps/showcase/src/main/resources/struts-tags-ui.xml
+++ b/apps/showcase/src/main/resources/struts-tags-ui.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="ui-tags" extends="velocity-default" namespace="/tags/ui">
diff --git a/apps/showcase/src/main/resources/struts-tags.xml b/apps/showcase/src/main/resources/struts-tags.xml
index c9482f1..eb7ee23 100644
--- a/apps/showcase/src/main/resources/struts-tags.xml
+++ b/apps/showcase/src/main/resources/struts-tags.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <include file="struts-tags-ui.xml"/>
diff --git a/apps/showcase/src/main/resources/struts-tiles.xml b/apps/showcase/src/main/resources/struts-tiles.xml
index 5fa2f80..7175d71 100644
--- a/apps/showcase/src/main/resources/struts-tiles.xml
+++ b/apps/showcase/src/main/resources/struts-tiles.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="tiles" extends="tiles-default" namespace="/tiles">
diff --git a/apps/showcase/src/main/resources/struts-token.xml b/apps/showcase/src/main/resources/struts-token.xml
index db67041..2b4a18d 100644
--- a/apps/showcase/src/main/resources/struts-token.xml
+++ b/apps/showcase/src/main/resources/struts-token.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="token" extends="struts-default" namespace="/token">
 
diff --git a/apps/showcase/src/main/resources/struts-validation.xml b/apps/showcase/src/main/resources/struts-validation.xml
index 31bcab4..de225d7 100755
--- a/apps/showcase/src/main/resources/struts-validation.xml
+++ b/apps/showcase/src/main/resources/struts-validation.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/apps/showcase/src/main/resources/struts-wait.xml b/apps/showcase/src/main/resources/struts-wait.xml
index 23784b9..b68431c 100644
--- a/apps/showcase/src/main/resources/struts-wait.xml
+++ b/apps/showcase/src/main/resources/struts-wait.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/apps/showcase/src/main/resources/struts.xml b/apps/showcase/src/main/resources/struts.xml
index 6354a36..f73963d 100644
--- a/apps/showcase/src/main/resources/struts.xml
+++ b/apps/showcase/src/main/resources/struts.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <!-- START SNIPPET: xworkSample -->
 <struts>
diff --git a/bundles/admin/src/main/resources/struts.xml b/bundles/admin/src/main/resources/struts.xml
index 2bb1bf1..2f00289 100644
--- a/bundles/admin/src/main/resources/struts.xml
+++ b/bundles/admin/src/main/resources/struts.xml
@@ -21,8 +21,8 @@
 -->
 
 <!DOCTYPE struts PUBLIC
-    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-    "https://struts.apache.org/dtds/struts-2.5.dtd">
+    "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+    "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <constant name="struts.enable.DynamicMethodInvocation" value="false" />
diff --git a/bundles/demo/src/main/resources/struts.xml b/bundles/demo/src/main/resources/struts.xml
index 003635f..2c9baf9 100644
--- a/bundles/demo/src/main/resources/struts.xml
+++ b/bundles/demo/src/main/resources/struts.xml
@@ -20,8 +20,8 @@
  */

 -->

 <!DOCTYPE struts PUBLIC

-    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

-    "https://struts.apache.org/dtds/struts-2.5.dtd">

+    "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"

+    "https://struts.apache.org/dtds/struts-6.0.dtd">

 

 <struts>

     <!-- Set some Struts 2 constants relevant to the OSGi Plugin.

diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java
index 4fc70bb..4f72330 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ActionChainResult.java
@@ -218,7 +218,7 @@
         }
         addToHistory(finalNamespace, finalActionName, finalMethodName);
 
-        Map<String, Object> extraContext = ActionContext.of(new HashMap<>())
+        Map<String, Object> extraContext = ActionContext.of()
             .withValueStack(invocation.getInvocationContext().getValueStack())
             .withParameters(invocation.getInvocationContext().getParameters())
             .with(CHAIN_HISTORY, ActionChainResult.getChainHistory())
diff --git a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java
index 5fd676b..fb7b0ab 100644
--- a/core/src/main/java/com/opensymphony/xwork2/ActionContext.java
+++ b/core/src/main/java/com/opensymphony/xwork2/ActionContext.java
@@ -58,79 +58,52 @@
  */
 public class ActionContext implements Serializable {
 
-    static ThreadLocal<ActionContext> actionContext = new ThreadLocal<>();
+    private static final ThreadLocal<ActionContext> actionContext = new ThreadLocal<>();
 
     /**
      * Constant for the name of the action being executed.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String ACTION_NAME = "com.opensymphony.xwork2.ActionContext.name";
+    private static final String ACTION_NAME = "org.apache.struts2.ActionContext.name";
 
     /**
      * Constant for the {@link com.opensymphony.xwork2.util.ValueStack OGNL value stack}.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String VALUE_STACK = ValueStack.VALUE_STACK;
+    private static final String VALUE_STACK = ValueStack.VALUE_STACK;
 
     /**
      * Constant for the action's session.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String SESSION = "com.opensymphony.xwork2.ActionContext.session";
+    private static final String SESSION = "org.apache.struts2.ActionContext.session";
 
     /**
      * Constant for the action's application context.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String APPLICATION = "com.opensymphony.xwork2.ActionContext.application";
+    private static final String APPLICATION = "org.apache.struts2.ActionContext.application";
 
     /**
      * Constant for the action's parameters.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String PARAMETERS = "com.opensymphony.xwork2.ActionContext.parameters";
+    private static final String PARAMETERS = "org.apache.struts2.ActionContext.parameters";
 
     /**
      * Constant for the action's locale.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String LOCALE = "com.opensymphony.xwork2.ActionContext.locale";
+    private static final String LOCALE = "org.apache.struts2.ActionContext.locale";
 
     /**
      * Constant for the action's {@link com.opensymphony.xwork2.ActionInvocation invocation} context.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String ACTION_INVOCATION = "com.opensymphony.xwork2.ActionContext.actionInvocation";
+    private static final String ACTION_INVOCATION = "org.apache.struts2.ActionContext.actionInvocation";
 
     /**
      * Constant for the map of type conversion errors.
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String CONVERSION_ERRORS = "com.opensymphony.xwork2.ActionContext.conversionErrors";
+    private static final String CONVERSION_ERRORS = "org.apache.struts2.ActionContext.conversionErrors";
 
     /**
      * Constant for the container
-     *
-     * @deprecated scope will be narrowed to "private", use helper methods instead
      */
-    @Deprecated
-    public static final String CONTAINER = "com.opensymphony.xwork2.ActionContext.container";
+    private static final String CONTAINER = "org.apache.struts2.ActionContext.container";
 
     private final Map<String, Object> context;
 
@@ -145,7 +118,6 @@
 
     /**
      * Creates a new ActionContext based on passed in Map
-     * and assign this instance to the current thread
      *
      * @param context a map with context values
      * @return new ActionContext
@@ -158,6 +130,15 @@
     }
 
     /**
+     * Creates a new ActionContext based on empty Map
+     *
+     * @return new ActionContext
+     */
+    public static ActionContext of() {
+        return of(new HashMap<>());
+    }
+
+    /**
      * Binds the provided context with the current thread
      *
      * @param actionContext context to bind to the thread
@@ -211,13 +192,7 @@
      * Sets the action invocation (the execution state).
      *
      * @param actionInvocation the action execution state.
-     * @deprecated use {@link #withActionInvocation(ActionInvocation)} instead
      */
-    @Deprecated
-    public void setActionInvocation(ActionInvocation actionInvocation) {
-        put(ACTION_INVOCATION, actionInvocation);
-    }
-
     public ActionContext withActionInvocation(ActionInvocation actionInvocation) {
         put(ACTION_INVOCATION, actionInvocation);
         return this;
@@ -236,13 +211,7 @@
      * Sets the action's application context.
      *
      * @param application the action's application context.
-     * @deprecated use {@link #withApplication(Map)} instead
      */
-    @Deprecated
-    public void setApplication(Map<String, Object> application) {
-        put(APPLICATION, application);
-    }
-
     public ActionContext withApplication(Map<String, Object> application) {
         put(APPLICATION, application);
         return this;
@@ -271,13 +240,7 @@
      * Sets conversion errors which occurred when executing the action.
      *
      * @param conversionErrors a Map of errors which occurred when executing the action.
-     * @deprecated use {@link #withConversionErrors(Map)} instead
      */
-    @Deprecated
-    public void setConversionErrors(Map<String, ConversionData> conversionErrors) {
-        put(CONVERSION_ERRORS, conversionErrors);
-    }
-
     public ActionContext withConversionErrors(Map<String, ConversionData> conversionErrors) {
         put(CONVERSION_ERRORS, conversionErrors);
         return this;
@@ -304,13 +267,7 @@
      * Sets the Locale for the current action.
      *
      * @param locale the Locale for the current action.
-     * @deprecated use {@link #withLocale(Locale)} instead
      */
-    @Deprecated
-    public void setLocale(Locale locale) {
-        put(LOCALE, locale);
-    }
-
     public ActionContext withLocale(Locale locale) {
         put(LOCALE, locale);
         return this;
@@ -327,7 +284,7 @@
 
         if (locale == null) {
             locale = Locale.getDefault();
-            setLocale(locale);
+            withLocale(locale);
         }
 
         return locale;
@@ -336,14 +293,8 @@
     /**
      * Sets the name of the current Action in the ActionContext.
      *
-     * @param name the name of the current action.
-     * @deprecated use {@link #withActionName(String)} instead
+     * @param actionName the name of the current action.
      */
-    @Deprecated
-    public void setName(String name) {
-        put(ACTION_NAME, name);
-    }
-
     public ActionContext withActionName(String actionName) {
         put(ACTION_NAME, actionName);
         return this;
@@ -354,15 +305,6 @@
      *
      * @return the name of the current action.
      */
-    public String getName() {
-        return (String) get(ACTION_NAME);
-    }
-
-    /**
-     * Gets the name of the current Action.
-     *
-     * @return the name of the current action.
-     */
     public String getActionName() {
         return (String) get(ACTION_NAME);
     }
@@ -372,10 +314,6 @@
      *
      * @param parameters the parameters for the current action.
      */
-    public void setParameters(HttpParameters parameters) {
-        put(PARAMETERS, parameters);
-    }
-
     public ActionContext withParameters(HttpParameters parameters) {
         put(PARAMETERS, parameters);
         return this;
@@ -396,13 +334,7 @@
      * Sets a map of action session values.
      *
      * @param session the session values.
-     * @deprecated use {@link #withSession(Map)} instead
      */
-    @Deprecated
-    public void setSession(Map<String, Object> session) {
-        put(SESSION, session);
-    }
-
     public ActionContext withSession(Map<String, Object> session) {
         put(SESSION, session);
         return this;
@@ -421,14 +353,8 @@
     /**
      * Sets the OGNL value stack.
      *
-     * @param stack the OGNL value stack.
-     * @deprecated Use {@link #withValueStack(ValueStack)} instead
+     * @param valueStack the OGNL value stack.
      */
-    @Deprecated
-    public void setValueStack(ValueStack stack) {
-        put(VALUE_STACK, stack);
-    }
-
     public ActionContext withValueStack(ValueStack valueStack) {
         put(VALUE_STACK, valueStack);
         return this;
@@ -446,14 +372,8 @@
     /**
      * Gets the container for this request
      *
-     * @param cont The container
-     * @deprecated use {@link #withContainer(Container)} instead
+     * @param container The container
      */
-    @Deprecated
-    public void setContainer(Container cont) {
-        put(CONTAINER, cont);
-    }
-
     public ActionContext withContainer(Container container) {
         put(CONTAINER, container);
         return this;
diff --git a/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java b/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java
index ec7a8d7..402af38 100644
--- a/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java
+++ b/core/src/main/java/com/opensymphony/xwork2/XWorkTestCase.java
@@ -101,7 +101,7 @@
     }
 
     protected Map<String, Object> createContextWithLocale(Locale locale) {
-        return ActionContext.of(new HashMap<>())
+        return ActionContext.of()
             .withLocale(locale)
             .getContextMap();
     }
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java
index 61d4b83..e60550c 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptor.java
@@ -52,9 +52,9 @@
  * <ul>
  *
  * <li>logEnabled (optional) - Should exceptions also be logged? (boolean true|false)</li>
- * 
+ *
  * <li>logLevel (optional) - what log level should we use (<code>trace, debug, info, warn, error, fatal</code>)? - defaut is <code>debug</code></li>
- * 
+ *
  * <li>logCategory (optional) - If provided we would use this category (eg. <code>com.mycompany.app</code>).
  * Default is to use <code>com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor</code>.</li>
  *
@@ -102,7 +102,7 @@
  * &lt;/xwork&gt;
  * <!-- END SNIPPET: example -->
  * </pre>
- * 
+ *
  * <p>
  * This second example will also log the exceptions using our own category
  * <code>com.mycompany.app.unhandled</code> at WARN level.
@@ -117,8 +117,8 @@
  *              &lt;interceptor-ref name="exception"&gt;
  *                  &lt;param name="logEnabled"&gt;true&lt;/param&gt;
  *                  &lt;param name="logCategory"&gt;com.mycompany.app.unhandled&lt;/param&gt;
- *                  &lt;param name="logLevel"&gt;WARN&lt;/param&gt;	        		
- *              &lt;/interceptor-ref&gt;	
+ *                  &lt;param name="logLevel"&gt;WARN&lt;/param&gt;
+ *              &lt;/interceptor-ref&gt;
  *              &lt;interceptor-ref name="i18n"/&gt;
  *              &lt;interceptor-ref name="staticParams"/&gt;
  *              &lt;interceptor-ref name="params"/&gt;
@@ -129,7 +129,7 @@
  *      &lt;/interceptors&gt;
  *
  *      &lt;default-interceptor-ref name="exceptionmappingStack"/&gt;
- *    
+ *
  *      &lt;global-results&gt;
  *           &lt;result name="unhandledException"&gt;/unhandled-exception.jsp&lt;/result&gt;
  *      &lt;/global-results&gt;
@@ -137,12 +137,12 @@
  *      &lt;global-exception-mappings&gt;
  *           &lt;exception-mapping exception="java.lang.Exception" result="unhandledException"/&gt;
  *      &lt;/global-exception-mappings&gt;
- *        
+ *
  *      &lt;action name="exceptionDemo" class="org.apache.struts2.showcase.exceptionmapping.ExceptionMappingAction"&gt;
  *          &lt;exception-mapping exception="org.apache.struts2.showcase.exceptionmapping.ExceptionMappingException"
  *                             result="damm"/&gt;
  *          &lt;result name="input"&gt;index.jsp&lt;/result&gt;
- *          &lt;result name="success"&gt;success.jsp&lt;/result&gt;            
+ *          &lt;result name="success"&gt;success.jsp&lt;/result&gt;
  *          &lt;result name="damm"&gt;damm.jsp&lt;/result&gt;
  *      &lt;/action&gt;
  *
@@ -151,18 +151,18 @@
  * <!-- END SNIPPET: example2 -->
  * </pre>
  *
- * @author Matthew E. Porter (matthew dot porter at metissian dot com) 
+ * @author Matthew E. Porter (matthew dot porter at metissian dot com)
  * @author Claus Ibsen
  */
 public class ExceptionMappingInterceptor extends AbstractInterceptor {
-    
+
     private static final Logger LOG = LogManager.getLogger(ExceptionMappingInterceptor.class);
 
     protected Logger categoryLogger;
     protected boolean logEnabled = false;
     protected String logCategory;
     protected String logLevel;
-    
+
 
     public boolean isLogEnabled() {
         return logEnabled;
@@ -204,7 +204,7 @@
                 Map<String, String> mappingParams = mappingConfig.getParams();
                 // create a mutable HashMap since some interceptors will remove parameters, and parameterMap is immutable
                 HttpParameters parameters = HttpParameters.create(mappingParams).build();
-                invocation.getInvocationContext().setParameters(parameters);
+                invocation.getInvocationContext().withParameters(parameters);
                 result = mappingConfig.getResult();
                 publishException(invocation, new ExceptionHolder(e));
             } else {
@@ -217,7 +217,7 @@
 
     /**
      * Handles the logging of the exception.
-     * 
+     *
      * @param e the exception to log.
      */
     protected void handleLogging(Exception e) {
@@ -231,10 +231,10 @@
     		doLog(LOG, e);
     	}
     }
-    
+
     /**
      * Performs the actual logging.
-     * 
+     *
      * @param logger  the provided logger to use.
      * @param e  the exception to log.
      */
@@ -243,7 +243,7 @@
     		logger.debug(e.getMessage(), e);
     		return;
     	}
-    	
+
     	if ("trace".equalsIgnoreCase(logLevel)) {
     		logger.trace(e.getMessage(), e);
     	} else if ("debug".equalsIgnoreCase(logLevel)) {
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java
index 6c918d0..4657380 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/NoParameters.java
@@ -30,7 +30,8 @@
  * parameters cannot be set by malicious users.
  * </p>
  *
- * @author Dick Zetterberg (dick@transitor.se)
+ * @deprecated since Struts 6.2.0, use {@link org.apache.struts2.action.NoParameters}
  */
+@Deprecated
 public interface NoParameters {
 }
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java
index 3f0414a..b695c7b 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptor.java
@@ -34,33 +34,33 @@
  * <!-- START SNIPPET: description -->
  *
  * The Parameter Filter Interceptor blocks parameters from getting
- * to the rest of the stack or your action. You can use multiple 
+ * to the rest of the stack or your action. You can use multiple
  * parameter filter interceptors for a given action, so, for example,
  * you could use one in your default stack that filtered parameters
- * you wanted blocked from every action and those you wanted blocked 
+ * you wanted blocked from every action and those you wanted blocked
  * from an individual action you could add an additional interceptor
  * for each action.
- * 
+ *
  * <!-- END SNIPPET: description -->
- * 
+ *
  * <!-- START SNIPPET: parameters -->
  *
  * <ul>
  * <li>allowed - a comma delimited list of parameter prefixes
  *  that are allowed to pass to the action</li>
- * <li>blocked - a comma delimited list of parameter prefixes 
+ * <li>blocked - a comma delimited list of parameter prefixes
  * that are not allowed to pass to the action</li>
  * <li>defaultBlock - boolean (default to false) whether by
  * default a given parameter is blocked. If true, then a parameter
- * must have a prefix in the allowed list in order to be able 
+ * must have a prefix in the allowed list in order to be able
  * to pass to the action
  * </ul>
- * 
+ *
  * <p>The way parameters are filtered for the least configuration is that
  * if a string is in the allowed or blocked lists, then any parameter
  * that is a member of the object represented by the parameter is allowed
  * or blocked respectively.</p>
- * 
+ *
  * <p>For example, if the parameters are:
  * <ul>
  * <li>blocked: person,person.address.createDate,personDao</li>
@@ -69,16 +69,16 @@
  * </ul>
  *
  * <p>
- * The parameters person.name, person.phoneNum etc would be blocked 
+ * The parameters person.name, person.phoneNum etc would be blocked
  * because 'person' is in the blocked list. However, person.address.street
  * and person.address.city would be allowed because person.address is
- * in the allowed list (the longer string determines permissions).</p> 
+ * in the allowed list (the longer string determines permissions).</p>
  * <!-- END SNIPPET: parameters -->
  *
  * <!-- START SNIPPET: extending -->
  * There are no known extension points to this interceptor.
  * <!-- END SNIPPET: extending -->
- * 
+ *
  * <pre>
  * <!-- START SNIPPET: example -->
  * &lt;interceptors&gt;
@@ -86,7 +86,7 @@
  *   &lt;interceptor name="parameterFilter" class="com.opensymphony.xwork2.interceptor.ParameterFilterInterceptor"/&gt;
  *   ...
  * &lt;/interceptors&gt;
- * 
+ *
  * &lt;action ....&gt;
  *   ...
  *   &lt;interceptor-ref name="parameterFilter"&gt;
@@ -96,7 +96,7 @@
  * &lt;/action&gt;
  * <!-- END SNIPPET: example -->
  * </pre>
- * 
+ *
  * @author Gabe
  */
 public class ParameterFilterInterceptor extends AbstractInterceptor {
@@ -133,7 +133,7 @@
             }
         }
 
-        invocation.getInvocationContext().setParameters(parameters);
+        invocation.getInvocationContext().withParameters(parameters);
 
         return invocation.invoke();
     }
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java
index 1003be9..c0f8376 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptor.java
@@ -23,120 +23,102 @@
 import com.opensymphony.xwork2.util.TextParseUtil;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
-import org.apache.struts2.dispatcher.Parameter;
+import org.apache.struts2.action.NoParameters;
 import org.apache.struts2.dispatcher.HttpParameters;
+import org.apache.struts2.dispatcher.Parameter;
 
 import java.util.Collections;
 import java.util.Set;
 
 /**
- * <!-- START SNIPPET: description -->
  * This is a simple XWork interceptor that allows parameters (matching
- * one of the paramNames attribute csv value) to be 
+ * one of the paramNames attribute csv value) to be
  * removed from the parameter map if they match a certain value
- * (matching one of the paramValues attribute csv value), before they 
- * are set on the action. A typical usage would be to want a dropdown/select 
- * to map onto a boolean value on an action. The select had the options 
- * none, yes and no with values -1, true and false. The true and false would 
- * map across correctly. However the -1 would be set to false. 
- * This was not desired as one might needed the value on the action to stay null. 
- * This interceptor fixes this by preventing the parameter from ever reaching 
+ * (matching one of the paramValues attribute csv value), before they
+ * are set on the action. A typical usage would be to want a dropdown/select
+ * to map onto a boolean value on an action. The select had the options
+ * none, yes and no with values -1, true and false. The true and false would
+ * map across correctly. However the -1 would be set to false.
+ * This was not desired as one might needed the value on the action to stay null.
+ * This interceptor fixes this by preventing the parameter from ever reaching
  * the action.
- * <!-- END SNIPPET: description -->
- * 
- * 
- * <!-- START SNIPPET: parameters -->
+ *
  * <ul>
- * 	<li>paramNames - A comma separated value (csv) indicating the parameter name 
- * 								    whose param value should be considered that if they match any of the
- *                                     comma separated value (csv) from paramValues attribute, shall be 
- *                                     removed from the parameter map such that they will not be applied
- *                                     to the action</li>
- * 	<li>paramValues - A comma separated value (csv) indicating the parameter value that if 
- * 							      matched shall have its parameter be removed from the parameter map 
- * 							      such that they will not be applied to the action</li>
+ * 	<li>paramNames - A comma separated value (csv) indicating the parameter name
+ *                   whose param value should be considered that if they match any of the
+ *                   comma separated value (csv) from paramValues attribute, shall be
+ *                   removed from the parameter map such that they will not be applied
+ *                   to the action</li>
+ * 	<li>paramValues - A comma separated value (csv) indicating the parameter value that if
+ *                    matched shall have its parameter be removed from the parameter map
+ *                    such that they will not be applied to the action</li>
  * </ul>
- * <!-- END SNIPPET: parameters -->
- * 
- * 
- * <!-- START SNIPPET: extending -->
+ * <p>
  * No intended extension point
- * <!-- END SNIPPET: extending -->
- * 
+ *
  * <pre>
- * <!-- START SNIPPET: example -->
- *	
  * &lt;action name="sample" class="org.martingilday.Sample"&gt;
  * 	&lt;interceptor-ref name="paramRemover"&gt;
- *   		&lt;param name="paramNames"&gt;aParam,anotherParam&lt;/param&gt;
- *   		&lt;param name="paramValues"&gt;--,-1&lt;/param&gt;
+ *          &lt;param name="paramNames"&gt;aParam,anotherParam&lt;/param&gt;
+ *          &lt;param name="paramValues"&gt;--,-1&lt;/param&gt;
  * 	&lt;/interceptor-ref&gt;
  * 	&lt;interceptor-ref name="defaultStack" /&gt;
  * 	...
  * &lt;/action&gt;
- *  
- * <!-- END SNIPPET: example -->
  * </pre>
- *  
- *  
- * @author martin.gilday
  */
 public class ParameterRemoverInterceptor extends AbstractInterceptor {
 
-	private static final Logger LOG = LogManager.getLogger(ParameterRemoverInterceptor.class);
+    private static final Logger LOG = LogManager.getLogger(ParameterRemoverInterceptor.class);
 
-	private static final long serialVersionUID = 1;
+    private Set<String> paramNames = Collections.emptySet();
+    private Set<String> paramValues = Collections.emptySet();
 
-	private Set<String> paramNames = Collections.emptySet();
-	private Set<String> paramValues = Collections.emptySet();
+    /**
+     * Decide if the parameter should be removed from the parameter map based on
+     * <code>paramNames</code> and <code>paramValues</code>.
+     *
+     * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor
+     */
+    @Override
+    public String intercept(ActionInvocation invocation) throws Exception {
+        if (!(invocation.getAction() instanceof NoParameters)
+            && (null != this.paramNames)) {
+            ActionContext ac = invocation.getInvocationContext();
+            HttpParameters parameters = ac.getParameters();
 
-	
-	/**
-	 * Decide if the parameter should be removed from the parameter map based on
-	 * <code>paramNames</code> and <code>paramValues</code>.
-	 * 
-	 * @see com.opensymphony.xwork2.interceptor.AbstractInterceptor
-	 */
-	@Override
-	public String intercept(ActionInvocation invocation) throws Exception {
-		if (!(invocation.getAction() instanceof NoParameters)
-				&& (null != this.paramNames)) {
-			ActionContext ac = invocation.getInvocationContext();
-			HttpParameters parameters = ac.getParameters();
-
-			if (parameters != null) {
+            if (parameters != null) {
                 for (String removeName : paramNames) {
-					try {
-						Parameter parameter = parameters.get(removeName);
-						if (parameter.isDefined() && this.paramValues.contains(parameter.getValue())) {
-							parameters.remove(removeName);
-						}
-					} catch (Exception e) {
-						LOG.error("Failed to convert parameter to string", e);
-					}
+                    try {
+                        Parameter parameter = parameters.get(removeName);
+                        if (parameter.isDefined() && this.paramValues.contains(parameter.getValue())) {
+                            parameters.remove(removeName);
+                        }
+                    } catch (Exception e) {
+                        LOG.error("Failed to convert parameter to string", e);
+                    }
                 }
-			}
-		}
-		return invocation.invoke();
-	}
+            }
+        }
+        return invocation.invoke();
+    }
 
-	/**
-	 * Allows <code>paramNames</code> attribute to be set as comma-separated-values (csv).
-	 * 
-	 * @param paramNames the paramNames to set
-	 */
-	public void setParamNames(String paramNames) {
-		this.paramNames = TextParseUtil.commaDelimitedStringToSet(paramNames);
-	}
+    /**
+     * Allows <code>paramNames</code> attribute to be set as comma-separated-values (csv).
+     *
+     * @param paramNames the paramNames to set
+     */
+    public void setParamNames(String paramNames) {
+        this.paramNames = TextParseUtil.commaDelimitedStringToSet(paramNames);
+    }
 
+    /**
+     * Allows <code>paramValues</code> attribute to be set as a comma-separated-values (csv).
+     *
+     * @param paramValues the paramValues to set
+     */
+    public void setParamValues(String paramValues) {
+        this.paramValues = TextParseUtil.commaDelimitedStringToSet(paramValues);
+    }
 
-	/**
-	 * Allows <code>paramValues</code> attribute to be set as a comma-separated-values (csv).
-	 * 
-	 * @param paramValues the paramValues to set
-	 */
-	public void setParamValues(String paramValues) {
-		this.paramValues = TextParseUtil.commaDelimitedStringToSet(paramValues);
-	}
 }
-
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
index f4079b8..9d32a8a 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptor.java
@@ -236,6 +236,6 @@
             combinedParams = HttpParameters.create(newParams);
             combinedParams = combinedParams.withExtraParams(previousParams);
         }
-        ac.setParameters(combinedParams.build());
+        ac.withParameters(combinedParams.build());
     }
 }
diff --git a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptor.java b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptor.java
index 4fc6b1f..8309d61 100644
--- a/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptor.java
+++ b/core/src/main/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptor.java
@@ -104,7 +104,7 @@
             }
         }
 
-        invocation.getInvocationContext().setParameters(parameters);
+        invocation.getInvocationContext().withParameters(parameters);
 
         return invocation.invoke();
     }
diff --git a/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java b/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java
index 24e5e9b..027dc4a 100644
--- a/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java
+++ b/core/src/main/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcher.java
@@ -87,8 +87,8 @@
         int s = 0;
         while (s < len) {
             int e = data.indexOf('{', s);
-            if (e < 0 && data.indexOf('}') > -1) {
-                throw new IllegalArgumentException("Missing openning '{' in [" + data + "]!");
+            if (e < 0 && data.indexOf('}', s) > -1) {
+                throw new IllegalArgumentException("Missing opening '{' in [" + data + "]!");
             }
             if (e < 0) {
                 regex.append(Pattern.quote(data.substring(s)));
diff --git a/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java b/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java
index d21bcb4..9e488a9 100644
--- a/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java
+++ b/core/src/main/java/com/opensymphony/xwork2/validator/validators/VisitorFieldValidator.java
@@ -138,7 +138,7 @@
 
         stack.push(object);
 
-        String visitorContext = (context == null) ? ActionContext.getContext().getName() : context;
+        String visitorContext = (context == null) ? ActionContext.getContext().getActionName() : context;
 
         if (value instanceof Collection) {
             Collection coll = (Collection) value;
diff --git a/core/src/main/java/org/apache/struts2/interceptor/NoParameters.java b/core/src/main/java/org/apache/struts2/action/NoParameters.java
similarity index 96%
rename from core/src/main/java/org/apache/struts2/interceptor/NoParameters.java
rename to core/src/main/java/org/apache/struts2/action/NoParameters.java
index c42aa80..80424a5 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/NoParameters.java
+++ b/core/src/main/java/org/apache/struts2/action/NoParameters.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.struts2.interceptor;
+package org.apache.struts2.action;
 
 /**
  * This marker interface should be implemented by actions that do not want any parameters set on
diff --git a/core/src/main/java/org/apache/struts2/components/FormButton.java b/core/src/main/java/org/apache/struts2/components/FormButton.java
index d9e75f1..0ed08d4 100644
--- a/core/src/main/java/org/apache/struts2/components/FormButton.java
+++ b/core/src/main/java/org/apache/struts2/components/FormButton.java
@@ -96,33 +96,33 @@
      * </ol>
      */
     protected void populateComponentHtmlId(Form form) {
-        String _tmp_id = "";
+        String tmpId = "";
         if (id != null) {
             // this check is needed for backwards compatibility with 2.1.x
-            _tmp_id = findString(id);
+            tmpId = findString(id);
         } else {
             if (form != null && form.getParameters().get("id") != null) {
-                _tmp_id = _tmp_id + form.getParameters().get("id").toString() + "_";
+                tmpId = tmpId + form.getParameters().get("id").toString() + "_";
             }
             if (name != null) {
-                _tmp_id = _tmp_id + escape(name);
+                tmpId = tmpId + escape(findString(name));
             } else if (action != null || method != null) {
                 if (action != null) {
-                    _tmp_id = _tmp_id + escape(action);
+                    tmpId = tmpId + escape(findString(action));
                 }
                 if (method != null) {
-                    _tmp_id = _tmp_id + "_" + escape(method);
+                    tmpId = tmpId + "_" + escape(findString(method));
                 }
             } else {
                 // if form is null, this component is used, without a form, i guess
                 // there's not much we could do then.
                 if (form != null) {
-                    _tmp_id = _tmp_id + form.getSequence();
+                    tmpId = tmpId + form.getSequence();
                 }
             }
         }
-        addParameter("id", _tmp_id);
-        addParameter("escapedId", escape(_tmp_id));
+        addParameter("id", tmpId);
+        addParameter("escapedId", escape(tmpId));
     }
 
     /**
diff --git a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
index 74780a1..51ae95d 100644
--- a/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
+++ b/core/src/main/java/org/apache/struts2/dispatcher/Dispatcher.java
@@ -78,7 +78,6 @@
 import java.io.File;
 import java.io.IOException;
 import java.util.Collection;
-import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Locale;
@@ -109,6 +108,8 @@
 
     public static final String MULTIPART_FORM_DATA_REGEX = "^multipart/form-data(?:\\s*;\\s*boundary=[0-9a-zA-Z'()+_,\\-./:=?]{1,70})?(?:\\s*;\\s*charset=[a-zA-Z\\-0-9]{3,14})?";
 
+    private static final String CONFIG_SPLIT_REGEX = "\\s*,\\s*";
+
     /**
      * Provide a thread local instance.
      */
@@ -427,10 +428,14 @@
         if (configPaths == null) {
             configPaths = DEFAULT_CONFIGURATION_PATHS;
         }
-        String[] files = configPaths.split("\\s*[,]\\s*");
+        loadConfigPaths(configPaths);
+    }
+
+    private void loadConfigPaths(String configPaths) {
+        String[] files = configPaths.split(CONFIG_SPLIT_REGEX);
         for (String file : files) {
             if (file.endsWith(".xml")) {
-                configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
+                configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, servletContext));
             } else {
                 throw new IllegalArgumentException("Invalid configuration file name");
             }
@@ -452,7 +457,7 @@
     private void init_JavaConfigurations() {
         String configClasses = initParams.get("javaConfigClasses");
         if (configClasses != null) {
-            String[] classes = configClasses.split("\\s*[,]\\s*");
+            String[] classes = configClasses.split(CONFIG_SPLIT_REGEX);
             for (String cname : classes) {
                 try {
                     Class<?> cls = ClassLoaderUtil.loadClass(cname, this.getClass());
@@ -476,7 +481,7 @@
     private void init_CustomConfigurationProviders() {
         String configProvs = initParams.get("configProviders");
         if (configProvs != null) {
-            String[] classes = configProvs.split("\\s*[,]\\s*");
+            String[] classes = configProvs.split(CONFIG_SPLIT_REGEX);
             for (String cname : classes) {
                 try {
                     Class cls = ClassLoaderUtil.loadClass(cname, this.getClass());
@@ -521,6 +526,13 @@
         configurationManager.addContainerProvider(new StrutsBeanSelectionProvider());
     }
 
+    /**
+     * `struts-deferred.xml` can be used to load configuration which is sensitive to loading order such as 'bean-selection' elements
+     */
+    private void init_DeferredXmlConfigurations() {
+        loadConfigPaths("struts-deferred.xml");
+    }
+
     private Container init_PreloadConfiguration() {
         return getContainer();
     }
@@ -554,6 +566,7 @@
             init_CustomConfigurationProviders(); // [5]
             init_FilterInitParameters(); // [6]
             init_AliasStandardObjects(); // [7]
+            init_DeferredXmlConfigurations();
 
             Container container = init_PreloadConfiguration();
             container.inject(this);
@@ -757,7 +770,7 @@
                                                 Map<String, Object> applicationMap,
                                                 HttpServletRequest request,
                                                 HttpServletResponse response) {
-        Map<String, Object> extraContext = ActionContext.of(new HashMap<>())
+        Map<String, Object> extraContext = ActionContext.of()
             .withParameters(parameters)
             .withSession(sessionMap)
             .withApplication(applicationMap)
diff --git a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
index 79cd0cc..69aa708 100644
--- a/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
+++ b/core/src/main/java/org/apache/struts2/interceptor/ActionMappingParametersInterceptor.java
@@ -75,7 +75,7 @@
 
     /**
      * Get the parameter map from ActionMapping associated with the provided ActionContext.
-     * 
+     *
      * @param ac The action context
      * @return the parameters from the action mapping in the context.  If none found, returns an empty map.
      */
@@ -102,6 +102,6 @@
         HttpParameters previousParams = ac.getParameters();
         HttpParameters.Builder combinedParams = HttpParameters.create().withParent(previousParams).withExtraParams(newParams);
 
-        ac.setParameters(combinedParams.buildNoNestedWrapping());
+        ac.withParameters(combinedParams.buildNoNestedWrapping());
     }
 }
diff --git a/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java b/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java
index a3bbfaf..6bc8672 100644
--- a/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java
+++ b/core/src/main/java/org/apache/struts2/result/ServletDispatcherResult.java
@@ -143,7 +143,7 @@
                 Map<String, Object> queryParams = queryStringParser.parse(queryString, true);
                 if (queryParams != null && !queryParams.isEmpty()) {
                     parameters = HttpParameters.create(queryParams).withParent(parameters).build();
-                    invocation.getInvocationContext().setParameters(parameters);
+                    invocation.getInvocationContext().withParameters(parameters);
                     // put to extraContext, see Dispatcher#createContextMap
                     invocation.getInvocationContext().getContextMap().put("parameters", parameters);
                 }
diff --git a/core/src/main/resources/template/simple/datetext.ftl b/core/src/main/resources/template/simple/datetextfield.ftl
similarity index 92%
rename from core/src/main/resources/template/simple/datetext.ftl
rename to core/src/main/resources/template/simple/datetextfield.ftl
index 6d8396c..c43a338 100644
--- a/core/src/main/resources/template/simple/datetext.ftl
+++ b/core/src/main/resources/template/simple/datetextfield.ftl
@@ -18,4 +18,4 @@
  * under the License.
  */
 -->
-<#lt/><div>Tag <pre style="display: inline-block">&lt;s:datetext/&gt;</pre> works only with the JavaTemplates Plugin!</div><#rt/>
+<#lt/><div>Tag <pre style="display: inline-block">&lt;s:datetextfield/&gt;</pre> works only with the JavaTemplates Plugin!</div><#rt/>
diff --git a/core/src/main/resources/template/simple/submit.ftl b/core/src/main/resources/template/simple/submit.ftl
index 48026b3..a932103 100644
--- a/core/src/main/resources/template/simple/submit.ftl
+++ b/core/src/main/resources/template/simple/submit.ftl
@@ -88,4 +88,4 @@
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/common-attributes.ftl" />
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/dynamic-attributes.ftl" />
 />
-</#if>
\ No newline at end of file
+</#if>
diff --git a/core/src/main/resources/template/xhtml/datetext.ftl b/core/src/main/resources/template/xhtml/datetextfield.ftl
similarity index 93%
rename from core/src/main/resources/template/xhtml/datetext.ftl
rename to core/src/main/resources/template/xhtml/datetextfield.ftl
index d15b24a..3efeab4 100644
--- a/core/src/main/resources/template/xhtml/datetext.ftl
+++ b/core/src/main/resources/template/xhtml/datetextfield.ftl
@@ -19,5 +19,5 @@
  */
 -->
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/controlheader.ftl" />
-<#include "/${parameters.templateDir}/simple/datetext.ftl" />
+<#include "/${parameters.templateDir}/simple/datetextfield.ftl" />
 <#include "/${parameters.templateDir}/${parameters.expandTheme}/controlfooter.ftl" />
diff --git a/core/src/main/resources/xwork-default.xml b/core/src/main/resources/xwork-default.xml
index b4dce65..c25cdc5 100644
--- a/core/src/main/resources/xwork-default.xml
+++ b/core/src/main/resources/xwork-default.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="xwork-default" abstract="true">
 
diff --git a/core/src/site/resources/tags/datetextfield.html b/core/src/site/resources/tags/datetextfield.html
index 330c3df..daec66f 100644
--- a/core/src/site/resources/tags/datetextfield.html
+++ b/core/src/site/resources/tags/datetextfield.html
@@ -12,7 +12,10 @@
 		<h2>Description</h2>
 		<p>
 		<!-- START SNIPPET: tagdescription -->
-		Render an HTML input fields with the date time
+		Render an HTML input fields with the date time.
+		<br/>
+		<br/>
+		<b>Hint:</b> This tag works only with the JavaTemplates plugin see <a href="https://struts.apache.org/plugins/javatemplates/ for more details.">the plugin documentation</a> for more details.
 		<!-- END SNIPPET: tagdescription -->
 		</p>
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java
index f5f9af2..bf86971 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionContextTest.java
@@ -65,7 +65,7 @@
         assertTrue(ActionContext.getContext().getApplication().containsKey(APPLICATION_KEY));
         assertTrue(ActionContext.getContext().getSession().containsKey(SESSION_KEY));
         assertTrue(ActionContext.getContext().getParameters().contains(PARAMETERS_KEY));
-        assertEquals(ActionContext.getContext().getName(), ACTION_NAME);
+        assertEquals(ActionContext.getContext().getActionName(), ACTION_NAME);
     }
 
     public void testGetContext() {
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java
index de0b5c1..454e02d 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionContextThreadLocalTest.java
@@ -38,7 +38,7 @@
     }
 
     public void testSetContext() {
-        ActionContext context = ActionContext.of(new HashMap<>()).bind();
+        ActionContext context = ActionContext.of().bind();
 
         assertEquals(context, ActionContext.getContext());
     }
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java
index e0f13c4..9b8ac87 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionInvocationTest.java
@@ -95,11 +95,11 @@
         HashMap<String, Object> params = new HashMap<>();
         params.put("blah", "this is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of()
+                .withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", "Foo", null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", "Foo", null, extraContext.getContextMap());
             proxy.execute();
             assertEquals("this is blah", proxy.getInvocation().getStack().findValue("[1].blah"));
         } catch (Exception e) {
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java
index cc4f017..4ef2ad8 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionNestingTest.java
@@ -93,7 +93,7 @@
         ValueStack stack = ActionContext.getContext().getValueStack();
         assertEquals(VALUE, stack.findValue(KEY));
 
-        Map<String, Object> extraContext = ActionContext.of(new HashMap<>())
+        Map<String, Object> extraContext = ActionContext.of()
             .withValueStack(stack)
             .getContextMap();
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java b/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java
index 0a357e8..65c38d3 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ActionSupportTest.java
@@ -159,7 +159,7 @@
         ActionContext.getContext().withLocale(Locale.ITALY);
         assertEquals(Locale.ITALY, as.getLocale());
 
-        ActionContext.of(new HashMap<>()).bind();
+        ActionContext.of().bind();
         assertEquals(defLocale, as.getLocale()); // ActionContext will create a new context, when it was set to null before
     }
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java
index 6ad6b84..db6e21b 100644
--- a/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/DefaultActionInvocationTest.java
@@ -367,13 +367,13 @@
         HashMap<String, Object> params = new HashMap<>();
         params.put("blah", "this is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of()
+                .withParameters(HttpParameters.create(params).build());
 
-        DefaultActionInvocation defaultActionInvocation = new DefaultActionInvocation(extraContext, true);
+        DefaultActionInvocation defaultActionInvocation = new DefaultActionInvocation(extraContext.getContextMap(), true);
         container.inject(defaultActionInvocation);
 
-        ActionProxy actionProxy = actionProxyFactory.createActionProxy("", "LazyFoo", null, extraContext);
+        ActionProxy actionProxy = actionProxyFactory.createActionProxy("", "LazyFoo", null, extraContext.getContextMap());
         defaultActionInvocation.init(actionProxy);
         defaultActionInvocation.invoke();
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/DefaultTextProviderTest.java b/core/src/test/java/com/opensymphony/xwork2/DefaultTextProviderTest.java
index 39c598a..511e6a8 100644
--- a/core/src/test/java/com/opensymphony/xwork2/DefaultTextProviderTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/DefaultTextProviderTest.java
@@ -129,7 +129,7 @@
     protected void setUp() throws Exception {
         super.setUp();
 
-        ActionContext.of(new HashMap<>()).withLocale(Locale.CANADA).bind();
+        ActionContext.of().withLocale(Locale.CANADA).bind();
 
         container.getInstance(LocalizedTextProvider.class).addDefaultResourceBundle(DefaultTextProviderTest.class.getName());
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/ProxyInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/ProxyInvocationTest.java
index 3c962a4..d1fd7e2 100644
--- a/core/src/test/java/com/opensymphony/xwork2/ProxyInvocationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/ProxyInvocationTest.java
@@ -20,6 +20,7 @@
 
 import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
 import org.apache.struts2.config.StrutsXmlConfigurationProvider;
+import org.apache.struts2.dispatcher.HttpParameters;
 
 import java.util.HashMap;
 import java.util.Map;
@@ -53,9 +54,9 @@
     private Map<String, Object> createDummyContext() {
         Map<String, Object> params = new HashMap<>();
         params.put("blah", "this is blah");
-        Map<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, params);
-        return extraContext;
+        return ActionContext.of()
+            .withParameters(HttpParameters.create(params).build())
+            .getContextMap();
     }
 
     @Override
diff --git a/core/src/test/java/com/opensymphony/xwork2/TestBean.java b/core/src/test/java/com/opensymphony/xwork2/TestBean.java
index 8b1a8ff..fd5bc59 100644
--- a/core/src/test/java/com/opensymphony/xwork2/TestBean.java
+++ b/core/src/test/java/com/opensymphony/xwork2/TestBean.java
@@ -20,25 +20,18 @@
 
 import java.util.Date;
 
-
-/**
- * TestBean
- *
- * @author Jason Carreira
- *         Created Aug 4, 2003 12:39:53 AM
- */
 public class TestBean {
 
     private Date birth;
     private String name;
     private int count;
-    
+    private String subName;
+
     private TestChildBean child = new TestChildBean();
 
     public TestBean() {
     }
 
-
     public void setBirth(Date birth) {
         this.birth = birth;
     }
@@ -63,13 +56,19 @@
         return name;
     }
 
-
     public TestChildBean getChild() {
         return child;
     }
 
-
     public void setChild(TestChildBean child) {
         this.child = child;
     }
+
+    public String getSubName() {
+        return subName;
+    }
+
+    public void setSubName(String subName) {
+        this.subName = subName;
+    }
 }
diff --git a/core/src/test/java/com/opensymphony/xwork2/config/ConfigurationTest.java b/core/src/test/java/com/opensymphony/xwork2/config/ConfigurationTest.java
index 7d46932..b52b9d4 100644
--- a/core/src/test/java/com/opensymphony/xwork2/config/ConfigurationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/config/ConfigurationTest.java
@@ -53,8 +53,8 @@
 
         try {
             ActionProxy proxy = actionProxyFactory.createActionProxy("/nonAbstract", "test", null, null);
-            assertTrue(proxy.getActionName().equals("test"));
-            assertTrue(proxy.getConfig().getClassName().equals(SimpleAction.class.getName()));
+            assertEquals("test", proxy.getActionName());
+            assertEquals(proxy.getConfig().getClassName(), SimpleAction.class.getName());
         } catch (Exception e) {
             e.printStackTrace();
             fail();
@@ -65,11 +65,11 @@
         HashMap<String, String> params = new HashMap<>();
         params.put("blah", "this is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of()
+                .withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("/does/not/exist", "Foo", null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("/does/not/exist", "Foo", null, extraContext.getContextMap());
             proxy.execute();
             assertEquals("this is blah", proxy.getInvocation().getStack().findValue("[1].blah"));
         } catch (Exception e) {
@@ -94,13 +94,12 @@
         ActionConfig config = configuration.getActionConfig("", "WildCard/Simple/input");
 
         assertNotNull(config);
-        assertTrue("Wrong class name, " + config.getClassName(),
-            "com.opensymphony.xwork2.SimpleAction".equals(config.getClassName()));
-        assertTrue("Wrong method name", "input".equals(config.getMethodName()));
+        assertEquals("Wrong class name, " + config.getClassName(), "com.opensymphony.xwork2.SimpleAction", config.getClassName());
+        assertEquals("Wrong method name", "input", config.getMethodName());
 
         Map<String, String> p = config.getParams();
-        assertTrue("Wrong parameter, " + p.get("foo"), "Simple".equals(p.get("foo")));
-        assertTrue("Wrong parameter, " + p.get("bar"), "input".equals(p.get("bar")));
+        assertEquals("Wrong parameter, " + p.get("foo"), "Simple", p.get("foo"));
+        assertEquals("Wrong parameter, " + p.get("bar"), "input", p.get("bar"));
     }
 
     public void testWildcardNamespace() {
@@ -109,12 +108,11 @@
         ActionConfig config = configuration.getActionConfig("/animals/dog", "commandTest");
 
         assertNotNull(config);
-        assertTrue("Wrong class name, " + config.getClassName(),
-            "com.opensymphony.xwork2.SimpleAction".equals(config.getClassName()));
+        assertEquals("Wrong class name, " + config.getClassName(), "com.opensymphony.xwork2.SimpleAction", config.getClassName());
 
         Map<String, String> p = config.getParams();
-        assertTrue("Wrong parameter, " + p.get("0"), "/animals/dog".equals(p.get("0")));
-        assertTrue("Wrong parameter, " + p.get("1"), "dog".equals(p.get("1")));
+        assertEquals("Wrong parameter, " + p.get("0"), "/animals/dog", p.get("0"));
+        assertEquals("Wrong parameter, " + p.get("1"), "dog", p.get("1"));
     }
 
     public void testGlobalResults() {
@@ -206,7 +204,7 @@
         assertNotNull(configuration.getActionConfig("", MockConfigurationProvider.FOO_ACTION_NAME));
     }
 
-    public void testMultipleContainerProviders() throws Exception {
+    public void testMultipleContainerProviders() {
         // to start from scratch
         configurationManager.destroyConfiguration();
         // to build basic configuration
diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/DateConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/DateConverterTest.java
index cf91282..3218729 100644
--- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/DateConverterTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/DateConverterTest.java
@@ -59,7 +59,7 @@
     public void testSqlTimeType() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
+        ActionContext context = ActionContext.of().withLocale(mxLocale);
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, TIME_01_59_10, Time.class);
         assertEquals("01:59:10", value.toString());
@@ -68,7 +68,7 @@
     public void testSqlTimestampType() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
+        ActionContext context = ActionContext.of().withLocale(mxLocale);
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, INPUT_TIME_STAMP_STR,
                 Timestamp.class);
@@ -83,8 +83,9 @@
         ValueStack stack = new StubValueStack();
         stack.push(new StubTextProvider(map));
 
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(new Locale("es_MX", "MX"))
-                .withValueStack(stack);
+        ActionContext context = ActionContext.of()
+            .withLocale(new Locale("es_MX", "MX"))
+            .withValueStack(stack);
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, DATE_STR, Date.class);
         assertTrue(value.toString().startsWith(DATE_CONVERTED));
@@ -98,7 +99,7 @@
         ValueStack stack = new StubValueStack();
         stack.push(new StubTextProvider(map));
 
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(new Locale("es_MX", "MX"))
+        ActionContext context = ActionContext.of().withLocale(new Locale("es_MX", "MX"))
                 .withValueStack(stack);
 
         try {
@@ -113,7 +114,7 @@
     public void testTypeConversionExceptionWhenUsingLongConstructor() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale);
+        ActionContext context = ActionContext.of().withLocale(mxLocale);
 
         try {
             converter.convertValue(context.getContextMap(), null, null, null, INPUT_WHEN_LONG_CONSTRUCTOR_STR, null);
@@ -127,7 +128,7 @@
     public void testLocalDateTimeType() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>());
+        ActionContext context = ActionContext.of();
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME_STR,
                 LocalDateTime.class);
@@ -142,7 +143,7 @@
         ValueStack stack = new StubValueStack();
         stack.push(new StubTextProvider(map));
 
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(mxLocale)
+        ActionContext context = ActionContext.of().withLocale(mxLocale)
                 .withValueStack(stack);
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATETIME1_STR,
@@ -153,7 +154,7 @@
     public void testLocalDateTimeTypeConversionExceptionWhenParseError() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>());
+        ActionContext context = ActionContext.of();
 
         try {
             converter.convertValue(context.getContextMap(), null, null, null, INVALID_LOCALDATETIME,
@@ -168,7 +169,7 @@
     public void testLocalDateType() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>());
+        ActionContext context = ActionContext.of();
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALDATE_STR,
                 LocalDate.class);
@@ -178,7 +179,7 @@
     public void testLocalTimeType() {
         DateConverter converter = new DateConverter();
 
-        ActionContext context = ActionContext.of(new HashMap<>());
+        ActionContext context = ActionContext.of();
 
         Object value = converter.convertValue(context.getContextMap(), null, null, null, LOCALTIME_STR,
                 LocalTime.class);
diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverterTest.java
index a1fb332..bef05ca 100644
--- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverterTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkBasicConverterTest.java
@@ -64,7 +64,7 @@
         ValueStack stack = new StubValueStack();
         stack.push(new StubTextProvider(map));
 
-        ActionContext context = ActionContext.of(new HashMap<>())
+        ActionContext context = ActionContext.of()
             .withLocale(new Locale("es_MX", "MX"))
             .withValueStack(stack);
 
@@ -83,7 +83,7 @@
 
         Locale locale = new Locale("pl", "PL");
 
-        ActionContext context = ActionContext.of(new HashMap<>())
+        ActionContext context = ActionContext.of()
             .withLocale(locale)
             .withValueStack(stack);
 
@@ -102,7 +102,7 @@
 
         Locale locale = new Locale("fr", "FR");
 
-        ActionContext context = ActionContext.of(new HashMap<>())
+        ActionContext context = ActionContext.of()
             .withLocale(locale)
             .withValueStack(stack);
 
@@ -121,7 +121,7 @@
 
         Locale locale = new Locale("en", "US");
 
-        ActionContext context = ActionContext.of(new HashMap<>())
+        ActionContext context = ActionContext.of()
             .withLocale(locale)
             .withValueStack(stack);
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
index 9ca0e0e..192fe87 100644
--- a/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/conversion/impl/XWorkConverterTest.java
@@ -26,6 +26,7 @@
 import com.opensymphony.xwork2.util.Cat;
 import com.opensymphony.xwork2.util.Foo;
 import com.opensymphony.xwork2.util.FurColor;
+import com.opensymphony.xwork2.util.ValueStack;
 import com.opensymphony.xwork2.util.reflection.ReflectionContextState;
 import ognl.OgnlRuntime;
 import ognl.TypeConverter;
@@ -46,43 +47,12 @@
 import java.util.Date;
 import java.util.Set;
 
-/**
- * @author $Author$
- * @version $Revision$
- */
 public class XWorkConverterTest extends XWorkTestCase {
 
     Map<String, Object> context;
     XWorkConverter converter;
     OgnlValueStack stack;
 
-//    public void testConversionToSetKeepsOriginalSetAndReplacesContents() {
-//        ValueStack stack = ValueStackFactory.getFactory().createValueStack();
-//
-//        Map stackContext = stack.getContext();
-//        stackContext.put(InstantiatingNullHandler.CREATE_NULL_OBJECTS, Boolean.TRUE);
-//        stackContext.put(XWorkMethodAccessor.DENY_METHOD_EXECUTION, Boolean.TRUE);
-//        stackContext.put(XWorkConverter.REPORT_CONVERSION_ERRORS, Boolean.TRUE);
-//
-//        String[] param = new String[] {"abc", "def", "ghi"};
-//        List paramList = Arrays.asList(param);
-//
-//        List originalList = new ArrayList();
-//        originalList.add("jkl");
-//        originalList.add("mno");
-//
-//        User user = new User();
-//        user.setList(originalList);
-//        stack.push(user);
-//
-//        stack.setValue("list", param);
-//
-//        List userList = user.getList();
-//        assertEquals(3,userList.size());
-//        assertEquals(paramList,userList);
-//        assertSame(originalList,userList);
-//    }
-
     public void testArrayToNumberConversion() {
         String[] value = new String[]{"12345"};
         assertEquals(12345, converter.convertValue(context, null, null, null, value, Integer.class));
@@ -131,7 +101,7 @@
         TextProvider tp = new StubTextProvider(lookupMap);
         StubValueStack valueStack = new StubValueStack();
         valueStack.push(tp);
-        context.put(ActionContext.VALUE_STACK, valueStack);
+        context.put(ValueStack.VALUE_STACK, valueStack);
 
         String dateToFormat = "2017---06--15";
         Object unparseableDate = converter.convertValue(context, null, null, null, dateToFormat, Date.class);
@@ -477,7 +447,7 @@
     }
 
     public void testStringToCustomTypeUsingCustomConverter() {
-        // the converter needs to be registered as the Bar.class converter 
+        // the converter needs to be registered as the Bar.class converter
         // it won't be detected from the Foo-conversion.properties
         // because the Foo-conversion.properties file is only used when converting a property of Foo
         converter.registerConverter(Bar.class.getName(), new FooBarConverter());
@@ -658,7 +628,7 @@
         assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "aa123", Double.class));
         assertEquals(1234d, converter.convertValue(context, null, null, null, "1,234", Double.class));
         assertEquals(1234.12, converter.convertValue(context, null, null, null, "1,234.12", Double.class));
-        // WRONG: locale separator is wrongly placed 
+        // WRONG: locale separator is wrongly placed
         assertEquals(123d, converter.convertValue(context, null, null, null, "1,23", Double.class));
         assertEquals(1.234, converter.convertValue(context, null, null, null, "1.234", Double.class));
         assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "1.234,12", Double.class));
@@ -675,14 +645,14 @@
         assertEquals(1234.12, converter.convertValue(context, null, null, null, "1.234,12", Double.class));
 
     }
-    
+
     public void testStringToEnum() {
         assertEquals(FurColor.BLACK, converter.convertValue(context, null, null, null, "BLACK", FurColor.class));
         assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "black", FurColor.class));
         assertEquals(OgnlRuntime.NoConversionPossible, converter.convertValue(context, null, null, null, "red", FurColor.class));
     }
 
-    // Testing for null result on non-primitive Number types supplied as empty String or 
+    // Testing for null result on non-primitive Number types supplied as empty String or
     public void testNotPrimitiveDefaultsToNull() {
         assertNull(converter.convertValue(context, null, null, null, null, Double.class));
         assertNull(converter.convertValue(context, null, null, null, "", Double.class));
@@ -829,4 +799,4 @@
         this.ints = ints;
     }
 
-}
\ No newline at end of file
+}
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/AliasInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/AliasInterceptorTest.java
index 00e9141..16108ef 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/AliasInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/AliasInterceptorTest.java
@@ -164,15 +164,15 @@
     }
 
     public void testNotExisting() throws Exception {
-        Map<String, Object> params = new HashMap<>();
         Map<String, Object> httpParams = new HashMap<>();
         httpParams.put("notExisting", "from http parameter");
-        params.put(ActionContext.PARAMETERS, HttpParameters.create(httpParams).build());
+        ActionContext context = ActionContext.of()
+            .withParameters(HttpParameters.create(httpParams).build());
 
         XmlConfigurationProvider provider = new StrutsXmlConfigurationProvider("xwork-sample.xml");
         container.inject(provider);
         loadConfigurationProviders(provider);
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "aliasTest", null, params);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "aliasTest", null, context.getContextMap());
         SimpleAction actionOne = (SimpleAction) proxy.getAction();
 
         // prevent ERROR result
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ChainingInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ChainingInterceptorTest.java
index d809e4b..0c6fd27 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ChainingInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ChainingInterceptorTest.java
@@ -154,7 +154,7 @@
         mockInvocation = new Mock(ActionInvocation.class);
         mockInvocation.expectAndReturn("getStack", stack);
         mockInvocation.expectAndReturn("invoke", Action.SUCCESS);
-        mockInvocation.expectAndReturn("getInvocationContext", ActionContext.of(new HashMap<>()).bind());
+        mockInvocation.expectAndReturn("getInvocationContext", ActionContext.of().bind());
         mockInvocation.expectAndReturn("getResult", new ActionChainResult());
         invocation = (ActionInvocation) mockInvocation.proxy();
         interceptor = new ChainingInterceptor();
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptorTest.java
index d2a0f83..628c069 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/DefaultWorkflowInterceptorTest.java
@@ -183,7 +183,7 @@
         EasyMock.replay(action);
         EasyMock.replay(proxy);
 
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withActionInvocation(invocation)
             .bind();
     }
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptorTest.java
index d14b2b8..5ef177d 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ExceptionMappingInterceptorTest.java
@@ -293,7 +293,7 @@
         stack = ActionContext.getContext().getValueStack();
         mockInvocation = new Mock(ActionInvocation.class);
         mockInvocation.expectAndReturn("getStack", stack);
-        mockInvocation.expectAndReturn("getInvocationContext", ActionContext.of(new HashMap<>()).bind());
+        mockInvocation.expectAndReturn("getInvocationContext", ActionContext.of().bind());
         interceptor = new ExceptionMappingInterceptor();
         interceptor.init();
     }
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java
index 79b23ce..da7cefc 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java
@@ -64,64 +64,64 @@
         runFilterTest(null,null,true,new String[] {"blah", "bladeblah", "bladebladeblah"});
         assertEquals(0, getParameterNames().size());
     }
-    
+
     public void testBasicAllowed() throws Exception {
         runFilterTest("blah",null,true,new String[] {"blah"});
-        assertEquals(1, getParameterNames().size()); 
+        assertEquals(1, getParameterNames().size());
     }
-    
+
     public void testBasicBlocked() throws Exception {
         runFilterTest(null,"blah",false,new String[] {"blah"});
-        assertEquals(0, getParameterNames().size()); 
-    }      
+        assertEquals(0, getParameterNames().size());
+    }
     public void testAllSubpropertiesBlocked() throws Exception {
         runFilterTest(null,"blah",false,new String[] {"blah.deblah", "blah.somethingelse", "blah(22)"});
-        assertEquals(0, getParameterNames().size()); 
+        assertEquals(0, getParameterNames().size());
     }
 
     public void testAllSubpropertiesAllowed() throws Exception {
         runFilterTest("blah",null,true,
                 new String[] {"blah.deblah", "blah.somethingelse", "blah(22)"});
-        assertEquals(3, getParameterNames().size()); 
+        assertEquals(3, getParameterNames().size());
     }
-    
+
     public void testTreeBlocking() throws Exception {
         runFilterTest("blah.deblah","blah,blah.deblah.deblah",false,
                 new String[] {"blah", "blah.deblah", "blah.deblah.deblah"});
         assertEquals(1, getParameterNames().size());
         assertEquals(getParameterNames().iterator().next(),"blah.deblah");
     }
-    
+
     public void testEnsureOnlyPropsBlocked() throws Exception {
         runFilterTest(null,"blah",false,new String[] {"blahdeblah"});
-        assertEquals(1, getParameterNames().size()); 
+        assertEquals(1, getParameterNames().size());
     }
-  
-    
+
+
     private void runFilterTest(String allowed, String blocked, boolean defaultBlocked, String[] paramNames) throws Exception {
         interceptor.setAllowed(allowed);
         interceptor.setBlocked(blocked);
         interceptor.setDefaultBlock(defaultBlocked);
         setUpParameters(paramNames);
         runAction();
-        
+
     }
-    
+
     private void setUpParameters(String [] paramNames) {
         Map<String, String> params = new HashMap<>();
         for (String paramName : paramNames) {
             params.put(paramName, "irrelevant what this is");
 
         }
-        ActionContext.getContext().setParameters(HttpParameters.create(params).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(params).build());
     }
-    
+
     private Collection<String> getParameterNames() {
         return ActionContext.getContext().getParameters().keySet();
     }
-    
+
     public void runAction() throws Exception  {
         interceptor.intercept(invocation);
     }
-    
+
 }
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java
index 928d13f..60131d9 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java
@@ -24,8 +24,8 @@
 import junit.framework.TestCase;
 import org.apache.struts2.dispatcher.HttpParameters;
 
+import java.util.HashMap;
 import java.util.LinkedHashMap;
-import java.util.Map;
 
 import static org.easymock.EasyMock.createMock;
 import static org.easymock.EasyMock.expect;
@@ -38,15 +38,12 @@
  */
 public class ParameterRemoverInterceptorTest extends TestCase {
 
-    protected Map<String, Object> contextMap;
-    protected ActionContext context;
-    protected ActionInvocation actionInvocation;
+    private ActionContext context;
+    private ActionInvocation actionInvocation;
 
     @Override
     protected void setUp() throws Exception {
-        contextMap = new LinkedHashMap<>();
-        context = ActionContext.of(contextMap).bind();
-
+        context = ActionContext.of();
         actionInvocation = createMock(ActionInvocation.class);
         expect(actionInvocation.getAction()).andStubReturn(new SampleAction());
         expect(actionInvocation.getInvocationContext()).andStubReturn(context);
@@ -54,7 +51,7 @@
     }
 
     public void testInterception1() throws Exception {
-        contextMap.put(ActionContext.PARAMETERS, HttpParameters.create(new LinkedHashMap<String, Object>() {
+        context.withParameters(HttpParameters.create(new LinkedHashMap<String, Object>() {
             {
                 put("param1", new String[]{"paramValue1"});
                 put("param2", new String[]{"paramValue2"});
@@ -70,7 +67,7 @@
         interceptor.setParamValues("paramValue1,paramValue2");
         interceptor.intercept(actionInvocation);
 
-        HttpParameters params = (HttpParameters) contextMap.get(ActionContext.PARAMETERS);
+        HttpParameters params = context.getParameters();
         assertEquals(params.keySet().size(), 2);
         assertTrue(params.contains("param3"));
         assertTrue(params.contains("param"));
@@ -82,7 +79,7 @@
 
 
     public void testInterception2() throws Exception {
-        contextMap.put(ActionContext.PARAMETERS, HttpParameters.create(new LinkedHashMap<String, Object>() {
+        context.withParameters(HttpParameters.create(new LinkedHashMap<String, Object>() {
             {
                 put("param1", new String[]{"paramValue2"});
                 put("param2", new String[]{"paramValue1"});
@@ -96,7 +93,7 @@
         interceptor.setParamValues("paramValue1,paramValue2");
         interceptor.intercept(actionInvocation);
 
-        HttpParameters params = (HttpParameters) contextMap.get(ActionContext.PARAMETERS);
+        HttpParameters params = context.getParameters();
         assertEquals(params.keySet().size(), 0);
 
         verify(actionInvocation);
@@ -104,7 +101,7 @@
 
 
     public void testInterception3() throws Exception {
-        contextMap.put(ActionContext.PARAMETERS, HttpParameters.create(new LinkedHashMap<String, Object>() {
+        context.withParameters(HttpParameters.create(new LinkedHashMap<String, Object>() {
             {
                 put("param1", new String[]{"paramValueOne"});
                 put("param2", new String[]{"paramValueTwo"});
@@ -118,7 +115,7 @@
         interceptor.setParamValues("paramValue1,paramValue2");
         interceptor.intercept(actionInvocation);
 
-        HttpParameters params = (HttpParameters) contextMap.get(ActionContext.PARAMETERS);
+        HttpParameters params = context.getParameters();
         assertEquals(params.keySet().size(), 2);
         assertTrue(params.contains("param1"));
         assertTrue(params.contains("param2"));
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
index 245e868..6f28dae 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java
@@ -220,10 +220,9 @@
         Map<String, Object> params = new HashMap<>();
         params.put("@java.lang.System@exit(1).dummy", "dumb value");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext.getContextMap());
         assertEquals(Action.SUCCESS, proxy.execute());
 
         String property = System.getProperty("xwork.security.test");
@@ -239,10 +238,9 @@
         params.put("name", nameVal);
         params.put("count", "15");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext.getContextMap());
         assertEquals(Action.SUCCESS, proxy.execute());
 
         ModelDrivenAction action = (ModelDrivenAction) proxy.getAction();
@@ -265,10 +263,9 @@
         params.put("('\u0023'%2b'session['user5']')(unused)", "0wn3d");
         params.put("('\\u0023'%2b'session['user5']')(unused)", "0wn3d");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         ValueStack stack = proxy.getInvocation().getStack();
         HashMap<String, Object> session = new HashMap<>();
         stack.getContext().put("session", session);
@@ -340,10 +337,9 @@
         params.put("('(aaa)(('\\u0023context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\u003d\\u0023foo')(\\u0023foo\\u003dnew java.lang.Boolean(\"true\")))", "");
         params.put("(asdf)(('\\u0023rt.exit(1)')(\\u0023rt\\u003d@java.lang.Runtime@getRuntime()))", "1");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         ValueStack stack = proxy.getInvocation().getStack();
 
         // when
@@ -361,10 +357,9 @@
         Map<String, Object> params = new HashMap<>();
         params.put("blah", "This is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah());
     }
@@ -376,10 +371,9 @@
         params.put("theProtectedMap[' p0p1 ']", "test3");
         params.put("theProtectedMap[' p0 p1 ']", "test4");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         Map<String, String> existingMap = ((SimpleAction) proxy.getAction()).getTheProtectedMap();
         assertEquals(0, existingMap.size());
@@ -389,10 +383,9 @@
         Map<String, Object> params = new HashMap<>();
         params.put("theProtectedMap['名字']", "test1");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         Map<String, String> existingMap = ((SimpleAction) proxy.getAction()).getTheProtectedMap();
         assertEquals(1, existingMap.size());
@@ -445,10 +438,9 @@
             }
         };
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
 
         ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
         ParametersInterceptor pi = (ParametersInterceptor) config.getInterceptors().get(0).getInterceptor();
@@ -476,10 +468,9 @@
             }
         };
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
 
         ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
         ParametersInterceptor pi = (ParametersInterceptor) config.getInterceptors().get(0).getInterceptor();
@@ -499,10 +490,9 @@
         params.put("protectedMap.foo", "This is blah");
         params.put("theProtectedMap.boo", "This is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         SimpleAction action = (SimpleAction) proxy.getAction();
         assertEquals(1, action.getTheProtectedMap().size());
@@ -515,10 +505,9 @@
         params.put("theSemiProtectedMap.foo", "This is blah");
         params.put("theProtectedMap.boo", "This is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         SimpleAction action = (SimpleAction) proxy.getAction();
         assertEquals(1, action.getTheProtectedMap().size());
@@ -539,10 +528,9 @@
             "@java.lang.Runtime@getRuntime().exec('mkdir /tmp/PWNAGE'))(meh)");
         params.put("top['blah'](0)", "true");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         @SuppressWarnings("unused")
         SimpleAction action = (SimpleAction) proxy.getAction();
@@ -557,10 +545,9 @@
         Map<String, Object> params = new LinkedHashMap<>();
         params.put("existingMap.boo", "This is blah");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         SimpleAction action = (SimpleAction) proxy.getAction();
         assertEquals(1, action.getTheExistingMap().size());
@@ -576,12 +563,11 @@
         Map<String, Object> params = new HashMap<>();
         params.put("not_a_property", "There is no action property named like this");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
         container.inject(config.getInterceptors().get(0).getInterceptor());
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         final String actionMessage = "" + ((SimpleAction) proxy.getAction()).getActionMessages().toArray()[0];
         assertTrue(actionMessage.contains("Error setting expression 'not_a_property' with value 'There is no action property named like this'"));
@@ -595,12 +581,11 @@
         Map<String, Object> params = new HashMap<>();
         params.put("not_a_property", "There is no action property named like this");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME);
         container.inject(config.getInterceptors().get(0).getInterceptor());
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         assertTrue(((SimpleAction) proxy.getAction()).getActionMessages().isEmpty());
     }
@@ -763,11 +748,10 @@
         Map<String, Object> params = new HashMap<>();
         params.put("beanList.name", new String[]{"Superman"});
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         ActionProxy proxy = actionProxyFactory.createActionProxy("",
-            MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext);
+            MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         SimpleAction action = (SimpleAction) proxy.getAction();
         assertNotNull(action);
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptorTest.java
index 6938d30..39358f2 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ScopedModelDrivenInterceptorTest.java
@@ -124,7 +124,7 @@
         User user = new User();
         user.setName("King George");
         Map session = new HashMap();
-        ActionContext.getContext().setSession(session);
+        ActionContext.getContext().withSession(session);
         ActionContext.getContext().getSession().put("king", user);
 
         ScopedModelDriven action = new MyUserScopedModelDrivenAction();
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptorTest.java
index 4f996f6..e393ce2 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/StaticParametersInterceptorTest.java
@@ -130,7 +130,7 @@
 
         User user = new User();
         ActionContext.getContext().getValueStack().push(user);
-        ActionContext.getContext().setParameters(HttpParameters.create().build());
+        ActionContext.getContext().withParameters(HttpParameters.create().build());
         int before = ActionContext.getContext().getValueStack().size();
         interceptor.setMerge("false");
         interceptor.intercept(mai);
@@ -152,7 +152,7 @@
 
         Map<String, String> existingParams = new HashMap<>();
         existingParams.put("name", "Akash");
-        ActionContext.getContext().setParameters(HttpParameters.create(existingParams).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(existingParams).build());
         int before = ActionContext.getContext().getValueStack().size();
 
         interceptor.setOverwrite("true");
@@ -175,7 +175,7 @@
 
         Map<String, String> existingParams = new HashMap<>();
         existingParams.put("name", "Akash");
-        ActionContext.getContext().setParameters(HttpParameters.create(existingParams).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(existingParams).build());
         int before = ActionContext.getContext().getValueStack().size();
 
         interceptor.setOverwrite("false");
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationErrorAwareTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationErrorAwareTest.java
index 79a126b..642fc34 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationErrorAwareTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationErrorAwareTest.java
@@ -87,7 +87,7 @@
         EasyMock.replay(action);
         EasyMock.replay(proxy);
 
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withActionInvocation(invocation)
             .bind();
     }
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationInterceptorPrefixMethodInvocationTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationInterceptorPrefixMethodInvocationTest.java
index 7e39be0..5799830 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationInterceptorPrefixMethodInvocationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ValidationInterceptorPrefixMethodInvocationTest.java
@@ -101,7 +101,7 @@
         EasyMock.replay(action);
         EasyMock.replay(proxy);
 
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withActionInvocation(invocation)
             .bind();
     }
diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptorTest.java
index ead2045..7f9b676 100644
--- a/core/src/test/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/annotations/AnnotationParameterFilterInterceptorTest.java
@@ -55,8 +55,8 @@
         parameterMap.put("job", "Baker");
         parameterMap.put("name", "Martin");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create(parameterMap).build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create(parameterMap).build());
 
         Action action = new BlockingByDefaultAction();
         stack.push(action);
@@ -92,8 +92,8 @@
         parameterMap.put("job", "Baker");
         parameterMap.put("name", "Martin");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create(parameterMap).build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create(parameterMap).build());
 
         Action action = new AllowingByDefaultAction();
         stack.push(action);
@@ -131,8 +131,8 @@
         parameterMap.put("m1", "s1");
         parameterMap.put("m2", "s2");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create(parameterMap).build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create(parameterMap).build());
         stack.push(new BlockingByDefaultModel());
 
         Mock mockInvocation = new Mock(ActionInvocation.class);
@@ -170,8 +170,8 @@
         parameterMap.put("m1", "s1");
         parameterMap.put("m2", "s2");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create(parameterMap).build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create(parameterMap).build());
         stack.push(new AllowingByDefaultModel());
 
         Mock mockInvocation = new Mock(ActionInvocation.class);
diff --git a/core/src/test/java/com/opensymphony/xwork2/util/MyBeanActionTest.java b/core/src/test/java/com/opensymphony/xwork2/util/MyBeanActionTest.java
index 5921db0..f66b85c 100644
--- a/core/src/test/java/com/opensymphony/xwork2/util/MyBeanActionTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/util/MyBeanActionTest.java
@@ -42,11 +42,10 @@
         params.put("annotatedBeanList(1234567890).name", "This is the bla bean by annotation");
         params.put("annotatedBeanList(1234567891).name", "This is the 2nd bla bean by annotation");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", "MyBean", null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", "MyBean", null, extraContext.getContextMap());
             proxy.execute();
             assertEquals(2, Integer.parseInt(proxy.getInvocation().getStack().findValue("beanList.size").toString()));
             assertEquals(MyBean.class.getName(), proxy.getInvocation().getStack().findValue("beanList.get(0)").getClass().getName());
@@ -85,11 +84,10 @@
         params.put("annotatedBeanMap[1234567890].name", "This is the bla bean by annotation");
         params.put("annotatedBeanMap[1234567891].name", "This is the 2nd bla bean by annotation");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", "MyBean", null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", "MyBean", null, extraContext.getContextMap());
             proxy.execute();
             MyBeanAction action = (MyBeanAction) proxy.getInvocation().getAction();
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java b/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java
index b5eda4f..da7f3f0 100644
--- a/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/util/NamedVariablePatternMatcherTest.java
@@ -53,6 +53,26 @@
         assertEquals("bob", pattern.getVariableNames().get(1));
         assertTrue(pattern.getPattern().matcher("foostar/jie").matches());
         assertFalse(pattern.getPattern().matcher("foo/star/jie").matches());
+
+        pattern = matcher.compilePattern("{urlLocale}/eula_cz");
+        assertEquals("([^/]+)\\Q/eula_cz\\E", pattern.getPattern().pattern());
+        assertEquals("urlLocale", pattern.getVariableNames().get(0));
+        assertTrue(pattern.getPattern().matcher("foostar/eula_cz").matches());
+        assertFalse(pattern.getPattern().matcher("foo/star/eula_cz").matches());
+
+        pattern = matcher.compilePattern("{test1}/path/{test2}");
+        assertEquals("([^/]+)\\Q/path/\\E([^/]+)", pattern.getPattern().pattern());
+        assertEquals("test1", pattern.getVariableNames().get(0));
+        assertEquals("test2", pattern.getVariableNames().get(1));
+        assertTrue(pattern.getPattern().matcher("test1/path/test2").matches());
+        assertFalse(pattern.getPattern().matcher("test/1/path/test2").matches());
+
+        pattern = matcher.compilePattern("path1/{test1}/path2/{test2}");
+        assertEquals("\\Qpath1/\\E([^/]+)\\Q/path2/\\E([^/]+)", pattern.getPattern().pattern());
+        assertEquals("test1", pattern.getVariableNames().get(0));
+        assertEquals("test2", pattern.getVariableNames().get(1));
+        assertTrue(pattern.getPattern().matcher("path1/test1/path2/test2").matches());
+        assertFalse(pattern.getPattern().matcher("path1/test/1/path2/test2").matches());
     }
 
     @Test(expected = IllegalArgumentException.class)
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java
index 98a5ed0..e4a8a73 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DateRangeValidatorTest.java
@@ -44,13 +44,12 @@
     public void testRangeValidation() throws Exception {
         Calendar date = Calendar.getInstance();
         date.set(2002, Calendar.NOVEMBER, 20);
-        Map<String, Object> context = new HashMap<>();
         HashMap<String, Object> params = new HashMap<>();
         params.put("date", date.getTime());
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
-        context.put(ActionContext.LOCALE, Locale.US);  // Force US Locale for date conversion tests on JDK9+
+        ActionContext context = ActionContext.of().withParameters(HttpParameters.create(params).build())
+                .withLocale(Locale.US);  // Force US Locale for date conversion tests on JDK9+
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context.getContextMap());
         proxy.execute();
         assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java
index 233952c..c6f4b3d 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DefaultActionValidatorManagerTest.java
@@ -67,7 +67,7 @@
         actionValidatorManager.setValidatorFactory((ValidatorFactory)mockValidatorFactory.proxy());
 
         stubValueStack = new StubValueStack();
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withValueStack(stubValueStack)
             .bind();
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java
index 41da48f..971517c 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/DoubleRangeFieldValidatorTest.java
@@ -52,12 +52,11 @@
 
     public void testRangeValidationWithError() throws Exception {
         //Explicitly set an out-of-range double for DoubleRangeValidatorTest
-        Map<String, Object> context = new HashMap<>();
         HashMap<String, Object> params = new HashMap<>();
         params.put("percentage", 100.12);
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext context = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, context.getContextMap());
         proxy.execute();
         assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
@@ -73,12 +72,11 @@
     }
 
     public void testRangeValidationNoError() throws Exception {
-        Map<String, Object> context = new HashMap<>();
         HashMap<String, Object> params = new HashMap<>();
         params.put("percentage", 1.234567d);
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext context = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "percentage", null, context);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "percentage", null, context.getContextMap());
         proxy.execute();
         assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
@@ -200,12 +198,11 @@
 
     public void testRangeValidationWithExpressionsFail() throws Exception {
         //Explicitly set an out-of-range double for DoubleRangeValidatorTest
-        Map<String, Object> context = new HashMap<>();
         HashMap<String, Object> params = new HashMap<>();
         params.put("percentage", 100.12);
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext context = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.EXPRESSION_VALIDATION_ACTION, null, context);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.EXPRESSION_VALIDATION_ACTION, null, context.getContextMap());
         proxy.execute();
         assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
@@ -311,7 +308,7 @@
         loadConfigurationProviders(provider, new MockConfigurationProvider());
         val = new DoubleRangeFieldValidator();
         val.setValueStack(ActionContext.getContext().getValueStack());
-        ActionContext.getContext().setParameters(HttpParameters.create().build());
+        ActionContext.getContext().withParameters(HttpParameters.create().build());
         tpf = container.getInstance(TextProviderFactory.class);
     }
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/ExpressionValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/ExpressionValidatorTest.java
index 500824c..2569ca6 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/ExpressionValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/ExpressionValidatorTest.java
@@ -71,10 +71,9 @@
         params.put("foo", "5");
         params.put("bar", "7");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         assertTrue(((ValidationAware) proxy.getAction()).hasActionErrors());
 
@@ -94,10 +93,9 @@
         params.put("foo", "10");
         params.put("bar", "7");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
         proxy.execute();
         assertFalse(((ValidationAware) proxy.getAction()).hasActionErrors());
     }
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/IntRangeValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/IntRangeValidatorTest.java
index fefece9..f42af3e 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/IntRangeValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/IntRangeValidatorTest.java
@@ -41,11 +41,10 @@
         HashMap<String, String> params = new HashMap<>();
         params.put("bar", "5");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
             proxy.execute();
             assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/LongRangeValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/LongRangeValidatorTest.java
index 4a24ca8..560c5d5 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/LongRangeValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/LongRangeValidatorTest.java
@@ -38,11 +38,10 @@
         HashMap<String, String> params = new HashMap<>();
         params.put("longFoo", "200");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
             proxy.execute();
             assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/ModelDrivenValidationTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/ModelDrivenValidationTest.java
index af59461..6014b27 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/ModelDrivenValidationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/ModelDrivenValidationTest.java
@@ -44,13 +44,12 @@
         Map<String, Object> params = new HashMap<>();
         params.put("count", new String[]{"11"});
 
-        Map<String, Object> context = new HashMap<>();
-        context.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext context = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         XmlConfigurationProvider provider = new StrutsXmlConfigurationProvider("xwork-sample.xml");
         container.inject(provider);
         loadConfigurationProviders(provider);
-        ActionProxy proxy = actionProxyFactory.createActionProxy(null, "TestModelDrivenValidation", null, context);
+        ActionProxy proxy = actionProxyFactory.createActionProxy(null, "TestModelDrivenValidation", null, context.getContextMap());
         assertEquals(Action.SUCCESS, proxy.execute());
 
         ModelDrivenAction action = (ModelDrivenAction) proxy.getAction();
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/ShortRangeValidatorTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/ShortRangeValidatorTest.java
index abada8f..aa176c9 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/ShortRangeValidatorTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/ShortRangeValidatorTest.java
@@ -38,11 +38,10 @@
         HashMap<String, Object> params = new HashMap<>();
         params.put("shortFoo", "200");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
             proxy.execute();
             assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/SimpleActionValidationTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/SimpleActionValidationTest.java
index b2e1f2a..76f9a24 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/SimpleActionValidationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/SimpleActionValidationTest.java
@@ -54,7 +54,7 @@
         params.put("date", "12/23/2002");
         params.put("percentage", "1.23456789");
 
-        Map<String, Object> extraContext = ActionContext.of(new HashMap<>())
+        Map<String, Object> extraContext = ActionContext.of()
             .withParameters(HttpParameters.create(params).build())
             .bind()
             .getContextMap();
@@ -67,7 +67,7 @@
             assertFalse(validationAware.hasFieldErrors());
 
             params.put("bar", "42");
-            extraContext = ActionContext.of(new HashMap<>())
+            extraContext = ActionContext.of()
                 .withParameters(HttpParameters.create(params).build())
                 .bind()
                 .getContextMap();
@@ -106,11 +106,10 @@
         //valid values
         params.put("bar", "7");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
             proxy.execute();
             assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
@@ -131,11 +130,10 @@
         HashMap<String, Object> params = new HashMap<>();
         params.put("foo", "200");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
             ValueStack stack = ActionContext.getContext().getValueStack();
             stack.getActionContext().withLocale(Locale.US);
 
@@ -183,11 +181,10 @@
         HashMap<String, Object> params = new HashMap<>();
         params.put("bar", "42");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_ACTION_NAME, null, extraContext.getContextMap());
             proxy.execute();
             assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
@@ -218,11 +215,10 @@
         // this should cause a message
         params.put("bean.count", "100");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         try {
-            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_SUBPROPERTY_NAME, null, extraContext);
+            ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.VALIDATION_SUBPROPERTY_NAME, null, extraContext.getContextMap());
             proxy.execute();
             assertTrue(((ValidationAware) proxy.getAction()).hasFieldErrors());
 
diff --git a/core/src/test/java/com/opensymphony/xwork2/validator/ValidatorAnnotationTest.java b/core/src/test/java/com/opensymphony/xwork2/validator/ValidatorAnnotationTest.java
index 100521a..0bb3195 100644
--- a/core/src/test/java/com/opensymphony/xwork2/validator/ValidatorAnnotationTest.java
+++ b/core/src/test/java/com/opensymphony/xwork2/validator/ValidatorAnnotationTest.java
@@ -42,10 +42,9 @@
         params.put("foo", "5");
         params.put("bar", "7");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "notAnnotatedMethod", null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "notAnnotatedMethod", null, extraContext.getContextMap());
         proxy.execute();
         assertFalse(((ValidationAware) proxy.getAction()).hasActionErrors());
 
@@ -54,11 +53,9 @@
     }
 
     public void testNotAnnotatedMethodSuccess2() throws Exception {
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create().build());
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create().build());
-
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "notAnnotatedMethod", null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "notAnnotatedMethod", null, extraContext.getContextMap());
         proxy.execute();
         assertFalse(((ValidationAware) proxy.getAction()).hasActionErrors());
 
@@ -67,11 +64,9 @@
     }
 
     public void testAnnotatedMethodFailure() throws Exception {
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create().build());
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create().build());
-
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext.getContextMap());
         proxy.execute();
         assertTrue(((ValidationAware) proxy.getAction()).hasActionErrors());
         Collection errors = ((ValidationAware) proxy.getAction()).getActionErrors();
@@ -88,10 +83,9 @@
         params.put("param1", "key1");
         params.put("param2", "key2");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext.getContextMap());
         proxy.execute();
         assertFalse(((ValidationAware) proxy.getAction()).hasActionErrors());
     }
@@ -102,10 +96,9 @@
         //make it not fail
         params.put("param2", "key2");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext.getContextMap());
         proxy.execute();
         assertFalse(((ValidationAware) proxy.getAction()).hasActionErrors());
     }
@@ -116,10 +109,9 @@
         //make it not fail
         params.put("param1", "key1");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
-        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext);
+        ActionProxy proxy = actionProxyFactory.createActionProxy("", "annotatedMethod", null, extraContext.getContextMap());
         proxy.execute();
         assertFalse(((ValidationAware) proxy.getAction()).hasActionErrors());
     }
diff --git a/core/src/test/java/org/apache/struts2/components/FormButtonTest.java b/core/src/test/java/org/apache/struts2/components/FormButtonTest.java
index bf0fe95..429ecfd 100644
--- a/core/src/test/java/org/apache/struts2/components/FormButtonTest.java
+++ b/core/src/test/java/org/apache/struts2/components/FormButtonTest.java
@@ -18,6 +18,7 @@
  */
 package org.apache.struts2.components;
 
+import com.opensymphony.xwork2.TestBean;
 import org.apache.struts2.StrutsInternalTestCase;
 import org.springframework.mock.web.MockHttpServletRequest;
 import org.springframework.mock.web.MockHttpServletResponse;
@@ -31,7 +32,7 @@
  */
 public class FormButtonTest extends StrutsInternalTestCase {
 
-    public void testPopulateComponentHtmlId1() throws Exception {
+    public void testPopulateComponentHtmlId1() {
         MockHttpServletRequest req = new MockHttpServletRequest();
         MockHttpServletResponse res = new MockHttpServletResponse();
         ValueStack stack = ActionContext.getContext().getValueStack();
@@ -47,7 +48,7 @@
         assertEquals("submitId", submit.getParameters().get("id"));
     }
 
-    public void testPopulateComponentHtmlId2() throws Exception {
+    public void testPopulateComponentHtmlId2() {
         MockHttpServletRequest req = new MockHttpServletRequest();
         MockHttpServletResponse res = new MockHttpServletResponse();
         ValueStack stack = ActionContext.getContext().getValueStack();
@@ -63,7 +64,7 @@
         assertEquals("formId_submitName", submit.getParameters().get("id"));
     }
 
-    public void testPopulateComponentHtmlId3() throws Exception {
+    public void testPopulateComponentHtmlId3() {
         MockHttpServletRequest req = new MockHttpServletRequest();
         MockHttpServletResponse res = new MockHttpServletResponse();
         ValueStack stack = ActionContext.getContext().getValueStack();
@@ -80,7 +81,7 @@
         assertEquals("formId_submitAction_submitMethod", submit.getParameters().get("id"));
     }
 
-    public void testPopulateComponentHtmlId4() throws Exception {
+    public void testPopulateComponentHtmlId4() {
         MockHttpServletRequest req = new MockHttpServletRequest();
         MockHttpServletResponse res = new MockHttpServletResponse();
         ValueStack stack = ActionContext.getContext().getValueStack();
@@ -93,7 +94,7 @@
         assertEquals("submitId", submit.getParameters().get("id"));
     }
 
-    public void testPopulateComponentHtmlId5() throws Exception {
+    public void testPopulateComponentHtmlId5() {
         MockHttpServletRequest req = new MockHttpServletRequest();
         MockHttpServletResponse res = new MockHttpServletResponse();
         ValueStack stack = ActionContext.getContext().getValueStack();
@@ -106,7 +107,7 @@
         assertEquals("submitName", submit.getParameters().get("id"));
     }
 
-    public void testPopulateComponentHtmlId6() throws Exception {
+    public void testPopulateComponentHtmlId6() {
         MockHttpServletRequest req = new MockHttpServletRequest();
         MockHttpServletResponse res = new MockHttpServletResponse();
         ValueStack stack = ActionContext.getContext().getValueStack();
@@ -119,4 +120,38 @@
 
         assertEquals("submitAction_submitMethod", submit.getParameters().get("id"));
     }
+
+    public void testPopulateComponentHtmlId7() {
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        TestBean bean = new TestBean();
+        bean.setName("secondAction");
+        stack.push(bean);
+
+        Submit submit = new Submit(stack, req, res);
+        submit.setName("%{name}");
+
+        submit.populateComponentHtmlId(null);
+
+        assertEquals("secondAction", submit.getParameters().get("id"));
+    }
+
+    public void testPopulateComponentHtmlId8() {
+        MockHttpServletRequest req = new MockHttpServletRequest();
+        MockHttpServletResponse res = new MockHttpServletResponse();
+        ValueStack stack = ActionContext.getContext().getValueStack();
+        TestBean bean = new TestBean();
+        bean.setName("boo");
+        bean.setSubName("foo");
+        stack.push(bean);
+
+        Submit submit = new Submit(stack, req, res);
+        submit.setAction("%{name}");
+        submit.setMethod("%{subName}");
+
+        submit.populateComponentHtmlId(null);
+
+        assertEquals("boo_foo", submit.getParameters().get("id"));
+    }
 }
diff --git a/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java b/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
index 241864a..73a5265 100644
--- a/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
+++ b/core/src/test/java/org/apache/struts2/dispatcher/DispatcherTest.java
@@ -51,6 +51,7 @@
 import java.util.HashSet;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * Test case for Dispatcher.
@@ -230,12 +231,13 @@
         du.init();
         Configuration config = du.getConfigurationManager().getConfiguration();
         assertNotNull(config);
-        HashSet<String> expected = new HashSet<>();
+        Set<String> expected = new HashSet<>();
         expected.add("struts-default.xml");
         expected.add("struts-beans.xml");
         expected.add("struts-excluded-classes.xml");
         expected.add("struts-plugin.xml");
         expected.add("struts.xml");
+        expected.add("struts-deferred.xml");
         assertEquals(expected, config.getLoadedFileNames());
         assertTrue(config.getPackageConfigs().size() > 0);
         PackageConfig packageConfig = config.getPackageConfig("struts-default");
@@ -462,10 +464,10 @@
 
         // When
         testDispatcher.prepare(request, response);
-        Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
+        ActionContext context = ActionContext.of(createTestContextMap(testDispatcher, request, response));
 
         // Then
-        assertEquals(Locale.GERMANY, contextMap.get(ActionContext.LOCALE));  // Expect the Dispatcher defaultLocale value "de_DE" from the test configuration.
+        assertEquals(Locale.GERMANY, context.getLocale());  // Expect the Dispatcher defaultLocale value "de_DE" from the test configuration.
         mock.verify();
     }
 
@@ -488,10 +490,10 @@
 
         // When
         testDispatcher.prepare(request, response);
-        Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
+        ActionContext context = ActionContext.of(createTestContextMap(testDispatcher, request, response));
 
         // Then
-        assertEquals(Locale.CANADA_FRENCH, contextMap.get(ActionContext.LOCALE));  // Expect the Dispatcher defaultLocale value.
+        assertEquals(Locale.CANADA_FRENCH, context.getLocale());  // Expect the Dispatcher defaultLocale value.
         mock.verify();
     }
 
@@ -516,10 +518,10 @@
 
         // When
         testDispatcher.prepare(request, response);
-        Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
+        ActionContext context = ActionContext.of(createTestContextMap(testDispatcher, request, response));
 
         // Then
-        assertEquals(Locale.UK, contextMap.get(ActionContext.LOCALE));  // Expect the request set value from Mock.
+        assertEquals(Locale.UK, context.getLocale());  // Expect the request set value from Mock.
         mock.verify();
     }
 
@@ -544,10 +546,10 @@
 
         // When
         testDispatcher.prepare(request, response);
-        Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
+        ActionContext context = ActionContext.of(createTestContextMap(testDispatcher, request, response));
 
         // Then
-        assertEquals(Locale.getDefault(), contextMap.get(ActionContext.LOCALE));  // Expect the system default value, when BOTH Dispatcher default Locale AND request access fail.
+        assertEquals(Locale.getDefault(), context.getLocale());  // Expect the system default value, when BOTH Dispatcher default Locale AND request access fail.
         mock.verify();
     }
 
@@ -574,10 +576,10 @@
 
         // When
         testDispatcher.prepare(request, response);
-        Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
+        ActionContext context = ActionContext.of(createTestContextMap(testDispatcher, request, response));
 
         // Then
-        assertEquals(Locale.CANADA_FRENCH, contextMap.get(ActionContext.LOCALE));  // Expect the request set value from Mock.
+        assertEquals(Locale.CANADA_FRENCH, context.getLocale());  // Expect the request set value from Mock.
         mock.verify();
     }
 
@@ -604,10 +606,10 @@
 
         // When
         testDispatcher.prepare(request, response);
-        Map<String, Object> contextMap = createTestContextMap(testDispatcher, request, response);
+        ActionContext context = ActionContext.of(createTestContextMap(testDispatcher, request, response));
 
         // Then
-        assertEquals(Locale.getDefault(), contextMap.get(ActionContext.LOCALE));  // Expect the system default value when Mock request access fails.
+        assertEquals(Locale.getDefault(), context.getLocale());  // Expect the system default value when Mock request access fails.
         mock.verify();
     }
 
diff --git a/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java
index c228d06..0fe5268 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/CheckboxInterceptorTest.java
@@ -29,25 +29,25 @@
 import org.apache.struts2.dispatcher.HttpParameters;
 
 /**
- * Unit test for ChecboxInterceptor. 
+ * Unit test for ChecboxInterceptor.
  */
 public class CheckboxInterceptorTest extends StrutsInternalTestCase {
 
     private CheckboxInterceptor interceptor;
     private MockActionInvocation ai;
     private Map<String, Object> param;
-    
+
     protected void setUp() throws Exception {
     	super.setUp();
     	param = new HashMap<>();
-    	
+
     	interceptor = new CheckboxInterceptor();
     	ai = new MockActionInvocation();
     	ai.setInvocationContext(ActionContext.getContext());
     }
 
 	private void prepare(ActionInvocation ai) {
-		ai.getInvocationContext().setParameters(HttpParameters.create(param).build());
+		ai.getInvocationContext().withParameters(HttpParameters.create(param).build());
 	}
 
 	public void testNoParam() throws Exception {
@@ -68,7 +68,7 @@
 		interceptor.init();
 		interceptor.intercept(ai);
 		interceptor.destroy();
-		
+
 		assertEquals(1, ai.getInvocationContext().getParameters().keySet().size());
 	}
 
@@ -81,7 +81,7 @@
 		interceptor.init();
 		interceptor.intercept(ai);
 		interceptor.destroy();
-		
+
 		assertEquals(2, ai.getInvocationContext().getParameters().keySet().size());
 	}
 
@@ -204,5 +204,5 @@
 		assertEquals("yes", parameters.get("superpower").getValue());
 		assertEquals("no", parameters.get("cool").getValue());
 	}
-	
+
 }
diff --git a/core/src/test/java/org/apache/struts2/interceptor/ClearSessionInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/ClearSessionInterceptorTest.java
index 2928648..8bd4e60 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/ClearSessionInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/ClearSessionInterceptorTest.java
@@ -34,15 +34,15 @@
     public void testCreateSession() throws Exception {
         ClearSessionInterceptor interceptor = new ClearSessionInterceptor();
         MockActionInvocation invocation = new MockActionInvocation();
-        ActionContext context = ActionContext.of(new HashMap<>()).bind();
+        ActionContext context = ActionContext.of().bind();
         Map<String, Object> session = new HashMap<>();
         session.put("Test1", "Test1");
         session.put("Test2", "Test2");
         session.put("Test3", "Test3");
-        context.setSession(session);
+        context.withSession(session);
         invocation.setInvocationContext(context);
         interceptor.intercept(invocation);
-        
+
         assertEquals(0, session.size());
     }
 }
diff --git a/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
index 5abd109..d603335 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/DateTextFieldInterceptorTest.java
@@ -30,25 +30,25 @@
 import org.apache.struts2.dispatcher.HttpParameters;
 
 /**
- * Unit test for DateTextFieldInterceptor. 
+ * Unit test for DateTextFieldInterceptor.
  */
 public class DateTextFieldInterceptorTest extends StrutsInternalTestCase {
 
     private DateTextFieldInterceptor interceptor;
     private MockActionInvocation ai;
     private Map<String, Object> param;
-    
+
     protected void setUp() throws Exception {
     	super.setUp();
     	param = new HashMap<>();
-    	
+
     	interceptor = new DateTextFieldInterceptor();
     	ai = new MockActionInvocation();
     	ai.setInvocationContext(ActionContext.getContext());
     }
-	
+
 	public void testNoParam() throws Exception {
-		ActionContext.getContext().setParameters(HttpParameters.create(param).build());
+		ActionContext.getContext().withParameters(HttpParameters.create(param).build());
 
 		interceptor.init();
 		interceptor.intercept(ai);
@@ -62,7 +62,7 @@
 		param.put("__month_name", new String[]{"06"});
 		param.put("__day_name", new String[]{"15"});
 
-		ActionContext.getContext().setParameters(HttpParameters.create(param).build());
+		ActionContext.getContext().withParameters(HttpParameters.create(param).build());
 
 		interceptor.init();
 		interceptor.intercept(ai);
@@ -74,7 +74,7 @@
 		assertFalse(parameters.contains("__day_name"));
 		assertTrue(parameters.contains("name"));
 		assertEquals(1, parameters.keySet().size());
-		Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2000-06-15"); 
+		Date date = new SimpleDateFormat("yyyy-MM-dd").parse("2000-06-15");
 		assertEquals(date, parameters.get("name").getObject());
 	}
 
diff --git a/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java
index 5c5f6c9..0e68740 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/FileUploadInterceptorTest.java
@@ -234,7 +234,7 @@
         mai.setResultCode("success");
         mai.setInvocationContext(ActionContext.getContext());
 
-        ActionContext.getContext().setParameters(HttpParameters.create().build());
+        ActionContext.getContext().withParameters(HttpParameters.create().build());
         ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequestMaxSize(req, 2000));
 
         interceptor.intercept(mai);
@@ -256,7 +256,7 @@
         mai.setResultCode("success");
         mai.setInvocationContext(ActionContext.getContext());
 
-        ActionContext.getContext().setParameters(HttpParameters.create().build());
+        ActionContext.getContext().withParameters(HttpParameters.create().build());
         ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequestMaxSize(req, 2000));
 
         interceptor.intercept(mai);
@@ -287,7 +287,7 @@
         mai.setResultCode("success");
         mai.setInvocationContext(ActionContext.getContext());
         Map<String, Object> param = new HashMap<>();
-        ActionContext.getContext().setParameters(HttpParameters.create(param).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(param).build());
         ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequestMaxSize(req, 2000));
 
         interceptor.intercept(mai);
@@ -348,7 +348,7 @@
         mai.setResultCode("success");
         mai.setInvocationContext(ActionContext.getContext());
         Map<String, Object> param = new HashMap<String, Object>();
-        ActionContext.getContext().setParameters(HttpParameters.create(param).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(param).build());
         ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequestMaxSize(req, 2000));
 
         interceptor.setAllowedTypes("text/html");
@@ -401,7 +401,7 @@
         mai.setResultCode("success");
         mai.setInvocationContext(ActionContext.getContext());
         Map<String, Object> param = new HashMap<>();
-        ActionContext.getContext().setParameters(HttpParameters.create(param).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(param).build());
         ActionContext.getContext().put(ServletActionContext.HTTP_REQUEST, createMultipartRequestMaxFiles(req, 3));
 
         interceptor.setAllowedTypes("text/html");
@@ -427,7 +427,7 @@
                 "Unit test of FileUploadInterceptor" +
                 "\r\n" +
                 "-----1234--\r\n");
-        req.setContent(content.getBytes("US-ASCII"));
+        req.setContent(content.getBytes(StandardCharsets.US_ASCII));
 
         MyFileupAction action = container.inject(MyFileupAction.class);
 
@@ -466,7 +466,7 @@
                 "Unit test of FileUploadInterceptor" +
                 "\r\n" +
                 "-----1234--\r\n");
-        req.setContent(content.getBytes("US-ASCII"));
+        req.setContent(content.getBytes(StandardCharsets.US_ASCII));
 
         MyFileupAction action = container.inject(MyFileupAction.class);
 
diff --git a/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
index e27ad43..a8fd842 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/I18nInterceptorTest.java
@@ -278,7 +278,7 @@
         Map<String, Serializable> params = new HashMap<>();
         params.put(key, value);
 
-        mai.getInvocationContext().setParameters(HttpParameters.create(params).build());
+        mai.getInvocationContext().withParameters(HttpParameters.create(params).build());
     }
 
     public void setUp() throws Exception {
@@ -287,7 +287,7 @@
         interceptor.init();
         session = new HashMap<>();
 
-        ac = ActionContext.of(new HashMap<>())
+        ac = ActionContext.of()
             .bind()
             .withSession(session)
             .withParameters(HttpParameters.create().build());
diff --git a/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java
index 4413099..e451f59 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/MessageStoreInterceptorTest.java
@@ -66,8 +66,8 @@
         action.addActionMessage("some action message 1");
         action.addFieldError("field2", "some field error 2");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create().build());
 
         HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class);
         HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class);
@@ -141,9 +141,10 @@
 
         EasyMock.replay(mockedRequest);
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
-        actionContext.setSession(sessionMap);
+        ActionContext actionContext = ActionContext.of()
+            .withParameters(HttpParameters.create().build())
+            .withSession(sessionMap)
+            .bind();
 
         mockActionInvocation.getInvocationContext();
         EasyMock.expectLastCall().andReturn(actionContext);
@@ -193,9 +194,10 @@
         action.addFieldError("field1", "some field error 1");
         action.addFieldError("field2", "some field error 2");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
-        actionContext.setSession(sessionMap);
+        ActionContext actionContext = ActionContext.of()
+            .withParameters(HttpParameters.create().build())
+            .withSession(sessionMap)
+            .bind();
 
         HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class);
         HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class);
@@ -236,8 +238,8 @@
         Map<String, Object> paramMap = new LinkedHashMap<>();
         paramMap.put("operationMode", new String[]{MessageStoreInterceptor.RETRIEVE_MODE});
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create(paramMap).build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create(paramMap).build());
 
         ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class);
         mockActionInvocation.getInvocationContext();
@@ -259,8 +261,8 @@
         Map<String, Object> paramMap = new LinkedHashMap<>();
         paramMap.put("operationMode", new String[]{MessageStoreInterceptor.STORE_MODE});
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create(paramMap).build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create(paramMap).build());
 
         ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class);
         mockActionInvocation.getInvocationContext();
@@ -279,8 +281,8 @@
 
     public void testRequestOperationMode3() {
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
+        ActionContext actionContext = ActionContext.of().bind();
+        actionContext.withParameters(HttpParameters.create().build());
 
         ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class);
         mockActionInvocation.getInvocationContext();
diff --git a/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java b/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java
index 6b85930..9fdcf3e 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/MessageStorePreResultListenerTest.java
@@ -43,8 +43,9 @@
 
     public void testSessionWasInvalidated() {
         // given
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
+        ActionContext actionContext = ActionContext.of()
+            .withParameters(HttpParameters.create().build())
+            .bind();
 
         ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class);
 
@@ -84,8 +85,9 @@
 
     public void testResponseWasComitted() {
         // given
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
+        ActionContext actionContext = ActionContext.of()
+            .withParameters(HttpParameters.create().build())
+            .bind();
 
         ActionInvocation mockActionInvocation = EasyMock.createControl().createMock(ActionInvocation.class);
 
@@ -131,9 +133,10 @@
         action.addFieldError("field1", "some field error 1");
         action.addFieldError("field2", "some field error 2");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
-        actionContext.setSession(sessionMap);
+        ActionContext actionContext = ActionContext.of()
+            .withParameters(HttpParameters.create().build())
+            .withSession(sessionMap)
+            .bind();
 
         HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class);
         HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class);
@@ -212,9 +215,10 @@
         action.addFieldError("field1", "some field error 1");
         action.addFieldError("field2", "some field error 2");
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setParameters(HttpParameters.create().build());
-        actionContext.setSession(sessionMap);
+        ActionContext actionContext = ActionContext.of()
+            .withParameters(HttpParameters.create().build())
+            .withSession(sessionMap)
+            .bind();
 
         HttpSession mockedSession = EasyMock.createControl().createMock(HttpSession.class);
         HttpServletRequest mockedRequest = EasyMock.createControl().createMock(HttpServletRequest.class);
@@ -283,4 +287,4 @@
     }
 
 
-}
\ No newline at end of file
+}
diff --git a/core/src/test/java/org/apache/struts2/interceptor/MultiselectInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/MultiselectInterceptorTest.java
index 88800e4..43c9a81 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/MultiselectInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/MultiselectInterceptorTest.java
@@ -44,7 +44,7 @@
         interceptor = new MultiselectInterceptor();

         ai = new MockActionInvocation();

         ai.setInvocationContext(ActionContext.getContext());

-        ActionContext.getContext().setParameters(HttpParameters.create(param).build());

+        ActionContext.getContext().withParameters(HttpParameters.create(param).build());

     }

 

     public void testNoParam() throws Exception {

@@ -81,7 +81,7 @@
         param.put("__multiselect_superpower", "");

         assertTrue(param.containsKey("__multiselect_superpower"));

 

-        ai.getInvocationContext().setParameters(HttpParameters.create(param).build());

+        ai.getInvocationContext().withParameters(HttpParameters.create(param).build());

 

         interceptor.init();

         interceptor.intercept(ai);

@@ -99,7 +99,7 @@
         param.put("__multiselect_superpower", "");

         assertTrue(param.containsKey("__multiselect_superpower"));

 

-        ai.getInvocationContext().setParameters(HttpParameters.create(param).build());

+        ai.getInvocationContext().withParameters(HttpParameters.create(param).build());

 

         interceptor.init();

         interceptor.intercept(ai);

@@ -120,7 +120,7 @@
         assertTrue(param.containsKey("__multiselect_superpower"));

         assertTrue(param.containsKey("__multiselect_cool"));

 

-        ai.getInvocationContext().setParameters(HttpParameters.create(param).build());

+        ai.getInvocationContext().withParameters(HttpParameters.create(param).build());

 

         interceptor.init();

         interceptor.intercept(ai);

diff --git a/core/src/test/java/org/apache/struts2/interceptor/ServletConfigInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/ServletConfigInterceptorTest.java
index c95e2c6..dd57019 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/ServletConfigInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/ServletConfigInterceptorTest.java
@@ -89,7 +89,7 @@
         MockActionInvocation mai = createActionInvocation(mock);
 
         HttpParameters params = HttpParameters.create().build();
-        mai.getInvocationContext().setParameters(params);
+        mai.getInvocationContext().withParameters(params);
 
         mock.withParameters(params);
         expectLastCall().times(1);
@@ -105,7 +105,7 @@
         MockActionInvocation mai = createActionInvocation(mock);
 
         Map<String, Object> session = new HashMap<String, Object>();
-        mai.getInvocationContext().setSession(session);
+        mai.getInvocationContext().withSession(session);
 
         mock.withSession(session);
         expectLastCall().times(1);
diff --git a/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java b/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java
index 2208047..7c3624e 100644
--- a/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java
+++ b/core/src/test/java/org/apache/struts2/interceptor/TokenInterceptorTest.java
@@ -98,7 +98,7 @@
         request.getParameterMap().put(TokenHelper.DEFAULT_TOKEN_NAME, new String[]{
             token
         });
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext.of(extraContext).withParameters(HttpParameters.create(params).build());
     }
 
     protected void setUp() throws Exception {
@@ -125,7 +125,7 @@
         oldContext = ActionContext.of(stack.getContext()).bind();
     }
 
-    protected ActionProxy buildProxy(String actionName) throws Exception {
+    protected ActionProxy buildProxy(String actionName) {
         return actionProxyFactory.createActionProxy("", actionName, null, extraContext);
     }
 }
diff --git a/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java b/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java
index 2ee6478..e8746aa 100644
--- a/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java
+++ b/core/src/test/java/org/apache/struts2/result/ServletRedirectResultTest.java
@@ -294,7 +294,7 @@
         ActionInvocation mockInvocation = control.createMock(ActionInvocation.class);
 
         ValueStack mockValueStack = control.createMock(ValueStack.class);
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).withContainer(container);
+        ActionContext actionContext = ActionContext.of().withContainer(container);
 
         expect(mockInvocation.getStack()).andReturn(mockValueStack);
         expect(mockValueStack.getActionContext()).andReturn(actionContext);
diff --git a/core/src/test/java/org/apache/struts2/util/InvocationSessionStoreTest.java b/core/src/test/java/org/apache/struts2/util/InvocationSessionStoreTest.java
index b581812..f9b4892 100644
--- a/core/src/test/java/org/apache/struts2/util/InvocationSessionStoreTest.java
+++ b/core/src/test/java/org/apache/struts2/util/InvocationSessionStoreTest.java
@@ -69,8 +69,9 @@
         ActionContext actionContext = ActionContext.getContext();
         InvocationSessionStore.storeInvocation(INVOCATION_KEY, TOKEN_VALUE, invocation);
 
-        ActionContext actionContext2 = ActionContext.of(new HashMap<>()).bind();
-        actionContext2.setSession(session);
+        ActionContext actionContext2 = ActionContext.of()
+            .withSession(session)
+            .bind();
 
         assertEquals(actionContext2, ActionContext.getContext());
 
@@ -91,7 +92,7 @@
         ByteArrayInputStream bais = new ByteArrayInputStream(b);
         ObjectInputStream ois = new ObjectInputStream(bais);
         session = (Map<String, Object>) ois.readObject();
-        ActionContext.getContext().setSession(session);
+        ActionContext.getContext().withSession(session);
         ois.close();
         bais.close();
 
@@ -116,7 +117,7 @@
 
         InvocationSessionStore.storeInvocation(INVOCATION_KEY, TOKEN_VALUE, invocation);
 
-        ActionContext actionContext2 = ActionContext.of(new HashMap<>())
+        ActionContext actionContext2 = ActionContext.of()
             .withSession(session)
             .withPageContext(mockPreviousPageContext)
             .bind();
diff --git a/core/src/test/java/org/apache/struts2/util/TokenHelperTest.java b/core/src/test/java/org/apache/struts2/util/TokenHelperTest.java
index e1bd5d7..4eba8f1 100644
--- a/core/src/test/java/org/apache/struts2/util/TokenHelperTest.java
+++ b/core/src/test/java/org/apache/struts2/util/TokenHelperTest.java
@@ -71,7 +71,7 @@
         params.put(TokenHelper.TOKEN_NAME_FIELD, new String[]{tokenName});
         params.put(tokenName, new String[]{token});
 
-        ActionContext.getContext().setParameters(HttpParameters.create(params).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(params).build());
 
         assertTrue(TokenHelper.validToken());
     }
@@ -87,9 +87,10 @@
     protected void setUp() throws Exception {
         session = new HashMap<>();
         Map<String, Object> ctxMap = new TreeMap<>();
-        ActionContext ctx = ActionContext.of(ctxMap).bind();
-        ctx.setSession(session);
-        ctx.setParameters(HttpParameters.create().build());
+        ActionContext ctx = ActionContext.of(ctxMap)
+            .withSession(session)
+            .withParameters(HttpParameters.create().build())
+            .bind();
     }
 
     protected void tearDown() {
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java
index dc35e36..4d3eb3b 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ActionTagTest.java
@@ -438,7 +438,7 @@
         tag.setNamespace("");
         tag.setName("testActionTagAction");
         tag.setExecuteResult(true);
-        ActionContext.getContext().setActionInvocation((ActionInvocation) mockActionInv.proxy());
+        ActionContext.getContext().withActionInvocation((ActionInvocation) mockActionInv.proxy());
 
         ActionInvocation oldInvocation = ActionContext.getContext().getActionInvocation();
         assertNotNull(oldInvocation);
@@ -471,7 +471,7 @@
 
         Map<String, String[]> params = new HashMap<>();
         params.put("user", new String[]{"Santa Claus"});
-        ActionContext.getContext().setParameters(HttpParameters.create(params).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(params).build());
 
         tag.doStartTag();
 
@@ -505,7 +505,7 @@
 
         Map<String, String[]> params = new HashMap<>();
         params.put("user", new String[]{"Santa Claus"});
-        ActionContext.getContext().setParameters(HttpParameters.create(params).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(params).build());
 
         tag.doStartTag();
         setComponentTagClearTagState(tag, true);  // Ensure component tag state clearing is set true (to match tag).
@@ -540,7 +540,7 @@
 
         Map<String, String[]> params = new HashMap<>();
         params.put("user", new String[]{"Santa Claus"});
-        ActionContext.getContext().setParameters(HttpParameters.create(params).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(params).build());
 
         tag.doStartTag();
 
@@ -573,7 +573,7 @@
 
         Map<String, String[]> params = new HashMap<>();
         params.put("user", new String[] { "Santa Claus" });
-        ActionContext.getContext().setParameters(HttpParameters.create(params).build());
+        ActionContext.getContext().withParameters(HttpParameters.create(params).build());
 
         tag.doStartTag();
         setComponentTagClearTagState(tag, true);  // Ensure component tag state clearing is set true (to match tag).
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java
index 0390866..c41aabe 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/NumberTagTest.java
@@ -55,7 +55,7 @@
 
     public void testSimpleFloatFormat_clearTagStateSet() throws Exception {
         // given
-        context.put(ActionContext.LOCALE, Locale.US);
+        ActionContext.of(context).withLocale(Locale.US);
 
         TestAction testAction = (TestAction) action;
         testAction.setFloatNumber(120.0f);
@@ -85,7 +85,7 @@
     public void testSimpleCurrencyUSFormat() throws Exception {
         // given
         context = ActionContext.of(context).withLocale(Locale.US).getContextMap();
-        
+
         TestAction testAction = (TestAction) action;
         testAction.setFloatNumber(120.0f);
 
@@ -110,7 +110,7 @@
 
     public void testSimpleCurrencyUSFormat_clearTagStateSet() throws Exception {
         // given
-        context.put(ActionContext.LOCALE, Locale.US);
+        ActionContext.of(context).withLocale(Locale.US);
 
         TestAction testAction = (TestAction) action;
         testAction.setFloatNumber(120.0f);
@@ -140,7 +140,7 @@
     public void testSimpleCurrencyPLFormat() throws Exception {
         // given
         context = ActionContext.of(context).withLocale(new Locale("pl", "PL")).getContextMap();
-        
+
         TestAction testAction = (TestAction) action;
         testAction.setFloatNumber(120.0f);
 
@@ -170,7 +170,7 @@
 
     public void testSimpleCurrencyPLFormat_clearTagStateSet() throws Exception {
         // given
-        context.put(ActionContext.LOCALE, new Locale("pl", "PL"));
+        ActionContext.of(context).withLocale(new Locale("pl", "PL"));
 
         TestAction testAction = (TestAction) action;
         testAction.setFloatNumber(120.0f);
@@ -187,7 +187,7 @@
         tag.doEndTag();
 
         // then
-        NumberFormat format = NumberFormat.getCurrencyInstance((Locale) context.get(ActionContext.LOCALE));
+        NumberFormat format = NumberFormat.getCurrencyInstance(ActionContext.of(context).getLocale());
         format.setRoundingMode(RoundingMode.CEILING);
         String expected = format.format(120.0f);
 
@@ -234,7 +234,7 @@
 
     public void testSimpleRoundingCeiling_clearTagStateSet() throws Exception {
         // given
-        context.put(ActionContext.LOCALE, Locale.US);
+        ActionContext.of(context).withLocale(new Locale("pl", "PL"));
 
         TestAction testAction = (TestAction) action;
         testAction.setFloatNumber(120.45f);
@@ -251,7 +251,7 @@
         tag.doEndTag();
 
         // then
-        NumberFormat format = NumberFormat.getInstance((Locale) context.get(ActionContext.LOCALE));
+        NumberFormat format = NumberFormat.getInstance(ActionContext.of(context).getLocale());
         format.setRoundingMode(RoundingMode.DOWN);
         String expected = format.format(120.45f);
 
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
index fa153e0..c8e0f24 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/TextTagTest.java
@@ -397,8 +397,9 @@
         final StringBuffer buffer = writer.getBuffer();
         buffer.delete(0, buffer.length());
         ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack();
-        newStack.getContext().put(ActionContext.LOCALE, foreignLocale);
-        newStack.getContext().put(ActionContext.CONTAINER, container);
+        ActionContext.of(newStack.getContext())
+            .withLocale(foreignLocale)
+                .withContainer(container);
         newStack.push(container.inject(TestAction1.class));
         request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack);
         assertNotSame(ActionContext.getContext().getValueStack().peek(), newStack.peek());
@@ -466,7 +467,7 @@
         Locale foreignLocale = getForeignLocale();
         assertNotSame(defaultLocale, foreignLocale);
 
-        ActionContext.getContext().setLocale(defaultLocale);
+        ActionContext.getContext().withLocale(defaultLocale);
         String key = "simpleKey";
         String value_default = getLocalizedMessage(defaultLocale);
         tag.setPerformClearTagStateForTagPoolingServers(true);  // Explicitly request tag state clearing.
@@ -489,9 +490,9 @@
         String value_int = getLocalizedMessage(foreignLocale);
         assertFalse(value_default.equals(value_int));
         ValueStack newStack = container.getInstance(ValueStackFactory.class).createValueStack(stack);
-        newStack.getContext().put(ActionContext.LOCALE, foreignLocale);
-        newStack.getContext().put(ActionContext.CONTAINER, container);
-        assertNotSame(newStack.getContext().get(ActionContext.LOCALE), ActionContext.getContext().getLocale());
+        ActionContext.of(newStack.getContext())
+            .withLocale(foreignLocale)
+                .withContainer(container);
         request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, newStack);
         assertEquals(ActionContext.getContext().getValueStack().peek(), newStack.peek());
         tag.setName(key);  // Required as WW-5124 fix clears tag state.
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
index 4bcec0c..2a06a65 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/URLTagTest.java
@@ -294,22 +294,22 @@
      */
     public void testIterableParameters() throws Exception {
         tag.setValue("/TestAction.action?p0=z");
-        
+
         tag.doStartTag();
         //Iterable
         List<ValueHolder> list = new ArrayList<>();
         list.add(new ValueHolder("a"));
         list.add(new ValueHolder("b"));
         tag.component.addParameter("p1", list);
-        
+
         //String[]
         tag.component.addParameter("p2", new String[] { "d", "e" });
         //ValueHolder[]
         tag.component.addParameter("p3", new ValueHolder[] {
                 new ValueHolder("f"), new ValueHolder("g") });
-        
+
         tag.doEndTag();
-        
+
         assertEquals("/TestAction.action?p0=z&amp;p1=a&amp;p1=b&amp;p2=d&amp;p2=e&amp;p3=f&amp;p3=g", writer.toString());
 
         // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
@@ -1524,11 +1524,11 @@
     public void testEmptyActionCustomMapper() throws Exception {
         Map<String,String> props = new HashMap<>();
         props.put("config", "struts-default.xml,struts-plugin.xml,struts.xml,org/apache/struts2/views/jsp/WW3090-struts.xml");
-        
+
         this.tearDown();
-        
+
         Dispatcher du = this.initDispatcher(props);
-        
+
         /**
          * create our standard mock objects
          */
@@ -1565,7 +1565,7 @@
                 response);
         // let's not set the locale -- there is a test that checks if Dispatcher actually picks this up...
         // ... but generally we want to just use no locale (let it stay system default)
-        extraContext.remove(ActionContext.LOCALE);
+        ActionContext.of(extraContext).withLocale(null);
         stack.getContext().putAll(extraContext);
 
         context.put(ServletActionContext.HTTP_REQUEST, request);
@@ -1577,7 +1577,7 @@
             .withServletResponse(response)
             .withServletContext(servletContext)
             .bind();
-        
+
         // Make sure we have an action invocation available
         ActionContext.getContext().withActionInvocation(new DefaultActionInvocation(null, true));
         DefaultActionProxyFactory apFactory = new DefaultActionProxyFactory();
@@ -1593,9 +1593,9 @@
         tag.setPageContext(pageContext);
         JspWriter jspWriter = new StrutsMockJspWriter(writer);
         pageContext.setJspWriter(jspWriter);
-        
+
         request.setRequestURI("/context/someAction.action");
-        
+
         tag.setAction(null);
         tag.setValue(null);
         tag.doStartTag();
@@ -1610,14 +1610,14 @@
         assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set.  " +
                 "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
                 strutsBodyTagsAreReflectionEqual(tag, freshTag));
-        
+
         writer = new StringWriter();
         jspWriter = new StrutsMockJspWriter(writer);
         pageContext.setJspWriter(jspWriter);
-        
+
         tag.doStartTag();
         tag.doEndTag();
-        
+
         assertEquals("/hello.action-blue", writer.toString());
 
         // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
@@ -1625,16 +1625,16 @@
         assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set.  " +
                 "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
                 strutsBodyTagsAreReflectionEqual(tag, freshTag));
-        
+
         writer = new StringWriter();
         jspWriter = new StrutsMockJspWriter(writer);
         pageContext.setJspWriter(jspWriter);
-        
+
         tag.doStartTag();
         tag.doEndTag();
-        
+
         assertEquals("/hello.action-red", writer.toString());
-        
+
         // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
         // URLTag clears component in doEndTag and has no additional state set here, so it compares as equal with the default tag clear state as well.
         assertTrue("Tag state after doEndTag() under default tag clear state is inequal to new Tag with pageContext/parent set.  " +
@@ -1645,11 +1645,11 @@
     public void testEmptyActionCustomMapper_clearTagStateSet() throws Exception {
         Map<String,String> props = new HashMap<String, String>();
         props.put("config", "struts-default.xml,struts-plugin.xml,struts.xml,org/apache/struts2/views/jsp/WW3090-struts.xml");
-        
+
         this.tearDown();
-        
+
         Dispatcher du = this.initDispatcher(props);
-        
+
         action = this.getAction();
         stack = ActionContext.getContext().getValueStack();
         context = stack.getContext();
@@ -1708,9 +1708,9 @@
         tag.setPageContext(pageContext);
         JspWriter jspWriter = new StrutsMockJspWriter(writer);
         pageContext.setJspWriter(jspWriter);
-        
+
         request.setRequestURI("/context/someAction.action");
-        
+
         tag.setAction(null);
         tag.setValue(null);
         tag.doStartTag();
@@ -1726,32 +1726,32 @@
         assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set.  " +
                 "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
                 strutsBodyTagsAreReflectionEqual(tag, freshTag));
-        
+
         writer = new StringWriter();
         jspWriter = new StrutsMockJspWriter(writer);
         pageContext.setJspWriter(jspWriter);
-        
+
         tag.doStartTag();
         setComponentTagClearTagState(tag, true);  // Ensure component tag state clearing is set true (to match tag).
         tag.doEndTag();
-        
+
         assertEquals("/hello.action-blue", writer.toString());
 
         // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
         assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set.  " +
                 "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
                 strutsBodyTagsAreReflectionEqual(tag, freshTag));
-        
+
         writer = new StringWriter();
         jspWriter = new StrutsMockJspWriter(writer);
         pageContext.setJspWriter(jspWriter);
-        
+
         tag.doStartTag();
         setComponentTagClearTagState(tag, true);  // Ensure component tag state clearing is set true (to match tag).
         tag.doEndTag();
-        
+
         assertEquals("/hello.action-red", writer.toString());
-        
+
         // Basic sanity check of clearTagStateForTagPoolingServers() behaviour for Struts Tags after doEndTag().
         assertTrue("Tag state after doEndTag() and explicit tag state clearing is inequal to new Tag with pageContext/parent set.  " +
                 "May indicate that clearTagStateForTagPoolingServers() calls are not working properly.",
@@ -2135,7 +2135,7 @@
             return "Foo is: " + title;
         }
     }
-    
+
     public static class ValueHolder {
         private String value;
 
@@ -2147,13 +2147,13 @@
         public String toString() {
             return value;
         }
-        
-        
+
+
     }
 
     @SuppressWarnings("unused")
     public static class RedBlueActionMapper extends DefaultActionMapper {
-        
+
         @Override
         public String getUriFromActionMapping(ActionMapping mapping) {
             String baseUri = super.getUriFromActionMapping(mapping);
@@ -2168,6 +2168,6 @@
                 return baseUri + "-blue";
             }
         }
-        
+
     }
 }
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java
index d6d62e1..64d7ca7 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/HiddenTest.java
@@ -136,7 +136,7 @@
 
         MockActionInvocation ai = new MockActionInvocation();
         ai.setAction(action);
-        ActionContext.getContext().setActionInvocation(ai);
+        ActionContext.getContext().withActionInvocation(ai);
 
         HiddenTag tag = new HiddenTag();
         tag.setPageContext(pageContext);
@@ -167,7 +167,7 @@
 
         MockActionInvocation ai = new MockActionInvocation();
         ai.setAction(action);
-        ActionContext.getContext().setActionInvocation(ai);
+        ActionContext.getContext().withActionInvocation(ai);
 
         HiddenTag tag = new HiddenTag();
         tag.setPerformClearTagStateForTagPoolingServers(true);  // Explicitly request tag state clearing.
diff --git a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
index 99eff80..2e80b46 100644
--- a/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
+++ b/core/src/test/java/org/apache/struts2/views/jsp/ui/SubmitTest.java
@@ -18,16 +18,15 @@
  */
 package org.apache.struts2.views.jsp.ui;
 
+import com.opensymphony.xwork2.TestBean;
 import org.apache.struts2.TestAction;
 import org.apache.struts2.views.jsp.AbstractUITagTest;
 
 import java.util.HashMap;
 import java.util.Map;
 
-
 /**
  * Unit test for {@link SubmitTag}.
- *
  */
 public class SubmitTest extends AbstractUITagTest {
 
@@ -699,4 +698,40 @@
 
         verify(TextFieldTag.class.getResource("Submit-12.txt"));
     }
+
+    public void testSubmitWithGeneratedId_shouldUseEvaluatedName() throws Exception {
+        TestAction testAction = (TestAction) action;
+        testAction.setFoo("entryEdit");
+
+        SubmitTag tag = new SubmitTag();
+        tag.setTheme("simple");
+        tag.setPageContext(pageContext);
+        tag.setName("%{foo}!saveDraft");
+        tag.setValue("Save");
+
+        tag.doStartTag();
+        tag.doEndTag();
+
+        verify(TextFieldTag.class.getResource("Submit-13.txt"));
+    }
+
+    public void testSubmitWithGeneratedId_shouldUseEvaluatedAction() throws Exception {
+        TestAction testAction = (TestAction) action;
+        testAction.setFoo("entryEdit");
+
+        TestBean bean = new TestBean();
+        bean.setName("mainAction");
+        stack.push(bean);
+
+        SubmitTag tag = new SubmitTag();
+        tag.setTheme("simple");
+        tag.setPageContext(pageContext);
+        tag.setAction("%{name}!saveDraft");
+        tag.setValue("Save");
+
+        tag.doStartTag();
+        tag.doEndTag();
+
+        verify(TextFieldTag.class.getResource("Submit-14.txt"));
+    }
 }
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder1/xwork-test-load-order.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder1/xwork-test-load-order.xml
index 805c5b6..14703dd 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder1/xwork-test-load-order.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder1/xwork-test-load-order.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts order="2">
 </struts>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder2/xwork-test-load-order.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder2/xwork-test-load-order.xml
index 602d778..e94277b 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder2/xwork-test-load-order.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder2/xwork-test-load-order.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts order="3">
 </struts>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder3/xwork-test-load-order.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder3/xwork-test-load-order.xml
index c54e17f..52846dc 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder3/xwork-test-load-order.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/loadorder3/xwork-test-load-order.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts order="1">
 </struts>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork- test.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork- test.xml
index e832300..7cc074f 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork- test.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork- test.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package-2.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package-2.xml
index f29ce17..8b4c873 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package-2.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package-2.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="namespace5" extends="namespace4" namespace="/namespace5">
         <action name="action5" class="com.opensymphony.xwork2.SimpleAction">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package.xml
index d9f87ec..b48a4c4 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-after-package.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="namespace4" extends="namespace1" namespace="/namespace4">
         <interceptors>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package-2.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package-2.xml
index 59ef1e9..58f2771 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package-2.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package-2.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="namespace2" extends="namespace1" namespace="/namespace2">
         <action name="action2" class="com.opensymphony.xwork2.SimpleAction">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package.xml
index 2ccff3a..ca67f9f 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-before-package.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
 
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-parent.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-parent.xml
index 758b55f..b02746d 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-parent.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-include-parent.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-default.xml" />
 
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-action-invalid.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-action-invalid.xml
index 8fa3369..33194f9 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-action-invalid.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-action-invalid.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions-packagedefaultclassref.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions-packagedefaultclassref.xml
index 42d2d5b..f7f4a8f 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions-packagedefaultclassref.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions-packagedefaultclassref.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="default">
 
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions.xml
index e832300..7cc074f 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-actions.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
index 85ada7e..247b4ef 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-allowed-methods.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="default" strict-method-invocation="false">
         <global-allowed-methods>input,cancel</global-allowed-methods>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-bad-inheritance.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-bad-inheritance.xml
index 5f6b1f0..7b475f2 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-bad-inheritance.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-bad-inheritance.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default" />
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-basic-packages.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-basic-packages.xml
index e6b3a7f..a934bce 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-basic-packages.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-basic-packages.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="default"/>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-default-package.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-default-package.xml
index d5869ca..f9ea310 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-default-package.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-default-package.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default" />
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-defaultclassref-package.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-defaultclassref-package.xml
index ae9c254..deedbed 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-defaultclassref-package.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-defaultclassref-package.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="hasDefaultClassRef">
         <default-class-ref class="com.opensymphony.xwork2.ActionSupport"/>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml
index a328c72..f74cb8e 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-envs-substitution.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 
     <constant name="foo" value="bar"/>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-exception-mappings.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-exception-mappings.xml
index bb7a345..ab503c1 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-exception-mappings.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-exception-mappings.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-global-result-inheritence.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-global-result-inheritence.xml
index 4852fae..143b9f5 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-global-result-inheritence.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-global-result-inheritence.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="parent" namespace="/base">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-include-wildcard.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-include-wildcard.xml
index afc3334..bec77a1 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-include-wildcard.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-include-wildcard.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
   <include file="com/opensymphony/xwork2/config/providers/xwork-include-*.xml"/>
 </struts>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-defaultref.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-defaultref.xml
index 955c123..c5290c3 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-defaultref.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-defaultref.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <!-- this package has a default interceptor ref - so actions with no refs should have the default ref -->
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-inheritance.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-inheritance.xml
index 5226d0a..919eb39 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-inheritance.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-inheritance.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-param-overriding.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-param-overriding.xml
index af8c52d..15f5ace 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-param-overriding.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-param-overriding.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-		"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-		"https://struts.apache.org/dtds/struts-2.5.dtd">
+		"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+		"https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
 	<package name="packageOne">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-params.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-params.xml
index e74d532..0b502a1 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-params.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-params.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-stack-param-overriding.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-stack-param-overriding.xml
index 7a54fcd..47eb82b 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-stack-param-overriding.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptor-stack-param-overriding.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="packageOne">
         <result-types>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-basic.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-basic.xml
index dec118d..c271410 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-basic.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-basic.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-spring.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-spring.xml
index 1adf5ed..89e30ca 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-spring.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-interceptors-spring.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-multilevel.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-multilevel.xml
index 2852fb6..2d4b0a6 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-multilevel.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-multilevel.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-package-inheritance.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-package-inheritance.xml
index c728ac8..f6c2b97 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-package-inheritance.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-package-inheritance.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default" namespace="/default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-reload.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-reload.xml
index c71e8b5..949a0cb 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-reload.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-reload.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 
     <constant name="struts.configuration.xml.reload" value="true" />
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-inheritance.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-inheritance.xml
index 5e0f97c..8d6300e 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-inheritance.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-inheritance.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-names.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-names.xml
index e00fd3c..4e5b93f 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-names.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-names.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-types.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-types.xml
index 569488e..5bfcaee 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-types.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-result-types.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml"/>
     <package name="xworkResultTypesTestPackage1">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-results.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-results.xml
index 76363a7..a4f279e 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-results.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-results.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="default">
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-1.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-1.xml
index b447dd6..7625286 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-1.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-1.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="default-1" />
 </struts>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-2.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-2.xml
index 3ffb56b..1bab2a1 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-2.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-2.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="default-2" />
 </struts>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-include.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-include.xml
index 60a69c2..2d7003f 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-include.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-test-wildcard-include.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-beans.xml" />
     <include file="com/opensymphony/xwork2/config/providers/xwork-test-wildcard-*.xml" />
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack-empty.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack-empty.xml
index 4ec37d6..7073d94 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack-empty.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack-empty.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <bean type="com.opensymphony.xwork2.UnknownHandler" name="uh1" class="com.opensymphony.xwork2.config.providers.SomeUnknownHandler"/>
     <bean type="com.opensymphony.xwork2.UnknownHandler" name="uh2" class="com.opensymphony.xwork2.config.providers.SomeUnknownHandler"/>
diff --git a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack.xml b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack.xml
index 6cf8010..ea0be85 100644
--- a/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack.xml
+++ b/core/src/test/resources/com/opensymphony/xwork2/config/providers/xwork-unknownhandler-stack.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <bean type="com.opensymphony.xwork2.UnknownHandler" name="uh1" class="com.opensymphony.xwork2.config.providers.SomeUnknownHandler"/>
     <bean type="com.opensymphony.xwork2.UnknownHandler" name="uh2" class="com.opensymphony.xwork2.config.providers.SomeUnknownHandler"/>
diff --git a/core/src/test/resources/includeTest.xml b/core/src/test/resources/includeTest.xml
index 16ff280..455834f 100644
--- a/core/src/test/resources/includeTest.xml
+++ b/core/src/test/resources/includeTest.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="includeTest" extends="default" namespace="includeTest">
         <action name="includeTest" class="com.opensymphony.xwork2.SimpleAction"></action>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-13.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-13.txt
new file mode 100644
index 0000000..9394631
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-13.txt
@@ -0,0 +1 @@
+<input type="submit" value="Save" id="entryEdit_saveDraft" name="entryEdit!saveDraft"/>
diff --git a/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-14.txt b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-14.txt
new file mode 100644
index 0000000..481c547
--- /dev/null
+++ b/core/src/test/resources/org/apache/struts2/views/jsp/ui/Submit-14.txt
@@ -0,0 +1 @@
+<input type="submit" value="Save" id="mainAction_saveDraft" name="action:mainAction!saveDraft"/>
diff --git a/core/src/test/resources/struts-object-factory-result-builder.xml b/core/src/test/resources/struts-object-factory-result-builder.xml
index a76b6f7..76b872f 100644
--- a/core/src/test/resources/struts-object-factory-result-builder.xml
+++ b/core/src/test/resources/struts-object-factory-result-builder.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/core/src/test/resources/struts-testing.xml b/core/src/test/resources/struts-testing.xml
index 62023b2..f1af997 100644
--- a/core/src/test/resources/struts-testing.xml
+++ b/core/src/test/resources/struts-testing.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-          "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-          "https://struts.apache.org/dtds/struts-2.5.dtd">
+          "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+          "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="struts-default.xml"/>
     <package name="default" extends="struts-default" namespace="/">
diff --git a/core/src/test/resources/xwork-class-param-test.xml b/core/src/test/resources/xwork-class-param-test.xml
index 74161ea..c0f3273 100644
--- a/core/src/test/resources/xwork-class-param-test.xml
+++ b/core/src/test/resources/xwork-class-param-test.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 
     <constant name="struts.devMode" value="true" />
diff --git a/core/src/test/resources/xwork-param-test.xml b/core/src/test/resources/xwork-param-test.xml
index 8eed0b5..2affaac 100644
--- a/core/src/test/resources/xwork-param-test.xml
+++ b/core/src/test/resources/xwork-param-test.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <constant name="struts.devMode" value="true" />
     <constant name="struts.excludedClasses" value="java.lang.Object,java.lang.Runtime" />
diff --git a/core/src/test/resources/xwork-proxyinvoke.xml b/core/src/test/resources/xwork-proxyinvoke.xml
index 3e95e62..ca2555e 100644
--- a/core/src/test/resources/xwork-proxyinvoke.xml
+++ b/core/src/test/resources/xwork-proxyinvoke.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <bean type="com.opensymphony.xwork2.ObjectFactory" name="default" class="com.opensymphony.xwork2.ProxyObjectFactory" />
 
diff --git a/core/src/test/resources/xwork-sample.xml b/core/src/test/resources/xwork-sample.xml
index c310234..4e62f4c 100644
--- a/core/src/test/resources/xwork-sample.xml
+++ b/core/src/test/resources/xwork-sample.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <include file="xwork-test-default.xml"/>
     <package name="default" extends="xwork-test-default">
diff --git a/core/src/test/resources/xwork-test-beans.xml b/core/src/test/resources/xwork-test-beans.xml
index c88a349..dca7091 100644
--- a/core/src/test/resources/xwork-test-beans.xml
+++ b/core/src/test/resources/xwork-test-beans.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 
     <constant name="struts.excludedClasses" value="java.lang.Object,java.lang.Runtime,ognl.OgnlContext,ognl.MemberAccess,ognl.ClassResolver,ognl.TypeConverter,com.opensymphony.xwork2.ognl.SecurityMemberAccess" />
diff --git a/core/src/test/resources/xwork-test-default.xml b/core/src/test/resources/xwork-test-default.xml
index d9f6ddd..95da09c 100644
--- a/core/src/test/resources/xwork-test-default.xml
+++ b/core/src/test/resources/xwork-test-default.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <package name="xwork-test-default">
         <result-types>
diff --git a/core/src/test/resources/xwork-test-validation.xml b/core/src/test/resources/xwork-test-validation.xml
index b58c661..90721d7 100644
--- a/core/src/test/resources/xwork-test-validation.xml
+++ b/core/src/test/resources/xwork-test-validation.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<include file="xwork-test-beans.xml" />
     <package name="xwork-test-default">
diff --git a/plugins/async/src/main/resources/struts-plugin.xml b/plugins/async/src/main/resources/struts-plugin.xml
index da2aee8..012c505 100644
--- a/plugins/async/src/main/resources/struts-plugin.xml
+++ b/plugins/async/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <bean type="com.opensymphony.xwork2.AsyncManager" name="default"
diff --git a/plugins/bean-validation/src/main/resources/struts-plugin.xml b/plugins/bean-validation/src/main/resources/struts-plugin.xml
index 69e4c51..326be2f 100644
--- a/plugins/bean-validation/src/main/resources/struts-plugin.xml
+++ b/plugins/bean-validation/src/main/resources/struts-plugin.xml
@@ -21,8 +21,8 @@
 -->
 
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <constant name="struts.beanValidation.providerClass" value=""/>
diff --git a/plugins/bean-validation/src/test/resources/bean-validation-test.xml b/plugins/bean-validation/src/test/resources/bean-validation-test.xml
index bd5716c..2f1728d 100644
--- a/plugins/bean-validation/src/test/resources/bean-validation-test.xml
+++ b/plugins/bean-validation/src/test/resources/bean-validation-test.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <constant name="struts.beanValidation.providerClass" value="org.hibernate.validator.HibernateValidator"/>
     <constant name="struts.beanValidation.ignoreXMLConfiguration" value="false"/>
diff --git a/plugins/cdi/src/main/resources/struts-plugin.xml b/plugins/cdi/src/main/resources/struts-plugin.xml
index b969296..a17a81e 100644
--- a/plugins/cdi/src/main/resources/struts-plugin.xml
+++ b/plugins/cdi/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/config-browser/src/main/resources/struts-plugin.xml b/plugins/config-browser/src/main/resources/struts-plugin.xml
index b2187d4..6cdb0ec 100644
--- a/plugins/config-browser/src/main/resources/struts-plugin.xml
+++ b/plugins/config-browser/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/convention/src/main/resources/struts-plugin.xml b/plugins/convention/src/main/resources/struts-plugin.xml
index 6cd8b04..c80ca9b 100644
--- a/plugins/convention/src/main/resources/struts-plugin.xml
+++ b/plugins/convention/src/main/resources/struts-plugin.xml
@@ -21,8 +21,8 @@
 -->
 
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts order="20">
   <bean type="com.opensymphony.xwork2.UnknownHandler" name="convention" class="org.apache.struts2.convention.ConventionUnknownHandler"/>
diff --git a/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java b/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
index 6d0abd4..c44ca33 100644
--- a/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
+++ b/plugins/convention/src/test/java/org/apache/struts2/convention/PackageBasedActionConfigBuilderTest.java
@@ -89,7 +89,7 @@
     @Override
     public void setUp() throws Exception {
         super.setUp();
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withContainer(new DummyContainer())
             .bind();
     }
diff --git a/plugins/embeddedjsp/src/main/resources/struts-plugin.xml b/plugins/embeddedjsp/src/main/resources/struts-plugin.xml
index 1651b3f..4df5875 100644
--- a/plugins/embeddedjsp/src/main/resources/struts-plugin.xml
+++ b/plugins/embeddedjsp/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */

 -->

 <!DOCTYPE struts PUBLIC

-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

-	"https://struts.apache.org/dtds/struts-2.5.dtd">

+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"

+	"https://struts.apache.org/dtds/struts-6.0.dtd">

 

 <struts>

     <package name="embeddedjsp-default" extends="struts-default" abstract="true">

diff --git a/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java b/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
index 4a8eee2..128462b 100644
--- a/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
+++ b/plugins/embeddedjsp/src/test/java/org/apache/struts2/EmbeddedJSPResultTest.java
@@ -359,7 +359,7 @@
 

         EasyMock.replay(container);

 

-        ActionContext.of(new HashMap<>())

+        ActionContext.of()

             .withParameters(HttpParameters.create(params).build())

             .withServletRequest(request)

             .withServletResponse(response)

diff --git a/plugins/gxp/src/main/resources/struts-plugin.xml b/plugins/gxp/src/main/resources/struts-plugin.xml
index dd39530..e14ea03 100644
--- a/plugins/gxp/src/main/resources/struts-plugin.xml
+++ b/plugins/gxp/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */

 -->

 <!DOCTYPE struts PUBLIC

-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

-	"https://struts.apache.org/dtds/struts-2.5.dtd">

+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"

+	"https://struts.apache.org/dtds/struts-6.0.dtd">

 

 <struts>

     <bean type="org.apache.struts2.views.gxp.inject.InjectedObjectContainer" class="org.apache.struts2.views.gxp.inject.InjectedObjectContainer" static="true" />

diff --git a/plugins/jasperreports/src/main/resources/struts-plugin.xml b/plugins/jasperreports/src/main/resources/struts-plugin.xml
index e992091..dee8ffd 100644
--- a/plugins/jasperreports/src/main/resources/struts-plugin.xml
+++ b/plugins/jasperreports/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="jasperreports-default" extends="struts-default">
diff --git a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/TextAreaHandler.java b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/TextAreaHandler.java
index 6274096..6b1cfa1 100644
--- a/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/TextAreaHandler.java
+++ b/plugins/javatemplates/src/main/java/org/apache/struts2/views/java/simple/TextAreaHandler.java
@@ -41,7 +41,9 @@
                 .addIfExists("id", params.get("id"))
                 .addIfExists("class", params.get("cssClass"))
                 .addIfExists("style", params.get("cssStyle"))
-                .addIfExists("title", params.get("title"));
+                .addIfExists("title", params.get("title"))
+                .addIfExists("minlength", params.get("minlength"))
+                .addIfExists("maxlength", params.get("maxlength"));
         start("textarea", attrs);
         String value = (String) params.get("nameValue");
         if (StringUtils.isNotEmpty(value))
diff --git a/plugins/javatemplates/src/main/resources/struts-plugin.xml b/plugins/javatemplates/src/main/resources/struts-plugin.xml
index 5ca258c..d4ae225 100644
--- a/plugins/javatemplates/src/main/resources/struts-plugin.xml
+++ b/plugins/javatemplates/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
index d0f0896..e1ad3f9 100644
--- a/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
+++ b/plugins/javatemplates/src/test/java/org/apache/struts2/views/java/simple/TokenTest.java
@@ -50,8 +50,9 @@
         super.setUp();
         this.tag = new Token(stack, request, response);
 
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
-        actionContext.setSession(new HashMap<>());
+        ActionContext.of()
+            .withSession(new HashMap<>())
+            .bind();
     }
 
     @Override
diff --git a/plugins/jfreechart/src/main/resources/struts-plugin.xml b/plugins/jfreechart/src/main/resources/struts-plugin.xml
index 68506ab..e692f44 100644
--- a/plugins/jfreechart/src/main/resources/struts-plugin.xml
+++ b/plugins/jfreechart/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="jfreechart-default" extends="struts-default">
diff --git a/plugins/json/src/main/resources/struts-plugin.xml b/plugins/json/src/main/resources/struts-plugin.xml
index a20a592..1291246 100644
--- a/plugins/json/src/main/resources/struts-plugin.xml
+++ b/plugins/json/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <bean type="org.apache.struts2.json.JSONWriter" name="struts" class="org.apache.struts2.json.DefaultJSONWriter"
diff --git a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java
index e7df647..84b76a1 100644
--- a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java
+++ b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsJUnit4TestCase.java
@@ -136,7 +136,7 @@
     }
 
     protected void initActionContext(ActionContext actionContext) {
-        actionContext.setParameters(HttpParameters.create(request.getParameterMap()).build());
+        actionContext.withParameters(HttpParameters.create(request.getParameterMap()).build());
         initSession(actionContext);
         // set the action context to the one used by the proxy
         ActionContext.bind(actionContext);
diff --git a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java
index 6e7c5f9..80a954f 100644
--- a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java
+++ b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsRestTestCase.java
@@ -121,7 +121,7 @@
 
         ActionContext invocationContext = proxy.getInvocation().getInvocationContext();
         invocationContext.getContextMap().put(ServletActionContext.ACTION_MAPPING, mapping);
-        invocationContext.setParameters(HttpParameters.create(request.getParameterMap()).build());
+        invocationContext.withParameters(HttpParameters.create(request.getParameterMap()).build());
         // set the action context to the one used by the proxy
         ActionContext.bind(invocationContext);
 
diff --git a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsTestCase.java b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsTestCase.java
index f0d9e7e..6083108 100644
--- a/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsTestCase.java
+++ b/plugins/junit/src/main/java/org/apache/struts2/junit/StrutsTestCase.java
@@ -119,7 +119,7 @@
     }
 
     protected void initActionContext(ActionContext actionContext) {
-        actionContext.setParameters(HttpParameters.create(request.getParameterMap()).build());
+        actionContext.withParameters(HttpParameters.create(request.getParameterMap()).build());
         initSession(actionContext);
         applyAdditionalParams(actionContext);
         // set the action context to the one used by the proxy
diff --git a/plugins/junit/src/test/resources/struts-convention-configuration.xml b/plugins/junit/src/test/resources/struts-convention-configuration.xml
index df72927..1c3768b 100644
--- a/plugins/junit/src/test/resources/struts-convention-configuration.xml
+++ b/plugins/junit/src/test/resources/struts-convention-configuration.xml
@@ -21,8 +21,8 @@
 -->
 
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java b/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
index b170af3..61b22c2 100644
--- a/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
+++ b/plugins/osgi/src/main/java/org/apache/struts2/osgi/OsgiConfigurationProvider.java
@@ -136,11 +136,9 @@
 
     /**
      * Creates a new empty ActionContext instance and binds it to the current thread.
-     * 
-     * @return 
      */
     protected ActionContext createActionContext() {
-        return ActionContext.of(new HashMap<>()).bind();
+        return ActionContext.of().bind();
     }
 
     /**
diff --git a/plugins/osgi/src/main/resources/struts-plugin.xml b/plugins/osgi/src/main/resources/struts-plugin.xml
index 22c1cd4..738f8b8 100644
--- a/plugins/osgi/src/main/resources/struts-plugin.xml
+++ b/plugins/osgi/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts order="10">
     <constant name="struts.objectFactory" value="osgi" />
diff --git a/plugins/oval/src/main/resources/struts-plugin.xml b/plugins/oval/src/main/resources/struts-plugin.xml
index da21088..9b56b8e 100644
--- a/plugins/oval/src/main/resources/struts-plugin.xml
+++ b/plugins/oval/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/oval/src/test/resources/oval-test.xml b/plugins/oval/src/test/resources/oval-test.xml
index e4a69b5..0cade6a 100644
--- a/plugins/oval/src/test/resources/oval-test.xml
+++ b/plugins/oval/src/test/resources/oval-test.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
     <bean type="org.apache.struts2.oval.interceptor.OValValidationManager"
           class="org.apache.struts2.oval.interceptor.DummyDefaultOValValidationManager"/>
diff --git a/plugins/pell-multipart/src/main/resources/struts-plugin.xml b/plugins/pell-multipart/src/main/resources/struts-plugin.xml
index a9fc10b..2640ad4 100644
--- a/plugins/pell-multipart/src/main/resources/struts-plugin.xml
+++ b/plugins/pell-multipart/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <bean type="org.apache.struts2.dispatcher.multipart.MultiPartRequest" name="pell" class="org.apache.struts2.dispatcher.multipart.PellMultiPartRequest" />
diff --git a/plugins/plexus/src/main/resources/struts-plugin.xml b/plugins/plexus/src/main/resources/struts-plugin.xml
index 43e2035..7059b0f 100644
--- a/plugins/plexus/src/main/resources/struts-plugin.xml
+++ b/plugins/plexus/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <bean type="com.opensymphony.xwork2.ObjectFactory" name="plexus" class="org.apache.struts2.plexus.PlexusObjectFactory" />
diff --git a/plugins/portlet-tiles/src/main/resources/struts-plugin.xml b/plugins/portlet-tiles/src/main/resources/struts-plugin.xml
index b7ad6ce..9aa82ca 100644
--- a/plugins/portlet-tiles/src/main/resources/struts-plugin.xml
+++ b/plugins/portlet-tiles/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/portlet/src/main/resources/struts-plugin.xml b/plugins/portlet/src/main/resources/struts-plugin.xml
index a664797..9e319ea 100644
--- a/plugins/portlet/src/main/resources/struts-plugin.xml
+++ b/plugins/portlet/src/main/resources/struts-plugin.xml
@@ -21,8 +21,8 @@
 -->

 

 <!DOCTYPE struts PUBLIC

-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"

-        "https://struts.apache.org/dtds/struts-2.5.dtd">

+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"

+        "https://struts.apache.org/dtds/struts-6.0.dtd">

 

 <struts>

 

diff --git a/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java b/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
index 56d7cb0..acea0be 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/StrutsTestCasePortletTests.java
@@ -45,7 +45,7 @@
  * Changes:  This is a copy of org.apache.struts2.StrutsTestCase from the Struts 2 junit-plugin, kept in
  *           in the same package org.apache.struts2 and renamed.  Removed some unused imports, made
  *           imports alphabetical and made some whitespace changes and modified a comment.
- *           The StrutsTestCasePortletTests is needed in order to break a dependency-cycle between the 
+ *           The StrutsTestCasePortletTests is needed in order to break a dependency-cycle between the
  *           portlet-plugin and junit-plugin with respect to StrutsTestCase.
  *
  * Note:     If the junit-plugin StrutsTestCase is updated/modified, it may be appropriate to update
@@ -130,7 +130,7 @@
     }
 
     protected void initActionContext(ActionContext actionContext) {
-        actionContext.setParameters(HttpParameters.create(request.getParameterMap()).build());
+        actionContext.withParameters(HttpParameters.create(request.getParameterMap()).build());
         initSession(actionContext);
         applyAdditionalParams(actionContext);
         // set the action context to the one used by the proxy
@@ -139,7 +139,7 @@
 
     protected void initSession(ActionContext actionContext) {
         if (actionContext.getSession() == null) {
-            actionContext.setSession(new HashMap<>());
+            actionContext.withSession(new HashMap<>());
             request.setSession(new MockHttpSession(servletContext));
         }
     }
diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/result/PortletResultTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/result/PortletResultTest.java
index 4994a13..60946f6 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/result/PortletResultTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/result/PortletResultTest.java
@@ -65,9 +65,10 @@
 

         Map<String, Object> sessionMap = new HashMap<>();

 

-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();

-        actionContext.setSession(sessionMap);

-        actionContext.setParameters(HttpParameters.create().build());

+        ActionContext actionContext = ActionContext.of()

+            .withSession(sessionMap)

+            .withParameters(HttpParameters.create().build())

+            .bind();

         actionContext.put(STRUTS_PORTLET_CONTEXT, mockCtx.proxy());

 

         mockProxy.stubs().method("getNamespace").will(returnValue("/test"));

@@ -160,7 +161,7 @@
         ActionContext ctx = ActionContext.getContext();

 

         Map<String, Object> session = new HashMap<>();

-        ctx.setSession(session);

+        ctx.withSession(session);

 

         ctx.put(REQUEST, mockRequest.proxy());

         ctx.put(RESPONSE, mockResponse.proxy());

diff --git a/plugins/portlet/src/test/java/org/apache/struts2/portlet/util/PortletUrlHelperTest.java b/plugins/portlet/src/test/java/org/apache/struts2/portlet/util/PortletUrlHelperTest.java
index f33f122..a5dc07b 100644
--- a/plugins/portlet/src/test/java/org/apache/struts2/portlet/util/PortletUrlHelperTest.java
+++ b/plugins/portlet/src/test/java/org/apache/struts2/portlet/util/PortletUrlHelperTest.java
@@ -69,7 +69,7 @@
         modeNamespaceMap.put("edit", "/edit");

         modeNamespaceMap.put("help", "/help");

 

-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();

+        ActionContext actionContext = ActionContext.of().bind();

         actionContext.put(REQUEST, renderRequest);

         actionContext.put(RESPONSE, renderResponse);

         actionContext.put(PHASE, PortletPhase.RENDER_PHASE);

diff --git a/plugins/portlet/src/test/resources/struts.xml b/plugins/portlet/src/test/resources/struts.xml
index afd0d9a..82cac42 100644
--- a/plugins/portlet/src/test/resources/struts.xml
+++ b/plugins/portlet/src/test/resources/struts.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/rest/src/main/resources/struts-plugin.xml b/plugins/rest/src/main/resources/struts-plugin.xml
index 589d12c..f680489 100644
--- a/plugins/rest/src/main/resources/struts-plugin.xml
+++ b/plugins/rest/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
 
diff --git a/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java b/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java
index 3e2a41e..8522668 100644
--- a/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java
+++ b/plugins/rest/src/test/java/org/apache/struts2/rest/ContentTypeHandlerManagerTest.java
@@ -58,7 +58,7 @@
         mockResponse = new MockHttpServletResponse();
         mockRequest = new MockHttpServletRequest();
         mockRequest.setMethod("GET");
-        ActionContext actionContext = ActionContext.of(new HashMap<>()).bind();
+        ActionContext actionContext = ActionContext.of().bind();
         actionContext.withServletRequest(mockRequest);
         actionContext.withServletResponse(mockResponse);
 
@@ -135,7 +135,7 @@
                 C.eq(ContentTypeHandlerManager.STRUTS_REST_HANDLER_OVERRIDE_PREFIX+"xml")), "xmlOverride");
         mockContainer.expectAndReturn("getInstance", C.args(C.eq(String.class),
                 C.eq(ContentTypeHandlerManager.STRUTS_REST_HANDLER_OVERRIDE_PREFIX+"json")), null);
-        
+
         DefaultContentTypeHandlerManager mgr = new DefaultContentTypeHandlerManager();
         mgr.setContainer((Container) mockContainer.proxy());
 
diff --git a/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java b/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java
index 45d82e4..33e3dd3 100644
--- a/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java
+++ b/plugins/rest/src/test/java/org/apache/struts2/rest/RestWorkflowInterceptorTest.java
@@ -51,7 +51,7 @@
         }, null);
         wf.setContentTypeHandlerManager((ContentTypeHandlerManager) mockContentTypeHandlerManager.proxy());
 
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withActionMapping(new ActionMapping())
             .bind();
 
diff --git a/plugins/rest/src/test/java/org/apache/struts2/rest/handler/JuneauXmlHandlerTest.java b/plugins/rest/src/test/java/org/apache/struts2/rest/handler/JuneauXmlHandlerTest.java
index 0398ebf..55351d6 100644
--- a/plugins/rest/src/test/java/org/apache/struts2/rest/handler/JuneauXmlHandlerTest.java
+++ b/plugins/rest/src/test/java/org/apache/struts2/rest/handler/JuneauXmlHandlerTest.java
@@ -51,7 +51,7 @@
             "</object>";
         handler = new JuneauXmlHandler();
         ai = new MockActionInvocation();
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(Locale.US);
+        ActionContext context = ActionContext.of().withLocale(Locale.US);
         ((MockActionInvocation) ai).setInvocationContext(context);
     }
 
@@ -95,4 +95,4 @@
                 .containsExactly("Adam", "Ewa");
     }
 
-}
\ No newline at end of file
+}
diff --git a/plugins/rest/src/test/java/org/apache/struts2/rest/handler/XStreamHandlerTest.java b/plugins/rest/src/test/java/org/apache/struts2/rest/handler/XStreamHandlerTest.java
index 732643b..3d036d2 100644
--- a/plugins/rest/src/test/java/org/apache/struts2/rest/handler/XStreamHandlerTest.java
+++ b/plugins/rest/src/test/java/org/apache/struts2/rest/handler/XStreamHandlerTest.java
@@ -56,7 +56,7 @@
         handler = new XStreamHandler();
         ai = new MockActionInvocation();
         ActionSupport action = new ActionSupport();
-        ActionContext context = ActionContext.of(new HashMap<>()).withLocale(Locale.US);
+        ActionContext context = ActionContext.of().withLocale(Locale.US);
         ai.setInvocationContext(context);
         ai.setAction(action);
     }
diff --git a/plugins/sitemesh/src/main/resources/struts-plugin.xml b/plugins/sitemesh/src/main/resources/struts-plugin.xml
index bad62b8..694e393 100644
--- a/plugins/sitemesh/src/main/resources/struts-plugin.xml
+++ b/plugins/sitemesh/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <bean class="org.apache.struts2.sitemesh.FreemarkerPageFilter" static="true" optional="true"/>
diff --git a/plugins/spring/src/main/resources/struts-plugin.xml b/plugins/spring/src/main/resources/struts-plugin.xml
index 7a54620..33f68db 100644
--- a/plugins/spring/src/main/resources/struts-plugin.xml
+++ b/plugins/spring/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <bean type="com.opensymphony.xwork2.ObjectFactory" name="spring" class="org.apache.struts2.spring.StrutsSpringObjectFactory" />
diff --git a/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java b/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
index 65a3700..559f59b 100644
--- a/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
+++ b/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/ActionsFromSpringTest.java
@@ -135,11 +135,10 @@
         params.put("exposeProxy", "true");
         params.put("issueId", "S2-047");
 
-        HashMap<String, Object> extraContext = new HashMap<>();
-        extraContext.put(ActionContext.PARAMETERS, HttpParameters.create(params).build());
+        ActionContext extraContext = ActionContext.of().withParameters(HttpParameters.create(params).build());
 
         ActionProxy proxy = actionProxyFactory.createActionProxy(null,
-            "chaintoAOPedTestSubBeanAction", null, extraContext);
+            "chaintoAOPedTestSubBeanAction", null, extraContext.getContextMap());
 
         // when
         proxy.execute();
diff --git a/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptorTest.java b/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptorTest.java
index 970c3ee..10697f3 100644
--- a/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptorTest.java
+++ b/plugins/spring/src/test/java/com/opensymphony/xwork2/spring/interceptor/ActionAutowiringInterceptorTest.java
@@ -110,7 +110,7 @@
     }
 
     public void testIfApplicationContextIsNullThenBeanWillNotBeWiredUp() throws Exception {
-        ActionContext.of(new HashMap<>())
+        ActionContext.of()
             .withApplication(new HashMap<>())
             .bind();
 
diff --git a/plugins/spring/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml b/plugins/spring/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
index 6364747..c454bac 100644
--- a/plugins/spring/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
+++ b/plugins/spring/src/test/resources/com/opensymphony/xwork2/spring/actionContext-xwork.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-        "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-        "https://struts.apache.org/dtds/struts-2.5.dtd">
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
 <struts>
 	<bean type="com.opensymphony.xwork2.ObjectFactory" class="com.opensymphony.xwork2.spring.SpringObjectFactory" />
 	<constant name="applicationContextPath" value="com/opensymphony/xwork2/spring/actionContext-spring.xml" />
diff --git a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java
index 4c801f4..a1e1c69 100644
--- a/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java
+++ b/plugins/tiles/src/main/java/org/apache/struts2/views/tiles/TilesResult.java
@@ -76,7 +76,7 @@
  *
  *
  * <!-- START SNIPPET: tilesconfig -->
- * You have to configure tiles itself. Therefore you can add <code>tiles.xml</code> either 
+ * You have to configure tiles itself. Therefore you can add <code>tiles.xml</code> either
  * to resources or WEB-INF. You may also use annotations like {@link TilesDefinition}.
  *
  * <!-- END SNIPPET: tilesconfig -->
@@ -109,7 +109,7 @@
         StrutsTilesAnnotationProcessor annotationProcessor = new StrutsTilesAnnotationProcessor();
         TilesDefinition tilesDefinition = null;
         Object action = invocation.getAction();
-        String actionName = invocation.getInvocationContext().getName();
+        String actionName = invocation.getInvocationContext().getActionName();
 
         if (StringUtils.isEmpty(location)) {
             LOG.trace("location not set -> action must have one @TilesDefinition");
diff --git a/plugins/tiles/src/main/resources/struts-plugin.xml b/plugins/tiles/src/main/resources/struts-plugin.xml
index 9ae060a..09d33f5 100644
--- a/plugins/tiles/src/main/resources/struts-plugin.xml
+++ b/plugins/tiles/src/main/resources/struts-plugin.xml
@@ -20,8 +20,8 @@
  */
 -->
 <!DOCTYPE struts PUBLIC
-	"-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
-	"https://struts.apache.org/dtds/struts-2.5.dtd">
+	"-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+	"https://struts.apache.org/dtds/struts-6.0.dtd">
 
 <struts>
     <package name="tiles-default" extends="struts-default">
diff --git a/core/src/main/resources/template/xhtml/datetext.ftl b/plugins/velocity/src/main/resources/struts-deferred.xml
similarity index 69%
copy from core/src/main/resources/template/xhtml/datetext.ftl
copy to plugins/velocity/src/main/resources/struts-deferred.xml
index d15b24a..914a649 100644
--- a/core/src/main/resources/template/xhtml/datetext.ftl
+++ b/plugins/velocity/src/main/resources/struts-deferred.xml
@@ -1,4 +1,5 @@
-<#--
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -18,6 +19,12 @@
  * under the License.
  */
 -->
-<#include "/${parameters.templateDir}/${parameters.expandTheme}/controlheader.ftl" />
-<#include "/${parameters.templateDir}/simple/datetext.ftl" />
-<#include "/${parameters.templateDir}/${parameters.expandTheme}/controlfooter.ftl" />
+<!DOCTYPE struts PUBLIC
+        "-//Apache Software Foundation//DTD Struts Configuration 6.0//EN"
+        "https://struts.apache.org/dtds/struts-6.0.dtd">
+
+<struts>
+
+    <bean-selection name="velocityBeans" class="org.apache.struts2.views.velocity.VelocityBeanSelectionProvider"/>
+
+</struts>
diff --git a/plugins/velocity/src/main/resources/struts-plugin.xml b/plugins/velocity/src/main/resources/struts-plugin.xml
index 48ae45b..7630d41 100644
--- a/plugins/velocity/src/main/resources/struts-plugin.xml
+++ b/plugins/velocity/src/main/resources/struts-plugin.xml
@@ -39,6 +39,4 @@
         </result-types>
     </package>
 
-    <bean-selection name="velocityBeans" class="org.apache.struts2.views.velocity.VelocityBeanSelectionProvider"/>
-
 </struts>
diff --git a/pom.xml b/pom.xml
index 7cb8213..1b22a1c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -116,7 +116,7 @@
         <log4j2.version>2.19.0</log4j2.version>
         <ognl.version>3.3.4</ognl.version>
         <slf4j.version>1.7.32</slf4j.version>
-        <spring.platformVersion>5.3.26</spring.platformVersion>
+        <spring.platformVersion>5.3.27</spring.platformVersion>
         <tiles.version>3.0.8</tiles.version>
         <tiles-request.version>1.0.7</tiles-request.version>
         <maven-surefire-plugin.version>3.0.0-M7</maven-surefire-plugin.version>
@@ -1091,7 +1091,7 @@
             <dependency>
                 <groupId>org.testng</groupId>
                 <artifactId>testng</artifactId>
-                <version>7.5</version><!-- the latest version supporting Java 1.8 -->
+                <version>7.5.1</version><!-- the latest version supporting Java 1.8 -->
             </dependency>
 
             <dependency>