diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java b/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java
new file mode 100644
index 00000000000..2a2e4d014a2
--- /dev/null
+++ b/org.springframework.expression/src/main/java/org/springframework/expression/AccessException.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2004-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.expression;
+
+/**
+ * An AccessException is thrown by an accessor if it has an unexpected problem.
+ *
+ * @author Andy Clement
+ */
+public class AccessException extends Exception {
+
+ /**
+ * Create an AccessException with a specific message and cause.
+ *
+ * @param message the message
+ * @param cause the cause
+ */
+ public AccessException(String message, Exception cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Create an AccessException with a specific message.
+ *
+ * @param message the message
+ */
+ public AccessException(String message) {
+ super(message);
+ }
+
+}
diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/CacheablePropertyAccessor.java b/org.springframework.expression/src/main/java/org/springframework/expression/CacheablePropertyAccessor.java
new file mode 100644
index 00000000000..4e654b54907
--- /dev/null
+++ b/org.springframework.expression/src/main/java/org/springframework/expression/CacheablePropertyAccessor.java
@@ -0,0 +1,57 @@
+package org.springframework.expression;
+
+// TODO (asc) Do we need a 'caching is allowed' option to be configurable at parse time?
+/**
+ * A CacheablePropertyAccessor is an optimized PropertyAccessor where the two parts of accessing the
+ * property are separated: (1) resolving the property and (2) retrieving its value. In some cases there is
+ * a large cost to discovering which property an expression refers to and once discovered it will
+ * always resolve to the same property. In these situations a CacheablePropertyAccessor enables the
+ * resolution to be done once and a reusable object (an executor) returned that can be called over and
+ * over to retrieve the property value without going through resolution again.
+ *
+ *
+ * @author Andy Clement
+ */
+public abstract class CacheablePropertyAccessor implements PropertyAccessor {
+
+ /**
+ * Attempt to resolve the named property and return an executor that can be called to
+ * get the value of that property. Return null if the property cannot be resolved.
+ *
+ * @param context the evaluation context
+ * @param target the target upon which the property is being accessed
+ * @param name the name of the property being accessed
+ * @return a reusable executor that can retrieve the property value
+ */
+ public abstract PropertyReaderExecutor getReaderAccessor(EvaluationContext context, Object target, Object name);
+
+ /**
+ * Attempt to resolve the named property and return an executor that can be called to
+ * set the value of that property. Return null if the property cannot be resolved.
+ *
+ * @param context the evaluation context
+ * @param target the target upon which the property is being accessed
+ * @param name the name of the property to be set
+ * @return a reusable executor that can set the property value
+ */
+ public abstract PropertyWriterExecutor getWriterAccessor(EvaluationContext context, Object target, Object name);
+
+ // Implementation of PropertyAccessor follows, based on the resolver/executor model
+
+ public final boolean canRead(EvaluationContext context, Object target, Object name) throws AccessException {
+ return getReaderAccessor(context,target,name) != null;
+ }
+
+ public final boolean canWrite(EvaluationContext context, Object target, Object name) throws AccessException {
+ return getWriterAccessor(context,target,name) != null;
+ }
+
+ public final Object read(EvaluationContext context, Object target, Object name) throws AccessException {
+ return getReaderAccessor(context,target,name).execute(context,target);
+ }
+
+ public final void write(EvaluationContext context, Object target, Object name, Object newValue) throws AccessException {
+ getWriterAccessor(context,target,name).execute(context,target,newValue);
+ }
+
+}
diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java
new file mode 100644
index 00000000000..11e1225f63e
--- /dev/null
+++ b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorExecutor.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2004-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.expression;
+
+// TODO (asc) Is the resolver/executor model too pervasive in this package?
+/**
+ * Executors are built by resolvers and can be cached by the infrastructure to repeat an operation quickly without going
+ * back to the resolvers. For example, the particular constructor to run on a class may be discovered by the reflection
+ * constructor resolver - it will then build a ConstructorExecutor that executes that constructor and the
+ * ConstructorExecutor can be reused without needing to go back to the resolver to discover the constructor again.
+ *
+ * They can become stale, and in that case should throw an AccessException - this will cause the infrastructure to go
+ * back to the resolvers to ask for a new one.
+ *
+ * @author Andy Clement
+ */
+public interface ConstructorExecutor {
+
+ /**
+ * Execute a constructor in the specified context using the specified arguments.
+ *
+ * @param context the evaluation context in which the command is being executed
+ * @param arguments the arguments to the constructor call, should match (in terms of number and type) whatever the
+ * command will need to run
+ * @return the new object
+ * @throws AccessException if there is a problem executing the command or the CommandExecutor is no longer valid
+ */
+ Object execute(EvaluationContext context, Object... arguments) throws AccessException;
+
+}
diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java
new file mode 100644
index 00000000000..87037c64c55
--- /dev/null
+++ b/org.springframework.expression/src/main/java/org/springframework/expression/ConstructorResolver.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2004-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.expression;
+
+/**
+ * A constructor resolver attempts locate a constructor and returns a ConstructorExecutor that can be used to invoke
+ * that constructor. The ConstructorExecutor will be cached but if it 'goes stale' the resolvers will be called again.
+ *
+ * @author Andy Clement
+ */
+public interface ConstructorResolver {
+
+ /**
+ * Within the supplied context determine a suitable constructor on the supplied type that can handle the specified
+ * arguments. Return a ConstructorExecutor that can be used to invoke that constructor (or null if no constructor
+ * could be found).
+ *
+ * @param context the current evaluation context
+ * @param typename the type upon which to look for the constructor
+ * @param argumentTypes the arguments that the constructor must be able to handle
+ * @return a ConstructorExecutor that can invoke the constructor, or null if non found
+ */
+ ConstructorExecutor resolve(EvaluationContext context, String typename, Class>[] argumentTypes)
+ throws AccessException;
+
+}
diff --git a/org.springframework.expression/src/main/java/org/springframework/expression/EvaluationContext.java b/org.springframework.expression/src/main/java/org/springframework/expression/EvaluationContext.java
new file mode 100644
index 00000000000..d6ac1f80e93
--- /dev/null
+++ b/org.springframework.expression/src/main/java/org/springframework/expression/EvaluationContext.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2004-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.expression;
+
+import java.util.List;
+
+import org.springframework.expression.spel.standard.StandardEvaluationContext;
+import org.springframework.expression.spel.standard.StandardTypeUtilities;
+
+/**
+ * Expressions are executed in an evaluation context. It is in this context that references are resolved when
+ * encountered during expression evaluation.
+ *
+ * There is a default implementation of the EvaluationContext, {@link StandardEvaluationContext} that can be extended,
+ * rather than having to implement everything.
+ *
+ * @author Andy Clement
+ */
+public interface EvaluationContext {
+
+ /**
+ * @return the root context object against which unqualified properties/methods/etc should be resolved
+ */
+ Object getRootContextObject();
+
+ /**
+ * @return a TypeUtilities implementation that can be used for looking up types, converting types, comparing types,
+ * and overloading basic operators for types. A standard implementation is provided in {@link StandardTypeUtilities}
+ */
+ TypeUtils getTypeUtils();
+
+ /**
+ * Look up a named variable within this execution context.
+ *
+ * @param name variable to lookup
+ * @return the value of the variable
+ */
+ Object lookupVariable(String name);
+
+ /**
+ * Set a named variable within this execution context to a specified value.
+ *
+ * @param name variable to set
+ * @param value value to be placed in the variable
+ */
+ void setVariable(String name, Object value);
+
+ // TODO (asc) lookupReference() - is it too expensive to return all objects within a context?
+ /**
+ * Look up an object reference in a particular context. If no contextName is specified (null), assume the default
+ * context. If no objectName is specified (null), return all objects in the specified context (List