diff --git a/exist-core/pom.xml b/exist-core/pom.xml
index 96cbbc310cf..262ffd0ac90 100644
--- a/exist-core/pom.xml
+++ b/exist-core/pom.xml
@@ -705,6 +705,7 @@
src/main/java/org/exist/xmlrpc/ACEAiderSerializer.java
src/main/java/org/exist/xquery/Cardinality.java
src/test/java/org/exist/xquery/ImportModuleTest.java
+ src/main/java/org/exist/xquery/Materializable.java
src/test/java/org/exist/xquery/XQueryContextAttributesTest.java
src/main/java/org/exist/xquery/functions/map/MapType.java
src/test/java/org/exist/xquery/functions/session/AbstractSessionTest.java
@@ -856,6 +857,7 @@ The original license statement is also included below.]]>
src/main/java/org/exist/xmlrpc/ACEAiderSerializer.java
src/main/java/org/exist/xquery/Cardinality.java
src/test/java/org/exist/xquery/ImportModuleTest.java
+ src/main/java/org/exist/xquery/Materializable.java
src/test/java/org/exist/xquery/XQueryContextAttributesTest.java
src/main/java/org/exist/xquery/functions/map/MapType.java
src/test/java/org/exist/xquery/functions/session/AbstractSessionTest.java
diff --git a/exist-core/src/main/java/org/exist/xquery/Expression.java b/exist-core/src/main/java/org/exist/xquery/Expression.java
index cec33b8cdb4..de4afa9c099 100644
--- a/exist-core/src/main/java/org/exist/xquery/Expression.java
+++ b/exist-core/src/main/java/org/exist/xquery/Expression.java
@@ -25,18 +25,12 @@
import org.exist.source.Source;
import org.exist.xquery.parser.XQueryAST;
import org.exist.xquery.util.ExpressionDumper;
-import org.exist.xquery.value.Item;
-import org.exist.xquery.value.Sequence;
-
-import javax.annotation.Nullable;
/**
* Base interface implemented by all classes which are part
- * of an XQuery/XPath expression. The main method is
- * {@link #eval(Sequence, Item)}. Please
- * read the description there.
+ * of an XQuery/XPath expression.
*/
-public interface Expression {
+public interface Expression extends Materializable {
// Flags to be passed to analyze:
/**
@@ -113,39 +107,6 @@ public interface Expression {
*/
public void analyze(AnalyzeContextInfo contextInfo) throws XPathException;
- /**
- * Evaluate the expression represented by this object.
- *
- * Depending on the context in which this expression is executed,
- * either the context sequence, the context item or both of them may
- * be set. An implementing class should know how to handle this.
- *
- * The general contract is as follows: if the {@link Dependency#CONTEXT_ITEM}
- * bit is set in the bit field returned by {@link #getDependencies()}, the eval method will
- * be called once for every item in the context sequence. The contextItem
- * parameter will be set to the current item. Otherwise, the eval method will only be called
- * once for the whole context sequence and contextItem will be null.
- *
- * eXist tries to process the entire context set in one, single step whenever
- * possible. Thus, most classes only expect context to contain a list of
- * nodes which represents the current context of the expression.
- *
- * The position() function in XPath is an example for an expression,
- * which requires both, context sequence and context item to be set.
- *
- * The context sequence might be a node set, a sequence of atomic values or a single
- * node or atomic value.
- *
- * @param contextSequence the current context sequence, or null if there is no context sequence.
- * @param contextItem a single item, taken from context, or null if there is no context item.
- * This defines the item, the expression should work on.
- *
- * @return the result sequence.
- *
- * @throws XPathException if an error occurs during evaluation.
- */
- public Sequence eval(@Nullable Sequence contextSequence, @Nullable Item contextItem) throws XPathException;
-
public void setPrimaryAxis(int axis);
public int getPrimaryAxis();
diff --git a/exist-core/src/main/java/org/exist/xquery/Materializable.java b/exist-core/src/main/java/org/exist/xquery/Materializable.java
new file mode 100644
index 00000000000..7f1782f8989
--- /dev/null
+++ b/exist-core/src/main/java/org/exist/xquery/Materializable.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This file was originally ported from FusionDB to eXist-db by
+ * Evolved Binary, for the benefit of the eXist-db Open Source community.
+ * Only the ported code as it appears in this file, at the time that
+ * it was contributed to eXist-db, was re-licensed under The GNU
+ * Lesser General Public License v2.1 only for use in eXist-db.
+ *
+ * This license grant applies only to a snapshot of the code as it
+ * appeared when ported, it does not offer or infer any rights to either
+ * updates of this source code or access to the original source code.
+ *
+ * The GNU Lesser General Public License v2.1 only license follows.
+ *
+ * ---------------------------------------------------------------------
+ *
+ * Copyright (C) 2014, Evolved Binary Ltd
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; version 2.1.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+package org.exist.xquery;
+
+import org.exist.xquery.value.Item;
+import org.exist.xquery.value.Sequence;
+
+import javax.annotation.Nullable;
+
+/**
+ * Marks an expression as being Materializable as per the
+ * Materialization query execution model.
+ *
+ * @author Adam Retter
+ */
+public interface Materializable {
+
+ /**
+ * Materialize the result.
+ *
+ * Depending on the context in which this expression is executed,
+ * either the context sequence, the context item or both of them may
+ * be set. An implementing class should know how to handle this.
+ *
+ * The general contract is as follows: if the {@link Dependency#CONTEXT_ITEM}
+ * bit is set in the bit field returned by {@link Expression#getDependencies()}, the eval method will
+ * be called once for every item in the context sequence. The contextItem
+ * parameter will be set to the current item. Otherwise, the eval method will only be called
+ * once for the whole context sequence and contextItem will be null.
+ *
+ * eXist-db tries to process the entire context set in one, single step whenever
+ * possible. Thus, most classes only expect context to contain a list of
+ * nodes which represents the current context of the expression.
+ *
+ * The position() function in XPath is an example for an expression,
+ * which requires both, context sequence and context item to be set.
+ *
+ * The context sequence might be a node set, a sequence of atomic values or a single
+ * node or atomic value.
+ *
+ * @param contextSequence the current context sequence, or null if there is no context sequence.
+ * @param contextItem a single item, taken from context, or null if there is no context item.
+ * This defines the item, the expression should work on.
+ *
+ * @return the result sequence.
+ *
+ * @throws XPathException if an error occurs during evaluation.
+ */
+ Sequence eval(@Nullable Sequence contextSequence, @Nullable Item contextItem) throws XPathException;
+}