diff --git a/api/pom.xml b/api/pom.xml
new file mode 100644
index 000000000..34202df98
--- /dev/null
+++ b/api/pom.xml
@@ -0,0 +1,54 @@
+
+
+ 4.0.0
+
+ org.apache.struts
+ struts2-parent
+ 2.0.5-SNAPSHOT
+
+ org.apache.struts
+ struts2-api
+ jar
+ Struts 2 API
+
+
+ scm:svn:http://svn.apache.org/repos/asf/struts/struts2/trunk/api/
+ scm:svn:https://svn.apache.org/repos/asf/struts/struts2/trunk/api/
+ http://svn.apache.org/viewcvs.cgi/struts/struts2/trunk/api/
+
+
+
+
+ javax.servlet
+ servlet-api
+ 2.4
+ provided
+
+
+ junit
+ junit
+ 3.8.1
+ test
+
+ true
+
+
+ org.easymock
+ easymock
+ test
+ 2.0
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-javadoc-plugin
+
+ false
+
+
+
+
+
diff --git a/api/src/main/java/org/apache/struts2/Action.java b/api/src/main/java/org/apache/struts2/Action.java
new file mode 100644
index 000000000..ae46570f2
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/Action.java
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2;
+
+/**
+ * Default action interface. Provided purely for user convenience. Struts does not require actions to implement any
+ * interfaces. Actions need only implement a public, no argument method which returns {@code String}. If a user does
+ * not specify a method name, Struts defaults to {@code execute()}.
+ *
+ *
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Action {
+
+ /**
+ * Executes this action.
+ *
+ * @return result name which matches a result name from the action mapping in the configuration file. See {@link
+ * ResultNames} for common suggestions.
+ */
+ String execute();
+}
diff --git a/api/src/main/java/org/apache/struts2/MessageAware.java b/api/src/main/java/org/apache/struts2/MessageAware.java
new file mode 100644
index 000000000..6dd380b53
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/MessageAware.java
@@ -0,0 +1,61 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2;
+
+/**
+ * Implemented by actions which may need to record errors or messages.
+ *
+ *
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface MessageAware {
+
+ /**
+ * Sets messages.
+ *
+ * @param messages messages
+ */
+ void setMessages(Messages messages);
+}
diff --git a/api/src/main/java/org/apache/struts2/Messages.java b/api/src/main/java/org/apache/struts2/Messages.java
new file mode 100644
index 000000000..bce30de5a
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/Messages.java
@@ -0,0 +1,216 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2;
+
+import java.util.List;
+import java.util.Set;
+import java.util.Map;
+
+/**
+ * Collection of messages. Supports nesting messages by field name.
+ *
+ *
Uses keys when adding instead of actual messages to decouple code from messages.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Messages {
+
+ // TODO: Use Object[] for args instead of String[].
+
+ /**
+ * Message severity.
+ */
+ public enum Severity {
+
+ /**
+ * Informational messages.
+ */
+ INFO,
+
+ /**
+ * Warning messages.
+ */
+ WARN,
+
+ /**
+ * Error messages.
+ */
+ ERROR,
+ }
+
+ /**
+ * Gets nested messages for the given field.
+ *
+ *
Supports dot notation to represent nesting. For example:
+ *
+ *
+ *
+ * @param fieldName name of the field
+ * @return nested {@code Messages} for given field name
+ */
+ Messages forField(String fieldName);
+
+ /**
+ * Gets map of field name to messages for that field.
+ *
+ * @return map of field name to {@code Messages}
+ */
+ Map forFields();
+
+ /**
+ * Adds informational message.
+ *
+ * @param key message key
+ * @see Severity.INFO
+ */
+ void addInformation(String key);
+
+ /**
+ * Adds informational message.
+ *
+ * @param key message key
+ * @param arguments message arguments
+ * @see Severity.INFO
+ */
+ void addInformation(String key, String... arguments);
+
+ /**
+ * Adds warning message.
+ *
+ * @param key message key
+ * @see Severity.WARN
+ */
+ void addWarning(String key);
+
+ /**
+ * Adds warning message.
+ *
+ * @param key message key
+ * @param arguments message arguments
+ * @see Severity.WARN
+ */
+ void addWarning(String key, String... arguments);
+
+ /**
+ * Adds error message.
+ *
+ * @param key message key
+ * @see Severity.ERROR
+ */
+ void addError(String key);
+
+ /**
+ * Adds error message.
+ *
+ * @param key message key
+ * @param arguments message arguments
+ * @see Severity.ERROR
+ */
+ void addError(String key, String... arguments);
+
+ /**
+ * Adds message.
+ *
+ * @param severity message severity
+ * @param key message key
+ */
+ void add(Severity severity, String key);
+
+ /**
+ * Adds request-scoped message.
+ *
+ * @param severity message severity
+ * @param key message key
+ * @param arguments message arguments
+ */
+ void add(Severity severity, String key, String... arguments);
+
+ /**
+ * Gets set of severities for which this {@code Messages} instance has messages. Not recursive.
+ *
+ * @return unmodifiable set of {@link Severity} sorted from least to most severe
+ */
+ Set getSeverities();
+
+ /**
+ * Gets message strings for the given severity. Not recursive.
+ *
+ * @param severity message severity
+ * @return unmodifiable list of messages
+ */
+ List forSeverity(Severity severity);
+
+ /**
+ * Gets error message strings for this {@code Messages} instance. Not recursive.
+ *
+ * @return unmodifiable list of messages
+ */
+ List getErrors();
+
+ /**
+ * Gets error message strings for this {@code Messages} instance. Not recursive.
+ *
+ * @return unmodifiable list of messages
+ */
+ List getWarnings();
+
+ /**
+ * Gets informational message strings for this {@code Messages} instance. Not recursive.
+ *
+ * @return unmodifiable list of messages
+ */
+ List getInformation();
+
+ /**
+ * Returns true if this or a nested {@code Messages} instance has error messages.
+ *
+ * @see Severity.ERROR
+ */
+ boolean hasErrors();
+
+ /**
+ * Returns true if this or a nested {@code Messages} instance has warning messages.
+ *
+ * @see Severity.WARN
+ */
+ boolean hasWarnings();
+
+ /**
+ * Returns true if this or a nested {@code Messages} instance has informational messages.
+ *
+ * @see Severity.INFO
+ */
+ boolean hasInformation();
+
+ /**
+ * Returns true if this and all nested {@code Messages} instances have no messages.
+ */
+ boolean isEmpty();
+
+ /**
+ * Returns true if this and all nested {@code Messages} instances have no messages for the given severity.
+ *
+ * @param severity message severity
+ */
+ boolean isEmpty(Severity severity);
+}
\ No newline at end of file
diff --git a/api/src/main/java/org/apache/struts2/ResultNames.java b/api/src/main/java/org/apache/struts2/ResultNames.java
new file mode 100644
index 000000000..fd5955ce0
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/ResultNames.java
@@ -0,0 +1,56 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2;
+
+/**
+ * Commonly used result names returned by action methods.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public final class ResultNames {
+
+ private ResultNames() {}
+
+ /**
+ * The action executed successfully.
+ */
+ public static final String SUCCESS = "success";
+
+ /**
+ * The action requires more input, i.e. a validation error occurred.
+ */
+ public static final String INPUT = "input";
+
+ /**
+ * The action requires the user to log in before executing.
+ */
+ public static final String LOGIN = "login";
+
+ /**
+ * The action execution failed irrecoverably.
+ */
+ public static final String ERROR = "error";
+
+ /**
+ * The action executed successfully, but do not execute a result.
+ */
+ public static final String NONE = "none";
+}
diff --git a/api/src/main/java/org/apache/struts2/Validatable.java b/api/src/main/java/org/apache/struts2/Validatable.java
new file mode 100644
index 000000000..1d59dddee
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/Validatable.java
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2;
+
+import org.apache.struts2.MessageAware;
+
+/**
+ * Implemented by actions which wish to execute some validation logic before their action method. Useful for
+ * cross-field validations.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Validatable extends MessageAware {
+
+ /**
+ * Validates input. Executes before action method.
+ */
+ public void validate();
+}
diff --git a/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java b/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java
new file mode 100644
index 000000000..df705fbe6
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/servlet/ParameterAware.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.servlet;
+
+import java.util.Map;
+
+/**
+ * Implemented by actions which need direct access to the request parameters.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ParameterAware {
+
+ /**
+ * Sets parameters.
+ *
+ * @param parameters map of parameter name to parameter values
+ */
+ void setParameters(Map parameters);
+}
diff --git a/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java b/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java
new file mode 100644
index 000000000..cf1a44c6b
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/servlet/ServletRequestAware.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.servlet;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Implemented by actions which need direct access to the servlet request.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ServletRequestAware {
+
+ /**
+ * Sets the servlet request.
+ *
+ * @param request servlet request.
+ */
+ void setServletRequest(HttpServletRequest request);
+}
diff --git a/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java b/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java
new file mode 100644
index 000000000..c36726fa2
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/servlet/ServletResponseAware.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.servlet;
+
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Implemented by actions which need direct access to the servlet response.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ServletResponseAware {
+
+ /**
+ * Sets the servlet response.
+ *
+ * @param response servlet response
+ */
+ void setServletResponse(HttpServletResponse response);
+}
diff --git a/api/src/main/java/org/apache/struts2/spi/ActionContext.java b/api/src/main/java/org/apache/struts2/spi/ActionContext.java
new file mode 100644
index 000000000..5546fa444
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/spi/ActionContext.java
@@ -0,0 +1,79 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.spi;
+
+import java.lang.reflect.Method;
+
+/**
+ * Context of an action execution.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ActionContext {
+
+ /**
+ * Gets action instance.
+ */
+ Object getAction();
+
+ /**
+ * Gets action method.
+ */
+ Method getMethod();
+
+ /**
+ * Gets action name.
+ */
+ String getActionName();
+
+ /**
+ * Gets the path for the action's namespace.
+ */
+ String getNamespacePath();
+
+ /**
+ * Gets the {@link Result} instance for the action.
+ *
+ * @return {@link Result} instance or {@code null} if we don't have a result yet.
+ */
+ Result getResult();
+
+ /**
+ * Adds a result interceptor for the action. Enables executing code before and after a result, executing an
+ * alternate result, etc.
+ */
+ void addResultInterceptor(Result interceptor);
+
+ /**
+ * Gets context of action which chained to us.
+ *
+ * @return context of previous action or {@code null} if this is the first action in the chain
+ */
+ ActionContext getPrevious();
+
+ /**
+ * Gets context of action which this action chained to.
+ *
+ * @return context of next action or {@code null} if we haven't chained to another action yet or this is the last
+ * action in the chain.
+ */
+ ActionContext getNext();
+}
diff --git a/api/src/main/java/org/apache/struts2/spi/Interceptor.java b/api/src/main/java/org/apache/struts2/spi/Interceptor.java
new file mode 100644
index 000000000..33cd84751
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/spi/Interceptor.java
@@ -0,0 +1,36 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.spi;
+
+/**
+ * Intercepts an action request.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Interceptor {
+
+ /**
+ * Intercepts an action request.
+ *
+ * @param requestContext current request context
+ */
+ String intercept(RequestContext requestContext) throws Exception;
+}
diff --git a/api/src/main/java/org/apache/struts2/spi/RequestContext.java b/api/src/main/java/org/apache/struts2/spi/RequestContext.java
new file mode 100644
index 000000000..c08b08a6f
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/spi/RequestContext.java
@@ -0,0 +1,121 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.spi;
+
+import org.apache.struts2.Messages;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Request context. A single request may span multiple actions with action chaining.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface RequestContext {
+
+ /**
+ * Gets context of the currently executing action.
+ *
+ * @return current action context
+ */
+ ActionContext getActionContext();
+
+ /**
+ * Convenience method. Equivalent to {@code getActionContext().getAction()}.
+ *
+ * @return currently executing action
+ */
+ Object getAction();
+
+ /**
+ * Gets map of request parameters.
+ */
+ Map getParameterMap();
+
+ /**
+ * Gets map of request attributes.
+ */
+ Map getAttributeMap();
+
+ /**
+ * Gets map of session attributes.
+ */
+ Map getSessionMap();
+
+ /**
+ * Gets map of application (servlet context) attributes.
+ */
+ Map getApplicationMap();
+
+ /**
+ * Finds cookies with the given name,
+ */
+ List findCookiesForName(String name);
+
+ /**
+ * Gets locale.
+ */
+ Locale getLocale();
+
+ /**
+ * Sets locale. Stores the locale in the session for future requests.
+ */
+ void setLocale(Locale locale);
+
+ /**
+ * Gets messages.
+ */
+ Messages getMessages();
+
+ /**
+ * Gets the servlet request.
+ */
+ HttpServletRequest getServletRequest();
+
+ /**
+ * Gets the servlet response.
+ */
+ HttpServletResponse getServletResponse();
+
+ /**
+ * Gets the servlet context.
+ */
+ ServletContext getServletContext();
+
+ /**
+ * Gets the value stack.
+ */
+ ValueStack getValueStack();
+
+ /**
+ * Invokes the next interceptor or the action method if no more interceptors remain.
+ *
+ * @return result name
+ * @throws IllegalStateException if already invoked or called from the action
+ */
+ String proceed() throws Exception;
+}
diff --git a/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java b/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java
new file mode 100644
index 000000000..342599b9e
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/spi/RequestContextAware.java
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.spi;
+
+import org.apache.struts2.spi.RequestContext;
+
+/**
+ * Implemented by actions that need access to the current {@link org.apache.struts2.spi.RequestContext}. Use
+ * judiciously.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface RequestContextAware {
+
+ /**
+ * Sets {@link org.apache.struts2.spi.RequestContext}.
+ *
+ * @param requestContext
+ */
+ void setRequestContext(RequestContext requestContext);
+}
diff --git a/api/src/main/java/org/apache/struts2/spi/Result.java b/api/src/main/java/org/apache/struts2/spi/Result.java
new file mode 100644
index 000000000..07913ccd3
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/spi/Result.java
@@ -0,0 +1,38 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.spi;
+
+import org.apache.struts2.spi.RequestContext;
+
+/**
+ * The result of an action request. Struts creates a new {@code Result} instance for each request.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface Result {
+
+ /**
+ * Executes result.
+ *
+ * @param requestContext
+ */
+ void execute(RequestContext requestContext) throws Exception;
+}
diff --git a/api/src/main/java/org/apache/struts2/spi/ValueStack.java b/api/src/main/java/org/apache/struts2/spi/ValueStack.java
new file mode 100644
index 000000000..bd6192206
--- /dev/null
+++ b/api/src/main/java/org/apache/struts2/spi/ValueStack.java
@@ -0,0 +1,113 @@
+/*
+ * $Id$
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.struts2.spi;
+
+/**
+ * A central fixture of the Struts framework, the {@code ValueStack} is a stack which contains the actions
+ * which have executed in addition to other objects. Users can get and set values on the stack using expressions. The
+ * {@code ValueStack} will search down the stack starting with the most recent objects until it finds an object to
+ * which the expression can apply.
+ *
+ * @author crazybob@google.com (Bob Lee)
+ */
+public interface ValueStack extends Iterable