diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/build.xml work-copy/build.xml
--- work-copy/build.xml	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/build.xml	2007-10-21 11:58:06.000000000 -0400
@@ -33,7 +33,7 @@
 
 	<!-- CONFIGURABLE PROPERTIES -->
 	<property name="javacc_home" value="../JavaCC" />
-	<property name="current_grammar" value="20060616-ext" />
+	<property name="current_grammar" value="20070624" />
 	<property name="library" value="sparql-core.jar" />
 	<property name="test_library" value="sparql-tests.jar" />
 	<property name="version" value="0.9" />
@@ -149,4 +149,4 @@
 	<!-- THIS WILL BUILD THE WHOLE DISTRIBUTION FROM GRAMMAR -->
 	<target name="dist_from_grammar" depends="grammar,dist" />
 
-</project>
\ No newline at end of file
+</project>
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/conf/grammars/20070624.jjt work-copy/conf/grammars/20070624.jjt
--- work-copy/conf/grammars/20070624.jjt	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/conf/grammars/20070624.jjt	2008-05-03 16:55:36.000000000 -0400
@@ -144,7 +144,7 @@
 	| <#WS: ("\u0020" | "\u0009" | "\r" | "\n") >
 	| <#VARNAME: (<PN_CHARS_U> | ["0"-"9"]) (<PN_CHARS_U> | ["0"-"9"] | "\u00B7" | ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] )* >
 	| <#PN_CHARS: <PN_CHARS_U> | "-" | ["0"-"9"] | "\u00B7" | ["\u0300"-"\u036F"] | ["\u203F"-"\u2040"] >
-	| <#PN_PREFIX: <PN_CHARS_U> ( (<PN_CHARS> | ".")* <PN_CHARS> )? >
+	| <#PN_PREFIX: ( "_" (<PN_CHARS> | ".")* <PN_CHARS> ) | ( <PN_CHARS_BASE> ( (<PN_CHARS> | ".")* <PN_CHARS> )? ) > /* don't accept the underscore alone because that is for BNODE_LABEL */
 	| <#PN_LOCAL: (<PN_CHARS_U> | ["0"-"9"]) ( (<PN_CHARS> | ".")* <PN_CHARS> )? >
 	| <#EXPONENT: ["E","e"] (["+","-"])? (["0"-"9"])+ >
 	| <#ECHAR: "\\" ["t","b","n","r","f","\\","'","\""] >
@@ -262,7 +262,7 @@
 }
 {
 	( ( ( "ASC" | "DESC" {ascending = false;} ) BracketedExpression() #AscOrder(ascending) ) #DescOrder(!ascending) ) 
-		| ( ( FunctionCall() | Var() | BracketedExpression() )#DefaultOrder )
+		| ( ( BuiltInCall() | FunctionCall() | Var() | BracketedExpression() )#DefaultOrder )
 }
 
 void LimitClause() #Limit :
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/AdvancedRdfSource.java work-copy/src/main/name/levering/ryan/sparql/common/AdvancedRdfSource.java
--- work-copy/src/main/name/levering/ryan/sparql/common/AdvancedRdfSource.java	1969-12-31 19:00:00.000000000 -0500
+++ work-copy/src/main/name/levering/ryan/sparql/common/AdvancedRdfSource.java	2008-08-13 16:22:22.000000000 -0400
@@ -0,0 +1,61 @@
+/*
+ * SPARQL Engine
+ * Copyright (C) 2005 Ryan Levering, All rights reserved.
+ * See LICENSE for full license information
+ */
+package name.levering.ryan.sparql.common;
+
+import java.util.Iterator;
+import java.util.List;
+
+import name.levering.ryan.sparql.common.URI;
+import name.levering.ryan.sparql.common.Value;
+
+/**
+ * Description...
+ * 
+ * @author Joshua Tauberer
+ * @version 1.0
+ */
+public interface AdvancedRdfSource extends RdfSource {
+    /**
+     * Gets all statements with a specific subject, predicate and/or object, within
+     * a certain set of graphs. The graphs might be from FROM or FROM NAMED clauses.
+     * subj, pred, obj, and graph may be null. If graph is null, both FROM and
+     * FROM NAMED graphs may match.
+     * 
+     * @param subj subject of pattern
+     * @param pred predicate of pattern
+     * @param obj object of pattern
+     * @param graph the context with which to match the statements against
+     * @return iterator over statements
+     */
+    public Iterator getStatements(Value[] subj, Value[] pred, Value[] obj, URI[] graph, Object[] litFilters, int limit);
+
+    /**
+     * Gets all statements with a specific subject, predicate and/or object in
+     * the default graph of the repository. All three parameters may be null to
+     * indicate wildcards. This is only used in SPARQL queries when no graph
+     * names are indicated.
+     * 
+     * @param subj subject of pattern
+     * @param pred predicate of pattern
+     * @param obj object of pattern
+     * @return iterator over statements
+     */
+    public Iterator getDefaultGraphStatements(Value[] subj, Value[] pred, Value[] obj, Object[] litFilters, int limit);
+    
+    /**
+     * Gets all statements with a specific subject, predicate and/or object in
+     * a named graph of the repository. All three parameters may be null to
+     * indicate wildcards. This is only used in SPARQL queries when no graph     * names are indicated.
+     * 
+     * @param subj subject of pattern
+     * @param pred predicate of pattern
+     * @param obj object of pattern
+     * @return iterator over statements
+     */
+    public Iterator getNamedGraphStatements(Value[] subj, Value[] pred, Value[] obj, Object[] litFilters, int limit);
+    
+}
+
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/impl/DateTime.java work-copy/src/main/name/levering/ryan/sparql/common/impl/DateTime.java
--- work-copy/src/main/name/levering/ryan/sparql/common/impl/DateTime.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/impl/DateTime.java	2008-08-09 17:06:38.000000000 -0400
@@ -33,6 +33,9 @@
 import java.util.NoSuchElementException;
 import java.util.StringTokenizer;
 
+import name.levering.ryan.sparql.common.URI;
+import name.levering.ryan.sparql.common.SPARQLConstants;
+
 /**
  * This class provides utility functions for comparisons operating on
  * <code>xml:dateTime</code> datatypes as specified in <a
@@ -47,6 +50,9 @@
 	/** Day part of the dateTime object as int */
 	private int days;
 
+	/** Whether or not this dateTime has time information (is a date or dateTime) */
+	private boolean hasTime = true;
+
 	/** Fractional seconds part of the dateTime object as int */
 	private int fractionalSeconds;
 
@@ -90,6 +96,26 @@
 	}
 
 	/**
+	 * Creates a new DateTime object for the supplied xsd:dateTime or xsd:date string value.
+	 * 
+	 * @param dateTimeString An xsd:date or xsd:dateTime value, for example
+	 *            <tt>1999-05-31T13:20:00-05:00</tt>.
+	 */
+	public DateTime(String dateTimeString, URI datatype) {
+		DateTimeFields fields;
+		if (datatype.equals(SPARQLConstants.DATETIME_TYPE)) {
+			fields = parseDateTimeString(dateTimeString);
+		} else if (datatype.equals(SPARQLConstants.DATE_TYPE)) {
+			fields = parseDateString(dateTimeString);
+			hasTime = false;
+		} else {
+			throw new IllegalArgumentException("datatype is not xsd:date or xsd:dateTime");
+		}
+		setNumericFields(fields, dateTimeString);
+		validateFieldValues(fields, dateTimeString);
+	}
+
+	/**
 	 * Wraps the standard memory cloning to throw a runtime exception rather
 	 * than the more annoying CloneNotSupportedException.
 	 * 
@@ -133,6 +159,8 @@
 			result = thisDT.months - otherDT.months;
 		} else if (thisDT.days != otherDT.days) {
 			result = thisDT.days - otherDT.days;
+		} else if (!hasTime) {
+			result = 0;
 		} else if (thisDT.hours != otherDT.hours) {
 			result = thisDT.hours - otherDT.hours;
 		} else if (thisDT.minutes != otherDT.minutes) {
@@ -300,18 +328,19 @@
 		result.append(formatInt(this.months, 2));
 		result.append('-');
 		result.append(formatInt(this.days, 2));
-		result.append('T');
-		result.append(formatInt(this.hours, 2));
-		result.append(':');
-		result.append(formatInt(this.minutes, 2));
-		result.append(':');
-		result.append(formatInt(this.seconds, 2));
-
-		if (this.fractionalSeconds > 0) {
-			result.append('.');
-			result.append(this.fractionalSeconds);
+		if (hasTime) {
+			result.append('T');
+			result.append(formatInt(this.hours, 2));
+			result.append(':');
+			result.append(formatInt(this.minutes, 2));
+			result.append(':');
+			result.append(formatInt(this.seconds, 2));
+	
+			if (this.fractionalSeconds > 0) {
+				result.append('.');
+				result.append(this.fractionalSeconds);
+			}
 		}
-
 		if (this.hasTimeZone) {
 			if (this.hoursTimeZone == 0 && this.minutesTimeZone == 0) {
 				result.append("Z");
@@ -409,6 +438,52 @@
 		return fields;
 	}
 
+	private DateTimeFields parseDateString(String dateString) {
+		if (dateString.length() < 10) {
+			throw new IllegalArgumentException("String value too short to be a valid xsd:date value: "
+					+ dateString);
+		}
+
+		DateTimeFields fields = new DateTimeFields();
+
+		String errMsg = "Invalid xsd:date value: " + dateString;
+
+		StringTokenizer st = new StringTokenizer(dateString, "+-TZ", true);
+		try {
+			fields.yearString = st.nextToken();
+			fields.isNegativeYear = fields.yearString.equals("-");
+			if (fields.isNegativeYear) {
+				fields.yearString = st.nextToken();
+			}
+			verifyTokenValue(st.nextToken(), "-", errMsg);
+			fields.monthsString = st.nextToken();
+			verifyTokenValue(st.nextToken(), "-", errMsg);
+			fields.daysString = st.nextToken();
+			fields.hoursString = "00";
+			fields.minutesString = "00";
+			fields.secondsString = "00";
+
+			String token = st.hasMoreTokens() ? st.nextToken() : null;
+
+			if ("+".equals(token) || "-".equals(token)) {
+				fields.isNegativeTimeZone = "-".equals(token);
+				fields.hoursTimeZoneString = st.nextToken();
+				verifyTokenValue(st.nextToken(), ":", errMsg);
+				fields.minutesTimeZoneString = st.nextToken();
+			} else if ("Z".equals(token)) {
+				fields.isNegativeTimeZone = false;
+				fields.hoursTimeZoneString = fields.minutesTimeZoneString = "00";
+			}
+
+			if (st.hasMoreTokens()) {
+				throw new IllegalArgumentException(errMsg);
+			}
+		} catch (NoSuchElementException e) {
+			throw new IllegalArgumentException(errMsg);
+		}
+		return fields;
+	}
+
 	private void setNumericFields(DateTimeFields fields, String dateTimeString) {
 		try {
 			this.year = Integer.parseInt(fields.yearString);
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/impl/InternalSPARQLValueFactory.java work-copy/src/main/name/levering/ryan/sparql/common/impl/InternalSPARQLValueFactory.java
--- work-copy/src/main/name/levering/ryan/sparql/common/impl/InternalSPARQLValueFactory.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/impl/InternalSPARQLValueFactory.java	2007-10-21 12:35:15.000000000 -0400
@@ -52,7 +52,7 @@
 	}
 
 	public URI createURI(String namespace, String localName) {
-		return new URIImpl(namespace, localName);
+		return new URIImpl(namespace + localName);
 	}
 
 	public URI createURI(URI baseURI) {
@@ -279,11 +279,8 @@
 		| Variables                              |
 		+---------------------------------------*/
 
-		/** The namespace. * */
-		private String _namespace;
-
-		/** local name * */
-		private String _localName;
+		/** complete URI * */
+		private String _uri;
 
 		/*---------------------------------------+
 		| Constructors                           |
@@ -297,68 +294,12 @@
 		 *             (absolute) URI.
 		 */
 		public URIImpl(String uri) {
-			// Find the place to split the uri
-			int i = uri.length() - 1;
-			while (i >= 0) {
-				char c = uri.charAt(i);
-				if (c == '#' || c == ':' || c == '/') {
-					break;
-				}
-				i--;
-			}
-
-			if (i > 0) {
-				// Split the uri
-				_namespace = uri.substring(0, i + 1);
-				_localName = uri.substring(i + 1);
-			} else {
-				throw new IllegalArgumentException("'" + uri + "' is not a legal (absolute) URI");
-			}
-		}
-
-		/**
-		 * Creates a new URI that will get the supplied namespace and local
-		 * name.
-		 * 
-		 * @param namespace A namespace.
-		 * @param localName A legal local name. A legal local name adheres to
-		 *            the definition of an NCName as specified at <a
-		 *            href="http://www.w3.org/TR/REC-xml-names/#NT-NCName">http://www.w3.org/TR/REC-xml-names/#NT-NCName</a>.
-		 */
-		public URIImpl(String namespace, String localName) {
-			if (namespace == null) {
-				throw new IllegalArgumentException("namespace must not be null");
-			}
-			if (localName == null) {
-				throw new IllegalArgumentException("localName must not be null");
-			}
-
-			_namespace = namespace;
-			_localName = localName;
-		}
-
-		/*---------------------------------------+
-		| Methods                                |
-		+---------------------------------------*/
-
-		// inherit comments
-		public String getNamespace() {
-			return _namespace;
-		}
-
-		// inherit comments
-		public String getLocalName() {
-			return _localName;
+			this._uri = uri;
 		}
 
 		// inherit comments
 		public String getURI() {
-			// This code is (much) more efficient then just concatenating the
-			// two strings.
-			char[] result = new char[_namespace.length() + _localName.length()];
-			_namespace.getChars(0, _namespace.length(), result, 0);
-			_localName.getChars(0, _localName.length(), result, _namespace.length());
-			return new String(result);
+			return _uri;
 		}
 
 		/**
@@ -376,7 +317,7 @@
 			if (o instanceof URI) {
 				URI other = (URI) o;
 
-				return _localName.equals(other.getLocalName()) && _namespace.equals(other.getNamespace());
+				return _uri.equals(other.getURI());
 			}
 
 			return false;
@@ -384,7 +325,7 @@
 
 		// Implements Object.hashCode()
 		public int hashCode() {
-			return _namespace.hashCode() ^ _localName.hashCode();
+			return _uri.hashCode();
 		}
 
 		/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/impl/RdfBindingSetImpl.java work-copy/src/main/name/levering/ryan/sparql/common/impl/RdfBindingSetImpl.java
--- work-copy/src/main/name/levering/ryan/sparql/common/impl/RdfBindingSetImpl.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/impl/RdfBindingSetImpl.java	2007-10-21 12:35:14.000000000 -0400
@@ -98,6 +98,8 @@
 		for (Iterator oldRows = oldSet.iterator(); oldRows.hasNext();) {
 			this.addRow((RdfBindingRow) oldRows.next());
 		}
+		setDistinct(oldSet.isDistinct());
+		setOrdered(oldSet.isOrdered());
 	}
 
 	/**
@@ -141,11 +143,10 @@
 		if (row == null) {
 			throw new NullPointerException("RdfBindingRow 'row' cannot be null");
 		}
-		List newValues = new ArrayList();
-		for (int i = 0; i < this.variables.length; i++) {
-			newValues.add(row.getValue(this.variables[i]));
-		}
-		this.values.add(newValues.toArray(new Value[0]));
+		Value[] newValues = new Value[this.variables.length];
+		for (int i = 0; i < this.variables.length; i++)
+			newValues[i] = row.getValue(this.variables[i]);
+		this.values.add(newValues);
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/impl/VariableImpl.java work-copy/src/main/name/levering/ryan/sparql/common/impl/VariableImpl.java
--- work-copy/src/main/name/levering/ryan/sparql/common/impl/VariableImpl.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/impl/VariableImpl.java	2008-02-09 10:17:15.000000000 -0500
@@ -77,4 +77,9 @@
 		return bindings.getValue(this);
 	}
 
+	public java.util.Set getVariables() {
+		java.util.HashSet ret = new java.util.HashSet();
+		ret.add(this);
+		return ret;
+	}
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/RdfSource.java work-copy/src/main/name/levering/ryan/sparql/common/RdfSource.java
--- work-copy/src/main/name/levering/ryan/sparql/common/RdfSource.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/RdfSource.java	2008-08-13 16:17:09.000000000 -0400
@@ -19,8 +19,10 @@
 public interface RdfSource {
 
     /**
-     * Gets all statements with a specific subject, predicate and/or object. All
-     * three parameters may be null to indicate wildcards.
+     * Gets all statements with a specific subject, predicate and/or object, within
+     * a certain set of graphs. The graphs might be from FROM or FROM NAMED clauses.
+     * subj, pred, and obj, and graph may be null. If graph is null, both FROM and
+     * FROM NAMED graphs may match.
      * 
      * @param subj subject of pattern
      * @param pred predicate of pattern
@@ -28,7 +30,7 @@
      * @param graph the context with which to match the statements against
      * @return iterator over statements
      */
-    public Iterator getStatements(Value subj, URI pred, Value obj, URI graph);
+    public Iterator getStatements(Value subj, URI pred, Value obj, URI[] graph);
 
     /**
      * Gets all statements with a specific subject, predicate and/or object in
@@ -41,57 +43,56 @@
      * @param obj object of pattern
      * @return iterator over statements
      */
-    public Iterator getDefaultStatements(Value subj, URI pred, Value obj);
+    public Iterator getDefaultGraphStatements(Value subj, URI pred, Value obj);
 
     /**
-     * Gets all the statements, regardless of graph context, with a specific
-     * subject, predicate and/or object in the default graph of the repository.
-     * All three parameters may be null to indicate wildcards.
+     * Gets all statements with a specific subject, predicate and/or object in
+     * a named graph of the repository. All three parameters may be null to
+     * indicate wildcards. This is only used in SPARQL queries when no graph     * names are indicated.
      * 
      * @param subj subject of pattern
      * @param pred predicate of pattern
      * @param obj object of pattern
      * @return iterator over statements
      */
-    public Iterator getStatements(Value subj, URI pred, Value obj);
+    public Iterator getNamedGraphStatements(Value subj, URI pred, Value obj);
 
     /**
-     * Checks whether some statement with a specific subject, predicate and/or
-     * object is present in the default graph of the repository. All three
-     * parameters may be null to indicate wildcards. This is only used in SPARQL
-     * queries when no graph names are indicated.
+     * Checks whether the statement exist with a specific subject, predicate and/or object, within
+     * a certain set of graphs. The graphs might be from FROM or FROM NAMED clauses.
+     * subj, pred, and obj may not be null.
      * 
-     * @param subj subject of statement
-     * @param pred predicate of statement
-     * @param obj object of statement
-     * @return boolean indicating if specified statement is present
+     * @param subj subject of pattern
+     * @param pred predicate of pattern
+     * @param obj object of pattern
+     * @param graph the context with which to match the statements against
+     * @return iterator over statements
      */
-    public boolean hasDefaultStatement(Value subj, URI pred, Value obj);
+    public boolean hasStatement(Value subj, URI pred, Value obj, URI[] graph);
 
     /**
-     * Checks whether some statement with a specific subject, predicate and/or
-     * object is present in any graph of the repository. All three parameters
-     * may be null to indicate wildcards.
+     * Checks whether the statement exists with a specific subject, predicate and/or object in
+     * the default graph of the repository. No parameters may be null.
+     * This is only used in SPARQL queries when no graph names are indicated.
      * 
-     * @param subj subject of statement
-     * @param pred predicate of statement
-     * @param obj object of statement
-     * @return boolean indicating if specified statement is present
+     * @param subj subject of pattern
+     * @param pred predicate of pattern
+     * @param obj object of pattern
+     * @return iterator over statements
      */
-    public boolean hasStatement(Value subj, URI pred, Value obj);
+    public boolean hasDefaultGraphStatement(Value subj, URI pred, Value obj);
 
     /**
-     * Checks whether some statement with a specific subject, predicate and/or
-     * object is present in the repository. All three parameters may be null to
-     * indicate wildcards.
+     * Checks whether the statement exists with a specific subject, predicate and/or object in
+     * a named graph of the repository. No parameters may be null.
+     * This is only used in SPARQL queries when no graph names are indicated.
      * 
-     * @param subj subject of statement
-     * @param pred predicate of statement
-     * @param obj object of statement
-     * @param graph the context to match the statements against
-     * @return boolean indicating if specified statement is present
+     * @param subj subject of pattern
+     * @param pred predicate of pattern
+     * @param obj object of pattern
+     * @return iterator over statements
      */
-    public boolean hasStatement(Value subj, URI pred, Value obj, URI graph);
+    public boolean hasNamedGraphStatement(Value subj, URI pred, Value obj);
 
     /**
      * This useful method returns a value factory that is actually used by the
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/SPARQLConstants.java work-copy/src/main/name/levering/ryan/sparql/common/SPARQLConstants.java
--- work-copy/src/main/name/levering/ryan/sparql/common/SPARQLConstants.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/SPARQLConstants.java	2008-03-06 07:55:03.000000000 -0500
@@ -26,42 +26,121 @@
 	public static final URI TYPE = initFactory.createURI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
 	
     /**
-     * The datatype for double precision numerals.
+     * The URI for xsd:duration.
      */
-    public static final URI DOUBLE_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#double");
+    public static final URI DURATION_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#duration");
 
     /**
-     * The datatype for a smaller precision decimal numeral.
+     * The URI for xsd:dateTime.
      */
-    public static final URI INTEGER_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#integer");
+    public static final URI DATETIME_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#dateTime");
+
+    /**
+    /**
+     * The URI for xsd:time.
+     */
+    public static final URI TIME_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#time");
 
     /**
-     * The datatype for the decimal type numeral, which is a generic
-     * non-fractional number.
+     * The URI for xsd:date.
      */
-    public static final URI DECIMAL_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#decimal");
+    public static final URI DATE_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#date");
+
+    /**
+     * The datatype for a true/false value.
+     */
+    public static final URI BOOLEAN_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#boolean");
 
     /**
      * The datatype for a single precision numeral.
      */
     public static final URI FLOAT_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#float");
 
-    /**
-     * The datatype for a date/time representation, represented according to
-     * ISO-8601.
+	/*
+     * The URI for xsd:double.
      */
-    public static final URI DATE_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#dateTime");
+    public static final URI DOUBLE_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#double");
+
+	/*
+     * The URI for xsd:anyURI.
+     */
+    public static final URI ANYURI_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#anyURI");
 
     /**
-     * The datatype for a string representation, which is a general sequence of
+     * The XSD datatype for a string representation, which is a general sequence of
      * UNICODE or ASCII characters.
      */
     public static final URI STRING_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#string");
 
     /**
-     * The datatype for a true/false value.
+     * xsd:decimal
      */
-    public static final URI BOOLEAN_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#boolean");
+    public static final URI DECIMAL_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#decimal");
+
+    /**
+     * xsd:integer
+     */
+    public static final URI INTEGER_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#integer");
+
+    /**
+     * xsd:nonPositiveInteger
+     */
+    public static final URI NONPOSITIVEINTEGER_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#nonPositiveInteger");
+
+    /**
+     * xsd:negativeInteger
+     */
+    public static final URI NEGATIVEINTEGER_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#negativeInteger");
+
+    /**
+     * The datatype for a higher precision decimal numeral.
+     */
+    public static final URI LONG_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#long");
+
+    /**
+     * The datatype for a smaller precision decimal numeral.
+     */
+    public static final URI INT_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#int");
+
+    /**
+     * The datatype for an even smaller precision decimal numeral.
+     */
+    public static final URI SHORT_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#short");
+
+    /**
+     * The datatype for an even smaller precision decimal numeral.
+     */
+    public static final URI BYTE_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#byte");
+
+    /**
+     * xsd:nonNegativeInteger
+     */
+    public static final URI NONNEGATIVEINTEGER_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#nonNegativeInteger");
+
+    /**
+     * xsd:positiveInteger
+     */
+    public static final URI POSITIVEINTEGER_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#positiveInteger");
+
+    /**
+     * The datatype for a higher precision decimal numeral.
+     */
+    public static final URI UNSIGNEDLONG_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#unsignedLong");
+
+    /**
+     * The datatype for a smaller precision decimal numeral.
+     */
+    public static final URI UNSIGNEDINT_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#unsignedInt");
+
+    /**
+     * The datatype for an even smaller precision decimal numeral.
+     */
+    public static final URI UNSIGNEDSHORT_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#unsignedShort");
+
+    /**
+     * The datatype for an even smaller precision decimal numeral.
+     */
+    public static final URI UNSIGNEDBYTE_TYPE = initFactory.createURI("http://www.w3.org/2001/XMLSchema#unsignedByte");
 
     /**
      * The datatype specifically for RDF data, that represents an URI in an RDF triple. 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/common/URI.java work-copy/src/main/name/levering/ryan/sparql/common/URI.java
--- work-copy/src/main/name/levering/ryan/sparql/common/URI.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/common/URI.java	2007-10-21 12:35:15.000000000 -0400
@@ -3,17 +3,10 @@
 public interface URI extends Resource {
 	
 	/**
-	 * Gets the namespace of this URI.
+	 * Gets the URI of this URI.
 	 *
-	 * @return The URI's namespace.
+	 * @return The URI as a string.
 	 **/
-	public String getNamespace();
-
-	/**
-	 * Gets the local name of this URI.
-	 *
-	 * @return The URI's local name.
-	 **/
-	public String getLocalName();
+	public String getURI();
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/FunctionalPredicateLogic.java work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/FunctionalPredicateLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/FunctionalPredicateLogic.java	2006-08-20 20:00:59.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/FunctionalPredicateLogic.java	2008-08-13 16:14:08.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.extensions.fpredicates;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -35,16 +36,11 @@
 	 * Delegates to the function to return a binding set based on the source and
 	 * the subject and object of the functional predicate statement.
 	 * 
-	 * @param bindings the current bindings, ignored
-	 * @param source the RDF source to pass to the function
-	 * @param defaultDatasets the default named graphs, ignored
-	 * @param namedDatasets the named graphs, ignored
 	 * @return a binding set according to the function
 	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
 		
-		return this.function.getBindingSet(this.data.getSubjectExpression(), this.data.getObjectExpression(), source);
+		return this.function.getBindingSet(this.data.getSubjectExpression(), this.data.getObjectExpression(), p.source);
 	}
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/ListMemberProperty.java work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/ListMemberProperty.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/ListMemberProperty.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/ListMemberProperty.java	2008-08-13 16:17:49.000000000 -0400
@@ -65,14 +65,14 @@
 
 			// Start off with two server queries to cache the members of all
 			// lists and the edges between lists
-			Iterator edgeStatements = source.getStatements(null, SPARQLConstants.LIST_REST, null); // list
+			Iterator edgeStatements = source.getStatements(null, SPARQLConstants.LIST_REST, null, null); // list
 			// edges
 			while (edgeStatements.hasNext()) {
 				Statement statement = (Statement) edgeStatements.next();
 				edgeCache.put(statement.getSubject(), statement.getObject());
 			}
 
-			Iterator memberStatements = source.getStatements(null, SPARQLConstants.LIST_FIRST, null); // list
+			Iterator memberStatements = source.getStatements(null, SPARQLConstants.LIST_FIRST, null, null); // list
 			// members
 			while (memberStatements.hasNext()) {
 				Statement statement = (Statement) memberStatements.next();
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/RdfsMemberProperty.java work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/RdfsMemberProperty.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/RdfsMemberProperty.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/fpredicates/RdfsMemberProperty.java	2008-08-13 16:44:25.000000000 -0400
@@ -83,7 +83,7 @@
 				objVar = (Value) this.objExpression;
 			}
 
-			return new RdfsMemberIterator(this.source.getStatements(subjVar, null, objVar));
+			return new RdfsMemberIterator(this.source.getStatements(subjVar, null, objVar, null));
 		}
 
 		/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/CountFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/CountFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/CountFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/CountFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -65,7 +65,7 @@
 			counter = set.size();
 			this.countCache.put(set, new Integer(counter));
 		}
-		return this.converter.convertInteger(counter);
+		return this.converter.convertInteger(java.math.BigInteger.valueOf(counter));
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMaxFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMaxFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMaxFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMaxFunction.java	2007-10-21 12:35:16.000000000 -0400
@@ -128,7 +128,7 @@
 		return new ExternalFunctionFactory() {
 
 			public ExternalFunction create(LogicFactory logicFactory, SPARQLValueFactory valueFactory) {
-				return new IsMaxFunction(logicFactory.getValueOrderingLogic());
+				return new IsMaxFunction(logicFactory.getValueOrderingLogic(valueFactory));
 			}
 
 		};
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMinFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMinFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMinFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/IsMinFunction.java	2007-10-21 12:35:16.000000000 -0400
@@ -126,7 +126,7 @@
 		return new ExternalFunctionFactory() {
 
 			public ExternalFunction create(LogicFactory logicFactory, SPARQLValueFactory valueFactory) {
-				return new IsMinFunction(logicFactory.getValueOrderingLogic());
+				return new IsMinFunction(logicFactory.getValueOrderingLogic(valueFactory));
 			}
 
 		};
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MaxFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MaxFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MaxFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MaxFunction.java	2007-10-21 12:35:16.000000000 -0400
@@ -121,7 +121,7 @@
 		return new ExternalFunctionFactory() {
 
 			public ExternalFunction create(LogicFactory logicFactory, SPARQLValueFactory valueFactory) {
-				return new MaxFunction(logicFactory.getValueOrderingLogic());
+				return new MaxFunction(logicFactory.getValueOrderingLogic(valueFactory));
 			}
 
 		};
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MinFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MinFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MinFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/aggregate/MinFunction.java	2007-10-21 12:35:16.000000000 -0400
@@ -121,7 +121,7 @@
 		return new ExternalFunctionFactory() {
 
 			public ExternalFunction create(LogicFactory logicFactory, SPARQLValueFactory valueFactory) {
-				return new MinFunction(logicFactory.getValueOrderingLogic());
+				return new MinFunction(logicFactory.getValueOrderingLogic(valueFactory));
 			}
 
 		};
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddDayFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddDayFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddDayFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddDayFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -51,7 +51,7 @@
 			throw new ExternalFunctionException("Values need to be literals to be understood");
 		}
 
-		int number = this.converter.convertInteger((Literal) daysToAdd);
+		int number = this.converter.convertInteger((Literal) daysToAdd).intValue();
 		DateTime date = this.converter.convertDateTime((Literal) origDate);
 
 		Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth() - 1, date.getDay(), date.getHour(), date
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddHourFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddHourFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddHourFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddHourFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -52,7 +52,7 @@
                     "Values need to be literals to be understood");
         }
 
-        int number = this.converter.convertInteger((Literal) hoursToAdd);
+        int number = this.converter.convertInteger((Literal) hoursToAdd).intValue();
         DateTime date = this.converter.convertDateTime((Literal) origDate);
 
         Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth() - 1, date.getDay(), date.getHour(), date.getMinute(), date.getSecond());
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMinuteFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMinuteFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMinuteFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMinuteFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -52,7 +52,7 @@
                     "Values need to be literals to be understood");
         }
 
-        int number = this.converter.convertInteger((Literal) minutesToAdd);
+        int number = this.converter.convertInteger((Literal) minutesToAdd).intValue();
         DateTime date = this.converter.convertDateTime((Literal) origDate);
 
         Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth() - 1, date.getDay(), date.getHour(), date.getMinute(), date.getSecond());
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMonthFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMonthFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMonthFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddMonthFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -52,7 +52,7 @@
                     "Values need to be literals to be understood");
         }
 
-        int number = this.converter.convertInteger((Literal) monthsToAdd);
+        int number = this.converter.convertInteger((Literal) monthsToAdd).intValue();
         DateTime date = this.converter.convertDateTime((Literal) origDate);
 
         Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth() - 1, date.getDay(), date.getHour(), date.getMinute(), date.getSecond());
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddSecondFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddSecondFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddSecondFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddSecondFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -52,7 +52,7 @@
                     "Values need to be literals to be understood");
         }
 
-        int number = this.converter.convertInteger((Literal) secondsToAdd);
+        int number = this.converter.convertInteger((Literal) secondsToAdd).intValue();
         DateTime date = this.converter.convertDateTime((Literal) origDate);
 
         Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth() - 1, date.getDay(), date.getHour(), date.getMinute(), date.getSecond());
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddYearFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddYearFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddYearFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/AddYearFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -52,7 +52,7 @@
                     "Values need to be literals to be understood");
         }
 
-        int number = this.converter.convertInteger((Literal) yearsToAdd);
+        int number = this.converter.convertInteger((Literal) yearsToAdd).intValue();
         DateTime date = this.converter.convertDateTime((Literal) origDate);
 
         Calendar cal = new GregorianCalendar(date.getYear(), date.getMonth() - 1, date.getDay(), date.getHour(), date.getMinute(), date.getSecond());
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/DayFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/DayFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/DayFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/DayFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -49,7 +49,7 @@
 
 		DateTime date = this.converter.convertDateTime((Literal) value);
 
-		return this.converter.convertInteger(date.getDay());
+		return this.converter.convertInteger(java.math.BigInteger.valueOf(date.getDay()));
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/HourFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/HourFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/HourFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/HourFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -49,7 +49,7 @@
         
         DateTime date = this.converter.convertDateTime((Literal) value);
         
-        return this.converter.convertInteger(date.getHour());
+        return this.converter.convertInteger(java.math.BigInteger.valueOf(date.getHour()));
     }
     
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MinuteFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MinuteFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MinuteFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MinuteFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -49,7 +49,7 @@
         
         DateTime date = this.converter.convertDateTime((Literal) value);
         
-        return this.converter.convertInteger(date.getMinute());
+        return this.converter.convertInteger(java.math.BigInteger.valueOf(date.getMinute()));
     }
     
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MonthFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MonthFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MonthFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/MonthFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -49,7 +49,7 @@
         
         DateTime date = this.converter.convertDateTime((Literal) value);
         
-        return this.converter.convertInteger(date.getMonth());
+        return this.converter.convertInteger(java.math.BigInteger.valueOf(date.getMonth()));
     }
     
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/SecondFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/SecondFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/SecondFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/SecondFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -49,7 +49,7 @@
         
         DateTime date = this.converter.convertDateTime((Literal) value);
         
-        return this.converter.convertInteger(date.getSecond());
+        return this.converter.convertInteger(java.math.BigInteger.valueOf(date.getSecond()));
     }
     
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/YearFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/YearFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/YearFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/datetime/YearFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -49,7 +49,7 @@
 
 		DateTime date = this.converter.convertDateTime((Literal) value);
 
-		return this.converter.convertInteger(date.getYear());
+		return this.converter.convertInteger(java.math.BigInteger.valueOf(date.getYear()));
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/LengthFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/LengthFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/LengthFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/LengthFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -48,7 +48,7 @@
 
 		String string = this.converter.convertString((Literal) stringValue);
 
-		return this.converter.convertInteger(string.length());
+		return this.converter.convertInteger(java.math.BigInteger.valueOf(string.length()));
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/SubstringFunction.java work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/SubstringFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/SubstringFunction.java	2007-10-07 07:19:16.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/functions/string/SubstringFunction.java	2008-07-11 15:28:33.000000000 -0400
@@ -48,7 +48,7 @@
 		}
 
 		String string = this.converter.convertString((Literal) stringValue);
-		int start = this.converter.convertInteger((Literal) startIndex);
+		int start = this.converter.convertInteger((Literal) startIndex).intValue();
 
 		return this.converter.convertString(string.substring(start));
 	}
@@ -72,8 +72,8 @@
 		}
 
 		String string = this.converter.convertString((Literal) stringValue);
-		int start = this.converter.convertInteger((Literal) startIndex);
-		int chars = this.converter.convertInteger((Literal) length);
+		int start = this.converter.convertInteger((Literal) startIndex).intValue();
+		int chars = this.converter.convertInteger((Literal) length).intValue();
 
 		return this.converter.convertString(string.substring(start, start + chars));
 	}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/extensions/with/DefaultWithConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/extensions/with/DefaultWithConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/extensions/with/DefaultWithConstraintLogic.java	2006-08-20 20:00:59.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/extensions/with/DefaultWithConstraintLogic.java	2008-08-13 16:14:32.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.extensions.with;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -37,16 +38,11 @@
 	 * Ignores the inputs and just lets the extension return a binding set to be
 	 * intersected with the current running set.
 	 * 
-	 * @param bindings the current bindings, ignored
-	 * @param source the source to query against, passed to the WITH extension
-	 * @param defaultDatasets the default data sets to query against, ignored
-	 * @param namedDatasets the named data sets to query against, ignored
 	 * @return the binding set created by the extension
 	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
 		return this.extension.getBindingSet((ExpressionLogic[]) this.data.getArguments().toArray(
-				new ExpressionLogic[] {}), source);
+				new ExpressionLogic[] {}), p.source);
 	}
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/BaseLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/BaseLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/BaseLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/BaseLogic.java	2008-02-09 10:18:23.000000000 -0500
@@ -25,7 +25,6 @@
 import name.levering.ryan.sparql.logic.function.LangLogic;
 import name.levering.ryan.sparql.logic.function.LangMatchesLogic;
 import name.levering.ryan.sparql.logic.function.RegexLogic;
-import name.levering.ryan.sparql.logic.function.SameTermLogic;
 import name.levering.ryan.sparql.logic.function.StrLogic;
 import name.levering.ryan.sparql.model.data.BinaryExpressionData;
 import name.levering.ryan.sparql.model.data.CallExpressionData;
@@ -90,16 +89,6 @@
 	}
 
 	/**
-	 * Gets the default variables evaluation logic.
-	 * 
-	 * @param data the variable the logic is evaluating
-	 * @return the logic handling the variable evaluation
-	 */
-	public ExpressionLogic getVariableLogic(Variable data) {
-		return new DefaultVariableLogic(data);
-	}
-
-	/**
 	 * Gets the default division logic.
 	 * 
 	 * @param data the binary data containing the expressions to divide
@@ -279,17 +268,6 @@
 	}
 
 	/**
-	 * Gets the default 'sameTerm' function logic.
-	 * 
-	 * @param data the function data containing arguments passed to the
-	 *            langMatches function
-	 * @return the logic handling the langMatches function
-	 */
-	public ExpressionLogic getSameTermLogic(CallExpressionData data, SPARQLValueFactory valueFactory) {
-		return new SameTermLogic(data, getValueConversionLogic(valueFactory));
-	}
-
-	/**
 	 * Gets the default 'regex' function logic.
 	 * 
 	 * @param data the function data containing arguments passed to the regex
@@ -357,8 +335,8 @@
 	 * 
 	 * @return the logic that orders Value objects
 	 */
-	public ValueOrderingLogic getValueOrderingLogic() {
-		return new DefaultValueOrderingLogic();
+	public ValueOrderingLogic getValueOrderingLogic(SPARQLValueFactory valueFactory) {
+		return new DefaultValueOrderingLogic(getNumericPromotionLogic(valueFactory), getValueConversionLogic(valueFactory));
 	}
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/BNodeRenamingConstructQueryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/BNodeRenamingConstructQueryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/BNodeRenamingConstructQueryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/BNodeRenamingConstructQueryLogic.java	2008-08-13 14:57:43.000000000 -0400
@@ -22,6 +22,7 @@
 import name.levering.ryan.sparql.model.GroupConstraint;
 import name.levering.ryan.sparql.model.TripleConstraint;
 import name.levering.ryan.sparql.model.data.ConstructQueryData;
+import name.levering.ryan.sparql.model.logic.ConstraintLogic;
 import name.levering.ryan.sparql.model.logic.ConstructQueryLogic;
 import name.levering.ryan.sparql.model.logic.OrderExpressionLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetRangeLogic;
@@ -85,31 +86,21 @@
 	 * @return an RDF graph containing the formed triples
 	 */
 	public RdfGraph execute(RdfSource source) {
+		ConstraintLogic.CallParams p = new ConstraintLogic.CallParams();
+		p.bindings = new RdfBindingSetImpl();
+		p.source = source;
+		
 		// Grab the necessary fields from the data
 		GroupConstraint constraint = this.data.getConstraint();
-		Collection defaultDatasets = this.data.getDefaultDatasets();
-		Collection namedDatasets = this.data.getNamedDatasets();
-		List orderExpressions = this.data.getOrderExpressions();
-		int limit = this.data.getLimit();
-		int offset = this.data.getOffset();
+		p.defaultDatasets = this.data.getDefaultDatasets();
+		p.namedDatasets = this.data.getNamedDatasets();
+		p.orderExpressions = this.data.getOrderExpressions();
+		p.limit = this.data.getLimit();
+		p.offset = this.data.getOffset();
+		p.rangeLogic = this.rangeLogic;
 
 		// First bind the result table
-		RdfBindingSet results = constraint.constrain(new RdfBindingSetImpl(), source, defaultDatasets, namedDatasets);
-
-		// Now apply ordering in reverse order to give priority to the first
-		// variable
-		for (int i = orderExpressions.size() - 1; i >= 0; i--) {
-			OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
-			orderer.order(results);
-		}
-
-		// Now apply limiting and offsetting
-		if (limit >= 0) {
-			results = this.rangeLogic.limit(results, limit);
-		}
-		if (offset >= 0) {
-			results = this.rangeLogic.offset(results, offset);
-		}
+		RdfBindingSet results = constraint.constrain(p);
 
 		// Now apply the solutions to the template
 		RdfGraphImpl graph = new RdfGraphImpl();
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/DebugLogicWrapper.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/DebugLogicWrapper.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/DebugLogicWrapper.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/DebugLogicWrapper.java	2008-07-11 15:31:54.000000000 -0400
@@ -89,8 +89,8 @@
 		return this.baseFactory.getDatatypeLogic(data);
 	}
 
-	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data) {
-		return this.baseFactory.getDescribeQueryLogic(data);
+	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data, SPARQLValueFactory valueFactory) {
+		return this.baseFactory.getDescribeQueryLogic(data, valueFactory);
 	}
 
 	public ExpressionLogic getDivisionLogic(BinaryExpressionData data, SPARQLValueFactory valueFactory) {
@@ -145,10 +145,6 @@
 		return this.baseFactory.getLangMatchesLogic(data, valueFactory);
 	}
 
-	public ExpressionLogic getSameTermLogic(CallExpressionData data, SPARQLValueFactory valueFactory) {
-		return this.baseFactory.getSameTermLogic(data, valueFactory);
-	}
-
 	public ExpressionLogic getLTELogic(BinaryExpressionData data, SPARQLValueFactory valueFactory) {
 		return this.baseFactory.getLTELogic(data, valueFactory);
 	}
@@ -177,8 +173,8 @@
 		return new OptionalConstraintDebug(this.baseFactory.getOptionalConstraintLogic(data, valueFactory), this.out);
 	}
 
-	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data) {
-		return this.baseFactory.getOrderExpressionLogic(data);
+	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data, SPARQLValueFactory valueFactory) {
+		return this.baseFactory.getOrderExpressionLogic(data, valueFactory);
 	}
 
 	public ExpressionLogic getOrLogic(BinaryExpressionData data, SPARQLValueFactory valueFactory) {
@@ -209,10 +205,6 @@
 		return new UnionConstraintDebug(this.baseFactory.getUnionConstraintLogic(data), this.out);
 	}
 
-	public ExpressionLogic getVariableLogic(Variable data) {
-		return this.baseFactory.getVariableLogic(data);
-	}
-
 	public ConstraintLogic getWithConstraintLogic(WithConstraintData data) {
 		if (this.baseFactory instanceof ExtendedLogicFactory) {
 			((ExtendedLogicFactory) this.baseFactory).getWithConstraintLogic(data);
@@ -240,8 +232,8 @@
 		return this.baseFactory.getValueConversionLogic(valueFactory);
 	}
 
-	public ValueOrderingLogic getValueOrderingLogic() {
-		return this.baseFactory.getValueOrderingLogic();
+	public ValueOrderingLogic getValueOrderingLogic(SPARQLValueFactory valueFactory) {
+		return this.baseFactory.getValueOrderingLogic(valueFactory);
 	}
 
 	public ConstructQueryLogic getConstructQueryLogic(ExtendedConstructQueryData data, SPARQLValueFactory valueFactory) {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/FilterConstraintDebug.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/FilterConstraintDebug.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/FilterConstraintDebug.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/FilterConstraintDebug.java	2007-10-21 12:35:15.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.logic.debug;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -19,11 +20,10 @@
 		this.out = listener;
 	}
 	
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
-        this.out.filterConstraintPreExecute(this.data, bindings);
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        this.out.filterConstraintPreExecute(this.data, p.bindings);
         long start = System.currentTimeMillis();
-        RdfBindingSet returnSet = this.filterLogic.constrain(bindings, source, defaultDatasets, namedDatasets);
+        RdfBindingSet returnSet = this.filterLogic.constrain(p);
         long end = System.currentTimeMillis();
         this.out.filterConstraintPostExecute(end-start, returnSet);
         return returnSet;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/GraphConstraintDebug.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/GraphConstraintDebug.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/GraphConstraintDebug.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/GraphConstraintDebug.java	2007-10-21 12:35:15.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.logic.debug;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -16,11 +17,10 @@
 		this.out = listener;
 	}
 
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
         this.out.graphConstraintPreExecute();
         long start = System.currentTimeMillis();
-        RdfBindingSet returnSet = this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+        RdfBindingSet returnSet = this.logic.constrain(p);
         long end = System.currentTimeMillis();
         this.out.graphConstraintPostExecute(end-start, returnSet);
         return returnSet;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/GroupConstraintDebug.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/GroupConstraintDebug.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/GroupConstraintDebug.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/GroupConstraintDebug.java	2007-10-21 12:35:15.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.logic.debug;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -16,11 +17,10 @@
 		this.out = listener;
 	}
 
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
         this.out.groupConstraintPreExecute();
         long start = System.currentTimeMillis();
-        RdfBindingSet returnSet = this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+        RdfBindingSet returnSet = this.logic.constrain(p);
         long end = System.currentTimeMillis();
         this.out.groupConstraintPostExecute(end-start, returnSet);
         return returnSet;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/OptionalConstraintDebug.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/OptionalConstraintDebug.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/OptionalConstraintDebug.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/OptionalConstraintDebug.java	2007-10-21 12:35:15.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.logic.debug;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -16,11 +17,10 @@
 		this.out = listener;
 	}
 
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
         this.out.optionalConstraintPreExecute();
         long start = System.currentTimeMillis();
-        RdfBindingSet returnSet = this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+        RdfBindingSet returnSet = this.logic.constrain(p);
         long end = System.currentTimeMillis();
         this.out.optionalConstraintPostExecute(end-start, returnSet);
         return returnSet;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/TripleConstraintDebug.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/TripleConstraintDebug.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/TripleConstraintDebug.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/TripleConstraintDebug.java	2007-10-21 12:35:15.000000000 -0400
@@ -6,6 +6,7 @@
 package name.levering.ryan.sparql.logic.debug;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -24,11 +25,10 @@
         this.out = listener;
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source,
-            Collection defaultDatasets, Collection namedDatasets) {
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
         this.out.tripleFetchPreExecute(this.data);
         long start = System.currentTimeMillis();
-        RdfBindingSet returnSet = this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+        RdfBindingSet returnSet = this.logic.constrain(p);
         long end = System.currentTimeMillis();
         this.out.tripleFetchPostExecute(end-start, returnSet);
         return returnSet;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/debug/UnionConstraintDebug.java work-copy/src/main/name/levering/ryan/sparql/logic/debug/UnionConstraintDebug.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/debug/UnionConstraintDebug.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/debug/UnionConstraintDebug.java	2007-10-21 12:35:15.000000000 -0400
@@ -1,6 +1,7 @@
 package name.levering.ryan.sparql.logic.debug;
 
 import java.util.Collection;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -16,11 +17,10 @@
 		this.out = listener;
 	}
 
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
         this.out.unionConstrainPreExecute();
         long start = System.currentTimeMillis();
-        RdfBindingSet returnSet = this.unionLogic.constrain(bindings, source, defaultDatasets, namedDatasets);
+        RdfBindingSet returnSet = this.unionLogic.constrain(p);
         long end = System.currentTimeMillis();
         this.out.unionConstraintPostExecute(end-start, returnSet);
         return returnSet;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultAskQueryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultAskQueryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultAskQueryLogic.java	2006-08-20 20:01:01.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultAskQueryLogic.java	2008-02-10 07:52:12.000000000 -0500
@@ -13,6 +13,8 @@
 import name.levering.ryan.sparql.model.GroupConstraint;
 import name.levering.ryan.sparql.model.data.AskQueryData;
 import name.levering.ryan.sparql.model.logic.AskQueryLogic;
+import name.levering.ryan.sparql.model.logic.ConstraintLogic;
+import name.levering.ryan.sparql.model.logic.helper.SetRangeLogic;
 
 /**
  * This is the simplest query logic in SPARQL, as it doesn't have to deal with
@@ -29,6 +31,8 @@
      * The data to delegate the data requests to.
      */
     private final AskQueryData data;
+    
+    private final SetRangeLogic rangeLogic;
 
     /**
      * Creates a new object that handles the logic of the ask query, delegating
@@ -36,8 +40,9 @@
      * 
      * @param data the ask query data object delegate
      */
-    public DefaultAskQueryLogic(AskQueryData data) {
+    public DefaultAskQueryLogic(AskQueryData data, SetRangeLogic rangeLogic) {
         this.data = data;
+        this.rangeLogic = rangeLogic;
     }
 
     /**
@@ -48,14 +53,19 @@
      * @return true if the delegated query data binds any value rows
      */
     public boolean execute(RdfSource source) {
-        // Grab the necessary fields from the data
+		  ConstraintLogic.CallParams p = new ConstraintLogic.CallParams();
+		  p.bindings = new RdfBindingSetImpl();
+		  p.source = source;
+
+		  // Grab the necessary fields from the data
         GroupConstraint constraint = this.data.getConstraint();
-        Collection defaultDatasets = this.data.getDefaultDatasets();
-        Collection namedDatasets = this.data.getNamedDatasets();
+        p.defaultDatasets = this.data.getDefaultDatasets();
+        p.namedDatasets = this.data.getNamedDatasets();
+        p.limit = 1;
+        p.rangeLogic = rangeLogic;
 
         // First bind the result table
-        RdfBindingSet results = constraint.constrain(new RdfBindingSetImpl(),
-                source, defaultDatasets, namedDatasets);
+        RdfBindingSet results = constraint.constrain(p);
 
         // Return whether or not the iterator returns any rows
         return results.iterator().hasNext();
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultConstructQueryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultConstructQueryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultConstructQueryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultConstructQueryLogic.java	2008-02-05 08:36:55.000000000 -0500
@@ -6,19 +6,32 @@
 package name.levering.ryan.sparql.logic;
 
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
+import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfGraph;
 import name.levering.ryan.sparql.common.RdfSource;
 import name.levering.ryan.sparql.common.impl.RdfBindingSetImpl;
+import name.levering.ryan.sparql.common.impl.RdfGraphImpl;
+import name.levering.ryan.sparql.common.impl.StatementImpl;
 import name.levering.ryan.sparql.model.GroupConstraint;
+import name.levering.ryan.sparql.model.TripleConstraint;
 import name.levering.ryan.sparql.model.data.ConstructQueryData;
+import name.levering.ryan.sparql.model.logic.ConstraintLogic;
 import name.levering.ryan.sparql.model.logic.ConstructQueryLogic;
 import name.levering.ryan.sparql.model.logic.OrderExpressionLogic;
 import name.levering.ryan.sparql.model.logic.helper.GraphTranslationLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetRangeLogic;
 
+import name.levering.ryan.sparql.common.BNode;
+import name.levering.ryan.sparql.common.URI;
+import name.levering.ryan.sparql.common.Value;
+import name.levering.ryan.sparql.common.BNode;
+
 /**
  * This query logic constructs an RDF graph by applying an RDF template to a set
  * of value bindings. It must first bind the variables values, then apply
@@ -67,33 +80,23 @@
      * @return an RDF graph containing the formed triples
      */
     public RdfGraph execute(RdfSource source) {
+		  ConstraintLogic.CallParams p = new ConstraintLogic.CallParams();
+		  p.bindings = new RdfBindingSetImpl();
+		  p.source = source;
+		
         // Grab the necessary fields from the data
         GroupConstraint constraint = this.data.getConstraint();
-        Collection defaultDatasets = this.data.getDefaultDatasets();
-        Collection namedDatasets = this.data.getNamedDatasets();
-        List orderExpressions = this.data.getOrderExpressions();
-        int limit = this.data.getLimit();
-        int offset = this.data.getOffset();
-
+        p.defaultDatasets = this.data.getDefaultDatasets();
+        p.namedDatasets = this.data.getNamedDatasets();
+        p.orderExpressions = this.data.getOrderExpressions();
+        p.limit = this.data.getLimit();
+        p.offset = this.data.getOffset();
+		  p.rangeLogic = this.rangeLogic;
+		  
         // First bind the result table
-        RdfBindingSet results = constraint.constrain(new RdfBindingSetImpl(),
-                source, defaultDatasets, namedDatasets);
-
-        // Now apply ordering in reverse order to give priority to the first
-        // variable
-        for (int i = orderExpressions.size() - 1; i >= 0; i--) {
-            OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
-            orderer.order(results);
-        }
-
-        // Now apply limiting and offsetting
-        if (limit >= 0) {
-            results = this.rangeLogic.limit(results, limit);
-        }
-        if (offset >= 0) {
-            results = this.rangeLogic.offset(results, offset);
-        }
+        RdfBindingSet results = constraint.constrain(p);
 
+		  // Then construct the triples output.
         return this.translationLogic.translate(this.data.getTriples(), results);
     }
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultDescribeQueryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultDescribeQueryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultDescribeQueryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultDescribeQueryLogic.java	2008-08-13 16:45:44.000000000 -0400
@@ -7,6 +7,7 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
@@ -19,12 +20,15 @@
 import name.levering.ryan.sparql.common.RdfGraph;
 import name.levering.ryan.sparql.common.RdfSource;
 import name.levering.ryan.sparql.common.Resource;
+import name.levering.ryan.sparql.common.SPARQLValueFactory;
+import name.levering.ryan.sparql.common.URI;
 import name.levering.ryan.sparql.common.Value;
 import name.levering.ryan.sparql.common.Variable;
 import name.levering.ryan.sparql.common.impl.RdfBindingSetImpl;
 import name.levering.ryan.sparql.common.impl.RdfGraphImpl;
 import name.levering.ryan.sparql.model.GroupConstraint;
 import name.levering.ryan.sparql.model.data.DescribeQueryData;
+import name.levering.ryan.sparql.model.logic.ConstraintLogic;
 import name.levering.ryan.sparql.model.logic.DescribeQueryLogic;
 import name.levering.ryan.sparql.model.logic.OrderExpressionLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetProjectionLogic;
@@ -50,12 +54,17 @@
 	 * The logic that projects the binding set to the desired variables for
 	 * construction.
 	 */
-	private final SetProjectionLogic logic;
+	private final SetProjectionLogic projectionLogic;
 
 	/**
 	 * The logic to handle limiting the rows of the binding set results.
 	 */
 	private final SetRangeLogic rangeLogic;
+	
+	/**
+	 * The logic to create resources.
+	 */
+	private final SPARQLValueFactory valueFactory;
 
 	/**
 	 * Creates a new object that handles the logic of the describe query,
@@ -67,10 +76,11 @@
 	 * @param logic the logic to use to project the variables to the desired
 	 *            variables to describe
 	 */
-	public DefaultDescribeQueryLogic(DescribeQueryData data, SetProjectionLogic logic, SetRangeLogic rangeLogic) {
+	public DefaultDescribeQueryLogic(DescribeQueryData data, SetProjectionLogic projectionLogic, SetRangeLogic rangeLogic, SPARQLValueFactory valueFactory) {
 		this.data = data;
-		this.logic = logic;
+		this.projectionLogic = projectionLogic;
 		this.rangeLogic = rangeLogic;
+		this.valueFactory = valueFactory;
 	}
 
 	/**
@@ -82,41 +92,35 @@
 	 * @return an RDF graph containing the formed triples
 	 */
 	public RdfGraph execute(RdfSource source) {
+		ConstraintLogic.CallParams p = new ConstraintLogic.CallParams();
+		p.bindings = new RdfBindingSetImpl();
+		p.source = source;
+		
 		// Grab the necessary fields from the data
 		GroupConstraint constraint = this.data.getConstraint();
-		Collection defaultDatasets = this.data.getDefaultDatasets();
-		Collection namedDatasets = this.data.getNamedDatasets();
-		List orderExpressions = this.data.getOrderExpressions();
+		p.defaultDatasets = this.data.getDefaultDatasets();
+		p.namedDatasets = this.data.getNamedDatasets();
+		p.orderExpressions = this.data.getOrderExpressions();
 		List queryResources = this.data.getQueryResources();
-		int limit = this.data.getLimit();
-		int offset = this.data.getOffset();
-
-		// First bind the result table
-		RdfBindingSet results = constraint.constrain(new RdfBindingSetImpl(), source, defaultDatasets, namedDatasets);
+		p.limit = this.data.getLimit();
+		p.offset = this.data.getOffset();
 
-		// Now project to the solution set
-		List variables = new ArrayList();
+		// Get the distinguished variables.
+		p.distinguishedVariables = new HashSet();
 		for (Iterator i = queryResources.iterator(); i.hasNext();) {
 			Object resource = i.next();
 			if (resource instanceof Variable) {
-				variables.add(resource);
+				p.distinguishedVariables.add(resource);
 			}
 		}
-		results = this.logic.project(results, variables);
-
-		// Now apply ordering in reverse order
-		for (int i = orderExpressions.size(); i >= 0; i--) {
-			OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
-			orderer.order(results);
-		}
+		
+		p.rangeLogic = this.rangeLogic;
+		p.projectionLogic = this.projectionLogic;
 
-		// Now apply limiting and offsetting
-		if (limit >= 0) {
-			results = this.rangeLogic.limit(results, limit);
-		}
-		if (offset >= 0) {
-			results = this.rangeLogic.offset(results, offset);
-		}
+		// First bind the result table
+		RdfBindingSet results = new RdfBindingSetImpl();
+		if (constraint != null)
+			results = constraint.constrain(p);
 
 		// Now find the next level of concrete nodes
 		// For every resource in the solution set
@@ -147,7 +151,7 @@
 		RdfGraphImpl graph = new RdfGraphImpl();
 		for (int i = 0; i < resources.length; i++) {
 			for (Iterator varResources = resources[i].iterator(); varResources.hasNext();) {
-				graph.addTriples(describe((Resource) varResources.next(), source, new HashSet()));
+				graph.addTriples(uniq(describe((Resource) varResources.next(), source, new HashSet(), -1, 0)));
 			}
 		}
 
@@ -163,27 +167,116 @@
 	 * @return all of the statements that give a one-level description of a
 	 *         resource
 	 */
-	private Collection describe(Value value, RdfSource source, Set alreadyDescribed) {
+	private Collection describe(Value value, RdfSource source, Set alreadyDescribed, int direction, int depth) {
 		// First add the current node to the described list
 		alreadyDescribed.add(value);
 
 		// Now accumulate statements
 		Collection descriptions = new ArrayList();
-		Iterator statements = source.getDefaultStatements(value, null, null);
-		while (statements.hasNext()) {
-			LenientStatement statement = (LenientStatement) statements.next();
-
-			// If the statement points to a blank node, recurse and describe
-			// that
-			if (statement.getObject() instanceof BNode) {
-				// Check if we covered the blank node already to prevent loops
-				if (!alreadyDescribed.contains(statement.getObject())) {
-					descriptions.addAll(describe(statement.getObject(), source, alreadyDescribed));
+
+		// do forward, then back links
+		for (int i = 0; i <= 1; i++) {
+			if (direction != -1 && direction != i) continue;
+			
+			Iterator statements;
+			if (i == 0) // forward
+				statements = source.getDefaultGraphStatements(value, null, null);
+			else // back links
+				statements = source.getDefaultGraphStatements(null, null, value);
+				
+			// Accumulate statements and objects by predicate.
+			HashMap statementsByPred = new HashMap();
+			HashMap objectsByPred = new HashMap();
+				
+			while (statements.hasNext()) {
+				LenientStatement statement = (LenientStatement) statements.next();
+				
+				Value predicate = statement.getPredicate();
+				
+				if (!statementsByPred.containsKey(predicate)) {
+					statementsByPred.put(predicate, new ArrayList());
+					objectsByPred.put(predicate, new HashSet());
+				}
+				
+				((ArrayList)statementsByPred.get(predicate)).add(statement);
+				
+				Value object;
+				if (i == 0)
+					object = statement.getObject();
+				else
+					object = statement.getSubject();
+
+				// If the statement points to a blank node or URI, add it to the list objects to describe.
+				if (object instanceof BNode || object instanceof URI) {
+					// Check if we covered the node already to prevent loops
+					if (!alreadyDescribed.contains(object)) {
+						((HashSet)objectsByPred.get(predicate)).add(object);
+					}
+				}
+			}
+			
+			// Don't include predicates for backlinks that have too many statement instances.
+			for (Iterator si = statementsByPred.keySet().iterator(); si.hasNext(); ) {
+				Object predicate = si.next();
+				ArrayList slist = (ArrayList)statementsByPred.get(predicate);
+				if ((i == 0 && slist.size() < (1024>>depth)) || (i == 1 && slist.size() < (512>>depth))) {
+					// Add all of the statements for this predicate.
+					descriptions.addAll(slist);
+					
+					// For each of the nodes on the other end of the statement
+					// that haven't yet been described (checked above), add
+					// descriptions for them too. For BNodes, do it recursively.
+					// But for URIs, just include statements on some common properties.
+					for (Iterator j = ((HashSet)objectsByPred.get(predicate)).iterator(); j.hasNext(); ) {
+						Value v = (Value)j.next();
+						if (v instanceof BNode) {
+							descriptions.addAll(describe(v, source, alreadyDescribed, direction, depth+1));
+						} else {
+							descriptions.addAll(toCollection(source.getDefaultGraphStatements(v, valueFactory.createURI("http://www.w3.org/2000/01/rdf-schema#label"), null)));
+							descriptions.addAll(toCollection(source.getDefaultGraphStatements(v, valueFactory.createURI("http://purl.org/dc/elements/1.1/title"), null)));
+							descriptions.addAll(toCollection(source.getDefaultGraphStatements(v, valueFactory.createURI("http://xmlns.com/foaf/0.1/name"), null)));
+						}
+					}
 				}
 			}
-			descriptions.add(statements.next());
 		}
+		
 		return descriptions;
 	}
 
+	/**
+	 * Makes a collection of statements unique by removing duplicate elements.
+	 * This preserves the order of the list and keeps the first occurrences of elements.
+	 */
+	private Collection uniq(Collection x) {
+		HashSet y = new HashSet();
+		Collection z = new ArrayList();
+		for (Iterator i = x.iterator(); i.hasNext(); ) {
+			LenientStatement a = (LenientStatement)i.next();
+			StatementWrapper w = new StatementWrapper(a);
+			if (y.contains(w)) continue;
+			y.add(w);
+			z.add(a);
+		}
+		return z;
+	}
+	
+	private class StatementWrapper {
+		LenientStatement s;
+		public StatementWrapper(LenientStatement s) { this.s = s; }
+		public int hashCode() {
+			return s.getSubject().hashCode() ^ s.getPredicate().hashCode() ^ s.getObject().hashCode();
+		}
+		public boolean equals(Object other) {
+			StatementWrapper t = (StatementWrapper)other;
+			return s.getSubject().equals(t.s.getSubject()) && s.getPredicate().equals(t.s.getPredicate()) && s.getObject().equals(t.s.getObject());
+		}
+	}
+	
+	private ArrayList toCollection(Iterator iter) {
+		ArrayList ret = new ArrayList();
+		while (iter.hasNext())
+			ret.add(iter.next());
+		return ret;
+	}
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultEffectiveBooleanLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultEffectiveBooleanLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultEffectiveBooleanLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultEffectiveBooleanLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -8,6 +8,7 @@
 import name.levering.ryan.sparql.common.SPARQLConstants;
 import name.levering.ryan.sparql.model.logic.helper.EffectiveBooleanLogic;
 import name.levering.ryan.sparql.model.logic.helper.ValueConversionLogic;
+import name.levering.ryan.sparql.logic.expression.TypeError;
 
 import name.levering.ryan.sparql.common.Literal;
 import name.levering.ryan.sparql.common.URI;
@@ -63,6 +64,10 @@
             return SPARQLConstants.FALSE_LITERAL;
         }
 
+			if (!(value instanceof Literal)) {
+				throw new TypeError("The value " + value + " cannot be used in some evaluated expression because it cannot be coerced to a boolean value");
+			}
+			
         Literal litValue = (Literal) value;
         URI datatype = litValue.getDatatype();
 
@@ -104,15 +109,15 @@
         }
 
         if (datatype.equals(SPARQLConstants.INTEGER_TYPE)) {
-            int java = this.converter.convertInteger(litValue);
-            if (java == 0) {
+            java.math.BigInteger v = this.converter.convertInteger(litValue);
+            if (v.equals(java.math.BigInteger.ZERO)) {
                 return SPARQLConstants.FALSE_LITERAL;
             }
         }
 
         if (datatype.equals(SPARQLConstants.DECIMAL_TYPE)) {
-            long java = this.converter.convertDecimal(litValue);
-            if (java == 0) {
+            java.math.BigDecimal v = this.converter.convertDecimal(litValue);
+            if (v.equals(java.math.BigDecimal.ZERO)) {
                 return SPARQLConstants.FALSE_LITERAL;
             }
         }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultGraphTranslationLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultGraphTranslationLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultGraphTranslationLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultGraphTranslationLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -5,18 +5,20 @@
 import java.util.Iterator;
 import java.util.Map;
 
-import name.levering.ryan.sparql.common.BNode;
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfGraph;
-import name.levering.ryan.sparql.common.SPARQLValueFactory;
-import name.levering.ryan.sparql.common.URI;
-import name.levering.ryan.sparql.common.Value;
 import name.levering.ryan.sparql.common.impl.RdfGraphImpl;
+import name.levering.ryan.sparql.common.SPARQLValueFactory;
 import name.levering.ryan.sparql.common.impl.StatementImpl;
+import name.levering.ryan.sparql.model.TripleConstraint;
 import name.levering.ryan.sparql.model.data.UnboundStatement;
 import name.levering.ryan.sparql.model.logic.helper.GraphTranslationLogic;
 
+import name.levering.ryan.sparql.common.BNode;
+import name.levering.ryan.sparql.common.URI;
+import name.levering.ryan.sparql.common.Value;
+
 public class DefaultGraphTranslationLogic implements GraphTranslationLogic {
 
 	private final SPARQLValueFactory valueFactory;
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultIntersectOrderLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultIntersectOrderLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultIntersectOrderLogic.java	2006-08-20 20:01:01.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultIntersectOrderLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -119,6 +119,7 @@
 						for (int i = 0; i < otherSets.size(); i++) {
 							if (otherSets.get(i) == set || otherSets.get(i) == oldAgg) {
 								otherSets.remove(i);
+								i--;
 							}
 						}
 						// And check to make sure this wasn't a final set, so we
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultNumericPromotionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultNumericPromotionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultNumericPromotionLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultNumericPromotionLogic.java	2008-08-09 17:04:42.000000000 -0400
@@ -56,6 +56,16 @@
 
         URI leftDatatype = leftLiteral.getDatatype();
         URI rightDatatype = rightLiteral.getDatatype();
+		  
+		  if (leftDatatype == null)
+			  leftDatatype = SPARQLConstants.STRING_TYPE;
+		  if (rightDatatype == null)
+			  rightDatatype = SPARQLConstants.STRING_TYPE;
+		  
+		  // Exit fast because if we are dealing with non-numeric types like dateTime,
+		  // we don't want to attempt to promote to a number.
+		  if (leftDatatype.equals(rightDatatype))
+			  return literals;
 
         if (leftDatatype.equals(SPARQLConstants.DOUBLE_TYPE)
                 || rightDatatype.equals(SPARQLConstants.DOUBLE_TYPE)) {
@@ -67,8 +77,14 @@
             return new Literal[] { promoteFloat(leftLiteral),
                     promoteFloat(rightLiteral) };
         }
-        return new Literal[] { promoteDecimal(leftLiteral),
-                promoteDecimal(rightLiteral) };
+
+        if (leftDatatype.equals(SPARQLConstants.DECIMAL_TYPE)
+                || rightDatatype.equals(SPARQLConstants.DECIMAL_TYPE)) {
+            return new Literal[] { promoteDecimal(leftLiteral),
+                    promoteDecimal(rightLiteral) };
+        }
+        return new Literal[] { promoteInteger(leftLiteral),
+                promoteInteger(rightLiteral) };
 
     }
 
@@ -83,7 +99,7 @@
         try {
             result = Double.valueOf(numeral.getLabel());
         } catch (NumberFormatException e) {
-            throw new TypeError("Cannot promote non-numeral to a double value");
+            throw new TypeError("Cannot promote non-numeral (" + numeral.getLabel() + "^^" + numeral.getDatatype() + ") to a double value");
         }
         return this.factory.createLiteral(result.toString(), SPARQLConstants.DOUBLE_TYPE);
     }
@@ -99,7 +115,7 @@
         try {
             result = Float.valueOf(numeral.getLabel());
         } catch (NumberFormatException e) {
-            throw new TypeError("Cannot promote non-numeral to a float value");
+            throw new TypeError("Cannot promote non-numeral (" + numeral.getLabel() + "^^" + numeral.getDatatype() + ") to a float value");
         }
         return this.factory.createLiteral(result.toString(), SPARQLConstants.FLOAT_TYPE);
     }
@@ -111,12 +127,28 @@
      * @return a xsd:double literal with the passed in literals value
      */
     private Literal promoteDecimal(Literal numeral) {
-        Long result;
+        java.math.BigDecimal result;
         try {
-            result = Long.valueOf(numeral.getLabel());
+            result = new java.math.BigDecimal(numeral.getLabel());
         } catch (NumberFormatException e) {
-            throw new TypeError("Cannot promote non-numeral to a decimal value");
+            throw new TypeError("Cannot promote " + numeral.getLabel() + " to a decimal value");
         }
         return this.factory.createLiteral(result.toString(), SPARQLConstants.DECIMAL_TYPE);
     }
+	 
+    /**
+     * Promotes a literal to an integer datatype, reparsing the label.
+     * 
+     * @param numeral the literal to promote to a decimal datatype
+     * @return a xsd:double literal with the passed in literals value
+     */
+    private Literal promoteInteger(Literal numeral) {
+        java.math.BigInteger result;
+        try {
+            result = new java.math.BigInteger(numeral.getLabel());
+        } catch (NumberFormatException e) {
+            throw new TypeError("Cannot promote non-numeral (" + numeral.getLabel() + "^^" + numeral.getDatatype() + ") to an integer value");
+        }
+        return this.factory.createLiteral(result.toString(), SPARQLConstants.INTEGER_TYPE);
+    }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultOrderExpressionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultOrderExpressionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultOrderExpressionLogic.java	2006-08-20 20:01:01.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultOrderExpressionLogic.java	2008-04-27 11:18:16.000000000 -0400
@@ -10,6 +10,7 @@
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -51,6 +52,11 @@
 		this.data = data;
 		this.orderingLogic = orderingLogic;
 	}
+	
+	public Set getVariables() {
+		return this.data.getExpression().getVariables();
+	}
+
 
 	/**
 	 * Orders the binding set, by comparing the Value result of each expression
@@ -67,6 +73,9 @@
 			sortedList.add(row);
 		}
 		Collections.sort(sortedList, new ExpressionComparator(this.data.getExpression()));
+		
+		if (data.getDirection() == OrderExpressionData.DESCENDING)
+			Collections.reverse(sortedList);
 
 		RdfBindingSetImpl newSet = new RdfBindingSetImpl(set.getVariables());
 		newSet.setOrdered(true);
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultSelectQueryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultSelectQueryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultSelectQueryLogic.java	2006-08-20 20:01:01.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultSelectQueryLogic.java	2008-04-27 11:05:53.000000000 -0400
@@ -6,12 +6,14 @@
 package name.levering.ryan.sparql.logic;
 
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.List;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
 import name.levering.ryan.sparql.model.GroupConstraint;
 import name.levering.ryan.sparql.model.data.SelectQueryData;
+import name.levering.ryan.sparql.model.logic.ConstraintLogic;
 import name.levering.ryan.sparql.model.logic.OrderExpressionLogic;
 import name.levering.ryan.sparql.model.logic.SelectQueryLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetDistinctionLogic;
@@ -36,7 +38,7 @@
     /**
      * The logic used to do the set projection onto the result variables.
      */
-    private final SetProjectionLogic logic;
+    private final SetProjectionLogic projectionLogic;
 
     /**
      * The logic to remove duplicates from a set.
@@ -58,9 +60,9 @@
      * @param rangeLogic the logic to use to limit and offset
      */
     public DefaultSelectQueryLogic(SelectQueryData data,
-            SetProjectionLogic logic, SetDistinctionLogic distinctLogic, SetRangeLogic rangeLogic) {
+            SetProjectionLogic projectionLogic, SetDistinctionLogic distinctLogic, SetRangeLogic rangeLogic) {
         this.data = data;
-        this.logic = logic;
+        this.projectionLogic = projectionLogic;
         this.distinctLogic = distinctLogic;
         this.rangeLogic = rangeLogic;
     }
@@ -74,46 +76,30 @@
      * @return an RDF graph containing the formed triples
      */
     public RdfBindingSet execute(RdfSource source) {
+		  ConstraintLogic.CallParams p = new ConstraintLogic.CallParams();
+		  p.source = source;
+		
         // Grab the necessary fields from the data
         GroupConstraint constraint = this.data.getConstraint();
-        Collection defaultDatasets = this.data.getDefaultDatasets();
-        Collection namedDatasets = this.data.getNamedDatasets();
-        List orderExpressions = this.data.getOrderExpressions();
-        List queryExpressions = this.data.getQueryVariables();
-        int limit = this.data.getLimit();
-        int offset = this.data.getOffset();
-        boolean distinct = this.data.getDistinct();
-
+        p.defaultDatasets = this.data.getDefaultDatasets();
+        p.namedDatasets = this.data.getNamedDatasets();
+        p.orderExpressions = this.data.getOrderExpressions();
+        if (this.data.getQueryVariables().isEmpty())
+			  p.distinguishedVariables = new HashSet(this.data.getVariables());
+		  else
+			  p.distinguishedVariables = new HashSet(this.data.getQueryVariables());
+        p.limit = this.data.getLimit();
+        p.offset = this.data.getOffset() > 0 ? this.data.getOffset() : 0;
+        if (this.data.getDistinct())
+			  p.distinct = ConstraintLogic.CallParams.DistinctType.DISTINCT;
+		  
+		  p.rangeLogic = this.rangeLogic;
+		  p.distinctionLogic = this.distinctLogic;
+		  p.projectionLogic = this.projectionLogic;
+		  
         // First bind the result table
-        RdfBindingSet results = constraint.constrain(null,
-                source, defaultDatasets, namedDatasets);
-
-        // Now project to the solution set or the variable set
-        if (!queryExpressions.isEmpty()) {
-            results = this.logic.project(results, queryExpressions);
-        } else {
-        	results = this.logic.project(results, this.data.getVariables());
-        }
-
-        // Now apply distinct
-        if (distinct) {
-            results = this.distinctLogic.makeDistinct(results);
-        }
-
-        // Now apply ordering in reverse order
-        for (int i = orderExpressions.size() - 1; i >= 0; i--) {
-            OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
-            results = orderer.order(results);
-        }
-
-        // Now apply limiting and offsetting
-        if (limit >= 0) {
-            results = this.rangeLogic.limit(results, limit);
-        }
-        if (offset >= 0) {
-            results = this.rangeLogic.offset(results, offset);
-        }
-
+        RdfBindingSet results = constraint.constrain(p);
+		  
         return results;
     }
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueConversionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueConversionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueConversionLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueConversionLogic.java	2008-08-09 17:06:38.000000000 -0400
@@ -57,26 +57,34 @@
             if (datatype.equals(SPARQLConstants.DOUBLE_TYPE)) {
                 return new Double(convertDouble(literal));
             }
-            if (datatype.equals(SPARQLConstants.INTEGER_TYPE)) {
-                return new Integer(convertInteger(literal));
-            }
             if (datatype.equals(SPARQLConstants.FLOAT_TYPE)) {
                 return new Float(convertFloat(literal));
             }
             if (datatype.equals(SPARQLConstants.DECIMAL_TYPE)) {
-                return new Long(convertDecimal(literal));
+					return convertDecimal(literal);
+				 }
+				 if (datatype.equals(SPARQLConstants.INTEGER_TYPE)
+					|| datatype.equals(SPARQLConstants.NONPOSITIVEINTEGER_TYPE) || datatype.equals(SPARQLConstants.NEGATIVEINTEGER_TYPE) || datatype.equals(SPARQLConstants.NONNEGATIVEINTEGER_TYPE) || datatype.equals(SPARQLConstants.POSITIVEINTEGER_TYPE)
+					|| datatype.equals(SPARQLConstants.LONG_TYPE)
+					|| datatype.equals(SPARQLConstants.UNSIGNEDLONG_TYPE)
+             || datatype.equals(SPARQLConstants.INT_TYPE) || datatype.equals(SPARQLConstants.SHORT_TYPE) || datatype.equals(SPARQLConstants.BYTE_TYPE)
+					|| datatype.equals(SPARQLConstants.UNSIGNEDINT_TYPE) || datatype.equals(SPARQLConstants.UNSIGNEDSHORT_TYPE) || datatype.equals(SPARQLConstants.UNSIGNEDBYTE_TYPE)) {
+                return convertInteger(literal);
             }
             if (datatype.equals(SPARQLConstants.BOOLEAN_TYPE)) {
                 return new Boolean(convertBoolean(literal));
             }
             if (datatype.equals(SPARQLConstants.DATE_TYPE)) {
+                return convertDate(literal);
+            }
+            if (datatype.equals(SPARQLConstants.DATETIME_TYPE)) {
                 return convertDateTime(literal);
             }
             if (datatype.equals(SPARQLConstants.STRING_TYPE)) {
                 return convertString(literal);
             }
             throw new ConversionException(
-                    "Literal can't be converted to primitive object");
+						"Literal can't be converted to primitive object: Unrecognized datatype: " + datatype);
         } else {
             return convertString(literal);
         }
@@ -95,14 +103,14 @@
         if (o instanceof Double) {
             return convertDouble(((Double) o).doubleValue());
         }
-        if (o instanceof Integer) {
-            return convertInteger(((Integer) o).intValue());
+        if (o instanceof java.math.BigInteger) {
+            return convertInteger((java.math.BigInteger) o);
         }
         if (o instanceof Float) {
             return convertFloat(((Float) o).floatValue());
         }
-        if (o instanceof Long) {
-            return convertDecimal(((Long) o).longValue());
+        if (o instanceof java.math.BigDecimal) {
+            return convertDecimal((java.math.BigDecimal) o);
         }
         if (o instanceof Boolean) {
             return convertBoolean(((Boolean) o).booleanValue());
@@ -191,27 +199,27 @@
     }
 
     /**
-     * Converts a double value to a xsd:integer type literal.
+     * Converts a java.math.BigInteger value to a xsd:integer type literal.
      * 
-     * @param value the int value to convert
+     * @param value the java.math.BigInteger value to convert
      * @return a correctly formed xsd:integer literal
      */
-    public Literal convertInteger(int value) {
-        return this.factory.createLiteral(Integer.toString(value),
+    public Literal convertInteger(java.math.BigInteger value) {
+        return this.factory.createLiteral(value.toString(),
                 SPARQLConstants.INTEGER_TYPE);
     }
 
     /**
-     * Converts a literal to a int value.
+     * Converts a literal to a java.math.BigInteger value.
      * 
      * @param literal the xsd:integer to convert
-     * @return a int value equating to the literal value
+     * @return a java.math.BigInteger value equating to the literal value
      * @throws ConversionException if the literal is of an incorrect type or is
      *             unparseable
      */
-    public int convertInteger(Literal literal) {
+    public java.math.BigInteger convertInteger(Literal literal) {
         try {
-            return Integer.parseInt(literal.getLabel());
+            return new java.math.BigInteger(literal.getLabel());
         } catch (NumberFormatException e) {
             throw new ConversionException(
                     "Could not parse literal label to int type");
@@ -232,6 +240,24 @@
     /**
      * Converts a literal to a DateTime value.
      * 
+     * @param literal the xsd:date to convert
+     * @return a DateTime value equating to the literal value
+     * @throws ConversionException if the literal is of an incorrect type or is
+     *             unparseable
+     */
+    public DateTime convertDate(Literal literal) {
+        try {
+            return new DateTime(literal.getLabel(), literal.getDatatype());
+        } catch (IllegalArgumentException e) {
+  				System.err.println(e);
+            throw new ConversionException(
+                    "Could not parse literal label to datetime type");
+        }
+    }
+
+    /**
+     * Converts a literal to a DateTime value.
+     * 
      * @param literal the xsd:dateTime to convert
      * @return a DateTime value equating to the literal value
      * @throws ConversionException if the literal is of an incorrect type or is
@@ -275,27 +301,27 @@
     }
 
     /**
-     * Converts a long value to a xsd:decimal type literal.
+     * Converts a java.math.BigDecimal value to a xsd:decimal type literal.
      * 
-     * @param value the long value to convert
+     * @param value the java.math.BigDecimal value to convert
      * @return a correctly formed xsd:decimal literal
      */
-    public Literal convertDecimal(long value) {
-        return this.factory.createLiteral(Long.toString(value),
+    public Literal convertDecimal(java.math.BigDecimal value) {
+        return this.factory.createLiteral(value.toString(),
                 SPARQLConstants.DECIMAL_TYPE);
     }
 
     /**
-     * Converts a literal to a long value.
+     * Converts a literal to a java.math.BigDecimal value.
      * 
      * @param literal the xsd:decimal to convert
-     * @return a long value equating to the literal value
+     * @return a java.math.BigDecimal value equating to the literal value
      * @throws ConversionException if the literal is of an incorrect type or is
      *             unparseable
      */
-    public long convertDecimal(Literal literal) {
+    public java.math.BigDecimal convertDecimal(Literal literal) {
         try {
-            return Long.parseLong(literal.getLabel());
+            return new java.math.BigDecimal(literal.getLabel());
         } catch (NumberFormatException e) {
             throw new ConversionException(
                     "Could not parse literal label to long type");
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueOrderingLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueOrderingLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueOrderingLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultValueOrderingLogic.java	2008-08-07 07:55:54.000000000 -0400
@@ -1,5 +1,10 @@
 package name.levering.ryan.sparql.logic;
 
+import name.levering.ryan.sparql.common.SPARQLConstants;
+import name.levering.ryan.sparql.common.impl.DateTime;
+
+import name.levering.ryan.sparql.model.logic.NumericPromotionLogic;
+import name.levering.ryan.sparql.model.logic.helper.ValueConversionLogic;
 import name.levering.ryan.sparql.model.logic.helper.ValueOrderingLogic;
 
 import name.levering.ryan.sparql.common.BNode;
@@ -22,6 +27,13 @@
  * @version 1.0
  */
 public class DefaultValueOrderingLogic implements ValueOrderingLogic {
+	NumericPromotionLogic promoter;
+	ValueConversionLogic converter;
+	
+	public DefaultValueOrderingLogic(NumericPromotionLogic promoter, ValueConversionLogic converter) {
+		this.promoter = promoter;
+		this.converter = converter;
+	}
 
 	/**
 	 * Compares two value objects according to section 10.1.
@@ -64,14 +76,44 @@
 			return -1;
 		}
 
-		// First value is an untyped literal
-		if (value1 instanceof Literal && ((Literal) value1).getDatatype() == null) {
-			if (value2 == null || value2 instanceof BNode || value2 instanceof URI) {
+		// First value is a literal
+		if (value1 instanceof Literal) {
+			if (value2 == null || value2 instanceof BNode || value2 instanceof URI)
 				return 1;
+
+			if (value2 instanceof Literal) {
+				if (((Literal) value1).getDatatype() == null && ((Literal) value2).getDatatype() == null)
+					return ((Literal) value1).getLabel().compareTo(((Literal) value2).getLabel());
+					
+				if (((Literal) value1).getDatatype() == null)
+					return -1;
+				if (((Literal) value2).getDatatype() == null)
+					return 1;
+				
+				if (((Literal) value1).getDatatype().equals(SPARQLConstants.STRING_TYPE) && ((Literal) value2).getDatatype().equals(SPARQLConstants.STRING_TYPE))
+					return ((Literal) value1).getLabel().compareTo(((Literal) value2).getLabel());
+
+				Literal[] promoted = promoter.promote(new Literal[] { (Literal) value1, (Literal) value2 } );
+				
+				Object v1 = converter.convertLiteral(promoted[0]);
+				Object v2 = converter.convertLiteral(promoted[1]);
+				
+				if (v1 instanceof Double)
+					return ((Double)v1).compareTo((Double)v2);
+				if (v1 instanceof Float)
+					return ((Float)v1).compareTo((Float)v2);
+				if (v1 instanceof java.math.BigDecimal)
+					return ((java.math.BigDecimal)v1).compareTo((java.math.BigDecimal)v2);
+				if (v1 instanceof java.math.BigInteger)
+					return ((java.math.BigInteger)v1).compareTo((java.math.BigInteger)v2);
+				if (v1 instanceof Boolean)
+					return ((Boolean)v1).compareTo((Boolean)v2);
+				if (v1 instanceof DateTime)
+					return ((DateTime)v1).compareTo((DateTime)v2);
+				if (v1 instanceof String)
+					return ((String)v1).compareTo((String)v2);
 			}
-			if (value2 instanceof Literal && ((Literal) value2).getDatatype() == null) {
-				return ((Literal) value1).getLabel().compareTo(((Literal) value2).getLabel());
-			}
+			
 			return -1;
 		}
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/DefaultVariableLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/DefaultVariableLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/DefaultVariableLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/DefaultVariableLogic.java	1969-12-31 19:00:00.000000000 -0500
@@ -1,50 +0,0 @@
-/*
- * SPARQL Engine
- * Copyright (C) 2005 Ryan Levering, All rights reserved.
- * See LICENSE for full license information
- */
-package name.levering.ryan.sparql.logic;
-
-import name.levering.ryan.sparql.common.RdfBindingRow;
-import name.levering.ryan.sparql.common.Variable;
-import name.levering.ryan.sparql.model.logic.ExpressionLogic;
-
-import name.levering.ryan.sparql.common.Value;
-
-/**
- * The main lowest level logic in variable expression resolution, this will
- * return the result of the variable binding in the current row being evaluated.
- * 
- * @author Ryan Levering
- * @version 1.0
- */
-public class DefaultVariableLogic implements ExpressionLogic {
-
-    /**
-     * The variable to return the value of in the current row.
-     */
-    private final Variable variable;
-
-    /**
-     * Creates a new default logic that returns the value bound to a variable in
-     * a binding row.
-     * 
-     * @param variable the variable to checking the binding for
-     */
-    public DefaultVariableLogic(Variable variable) {
-        this.variable = variable;
-    }
-
-    /**
-     * Returns the object bound to the variable header in the current binding
-     * row.
-     * 
-     * @param bindings the bindings used to evaluate the variable
-     * @return the current bound Value object to the Variable in the row, or
-     *         null if it isn't bound
-     */
-    public Value evaluate(RdfBindingRow bindings) {
-        return bindings.getValue(this.variable);
-    }
-
-}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/AdditionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/AdditionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/AdditionLogic.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/AdditionLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -38,8 +38,8 @@
      * @param num2 the second number to add
      * @return the sum of the two numbers
      */
-    public int evaluateInteger(int num1, int num2) {
-        return num1 + num2;
+    public java.math.BigInteger evaluateInteger(java.math.BigInteger num1, java.math.BigInteger num2) {
+        return num1.add(num2);
     }
 
     /**
@@ -71,8 +71,8 @@
      * @param num2 the second number to add
      * @return the sum of the two numbers
      */
-    public long evaluateDecimal(long num1, long num2) {
-        return num1 + num2;
+    public java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num1, java.math.BigDecimal num2) {
+        return num1.add(num2);
     }
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/BinaryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/BinaryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/BinaryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/BinaryLogic.java	2008-05-03 17:13:37.000000000 -0400
@@ -59,5 +59,20 @@
      * @return the result of evaluating the operation
      */
     public abstract Value evaluate(Value leftValue, Value rightValue);
+	 
+	 public java.util.Set getVariables() {
+		 java.util.HashSet ret = new java.util.HashSet();
+		 ret.addAll(this.data.getLeftExpression().getVariables());
+		 ret.addAll(this.data.getRightExpression().getVariables());
+		 return ret;
+	 }
+	 
+	public ExpressionLogic getLeftExpression() {
+		return this.data.getLeftExpression();
+	}
+
+	public ExpressionLogic getRightExpression() {
+		return this.data.getRightExpression();
+	}
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/DivisionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/DivisionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/DivisionLogic.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/DivisionLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -38,8 +38,8 @@
      * @param num2 the second number to divide
      * @return the result of division of the two numbers
      */
-    public int evaluateInteger(int num1, int num2) {
-        return num1 / num2;
+    public java.math.BigInteger evaluateInteger(java.math.BigInteger num1, java.math.BigInteger num2) {
+        return num1.divide(num2);
     }
 
     /**
@@ -71,8 +71,8 @@
      * @param num2 the second number to divide
      * @return the result of division of the two numbers
      */
-    public long evaluateDecimal(long num1, long num2) {
-        return num1 / num2;
+    public java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num1, java.math.BigDecimal num2) {
+        return num1.divide(num2);
     }
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/EqualsLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/EqualsLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/EqualsLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/EqualsLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -34,71 +34,9 @@
         super(data, numLogic, converter);
     }
 
-    /**
-     * Evaluates any integer comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are equal
-     */
-    public boolean evaluateInteger(int num1, int num2) {
-        return num1 == num2;
-    }
-
-    /**
-     * Evaluates any float comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are equal
-     */
-    public boolean evaluateFloat(float num1, float num2) {
-        return num1 == num2;
-    }
-
-    /**
-     * Evaluates any double comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are equal
-     */
-    public boolean evaluateDouble(double num1, double num2) {
-        return num1 == num2;
-    }
-
-    /**
-     * Evaluates any long comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are equal
-     */
-    public boolean evaluateDecimal(long num1, long num2) {
-        return num1 == num2;
-    }
-
-    /**
-     * Evaluates any date/time comparison.
-     * 
-     * @param cal1 the first date to compare
-     * @param cal2 the second date to compare
-     * @return true if the two date/times are equal
-     */
-    public boolean evaluateDate(DateTime cal1, DateTime cal2) {
-        return cal1.compareTo(cal2) == 0;
-    }
-
-    /**
-     * Evaluates any String comparison.
-     * 
-     * @param string1 the first String to compare
-     * @param string2 the second String to compare
-     * @return true if the two Strings are equal
-     */
-    public boolean evaluateString(String string1, String string2) {
-        return string1.equals(string2);
-    }
+  	 protected boolean comparisonResult(int comparison) {
+		 return comparison == 0;
+	 }
 
     /**
      * Evaluates any non-overloaded Value comparison.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanEqualsLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanEqualsLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanEqualsLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanEqualsLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -36,73 +36,10 @@
         super(data, numLogic, converter);
     }
 
-    /**
-     * Evaluates any integer comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than or equal to the second
-     */
-    public boolean evaluateInteger(int num1, int num2) {
-        return num1 >= num2;
-    }
-
-    /**
-     * Evaluates any float comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than or equal to the second
-     */
-    public boolean evaluateFloat(float num1, float num2) {
-        return num1 >= num2;
-    }
-
-    /**
-     * Evaluates any double comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than or equal to the second
-     */
-    public boolean evaluateDouble(double num1, double num2) {
-        return num1 >= num2;
-    }
-
-    /**
-     * Evaluates any long comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than or equal to the second
-     */
-    public boolean evaluateDecimal(long num1, long num2) {
-        return num1 >= num2;
-    }
-
-    /**
-     * Evaluates any date comparison.
-     * 
-     * @param cal1 the first date to compare
-     * @param cal2 the second date to compare
-     * @return true if the first date is after or the same as the second
-     */
-    public boolean evaluateDate(DateTime cal1, DateTime cal2) {
-        return cal1.compareTo(cal2) >= 0;
-    }
-
-    /**
-     * Evaluates any String comparison.
-     * 
-     * @param string1 the first String to compare
-     * @param string2 the second String to compare
-     * @return never
-     * @throws UnsupportedOperationException always
-     */
-    public boolean evaluateString(String string1, String string2) {
-        throw new UnsupportedOperationException("Strings cannot be compared using a >= operation");
-    }
-
+  	 protected boolean comparisonResult(int comparison) {
+		 return comparison >= 0;
+	 }
+	 
     /**
      * Evaluates any non-overloaded Value comparison.
      * 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/GreaterThanLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -36,72 +36,9 @@
         super(data, numLogic, converter);
     }
 
-    /**
-     * Evaluates any integer comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than the second
-     */
-    public boolean evaluateInteger(int num1, int num2) {
-        return num1 > num2;
-    }
-
-    /**
-     * Evaluates any float comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than the second
-     */
-    public boolean evaluateFloat(float num1, float num2) {
-        return num1 > num2;
-    }
-
-    /**
-     * Evaluates any double comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than the second
-     */
-    public boolean evaluateDouble(double num1, double num2) {
-        return num1 > num2;
-    }
-
-    /**
-     * Evaluates any long comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is greater than the second
-     */
-    public boolean evaluateDecimal(long num1, long num2) {
-        return num1 > num2;
-    }
-
-    /**
-     * Evaluates any date comparison.
-     * 
-     * @param cal1 the first date to compare
-     * @param cal2 the second date to compare
-     * @return true if the first date is after the second
-     */
-    public boolean evaluateDate(DateTime cal1, DateTime cal2) {
-        return cal1.compareTo(cal2) > 0;
-    }
-
-    /**
-     * Evaluates any String comparison.
-     * 
-     * @param string1 the first String to compare
-     * @param string2 the second String to compare
-     * @return never
-     * @throws UnsupportedOperationException always
-     */
-    public boolean evaluateString(String string1, String string2) {
-        throw new UnsupportedOperationException("Strings cannot be compared using a > operation");
-    }
+	 protected boolean comparisonResult(int comparison) {
+		 return comparison > 0;
+	 }
 
     /**
      * Evaluates any non-overloaded Value comparison.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanEqualsLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanEqualsLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanEqualsLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanEqualsLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -36,72 +36,9 @@
         super(data, numLogic, converter);
     }
 
-    /**
-     * Evaluates any integer comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than or equal to the second
-     */
-    public boolean evaluateInteger(int num1, int num2) {
-        return num1 <= num2;
-    }
-
-    /**
-     * Evaluates any float comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than or equal to the second
-     */
-    public boolean evaluateFloat(float num1, float num2) {
-        return num1 <= num2;
-    }
-
-    /**
-     * Evaluates any double comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than or equal to the second
-     */
-    public boolean evaluateDouble(double num1, double num2) {
-        return num1 <= num2;
-    }
-
-    /**
-     * Evaluates any long comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than or equal to the second
-     */
-    public boolean evaluateDecimal(long num1, long num2) {
-        return num1 <= num2;
-    }
-
-    /**
-     * Evaluates any date comparison.
-     * 
-     * @param cal1 the first date to compare
-     * @param cal2 the second date to compare
-     * @return true if the first date is before or the same as the second
-     */
-    public boolean evaluateDate(DateTime cal1, DateTime cal2) {
-        return cal1.compareTo(cal2) <= 0;
-    }
-
-    /**
-     * Evaluates any String comparison.
-     * 
-     * @param string1 the first String to compare
-     * @param string2 the second String to compare
-     * @return never
-     * @throws UnsupportedOperationException always
-     */
-    public boolean evaluateString(String string1, String string2) {
-        throw new UnsupportedOperationException("Strings cannot be compared using a <= operation");
-    }
+	 protected boolean comparisonResult(int comparison) {
+		 return comparison <= 0;
+	 }
 
     /**
      * Evaluates any non-overloaded Value comparison.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/LessThanLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -36,72 +36,10 @@
         super(data, numLogic, converter);
     }
 
-    /**
-     * Evaluates any integer comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than the second
-     */
-    public boolean evaluateInteger(int num1, int num2) {
-        return num1 < num2;
-    }
-
-    /**
-     * Evaluates any float comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than the second
-     */
-    public boolean evaluateFloat(float num1, float num2) {
-        return num1 < num2;
-    }
-
-    /**
-     * Evaluates any double comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than the second
-     */
-    public boolean evaluateDouble(double num1, double num2) {
-        return num1 < num2;
-    }
-
-    /**
-     * Evaluates any long comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the first number is less than the second
-     */
-    public boolean evaluateDecimal(long num1, long num2) {
-        return num1 < num2;
-    }
+	 protected boolean comparisonResult(int comparison) {
+		 return comparison < 0;
+	 }
 
-    /**
-     * Evaluates any date comparison.
-     * 
-     * @param cal1 the first date to compare
-     * @param cal2 the second date to compare
-     * @return true if the first date is before the second
-     */
-    public boolean evaluateDate(DateTime cal1, DateTime cal2) {
-        return cal1.compareTo(cal2) < 0;
-    }
-
-    /**
-     * Evaluates any String comparison.
-     * 
-     * @param string1 the first String to compare
-     * @param string2 the second String to compare
-     * @return never
-     * @throws UnsupportedOperationException always
-     */
-    public boolean evaluateString(String string1, String string2) {
-        throw new UnsupportedOperationException("Fix this");
-    }
     
     /**
      * Evaluates any non-overloaded Value comparison.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/MinusLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/MinusLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/MinusLogic.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/MinusLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -34,8 +34,8 @@
      * @param num the number to negate
      * @return the negation of the number
      */
-    public long evaluateDecimal(long num) {
-        return -num;
+    public java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num) {
+        return num.negate();
     }
 
     /**
@@ -64,8 +64,8 @@
      * @param num the number to negate
      * @return the negation of the number
      */
-    public int evaluateInteger(int num) {
-        return -num;
+    public java.math.BigInteger evaluateInteger(java.math.BigInteger num) {
+        return num.negate();
     }
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/MultiplicationLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/MultiplicationLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/MultiplicationLogic.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/MultiplicationLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -38,8 +38,8 @@
      * @param num2 the second number to multiply
      * @return the result of multiplication of the two numbers
      */
-    public int evaluateInteger(int num1, int num2) {
-        return num1 * num2;
+    public java.math.BigInteger evaluateInteger(java.math.BigInteger num1, java.math.BigInteger num2) {
+        return num1.multiply(num2);
     }
 
     /**
@@ -71,8 +71,8 @@
      * @param num2 the second number to multiply
      * @return the result of multiplication of the two numbers
      */
-    public long evaluateDecimal(long num1, long num2) {
-        return num1 * num2;
+    public java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num1, java.math.BigDecimal num2) {
+        return num1.multiply(num2);
     }
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/NotEqualsLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/NotEqualsLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/NotEqualsLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/NotEqualsLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -36,71 +36,9 @@
         super(data, numLogic, converter);
     }
 
-    /**
-     * Evaluates any integer comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are not equal
-     */
-    public boolean evaluateInteger(int num1, int num2) {
-        return num1 != num2;
-    }
-
-    /**
-     * Evaluates any float comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are not equal
-     */
-    public boolean evaluateFloat(float num1, float num2) {
-        return num1 != num2;
-    }
-
-    /**
-     * Evaluates any double comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are not equal
-     */
-    public boolean evaluateDouble(double num1, double num2) {
-        return num1 != num2;
-    }
-
-    /**
-     * Evaluates any long comparison.
-     * 
-     * @param num1 the first number to compare
-     * @param num2 the second number to compare
-     * @return true if the two numbers are not equal
-     */
-    public boolean evaluateDecimal(long num1, long num2) {
-        return num1 != num2;
-    }
-
-    /**
-     * Evaluates any date/time comparison.
-     * 
-     * @param cal1 the first date to compare
-     * @param cal2 the second date to compare
-     * @return true if the two date/times are not equal
-     */
-    public boolean evaluateDate(DateTime cal1, DateTime cal2) {
-        return cal1.compareTo(cal2) != 0;
-    }
-
-    /**
-     * Evaluates any String comparison.
-     * 
-     * @param string1 the first String to compare
-     * @param string2 the second String to compare
-     * @return true if the two Strings are not equal
-     */
-    public boolean evaluateString(String string1, String string2) {
-        return !string1.equals(string2);
-    }
+	 protected boolean comparisonResult(int comparison) {
+		 return comparison != 0;
+	 }
 
     /**
      * Evaluates any non-overloaded Value comparison.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericBinaryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericBinaryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericBinaryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericBinaryLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -82,10 +82,10 @@
             Object leftEvaluate = this.converter.convertLiteral(leftLiteral);
             Object rightEvaluate = this.converter.convertLiteral(rightLiteral);
 
-            if (leftEvaluate instanceof Long && rightEvaluate instanceof Long) {
-                long result = evaluateDecimal(
-                        ((Long) leftEvaluate).longValue(),
-                        ((Long) rightEvaluate).longValue());
+            if (leftEvaluate instanceof java.math.BigDecimal && rightEvaluate instanceof java.math.BigDecimal) {
+                java.math.BigDecimal result = evaluateDecimal(
+                        (java.math.BigDecimal) leftEvaluate,
+                        (java.math.BigDecimal) rightEvaluate);
                 return this.converter.convertDecimal(result);
             } else if (leftEvaluate instanceof Double
                     && rightEvaluate instanceof Double) {
@@ -99,11 +99,11 @@
                         ((Float) leftEvaluate).floatValue(),
                         ((Float) rightEvaluate).floatValue());
                 return this.converter.convertFloat(result);
-            } else if (leftEvaluate instanceof Integer
-                    && rightEvaluate instanceof Integer) {
-                int result = evaluateInteger(
-                        ((Integer) leftEvaluate).intValue(),
-                        ((Integer) rightEvaluate).intValue());
+            } else if (leftEvaluate instanceof java.math.BigInteger
+                    && rightEvaluate instanceof java.math.BigInteger) {
+                java.math.BigInteger result = evaluateInteger(
+                        (java.math.BigInteger) leftEvaluate,
+                        (java.math.BigInteger) rightEvaluate);
                 return this.converter.convertInteger(result);
             }
             throw new TypeError(
@@ -120,7 +120,7 @@
      * @param num2 the second numeric operand
      * @return the result of the numeric binary operation
      */
-    public abstract int evaluateInteger(int num1, int num2);
+    public abstract java.math.BigInteger evaluateInteger(java.math.BigInteger num1, java.math.BigInteger num2);
 
     /**
      * Performs an float precision numeric operation.
@@ -147,6 +147,6 @@
      * @param num2 the second numeric operand
      * @return the result of the numeric binary operation
      */
-    public abstract long evaluateDecimal(long num1, long num2);
+    public abstract java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num1, java.math.BigDecimal num2);
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericUnaryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericUnaryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericUnaryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/NumericUnaryLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -50,9 +50,9 @@
     public Value evaluate(Value value) {
         if (value instanceof Literal) {
             Object evaluation = this.converter.convertLiteral((Literal) value);
-            if (evaluation instanceof Integer) {
-                int result = evaluateInteger(((Integer) evaluation).intValue());
-                return this.converter.convertObject(new Integer(result));
+            if (evaluation instanceof java.math.BigInteger) {
+                java.math.BigInteger result = evaluateInteger((java.math.BigInteger) evaluation);
+                return this.converter.convertObject(result);
             }
             if (evaluation instanceof Float) {
                 float result = evaluateFloat(((Float) evaluation).floatValue());
@@ -62,9 +62,9 @@
                 double result = evaluateDouble(((Double) evaluation).doubleValue());
                 return this.converter.convertObject(new Double(result));
             }
-            if (evaluation instanceof Long) {
-                long result = evaluateDecimal(((Long) evaluation).longValue());
-                return this.converter.convertObject(new Long(result));
+            if (evaluation instanceof java.math.BigDecimal) {
+                java.math.BigDecimal result = evaluateDecimal((java.math.BigDecimal) evaluation);
+                return this.converter.convertObject(result);
             }
         }
         throw new TypeError(
@@ -77,7 +77,7 @@
      * @param num the numeric operand
      * @return the result of the numeric operation
      */
-    public abstract int evaluateInteger(int num);
+    public abstract java.math.BigInteger evaluateInteger(java.math.BigInteger num);
 
     /**
      * Performs a float precision numeric operation.
@@ -101,6 +101,6 @@
      * @param num the numeric operand
      * @return the result of the numeric operation
      */
-    public abstract long evaluateDecimal(long num);
+    public abstract java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num);
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/OrLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/OrLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/OrLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/OrLogic.java	2008-07-11 15:31:54.000000000 -0400
@@ -46,14 +46,13 @@
      */
     public Value evaluate(RdfBindingRow bindings) {
 
-        boolean caughtError = false;
-
         boolean leftEvaluate;
+		  RuntimeException leftException = null;
         try {
             Literal leftBool = this.boolLogic.forceBoolean(this.data.getLeftExpression().evaluate(bindings));
             leftEvaluate = this.converter.convertBoolean(leftBool);
-        } catch (TypeError e) {
-            caughtError = true;
+        } catch (RuntimeException e) {
+            leftException = e;
             leftEvaluate = false;
         }
 
@@ -61,10 +60,10 @@
         try {
             Literal rightBool = this.boolLogic.forceBoolean(this.data.getRightExpression().evaluate(bindings));
             rightEvaluate = this.converter.convertBoolean(rightBool);
-        } catch (TypeError e) {
-            if (caughtError) {
+        } catch (RuntimeException e) {
+            if (leftException != null) {
                 throw new TypeError(
-                        "Both expressions of the disjunction produced type errors");
+						     "Both expressions of the disjunction produced type or cast errors: (left side) " + leftException + ", (right side) " + e);
             }
             rightEvaluate = false;
         }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/PlusLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/PlusLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/PlusLogic.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/PlusLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -35,7 +35,7 @@
      * @param num the number to positivize
      * @return the positivation of the number
      */
-    public long evaluateDecimal(long num) {
+    public java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num) {
         return num;
     }
 
@@ -65,7 +65,7 @@
      * @param num the number to positivize
      * @return the positivation of the number
      */
-    public int evaluateInteger(int num) {
+    public java.math.BigInteger evaluateInteger(java.math.BigInteger num) {
         return num;
     }
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/RelationalLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/RelationalLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/RelationalLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/RelationalLogic.java	2008-08-09 17:02:35.000000000 -0400
@@ -30,6 +30,8 @@
 	private ValueConversionLogic converter;
 
 	private NumericPromotionLogic numLogic;
+	
+	
 
 	/**
 	 * Creates a new relational logic object with particular expression data to
@@ -65,16 +67,9 @@
 			Literal rightLiteral = (Literal) rightValue;
 			URI leftDatatype = leftLiteral.getDatatype();
 
-			// First check numeric promotion
-			if (leftDatatype != null
-					&& (leftDatatype.equals(SPARQLConstants.FLOAT_TYPE)
-							|| leftDatatype.equals(SPARQLConstants.DECIMAL_TYPE)
-							|| leftDatatype.equals(SPARQLConstants.INTEGER_TYPE) || leftDatatype
-							.equals(SPARQLConstants.DOUBLE_TYPE))) {
-				Literal[] promoted = this.numLogic.promote(new Literal[] { leftLiteral, rightLiteral });
-				leftLiteral = promoted[0];
-				rightLiteral = promoted[1];
-			}
+			Literal[] promoted = this.numLogic.promote(new Literal[] { leftLiteral, rightLiteral });
+			leftLiteral = promoted[0];
+			rightLiteral = promoted[1];
 
 			// Now convert to java types
 			Object leftEvaluate;
@@ -83,16 +78,16 @@
 			try {
 				leftEvaluate = this.converter.convertLiteral(leftLiteral);
 				rightEvaluate = this.converter.convertLiteral(rightLiteral);
-
+				
 				if (leftEvaluate instanceof Double && rightEvaluate instanceof Double) {
 					result = evaluateDouble(((Double) leftEvaluate).doubleValue(), ((Double) rightEvaluate)
 							.doubleValue());
 				} else if (leftEvaluate instanceof Float && rightEvaluate instanceof Float) {
 					result = evaluateFloat(((Float) leftEvaluate).floatValue(), ((Float) rightEvaluate).floatValue());
-				} else if (leftEvaluate instanceof Long && rightEvaluate instanceof Long) {
-					result = evaluateDecimal(((Long) leftEvaluate).longValue(), ((Long) rightEvaluate).longValue());
-				} else if (leftEvaluate instanceof Integer && rightEvaluate instanceof Integer) {
-					result = evaluateInteger(((Integer) leftEvaluate).intValue(), ((Integer) rightEvaluate).intValue());
+				} else if (leftEvaluate instanceof java.math.BigDecimal && rightEvaluate instanceof java.math.BigDecimal) {
+					result = evaluateDecimal((java.math.BigDecimal) leftEvaluate, (java.math.BigDecimal) rightEvaluate);
+				} else if (leftEvaluate instanceof java.math.BigInteger && rightEvaluate instanceof java.math.BigInteger) {
+					result = evaluateInteger((java.math.BigInteger) leftEvaluate, (java.math.BigInteger) rightEvaluate);
 				} else if (leftEvaluate instanceof DateTime && rightEvaluate instanceof DateTime) {
 					result = evaluateDate((DateTime) leftEvaluate, (DateTime) rightEvaluate);
 				} else if (leftEvaluate instanceof String && rightEvaluate instanceof String) {
@@ -129,7 +124,9 @@
 	 * @param num2 the right value to compare
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
-	public abstract boolean evaluateInteger(int num1, int num2);
+	 public boolean evaluateInteger(java.math.BigInteger num1, java.math.BigInteger num2) {
+		 return comparisonResult(num1.compareTo(num2));
+	 }
 
 	/**
 	 * Template method delegation to subclass relational logic implementation.
@@ -138,7 +135,9 @@
 	 * @param num2 the right value to compare
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
-	public abstract boolean evaluateFloat(float num1, float num2);
+	 public boolean evaluateFloat(float num1, float num2) {
+		 return comparisonResult(Float.compare(num1, num2));
+	 }
 
 	/**
 	 * Template method delegation to subclass relational logic implementation.
@@ -147,7 +146,9 @@
 	 * @param num2 the right value to compare
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
-	public abstract boolean evaluateDouble(double num1, double num2);
+	 public boolean evaluateDouble(double num1, double num2) {
+		 return comparisonResult(Double.compare(num1, num2));
+	 }
 
 	/**
 	 * Template method delegation to subclass relational logic implementation.
@@ -156,7 +157,9 @@
 	 * @param num2 the right value to compare
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
-	public abstract boolean evaluateDecimal(long num1, long num2);
+	 public boolean evaluateDecimal(java.math.BigDecimal num1, java.math.BigDecimal num2) {
+		 return comparisonResult(num1.compareTo(num2));
+	 }
 
 	/**
 	 * Template method delegation to subclass relational logic implementation.
@@ -165,7 +168,9 @@
 	 * @param cal2 the right value to compare
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
-	public abstract boolean evaluateDate(DateTime cal1, DateTime cal2);
+	 public boolean evaluateDate(DateTime cal1, DateTime cal2) {
+		 return comparisonResult(cal1.compareTo(cal2));
+	 }
 
 	/**
 	 * Template method delegation to subclass relational logic implementation.
@@ -174,7 +179,9 @@
 	 * @param string2 the right value to compare
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
-	public abstract boolean evaluateString(String string1, String string2);
+	 public boolean evaluateString(String string1, String string2) {
+		 return comparisonResult(string1.compareTo(string2));
+	 }
 
 	/**
 	 * Template method delegation to subclass relational logic implementation.
@@ -184,5 +191,7 @@
 	 * @return true if the underlying implementation evaluates the expression to be true
 	 */
 	public abstract boolean evaluateValue(Value value1, Value value2);
+	
+	protected abstract boolean comparisonResult(int comparison);
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/SubtractionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/SubtractionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/SubtractionLogic.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/SubtractionLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -38,8 +38,8 @@
      * @param num2 the second number to subtract
      * @return the difference of the two numbers
      */
-    public int evaluateInteger(int num1, int num2) {
-        return num1 - num2;
+    public java.math.BigInteger evaluateInteger(java.math.BigInteger num1, java.math.BigInteger num2) {
+        return num1.subtract(num2);
     }
 
     /**
@@ -71,8 +71,8 @@
      * @param num2 the second number to subtract
      * @return the difference of the two numbers
      */
-    public long evaluateDecimal(long num1, long num2) {
-        return num1 - num2;
+    public java.math.BigDecimal evaluateDecimal(java.math.BigDecimal num1, java.math.BigDecimal num2) {
+        return num1.subtract(num2);
     }
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/expression/UnaryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/expression/UnaryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/expression/UnaryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/expression/UnaryLogic.java	2008-05-03 17:13:33.000000000 -0400
@@ -56,4 +56,8 @@
      * @return the result of evaluating the operation
      */
     public abstract Value evaluate(Value value);
+
+	 public java.util.Set getVariables() {
+		 return this.data.getExpression().getVariables();
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/ExtendedConstructQueryLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/ExtendedConstructQueryLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/ExtendedConstructQueryLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/ExtendedConstructQueryLogic.java	2008-08-13 16:13:21.000000000 -0400
@@ -87,32 +87,23 @@
 	 * @return an RDF graph containing the formed triples
 	 */
 	public RdfGraph execute(RdfSource source) {
+		ConstraintLogic.CallParams p = new ConstraintLogic.CallParams();
+		p.bindings = new RdfBindingSetImpl();
+		p.source = source;
+
 		// Grab the necessary fields from the data
 		GroupConstraint constraint = this.data.getConstraint();
-		Collection defaultDatasets = this.data.getDefaultDatasets();
-		Collection namedDatasets = this.data.getNamedDatasets();
-		List orderExpressions = this.data.getOrderExpressions();
-		int limit = this.data.getLimit();
-		int offset = this.data.getOffset();
-		boolean distinct = this.data.isDistinct();
+		p.defaultDatasets = this.data.getDefaultDatasets();
+		p.namedDatasets = this.data.getNamedDatasets();
+		p.orderExpressions = this.data.getOrderExpressions();
+		p.limit = this.data.getLimit();
+		p.offset = this.data.getOffset();
+		p.rangeLogic = this.rangeLogic;
+		// would be nice to only get distinct bindings, but we first
+		// need to get a SetDistinctionLogic
 
 		// First bind the result table
-		RdfBindingSet results = constraint.constrain(new RdfBindingSetImpl(), source, defaultDatasets, namedDatasets);
-
-		// Now apply ordering in reverse order to give priority to the first
-		// variable
-		for (int i = orderExpressions.size() - 1; i >= 0; i--) {
-			OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
-			orderer.order(results);
-		}
-
-		// Now apply limiting and offsetting
-		if (limit >= 0) {
-			results = this.rangeLogic.limit(results, limit);
-		}
-		if (offset >= 0) {
-			results = this.rangeLogic.offset(results, offset);
-		}
+		RdfBindingSet results = constraint.constrain(p);
 
 		Collection triples;
 		if (this.data.getTriples().isEmpty()) {
@@ -123,7 +114,7 @@
 		}
 		RdfGraph graph = this.translationLogic.translate(triples, results);
 
-		if (distinct) {
+		if (this.data.isDistinct()) {
 			graph = this.distinctionLogic.makeDistinct(graph);
 		}
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/BoundLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/BoundLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/BoundLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/BoundLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -9,6 +9,7 @@
 import name.levering.ryan.sparql.common.Variable;
 import name.levering.ryan.sparql.model.data.CallExpressionData;
 import name.levering.ryan.sparql.model.logic.ExpressionLogic;
+import name.levering.ryan.sparql.model.logic.LogicFactory;
 import name.levering.ryan.sparql.model.logic.helper.ValueConversionLogic;
 
 import name.levering.ryan.sparql.common.Value;
@@ -21,12 +22,7 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class BoundLogic implements ExpressionLogic {
-
-    /**
-     * The data holding the arguments of the bound function.
-     */
-    private final CallExpressionData data;
+public class BoundLogic extends FunctionLogic {
 
     /**
      * The logic to return the correct boolean value.
@@ -41,7 +37,7 @@
      */
     public BoundLogic(CallExpressionData data, ValueConversionLogic converter) {
         //TODO Check for whether the argument is a variable
-        this.data = data;
+        super(data);
         this.converter = converter;
     }
 
@@ -56,5 +52,5 @@
         boolean result = (bindings.getValue(variable) != null);
         return this.converter.convertBoolean(result);
     }
-
+ 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/CastFunction.java work-copy/src/main/name/levering/ryan/sparql/logic/function/CastFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/CastFunction.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/CastFunction.java	2008-08-09 17:06:38.000000000 -0400
@@ -75,7 +75,7 @@
         if (dataType.equals(SPARQLConstants.INTEGER_TYPE)) {
             return castInteger(literal);
         }
-        if (dataType.equals(SPARQLConstants.DATE_TYPE)) {
+        if (dataType.equals(SPARQLConstants.DATETIME_TYPE)) {
             return castDateTime(literal);
         }
         if (dataType.equals(SPARQLConstants.BOOLEAN_TYPE)) {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/DataTypeLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/DataTypeLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/DataTypeLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/DataTypeLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -21,22 +21,17 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class DataTypeLogic implements ExpressionLogic {
+public class DataTypeLogic extends FunctionLogic {
 
-	/**
-	 * The data holding the argument to evaluate.
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * Creates a new logic object that returns the IRI of the datatype of a
-	 * particular typed literal.
-	 * 
-	 * @param data the argument data
-	 */
-	public DataTypeLogic(CallExpressionData data) {
-		this.data = data;
-	}
+    /**
+     * Creates a new logic object that returns the IRI of the datatype of a
+     * particular typed literal.
+     * 
+     * @param data the argument data
+     */
+    public DataTypeLogic(CallExpressionData data) {
+        super(data);
+    }
 
 	/**
 	 * Evaluates the datatype of a typed literal that is an argument.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/DateTimeCastFunction.java work-copy/src/main/name/levering/ryan/sparql/logic/function/DateTimeCastFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/DateTimeCastFunction.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/DateTimeCastFunction.java	2008-08-09 17:06:38.000000000 -0400
@@ -44,7 +44,7 @@
     public Value castString(Literal literal) throws IllegalCastException {
         try {
             new DateTime(literal.getLabel());
-            return this.factory.createLiteral(literal.getLabel(), SPARQLConstants.DATE_TYPE);
+            return this.factory.createLiteral(literal.getLabel(), SPARQLConstants.DATETIME_TYPE);
         } catch (IllegalArgumentException e) {
             throw new IllegalCastException("Unable to cast string to dateTime");
         }
@@ -101,7 +101,7 @@
      * @return a literal of type xsd:dateTime, representing the cast value
      */
     public Value castDateTime(Literal literal) throws IllegalCastException {
-        return this.factory.createLiteral(literal.getLabel(), SPARQLConstants.DATE_TYPE);
+        return this.factory.createLiteral(literal.getLabel(), SPARQLConstants.DATETIME_TYPE);
     }
 
     /**
@@ -137,7 +137,7 @@
     public Value castLiteral(Literal literal) throws IllegalCastException {
         try {
             new DateTime(literal.getLabel());
-            return this.factory.createLiteral(literal.getLabel(), SPARQLConstants.DATE_TYPE);
+            return this.factory.createLiteral(literal.getLabel(), SPARQLConstants.DATETIME_TYPE);
         } catch (IllegalArgumentException e) {
             throw new IllegalCastException("Unable to cast string to dateTime");
         }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/DecimalCastFunction.java work-copy/src/main/name/levering/ryan/sparql/logic/function/DecimalCastFunction.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/DecimalCastFunction.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/DecimalCastFunction.java	2007-10-21 12:35:15.000000000 -0400
@@ -144,11 +144,11 @@
      */
     public Value castLiteral(Literal literal) throws IllegalCastException {
         try {
-            Long.parseLong(literal.getLabel());
+            Double.parseDouble(literal.getLabel());
             return this.factory.createLiteral(literal.getLabel(),
                     SPARQLConstants.DECIMAL_TYPE);
         } catch (NumberFormatException e) {
-            throw new IllegalCastException("Unable to cast string to integer");
+            throw new IllegalCastException("Unable to cast string to double");
         }
     }
     
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/ExternalFunctionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/ExternalFunctionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/ExternalFunctionLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/ExternalFunctionLogic.java	2008-07-11 15:31:54.000000000 -0400
@@ -23,34 +23,29 @@
  * @author Ryan Levering
  * @version 1.1
  */
-public class ExternalFunctionLogic implements ExpressionLogic {
+public class ExternalFunctionLogic extends FunctionLogic {
 
-	/**
-	 * The data containing the argument expressions to evaluate
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * The function to delegate the logic to.
-	 */
-	private final ExternalFunction function;
-
-	/**
-	 * The factory that's used to convert returns into SPARQL values.
-	 */
-	private final SPARQLValueFactory factory;
-
-	/**
-	 * Creates a new external function logic that evaluates a function call to
-	 * produce a Value.
-	 * 
-	 * @param data the data containing the function arguments and it's name
-	 */
-	public ExternalFunctionLogic(CallExpressionData data, ExternalFunction function, SPARQLValueFactory factory) {
-		this.data = data;
-		this.function = function;
-		this.factory = factory;
-	}
+    /**
+     * The function to delegate the logic to.
+     */
+    private final ExternalFunction function;
+
+    /**
+     * The factory that's used to convert returns into SPARQL values.
+     */
+    private SPARQLValueFactory factory;
+    
+    /**
+     * Creates a new external function logic that evaluates a function call to
+     * produce a Value.
+     * 
+     * @param data the data containing the function arguments and it's name
+     */
+    public ExternalFunctionLogic(CallExpressionData data, ExternalFunction function, SPARQLValueFactory factory) {
+        super(data);
+        this.function = function;
+        this.factory = factory;
+    }
 
 	/**
 	 * Evaluates the function by evaluating the arguments and passing them to
@@ -68,8 +63,7 @@
 			// Convert the return value to an evaluable Value
 			return this.factory.createValue(value);
 		} catch (ExternalFunctionException e) {
-			// TODO Should be some exception?
-			return null;
+			throw new RuntimeException("External function " + this.function + " threw an exception: " + e);
 		}
 
 	}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/FunctionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/FunctionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/FunctionLogic.java	1969-12-31 19:00:00.000000000 -0500
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/FunctionLogic.java	2008-08-06 17:38:02.000000000 -0400
@@ -0,0 +1,48 @@
+/*
+ * SPARQL Engine
+ * Copyright (C) 2005 Ryan Levering, All rights reserved.
+ * See LICENSE for full license information
+ */
+package name.levering.ryan.sparql.logic.function;
+
+import java.util.Iterator;
+import java.util.Set;
+
+import name.levering.ryan.sparql.common.RdfBindingRow;
+import name.levering.ryan.sparql.common.Variable;
+import name.levering.ryan.sparql.model.data.CallExpressionData;
+import name.levering.ryan.sparql.model.logic.ExpressionLogic;
+import name.levering.ryan.sparql.model.logic.helper.ValueConversionLogic;
+
+import name.levering.ryan.sparql.common.Value;
+
+/**
+ * The base class of function-type logics.
+ * 
+ * @author Ryan Levering
+ * @version 1.0
+ */
+public abstract class FunctionLogic implements ExpressionLogic {
+
+    /**
+     * The data holding the arguments of the bound function.
+     */
+    protected CallExpressionData data;
+
+    /**
+     * Creates a new logic object that handles sop:bound function calls.
+     * 
+     * @param data the data holding the expression arguments to evaluate
+     * @param converter
+     */
+    public FunctionLogic(CallExpressionData data) {
+        this.data = data;
+    }
+
+	 public java.util.Set getVariables() {
+		 java.util.HashSet ret = new java.util.HashSet();
+		 for (Iterator i = this.data.getArguments().iterator(); i.hasNext(); )
+			 ret.addAll(((ExpressionLogic)i.next()).getVariables());
+		 return ret;
+	 }
+}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/IsBlankLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/IsBlankLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/IsBlankLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/IsBlankLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -21,30 +21,23 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class IsBlankLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the argument to evaluate for blank node.
-	 */
-	private final CallExpressionData data;
-
+public class IsBlankLogic extends FunctionLogic {
 	/**
 	 * The converter used to return the true or false value.
 	 */
 	private final ValueConversionLogic converter;
 
-	/**
-	 * Creates a new logic object that can evaluate whether a bound variable or
-	 * value is a blank node.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 * @param converter the value conversion logic to convert the boolean to a
-	 *            literal
-	 */
-	public IsBlankLogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
-		this.converter = converter;
-	}
+    /**
+     * Creates a new logic object that can evaluate whether a bound variable or
+     * value is a blank node.
+     * 
+     * @param data the data holding the argument for evaluation
+     * @param converter the value conversion logic to convert the boolean to a literal
+     */
+    public IsBlankLogic(CallExpressionData data, ValueConversionLogic converter) {
+        super(data);
+        this.converter = converter;
+    }
 
 	/**
 	 * Evaluates whether the value returned by an expression is a blank node.
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/IsIRILogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/IsIRILogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/IsIRILogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/IsIRILogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -21,38 +21,30 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class IsIRILogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the argument to evaluate for IRI.
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * The converter used to return the true or false value.
-	 */
-	private final ValueConversionLogic converter;
-
-	/**
-	 * Creates a new logic object that can evaluate whether a bound variable or
-	 * value is an IRI.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 * @param converter the value conversion logic to convert the boolean to a
-	 *            literal
-	 */
-	public IsIRILogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
-		this.converter = converter;
-	}
-
-	/**
-	 * Evaluates whether the value returned by an expression is an IRI.
-	 * 
-	 * @param bindings the value bindings to use in argument evaluation
-	 * @return true or false literals representing whether the argument is an
-	 *         IRI
-	 */
+public class IsIRILogic extends FunctionLogic {
+    /**
+     * The converter used to return the true or false value.
+     */
+    private final ValueConversionLogic converter;
+    
+    /**
+     * Creates a new logic object that can evaluate whether a bound variable or
+     * value is an IRI.
+     * 
+     * @param data the data holding the argument for evaluation
+     * @param converter the value conversion logic to convert the boolean to a literal
+     */
+    public IsIRILogic(CallExpressionData data, ValueConversionLogic converter) {
+        super(data);
+        this.converter = converter;
+    }
+    
+    /**
+     * Evaluates whether the value returned by an expression is an IRI.
+     * 
+     * @param bindings the value bindings to use in argument evaluation
+     * @return true or false literals representing whether the argument is an IRI
+     */
 	public Value evaluate(RdfBindingRow bindings) {
 		ExpressionLogic expression = (ExpressionLogic) this.data.getArguments().get(0);
 		Object value = expression.evaluate(bindings);
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/IsLiteralLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/IsLiteralLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/IsLiteralLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/IsLiteralLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -21,38 +21,31 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class IsLiteralLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the argument to evaluate for literal.
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * The converter used to return the true or false value.
-	 */
-	private final ValueConversionLogic converter;
-
-	/**
-	 * Creates a new logic object that can evaluate whether a bound variable or
-	 * value is a literal.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 * @param converter the value conversion logic to convert the boolean to a
-	 *            literal
-	 */
-	public IsLiteralLogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
-		this.converter = converter;
-	}
-
-	/**
-	 * Evaluates whether the value returned by an expression is a literal.
-	 * 
-	 * @param bindings the value bindings to use in argument evaluation
-	 * @return true or false literals representing whether the argument is an
-	 *         literal
-	 */
+public class IsLiteralLogic extends FunctionLogic {
+   
+    /**
+     * The converter used to return the true or false value.
+     */
+    private final ValueConversionLogic converter;
+    
+    /**
+     * Creates a new logic object that can evaluate whether a bound variable or
+     * value is a literal.
+     * 
+     * @param data the data holding the argument for evaluation
+     * @param converter the value conversion logic to convert the boolean to a literal
+     */
+    public IsLiteralLogic(CallExpressionData data, ValueConversionLogic converter) {
+        super(data);
+        this.converter = converter;
+    }
+    
+    /**
+     * Evaluates whether the value returned by an expression is a literal.
+     * 
+     * @param bindings the value bindings to use in argument evaluation
+     * @return true or false literals representing whether the argument is an literal
+     */
 	public Value evaluate(RdfBindingRow bindings) {
 		ExpressionLogic expression = (ExpressionLogic) this.data.getArguments().get(0);
 		Object value = expression.evaluate(bindings);
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/LangLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/LangLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/LangLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/LangLogic.java	2008-07-11 15:31:54.000000000 -0400
@@ -11,6 +11,7 @@
 import name.levering.ryan.sparql.model.data.CallExpressionData;
 import name.levering.ryan.sparql.model.logic.ExpressionLogic;
 import name.levering.ryan.sparql.model.logic.helper.ValueConversionLogic;
+import name.levering.ryan.sparql.logic.expression.TypeError;
 
 /**
  * The logic to evaluate the sop:lang SPARQL function, found in section 11.2.3.8
@@ -20,30 +21,22 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class LangLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the argument to evaluate for literal language.
-	 */
-	private final CallExpressionData data;
-
+public class LangLogic extends FunctionLogic {
 	/**
 	 * The converter used to return the string value.
 	 */
 	private final ValueConversionLogic converter;
 
-	/**
-	 * Creates a new logic object that can return the language of a given
-	 * literal.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 * @param converter the value conversion logic to convert the string to a
-	 *            literal
-	 */
-	public LangLogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
-		this.converter = converter;
-	}
+   /**
+    * Creates a new logic object that can return the language of a given literal.
+    * 
+    * @param data the data holding the argument for evaluation
+    * @param converter the value conversion logic to convert the string to a literal
+    */
+    public LangLogic(CallExpressionData data, ValueConversionLogic converter) {
+        super(data);
+        this.converter = converter;
+    }
 
 	/**
 	 * Returns the language of a language tagged literal.
@@ -53,8 +46,14 @@
 	 */
 	public Value evaluate(RdfBindingRow bindings) {
 		ExpressionLogic expression = (ExpressionLogic) this.data.getArguments().get(0);
-		Literal literal = (Literal) expression.evaluate(bindings);
+		Value value = expression.evaluate(bindings);
+		if (!(value instanceof Literal))
+			throw new TypeError("The lang function only works on literals");
+
+		Literal literal = (Literal) value;
 		String result = literal.getLanguage();
+		if (result == null)
+			result = "";
 
 		return this.converter.convertString(result);
 	}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/LangMatchesLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/LangMatchesLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/LangMatchesLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/LangMatchesLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -20,14 +20,7 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public class LangMatchesLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the arguments to evaluate for language range and
-	 * literal to match.
-	 */
-	private final CallExpressionData data;
-
+public class LangMatchesLogic extends FunctionLogic {
 	/**
 	 * The converter used to return the boolean value.
 	 */
@@ -42,7 +35,7 @@
 	 *            literal
 	 */
 	public LangMatchesLogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
+		super(data);
 		this.converter = converter;
 	}
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/RegexLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/RegexLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/RegexLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/RegexLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -25,31 +25,25 @@
  * @author Ryan Levering
  * @version 1.1
  */
-public class RegexLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the argument to evaluate for string matching.
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * The converter used to return the boolean literal and convert the string
-	 * value.
-	 */
-	private final ValueConversionLogic converter;
-
-	/**
-	 * Creates a new logic object that can evaluate whether one string occurs in
-	 * another.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 * @param converter the value conversion logic to convert the result to a
-	 *            literal and the strings to Java strings
-	 */
-	public RegexLogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
-		this.converter = converter;
-	}
+public class RegexLogic extends FunctionLogic {
+    /**
+     * The converter used to return the boolean literal and convert the string
+     * value.
+     */
+    private final ValueConversionLogic converter;
+
+    /**
+     * Creates a new logic object that can evaluate whether one string occurs in
+     * another.
+     * 
+     * @param data the data holding the argument for evaluation
+     * @param converter the value conversion logic to convert the result to a
+     *            literal and the strings to Java strings
+     */
+    public RegexLogic(CallExpressionData data, ValueConversionLogic converter) {
+        super(data);
+        this.converter = converter;
+    }
 
 	/**
 	 * Converts the evaluated arguments to strings and uses Java string matching
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/SameTermLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/SameTermLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/SameTermLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/SameTermLogic.java	1969-12-31 19:00:00.000000000 -0500
@@ -1,65 +0,0 @@
-/*
- * SPARQL Engine
- * Copyright (C) 2005 Ryan Levering, All rights reserved.
- * See LICENSE for full license information
- */
-package name.levering.ryan.sparql.logic.function;
-
-import name.levering.ryan.sparql.common.RdfBindingRow;
-import name.levering.ryan.sparql.model.data.CallExpressionData;
-import name.levering.ryan.sparql.model.logic.ExpressionLogic;
-import name.levering.ryan.sparql.model.logic.helper.ValueConversionLogic;
-
-import name.levering.ryan.sparql.common.Value;
-
-/**
- * The logic to evaluate the sop:langMatches SPARQL function, found in section
- * 11.4.11 of the specification. It returns whether or not a literal has a
- * language tag in the language range specified by the second argument.
- * 
- * @author Ryan Levering
- * @version 1.0
- */
-public class SameTermLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the arguments to evaluate for language range and
-	 * literal to match.
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * The converter used to return the boolean value.
-	 */
-	private final ValueConversionLogic converter;
-
-	/**
-	 * Creates a new logic object that can check a literal for being in a
-	 * certain language range.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 * @param converter the value conversion logic to convert the boolean to a
-	 *            literal
-	 */
-	public SameTermLogic(CallExpressionData data, ValueConversionLogic converter) {
-		this.data = data;
-		this.converter = converter;
-	}
-
-	/**
-	 * Returns whether or not a literal falls within a language range.
-	 * 
-	 * @param bindings the value bindings to use in argument evaluation
-	 * @return boolean literal representing the language match outcome
-	 */
-	public Value evaluate(RdfBindingRow bindings) {
-		ExpressionLogic expression = (ExpressionLogic) this.data.getArguments().get(0);
-		Value value = expression.evaluate(bindings);
-
-		expression = (ExpressionLogic) this.data.getArguments().get(1);
-		Value value2 = expression.evaluate(bindings);
-
-		return this.converter.convertBoolean(value.equals(value2));
-	}
-
-}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/function/StrLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/function/StrLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/function/StrLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/function/StrLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -22,28 +22,22 @@
  * @author Ryan Levering
  * @version 1.2
  */
-public class StrLogic implements ExpressionLogic {
-
-	/**
-	 * The data that holds the argument to evaluate for string conversion.
-	 */
-	private final CallExpressionData data;
-
-	/**
-	 * The factory used to create new string literals.
-	 */
-	private final SPARQLValueFactory factory;
-
-	/**
-	 * Creates a new logic object that can evaluate the string representation of
-	 * a IRI or literal.
-	 * 
-	 * @param data the data holding the argument for evaluation
-	 */
-	public StrLogic(CallExpressionData data, SPARQLValueFactory factory) {
-		this.data = data;
-		this.factory = factory;
-	}
+public class StrLogic extends FunctionLogic {
+    /**
+     * The factory used to create new string literals.
+     */
+    private final SPARQLValueFactory factory;
+
+    /**
+     * Creates a new logic object that can evaluate the string representation of
+     * a IRI or literal.
+     * 
+     * @param data the data holding the argument for evaluation
+     */
+    public StrLogic(CallExpressionData data, SPARQLValueFactory factory) {
+        super(data);
+        this.factory = factory;
+    }
 
 	/**
 	 * Evaluates the argument to the function and does simplistic conversion to
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultFilterConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultFilterConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultFilterConstraintLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultFilterConstraintLogic.java	2008-08-13 15:24:48.000000000 -0400
@@ -8,6 +8,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Iterator;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -67,24 +68,18 @@
      * Filters the passed in binding set, only adding those rows that return a
      * true boolean value to the returned binding set.
      * 
-     * @param bindings the current bound values
-     * @param source the RDF source, not used in this constraint
-     * @param defaultDatasets the datasets to query, not used in this constraint
-     * @param namedDatasets the named datasets for graph queries, not used in
-     *            this constraint
      * @return a binding set with values that pass through the filter expression
      */
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source,
-            Collection defaultDatasets, Collection namedDatasets) {
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
         // Grab the necessary fields from the data
         ExpressionLogic filterExpression = this.data.getExpression();
 
         // Create a new binding set with the same variables
         RdfBindingSetImpl newBindings = new RdfBindingSetImpl(
-                bindings.getVariables());
+                p.bindings.getVariables());
 
         // Only add rows to the new set if they return true boolean literals
-        for (Iterator rows = bindings.iterator(); rows.hasNext();) {
+        for (Iterator rows = p.bindings.iterator(); rows.hasNext();) {
             RdfBindingRow row = (RdfBindingRow) rows.next();
             try {
                 Value rawEvaluate = filterExpression.evaluate(row);
@@ -97,16 +92,4 @@
         }
         return newBindings;
     }
-
-    /**
-     * Currently does nothing, as I'm not even sure what this method is used for
-     * and the filter constraint doesn't really change the variable bindings at
-     * all.
-     * 
-     * @return an empty list always
-     */
-    public Collection getVariables() {
-        return Collections.EMPTY_LIST;
-    }
-
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultGroupConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultGroupConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultGroupConstraintLogic.java	2006-08-20 20:01:01.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultGroupConstraintLogic.java	2008-08-13 15:24:36.000000000 -0400
@@ -9,6 +9,7 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -64,27 +65,20 @@
 	/**
 	 * Applies each subconstraint in turn, saving filter and optional
 	 * constraints for last, as according to specification.
-	 * 
-	 * @param bindings the current running bindings, ignored here
-	 * @param source the source to query RDF triples, passed on to
-	 *            subconstraints
-	 * @param defaultDatasets the datasets to query by default, passed on to
-	 *            subconstraints
-	 * @param namedDatasets the named datasets to query in an unbound graph
-	 *            query, passed on to subconstraints
 	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
-		return this.constrain(bindings, source, defaultDatasets, namedDatasets, true);
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+		return this.constrain(p, true);
 	}
 
-	private RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets, boolean withFilter) {
+	private RdfBindingSet constrain(ConstraintLogic.CallParams p, boolean withFilter) {
 
 		List filterQueue = new LinkedList();
 		List optionalQueue = new LinkedList();
 		List graphQueue = new LinkedList();
 
+		ConstraintLogic.CallParams p2 = p.clone();
+		p2.bindings = null;
+
 		RdfBindingSet current = null;
 		// Constrain in order, unless we hit an optional, graph, or value filter
 		// These things all kind of depend on the previous bindings
@@ -99,7 +93,7 @@
 			} else if (c instanceof GraphConstraintData) {
 				graphQueue.add(c);
 			} else {
-				this.orderLogic.addBindingSet(c.constrain(null, source, defaultDatasets, namedDatasets));
+				this.orderLogic.addBindingSet(c.constrain(p2));
 			}
 
 		}
@@ -108,10 +102,18 @@
 		// This scoped graphing isn't required by the spec, but it's allowed
 		for (Iterator graphs = graphQueue.iterator(); graphs.hasNext();) {
 			ConstraintLogic c = (ConstraintLogic) graphs.next();
+			p2.bindings = current;
+			
+			// we would have to do more to pass these down reliably/usefully
+			p2.offset = 0;
+			p2.limit = -1;
+			p2.distinguishedVariables = null;
+			p2.orderExpressions = null;
+				
 			if (current == null) {
-				current = c.constrain(null, source, defaultDatasets, namedDatasets);
+				current = c.constrain(p2);
 			} else {
-				current = this.logic.intersect(current, c.constrain(current, source, defaultDatasets, namedDatasets));
+				current = this.logic.intersect(current, c.constrain(p2));
 			}
 		}
 
@@ -123,12 +125,18 @@
 
 		for (Iterator optionals = optionalQueue.iterator(); optionals.hasNext();) {
 			ConstraintLogic c = (ConstraintLogic) optionals.next();
-			current = c.constrain(current, source, defaultDatasets, namedDatasets);
+			p2.bindings = current;
+			// note that we pass down the limit
+			current = c.constrain(p2);
 		}
 		for (Iterator filters = filterQueue.iterator(); filters.hasNext();) {
 			ConstraintLogic c = (ConstraintLogic) filters.next();
-			current = c.constrain(current, source, defaultDatasets, namedDatasets);
+			p2.bindings = current;
+			current = c.constrain(p2);
 		}
+		
+		current = p.projectOrderDistinctLimit(current);
+		
 		return current;
 	}
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultOptionalConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultOptionalConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultOptionalConstraintLogic.java	2006-08-20 20:01:01.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultOptionalConstraintLogic.java	2008-08-13 15:24:56.000000000 -0400
@@ -6,9 +6,12 @@
 package name.levering.ryan.sparql.logic.naive;
 
 import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
@@ -16,8 +19,12 @@
 import name.levering.ryan.sparql.model.FilterConstraint;
 import name.levering.ryan.sparql.model.GraphConstraint;
 import name.levering.ryan.sparql.model.OptionalConstraint;
+import name.levering.ryan.sparql.model.data.ConstraintData;
+import name.levering.ryan.sparql.model.data.FilterConstraintData;
+import name.levering.ryan.sparql.model.data.GroupConstraintData;
 import name.levering.ryan.sparql.model.data.OptionalConstraintData;
 import name.levering.ryan.sparql.model.logic.ConstraintLogic;
+import name.levering.ryan.sparql.model.logic.LogicFactory;
 import name.levering.ryan.sparql.model.logic.helper.IntersectOrderLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetIntersectLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetJoinLogic;
@@ -43,9 +50,7 @@
 	 */
 	private final SetJoinLogic logic;
 
-	private final IntersectOrderLogic orderLogic;
-
-	private final SetIntersectLogic intersectLogic;
+	private final LogicFactory factory;
 
 	/**
 	 * Creates a new optional constraint logic object that expands a binding set
@@ -54,75 +59,56 @@
 	 * @param data the data that holds the constraints
 	 * @param logic the logic to calculate the set join operation
 	 */
-	public DefaultOptionalConstraintLogic(OptionalConstraintData data, SetIntersectLogic intersectLogic,
-			IntersectOrderLogic orderLogic, SetJoinLogic logic) {
+	public DefaultOptionalConstraintLogic(OptionalConstraintData data, SetJoinLogic logic, LogicFactory factory) {
 		this.data = data;
 		this.logic = logic;
-		this.orderLogic = orderLogic;
-		this.intersectLogic = intersectLogic;
+		this.factory = factory;
 	}
 
 	/**
 	 * Calculates a new binding set by expanding the passed bindings with the
 	 * bindings from the enclosed constraints.
-	 * 
-	 * @param bindings the current value bindings, used as the base for
-	 *            expansion
-	 * @param source the RDF triple source, passed onto the grouped constraint
-	 * @param defaultDatasets the datasets to query, passed onto the grouped
-	 *            constraint
-	 * @param namedDatasets the named datasets for named queries, passed onto
-	 *            the grouped constraint
 	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+		
+		// Interestingly, some filters will reference variables at a higher scope,
+		// and so we have to delay applying at least those filters (but for now
+		// all filters) until the join.
+
 		List filterQueue = new LinkedList();
-		List optionalQueue = new LinkedList();
-		List graphQueue = new LinkedList();
+		OptionalGroupConstraintData groupData = new OptionalGroupConstraintData();
 
-		RdfBindingSet current = null;
-		// Constrain in order, unless we hit an optional, graph, or value filter
-		// These things all kind of depend on the previous bindings
-		// Graph probably shouldn't technically, but I think in this
-		// implementation it does
 		for (Iterator cons = this.data.getConstraint().getConstraints().iterator(); cons.hasNext();) {
 			ConstraintLogic c = (ConstraintLogic) cons.next();
-			if (c instanceof OptionalConstraint) {
-				optionalQueue.add(c);
-			} else if (c instanceof FilterConstraint) {
+			if (c instanceof FilterConstraintData) {
 				filterQueue.add(c);
-			} else if (c instanceof GraphConstraint) {
-				graphQueue.add(c);
-			} else {
-				this.orderLogic.addBindingSet(c.constrain(null, source, defaultDatasets, namedDatasets));
-			}
-
-		}
-		current = this.orderLogic.removeIntersectedSet();
-
-		// This isn't required by the spec, but it's allowed
-		for (Iterator graphs = graphQueue.iterator(); graphs.hasNext();) {
-			ConstraintLogic c = (ConstraintLogic) graphs.next();
-			if (current == null) {
-				current = c.constrain(null, source, defaultDatasets, namedDatasets);
 			} else {
-				current = this.intersectLogic.intersect(current, c.constrain(current, source, defaultDatasets,
-						namedDatasets));
+				groupData.constraints.add(c);
 			}
 		}
-
-		// At this point, we don't have any constraints so just bring the whole
-		// set in
-		if (current == null) {
-			current = new RdfBindingSetImpl();
-		}
-
-		for (Iterator optionals = optionalQueue.iterator(); optionals.hasNext();) {
-			ConstraintLogic c = (ConstraintLogic) optionals.next();
-			current = c.constrain(current, source, defaultDatasets, namedDatasets);
-		}
 		
-		return this.logic.join(bindings, current, filterQueue);
+		// Use a GroupConstraintLogic to perform the intersections within this OPTIONAL.
+		ConstraintLogic group = factory.getGroupConstraintLogic(groupData);
+		RdfBindingSet bindings = group.constrain(p);
+		
+		// Join our bindings with the caller's outer bindings.
+		bindings = this.logic.join(p.bindings, bindings, filterQueue);
+		
+		bindings = p.projectOrderDistinctLimit(bindings);
+		
+		return bindings;
 	}
 
+	public class OptionalGroupConstraintData implements GroupConstraintData {
+		public LinkedList constraints = new LinkedList();
+		public Collection getConstraints() { return constraints; }
+		public Set getVariables() {
+        Set variableList = new HashSet();
+        for (Iterator cons = getConstraints().iterator(); cons.hasNext();) {
+            ConstraintData c = (ConstraintData) cons.next();
+            variableList.addAll(c.getVariables());
+        }
+        return variableList;
+	 	}
+	}
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultTripleConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultTripleConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultTripleConstraintLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultTripleConstraintLogic.java	2008-08-17 11:20:44.000000000 -0400
@@ -9,7 +9,10 @@
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
+import name.levering.ryan.sparql.common.AdvancedRdfSource;
 import name.levering.ryan.sparql.common.GraphStatement;
 import name.levering.ryan.sparql.common.LenientStatement;
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -54,16 +57,8 @@
      * Returns a binding set of bound values matching a particular subject,
      * predicate, and object where one or more of them is a wildcard.
      * 
-     * @param bindings the current bindings, not used in this constraint
-     * @param source the source to query for the statement constraints
-     * @param defaultDatasets the datasets to query, if non-default graphs are
-     *            being used
-     * @param namedDatasets the named datasets to use in graph constraints, not
-     *            used in this constraint
-     * 
      */
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source,
-            Collection defaultDatasets, Collection namedDatasets) {
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
 
         ExpressionLogic subExpr = this.data.getSubjectExpression();
         ExpressionLogic predExpr = this.data.getPredicateExpression();
@@ -104,81 +99,80 @@
             object = (Value) objExpr;
         }
 
-        RdfBindingSetImpl newBindings = new RdfBindingSetImpl(
+        if (variables.isEmpty()) {
+	        RdfBindingSetImpl emptyBindings = new RdfBindingSetImpl(
                 (Variable[]) variables.toArray(new Variable[0]));
-
-        Iterator statements;
-        if (!variables.isEmpty()) {
-            if (defaultDatasets == null) {
-                // This adds an extra column to the returned set for the GRAPH
-                // constraint to process
-                variables.add(StreamedGraphConstraintLogic.CONTEXT_VARIABLE);
-                newBindings = new RdfBindingSetImpl(
-                        (Variable[]) variables.toArray(new Variable[0]));
-                statements = source.getStatements(subject, verb, object);
-                addGraphStatements(newBindings, statements, flags);
-            } else {
-                if (defaultDatasets.isEmpty()) {
-                    // This is if no FROM graphs are specified
-                    statements = source.getDefaultStatements(subject, verb,
-                            object);
-                    addStatements(newBindings, statements, flags);
-                } else {
-                    // This is if FROM graphs are specified or FROM NAMED and
-                    // we're in a GRAPH constraint
-                    for (Iterator i = defaultDatasets.iterator(); i.hasNext();) {
-                        statements = source.getStatements(subject, verb,
-                                object, (URI) i.next());
-                        addStatements(newBindings, statements, flags);
-                    }
-                }
-            }
+        	return emptyBindings;
         }
-        return newBindings;
-    }
+        
+		if (p.graphVariable != null) {
+			variables.add(p.graphVariable);
+		}
+		
+        RdfBindingSetImpl newBindings = new RdfBindingSetImpl(
+                        (Variable[]) variables.toArray(new Variable[0]));
+        Iterator statements;
 
-    /**
-     * Adds statements to a binding set, according to whether the field was
-     * being bound to a variable or not.
-     * 
-     * @param set the set to add the statements to
-     * @param statements the fully realized statements from the source
-     * @param flags an array holding flags that specify which fields to use
-     */
-    private void addStatements(RdfBindingSetImpl set, Iterator statements,
-            int[] flags) {
-        while (statements.hasNext()) {
-            LenientStatement statement = (LenientStatement) statements.next();
-            if (flags[0] != 0 && flags[0] == flags[2]) {
-                if (!statement.getSubject().equals(statement.getObject())) {
-                    continue;
-                }
-            }
-            if (flags[0] != 0 && flags[0] == flags[1]) {
-                if (!statement.getSubject().equals(statement.getPredicate())) {
-                    continue;
-                }
-            }
-            if (flags[1] != 0 && flags[1] == flags[2]) {
-                if (!statement.getPredicate().equals(statement.getObject())) {
-                    continue;
-                }
-            }
-            
-            RdfBindingRowImpl newRow = new RdfBindingRowImpl();
-            if (flags[0] == 1) {
-                newRow.addBinding((Variable) this.data.getSubjectExpression(), statement.getSubject());
-            }
-            if (flags[1] == 2) {
-                newRow.addBinding((Variable) this.data.getPredicateExpression(), statement.getPredicate());
-            }
-            if (flags[2] == 3) {
-                newRow.addBinding((Variable) this.data.getObjectExpression(), statement.getObject());
-            }
-            set.addRow(newRow);
-        }
+		if (!(p.source instanceof AdvancedRdfSource)) {
+			if (p.sourceDatasets == null) {
+				// When querying the default dataset, we always use this method and do not pass
+				// any graph information. It is up to the data source to handle FROM clauses.
+				statements = p.source.getDefaultGraphStatements(subject, verb, object);
+				/*if (p.defaultDatasets.size() == 0) {
+					statements = p.source.getDefaultGraphStatements(subject, verb, object);
+				} else {
+					statements = p.source.getStatements(subject, verb, object, (URI[])p.defaultDatasets.toArray(new URI[0]));
+				}*/
+		  } else {
+			 if (p.sourceDatasets.size() == 0) {
+					 statements = p.source.getNamedGraphStatements(subject, verb, object);
+				} else {
+					statements = p.source.getStatements(subject, verb, object, (URI[])p.sourceDatasets.toArray(new URI[0]));
+				}
+		  }
+	    } else {
+	    	AdvancedRdfSource src = (AdvancedRdfSource)p.source;
+
+			Value[] subject2 = getValues(subExpr, p);
+			Value[] verb2 = getValues(predExpr, p);
+			Value[] object2 = getValues(objExpr, p);
+			Object[] litFilters = getFilters(objExpr, p);
+
+			if (p.sourceDatasets == null) {
+			    if (p.defaultDatasets.size() == 0) {
+	                statements = src.getDefaultGraphStatements(subject2, verb2, object2, litFilters, p.limit);
+	            } else {
+	            	statements = src.getStatements(subject2, verb2, object2, (URI[])p.defaultDatasets.toArray(new URI[0]), litFilters, p.limit);
+	            }
+	        } else {
+			    if (p.sourceDatasets.size() == 0) {
+	                statements = src.getNamedGraphStatements(subject2, verb2, object2, litFilters, p.limit);
+	            } else {
+	            	statements = src.getStatements(subject2, verb2, object2, (URI[])p.sourceDatasets.toArray(new URI[0]), litFilters, p.limit);
+	            }
+	        }
+	    }
+        
+        addStatements(newBindings, statements, flags, p.graphVariable);
+        
+        return p.projectOrderDistinctLimit(newBindings);
     }
 
+	private Value[] getValues(ExpressionLogic value, ConstraintLogic.CallParams p) {
+		if (!(value instanceof Variable)) return new Value[] { (Value)value };
+		if (p.knownValues == null) return null;
+		Set values = (Set)p.knownValues.get((Variable)value);
+		if (values == null) return null;
+		return (Value[])values.toArray(new Value[0]);
+	}
+	private Object[] getFilters(ExpressionLogic value, ConstraintLogic.CallParams p) {
+		if (!(value instanceof Variable)) return null;
+		if (p.knownFilters == null) return null;
+		List filters = (List)p.knownFilters.get((Variable)value);
+		if (filters == null) return null;
+		return filters.toArray();
+	}
+
     /**
      * Adds statements to a binding set, according to whether the field was
      * being bound to a variable or not.
@@ -187,8 +181,8 @@
      * @param statements the fully realized statements from the source
      * @param flags an array holding flags that specify which fields to use
      */
-    private void addGraphStatements(RdfBindingSetImpl set, Iterator statements,
-            int[] flags) {
+    private void addStatements(RdfBindingSetImpl set, Iterator statements,
+            int[] flags, Variable graphVariable) {
         while (statements.hasNext()) {
             GraphStatement statement = (GraphStatement) statements.next();
             if (flags[0] != 0 && flags[0] == flags[2]) {
@@ -217,7 +211,9 @@
             if (flags[2] == 3) {
                 newRow.addBinding((Variable) this.data.getObjectExpression(), statement.getObject());
             }
-            newRow.addBinding(StreamedGraphConstraintLogic.CONTEXT_VARIABLE, statement.getGraphName());
+            if (graphVariable != null) {
+                newRow.addBinding(graphVariable, statement.getGraphName());
+            }
             set.addRow(newRow);
         }
     }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultUnionConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultUnionConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultUnionConstraintLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/DefaultUnionConstraintLogic.java	2008-09-08 07:53:55.000000000 -0400
@@ -7,9 +7,12 @@
 
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.common.RdfSource;
+import name.levering.ryan.sparql.common.impl.RdfBindingSetImpl;
+import name.levering.ryan.sparql.model.GroupConstraint;
 import name.levering.ryan.sparql.model.data.UnionConstraintData;
 import name.levering.ryan.sparql.model.logic.ConstraintLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetUnionLogic;
@@ -51,27 +54,79 @@
 	 * Iterates over the collection of binding sets returned by the group
 	 * constraints and forms the aggregate union of all of them.
 	 * 
-	 * @param bindings the current bindings, not used in this constraint
-	 * @param source the RDF triple source, passed onto the sub constraints
-	 * @param defaultDatasets the default graphs to query, passed on to the sub
-	 *            constraints
-	 * @param namedDatasets the named graphs to query, passed on to the sub
-	 *            constraints
 	 * @return a set containing the union of all the bound values of all the sub
 	 *         constraints
 	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
 		RdfBindingSet current = null;
-		for (Iterator groupOrUnions = this.data.getConstraints().iterator(); groupOrUnions.hasNext();) {
-			ConstraintLogic group = (ConstraintLogic) groupOrUnions.next();
-			if (current == null) {
-				current = group.constrain(current, source, defaultDatasets, namedDatasets);
-			} else {
-				current = this.logic.union(current, group.constrain(current, source, defaultDatasets, namedDatasets));
+		
+		// Because of DISTINCT, we can't quite know how
+		// many rows to ask from each part to reach our limit.
+		// So we do something adaptive.
+		
+		int lastCount = 0;
+		int limitFactor = 1;
+		while (limitFactor < 10000) {
+			current = null;
+			
+			for (Iterator groupOrUnions = this.data.getConstraints().iterator(); groupOrUnions.hasNext();) {
+				ConstraintLogic group = (ConstraintLogic) groupOrUnions.next();
+				
+				ConstraintLogic.CallParams p2 = p.clone();
+				if (p2.distinguishedVariables != null)
+					p2.distinguishedVariables.addAll(p2.getOrderVariables());
+				
+				if (current == null) {
+					// If an offset is specified for the global results, I'm not
+					// sure how to pass down the limit, especially if the results
+					// are ordered.
+					if (p.offset != 0) {
+						// TODO
+						p2.offset = 0;
+						p2.limit = -1;
+					} else {
+						p2.limit *= limitFactor;
+					}
+					
+					current = group.constrain(p2);
+				} else {
+					// If a limit is provided, subtract from the limit the number
+					// of rows found already, and if we don't need any more, stop.
+					if (p.offset == 0 && p.limit >= 0) {
+						p2.limit = p.limit - current.size();
+						
+						if (p2.limit <= 0)
+							break;
+						
+						// But because of DISTINCT, it might be that none of the rows
+						// we get are new. So, we multiple our request by the limitFactor
+						// which increases adaptively.
+						p2.limit *= limitFactor;
+						
+					} else if (p.offset != 0) {
+						// TODO
+						p2.offset = 0;
+						p2.limit = -1;
+					}
+
+					current = this.logic.union(current, group.constrain(p2));
+				}
 			}
+	
+			current = p.projectOrderDistinctLimit(current);
+			
+			// When we've reached our limit, or if there is no limit,
+			// or if we didn't get any more bindings than with the last
+			// adaptive limit, we're done.
+			if (p.limit == -1 || current.size() >= p.limit || current.size() == lastCount)
+				break;
+			
+			lastCount = current.size();
+			
+			// Increase the factor to get more results next time.
+			limitFactor *= 3;
 		}
-
+		
 		return current;
 	}
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/NaiveSetJoinLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/NaiveSetJoinLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/NaiveSetJoinLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/NaiveSetJoinLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -121,6 +121,7 @@
                 }
             }
             if (!outerMatched) {
+                List values = new ArrayList();
                 RdfBindingRowImpl newRow = new RdfBindingRowImpl();
                 for (Iterator k = oldVariables.iterator(); k.hasNext();) {
                 	Variable var = (Variable) k.next();
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetRangeLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetRangeLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetRangeLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetRangeLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -5,6 +5,7 @@
  */
 package name.levering.ryan.sparql.logic.naive;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
 
@@ -13,8 +14,11 @@
 import name.levering.ryan.sparql.common.Variable;
 import name.levering.ryan.sparql.common.impl.RdfBindingRowImpl;
 import name.levering.ryan.sparql.common.impl.RdfBindingSetImpl;
+import name.levering.ryan.sparql.model.logic.ExpressionLogic;
 import name.levering.ryan.sparql.model.logic.helper.SetRangeLogic;
 
+import name.levering.ryan.sparql.common.Value;
+
 /**
  * This is the default in-memory algorithm to do set ranges and offsets. It
  * should only be used if caching of some sort is important, so a concrete
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetUnionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetUnionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetUnionLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/naive/StaticSetUnionLogic.java	2008-02-05 08:50:39.000000000 -0500
@@ -16,6 +16,8 @@
 import name.levering.ryan.sparql.common.impl.RdfBindingSetImpl;
 import name.levering.ryan.sparql.model.logic.helper.SetUnionLogic;
 
+import name.levering.ryan.sparql.common.Value;
+
 /**
  * This implements the default set union logic, which returns a binding set that
  * is the aggregation of two other binding sets. This implementation does this
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/AdvancedGroupConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/AdvancedGroupConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/AdvancedGroupConstraintLogic.java	1969-12-31 19:00:00.000000000 -0500
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/AdvancedGroupConstraintLogic.java	2008-08-13 16:24:53.000000000 -0400
@@ -0,0 +1,621 @@
+/*
+ * SPARQL Engine
+ * Copyright (C) 2005 Ryan Levering, All rights reserved.
+ * See LICENSE for full license information
+ */
+package name.levering.ryan.sparql.logic;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import name.levering.ryan.sparql.common.URI;
+import name.levering.ryan.sparql.common.BNode;
+import name.levering.ryan.sparql.common.Literal;
+import name.levering.ryan.sparql.common.Value;
+
+import name.levering.ryan.sparql.common.impl.AbstractRdfBindingRow;
+import name.levering.ryan.sparql.common.impl.InternalSPARQLValueFactory;
+import name.levering.ryan.sparql.common.RdfBindingSet;
+import name.levering.ryan.sparql.common.RdfBindingRow;
+import name.levering.ryan.sparql.common.RdfSource;
+import name.levering.ryan.sparql.common.Variable;
+import name.levering.ryan.sparql.common.impl.RdfBindingSetImpl;
+import name.levering.ryan.sparql.logic.function.ExternalFunctionLogic;
+import name.levering.ryan.sparql.logic.expression.AndLogic;
+import name.levering.ryan.sparql.logic.expression.BinaryLogic;
+import name.levering.ryan.sparql.logic.expression.EqualsLogic;
+import name.levering.ryan.sparql.logic.expression.OrLogic;
+import name.levering.ryan.sparql.model.TripleConstraint;
+import name.levering.ryan.sparql.model.data.ConstraintData;
+import name.levering.ryan.sparql.model.data.FilterConstraintData;
+import name.levering.ryan.sparql.model.data.GroupConstraintData;
+import name.levering.ryan.sparql.model.data.OptionalConstraintData;
+import name.levering.ryan.sparql.model.logic.ConstraintLogic;
+import name.levering.ryan.sparql.model.logic.ExpressionLogic;
+import name.levering.ryan.sparql.model.logic.helper.SetIntersectLogic;
+import name.levering.ryan.sparql.parser.model.ASTVar;
+import name.levering.ryan.sparql.parser.model.DelegatingTripleConstraint;
+import name.levering.ryan.sparql.parser.model.EmptyVisitor;
+import name.levering.ryan.sparql.parser.model.SimpleNode;
+
+/**
+ * This logic is the default logic for the main constraint that is used as an
+ * aggregate of other constraints. TripleConstraints, UnionConstraints, and
+ * GraphConstraints all are intersected with the running binding set. After
+ * that, OptionalConstraints and FilterConstraints modify the set themselves.
+ * 
+ * @author Ryan Levering
+ * @version 1.0
+ */
+public class AdvancedGroupConstraintLogic implements ConstraintLogic {
+
+    /**
+     * The data that holds the constraints that this group constraint
+     * aggregates.
+     */
+    private final GroupConstraintData data;
+
+    /**
+     * This logic that intersects the parts of the graph pattern.
+     */
+    private final SetIntersectLogic logic;
+	 
+	 InternalSPARQLValueFactory valueFactory = new InternalSPARQLValueFactory();
+
+    private static final Map
+		isFunctional = new HashMap(),
+    	isInverseFunctional = new HashMap();
+    
+    /**
+     * Creates a new default group logic, with the given subconstraints found in
+     * the data.
+     * 
+     * @param data the data holding the subconstraints to bind
+     */
+    public AdvancedGroupConstraintLogic(GroupConstraintData data, SetIntersectLogic logic) {
+        this.logic = logic;
+        this.data = data;
+    }
+
+    /**
+     * Applies each subconstraint in turn, saving filter and optional
+     * constraints for last, as according to specification.
+     */
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+	
+		// Build separate lists for the different constraints that this group may contain.
+
+		List tripleConstraints = new LinkedList();
+        List filterQueue = new LinkedList();
+        List optionalQueue = new LinkedList();
+		List otherQueue = new LinkedList();
+
+		// Get a ConstraintLogic.CallParams to pass to the triple queries.
+		
+		ConstraintLogic.CallParams p2 = p.clone();
+		if (p2.knownValues == null)
+			p2.knownValues = new HashMap();
+		if (p2.knownFilters == null)
+			p2.knownFilters = new HashMap();
+
+		if (p2.offset > 0) {
+			p2.offset = 0;
+			p2.limit = -1;
+		}
+		
+		if (p2.distinguishedVariables != null)
+			p2.distinguishedVariables.addAll(p2.getOrderVariables());
+		p2.orderExpressions = null; // There is no reason to order the results either.
+		
+		// Get a list of variables that have known values, and of those the ones that are really cheap
+		// (i.e. have just a few values).
+		// We'll build these sets in the course of reordering the statements to query most efficiently.
+
+		Set knownVars = new HashSet();
+		Set cheapVars = new HashSet();
+		
+		// Any variables known by groups on top of us are known here, and cheap (I guess).
+		knownVars.addAll(p2.knownValues.keySet());
+		cheapVars.addAll(p2.knownValues.keySet());
+		
+		// Split out the types of constraints and look for filters that tell us interesting things.
+		
+        for (Iterator cons = data.getConstraints().iterator(); cons.hasNext();) {
+            ConstraintData c = (ConstraintData) cons.next();
+            if (c instanceof OptionalConstraintData) {
+				optionalQueue.add(c);
+            } else if (c instanceof FilterConstraintData) {
+				filterQueue.add(c);
+				
+				FilterConstraintData f = (FilterConstraintData)c;
+				if (f.getExpression() instanceof BinaryLogic) {
+					// If this filter is of the form FILTER(?var = <uri> || ?var = <uri> || ...)
+					// then this is giving us some known values for the variable.
+					BinaryLogic b = (BinaryLogic)f.getExpression();
+					Variable v = getFilterPrimaryVariable(b);
+					if (v != null) {
+						Set values = new HashSet();
+						getFilterValues(b, values);
+						if (!p2.knownValues.containsKey(v)) {
+							p2.knownValues.put(v, values);
+							knownVars.add(v);
+							cheapVars.add(v);
+						} else {
+							Set othervalues = (Set)p2.knownValues.get(v);
+							othervalues.retainAll(values);
+						}
+					}
+				}
+				
+				// This by default does nothing, but subclassors may decide to do things here.
+				extractLiteralFilters(f.getExpression(), p2.knownFilters);
+			} else if (c instanceof TripleConstraint) {
+				tripleConstraints.add(c);
+			} else {
+				otherQueue.add(c);
+			}
+		}
+		
+		// If a subclass can answer this query's entire set of triple
+		// constraints at once, we pass it p2_batched, which is a bit
+		// different.
+
+		ConstraintLogic.CallParams p2_batched = p2.clone();
+		
+		// Make sure we add all of the variables in scope here to the distinguished
+		// set that we pass down to the individual triple constraints.
+
+		if (p2.distinguishedVariables != null) {
+			for (Iterator cons = data.getConstraints().iterator(); cons.hasNext();) {
+				ConstraintData c = (ConstraintData) cons.next();
+				p2.distinguishedVariables.addAll(c.getVariables());
+
+				// But don't make variables in triple constraints distinguished
+				// for the batched code path. We only need variables in use
+				// in the  filters and optionals.
+				if (c instanceof TripleConstraint)
+					continue;
+				p2_batched.distinguishedVariables.addAll(c.getVariables());
+			}
+		}
+			
+		// Reorder the triple constraints so that complex constraints are done
+		// after some of their variables have already been evaluated.  This is
+		// a bit N^2-ish in the number of triple constraints, but it can be improved.
+		List constraintOrder = new LinkedList();
+		if (true) {
+		Set selectedVars = new HashSet();
+		while (tripleConstraints.size() > 0) {
+			TripleConstraint leastConstraint = null;
+			float leastComplexity = -1;
+			
+			if (tripleConstraints.size() == 1) {
+				leastConstraint = (TripleConstraint)tripleConstraints.get(0);
+			} else {
+				//System.err.println(">>>");
+				
+				for (Iterator cons = tripleConstraints.iterator(); cons.hasNext();) {
+					TripleConstraint c = (TripleConstraint) cons.next();
+					float complexity = getComplexity(c, knownVars, cheapVars, p2.knownFilters, p2.source);
+					//System.err.println(">>> " + complexity + "\t" + c);
+					if (leastConstraint == null || complexity < leastComplexity) {
+						leastComplexity = complexity;
+						leastConstraint = c;
+					}
+				}
+			}
+
+			tripleConstraints.remove(leastConstraint);
+			constraintOrder.add(leastConstraint);
+			
+			// Get the variables mentioned in this triple constraint
+			Set constraintVars = new HashSet();
+			getVariables(leastConstraint, constraintVars);
+			
+			// Keep a list of variables that have been selected on so far
+			selectedVars.addAll(constraintVars);
+			
+			// And all of these variables are now considered 'known' for the purposes of
+			// selecting which statement goes next.  But they're not considered 'cheap'.
+			knownVars.addAll(constraintVars);
+			
+			// Well, if this triple was functional or inverse functional, we *can*
+			// consider the variables mentioned in the triple cheap.
+			if (leastComplexity <= 1)
+				cheapVars.addAll(constraintVars);
+			
+			// Perform any filters that are such that all of the
+			// variables mentioned in the filter have already been selected
+			// on.  The earlier we filter the better.  (We have to know not just
+			// which variables are known so far, because ones that are known from
+			// filters may not yet be actually bound in the binding set.  Rather,
+			// we have to know which ones have actually been selected on in a
+			// triple.  Here, we only know what's been selected on in this group,
+			// and not at a higher level.)
+	        for (Iterator filters = filterQueue.iterator(); filters.hasNext();) {
+	            FilterConstraintData c = (FilterConstraintData) filters.next();
+	            /*boolean allvarsknown = true;
+	            Set filterVars = getFilterVariables((SimpleNode)c);
+	            for (Iterator vars = filterVars.iterator(); vars.hasNext(); ) {
+	            	if (!selectedVars.contains(vars.next())) {
+	            		allvarsknown = false;
+	            		break;
+	            	}
+	            }
+	            if (allvarsknown) {
+	            	constraintOrder.add(c);
+	            	filters.remove();
+	            }*/
+	        }
+        }
+        } else {
+        constraintOrder.addAll(tripleConstraints);
+		}
+		
+		// Add the otherQueue back in.
+		constraintOrder.addAll(otherQueue);
+
+		// Because of filters and intersections, we can't pass limits directly down into
+		// the queries. However, we can adaptively limit. Try the limit,
+		// apply filters, and if we still have enough rows we're done.
+		// Otherwise, "double" the limit we pass down and try again.
+		
+		// Run the constraints in the new order.
+		RdfBindingSet current = null;
+		
+		int adaptiveLimitMultiplier = 1;
+		while (adaptiveLimitMultiplier < 1000) {
+			// What limit do we pass down to the queries?
+			p2_batched.offset = 0;
+			p2.offset = 0;
+			if (p.offset == 0 && p.limit > 0) {
+				p2.limit = p.limit * adaptiveLimitMultiplier;
+				p2_batched.limit = p.limit * adaptiveLimitMultiplier;
+			}
+			
+			boolean didFilter = false;
+			
+			// Clone p2 so we can modify the knownValues map but without
+			// destroying the original in case we loop around while doing
+			// the adaptive filter.
+			ConstraintLogic.CallParams p22 = p2.clone();
+			
+			// Allow a subclass to take over running the constraints.
+			current = runTripleConstraints(constraintOrder, p2_batched);
+			
+			if (current != null && current.size() >= p2_batched.limit)
+				didFilter = true;
+			
+			if (current != null && optionalQueue.size() > 0)
+				current = updateKnownVariables(current, p22.knownValues);
+			
+			if (current == null) {
+				// No subclass took over the intersections.
+				
+				for (Iterator cons = constraintOrder.iterator(); cons.hasNext();) {
+					ConstraintLogic c = (ConstraintLogic) cons.next();
+					
+					p22.bindings = current;
+					
+					if (current == null) {
+						current = c.constrain(p22);
+						if (current.size() >= p22.limit)
+							didFilter = true;
+					} else {
+						RdfBindingSet next = c.constrain(p22);
+						if (next.size() >= p22.limit)
+							didFilter = true;
+						current = logic.intersect(current, next);
+					}
+					
+					if (cons.hasNext() || optionalQueue.size() > 0)
+						current = updateKnownVariables(current, p22.knownValues);
+				}
+			}
+			
+			// At this point, we're operating on the set, so let's make it an empty one
+			if (current == null)
+				current = new RdfBindingSetImpl();
+			
+			// Any optionals...
+			for (Iterator optionals = optionalQueue.iterator(); optionals.hasNext();) {
+				ConstraintLogic c = (ConstraintLogic) optionals.next();
+				p22.bindings = current;
+				// note that we pass down the limit
+				current = c.constrain(p22);
+			}
+			
+			// Any filters that were not moved up in the logic to process them as early as possible.
+			for (Iterator filters = filterQueue.iterator(); filters.hasNext();) {
+				ConstraintLogic c = (ConstraintLogic) filters.next();
+				p22.bindings = current;
+				current = c.constrain(p22);
+			}
+			
+			current = p.projectOrderDistinctLimit(current);
+			
+			// Are we done with the adaptive filter?
+			if (p.limit == -1 || current.size() >= p.limit || !didFilter || filterQueue.size() == 0)
+				break;
+			
+			adaptiveLimitMultiplier *= 5;
+		}
+		
+		return current;
+   }
+
+	protected RdfBindingSet runTripleConstraints(List tripleConstraints, ConstraintLogic.CallParams p) {
+		return null;
+	}
+	
+	private RdfBindingSet updateKnownVariables(RdfBindingSet current, Map knownValues) {
+		// If there are more things happening later, update our knownValue
+		// mapping based on what has currently been queried.  We have to
+		// loop through all of the bindings found so far, so we'll put
+		// those bindings into a new set to cache them.
+		
+		current = new RdfBindingSetImpl(current);
+		List variables = current.getVariables();
+		
+		Set hadNewValues = new HashSet();
+		for (Iterator biter = current.iterator(); biter.hasNext(); ) {
+			RdfBindingRow row = (RdfBindingRow)biter.next();
+			List rowvalues = row.getValues();
+			
+			for (int i = 0; i < variables.size(); i++) {
+				Variable var = (Variable) variables.get(i);
+				Value val = (Value) rowvalues.get(i);
+				
+				if (val == null) continue;
+				
+				Set values = (Set)knownValues.get(var);
+				
+				// If knownValues has no mapping for this variable yet,
+				// or if knownValues had a mapping, we want to clear
+				// the mapping and start fresh with the values actually
+				// found.
+				if (values == null || !hadNewValues.contains(var)) { 
+					values = new HashSet();
+					knownValues.put(var, values);
+					hadNewValues.add(var);
+				}
+					
+				values.add(val);
+			}
+		}
+		
+		extractVariableFunctions(knownValues);	
+		
+		return current;
+	}
+	
+    /**
+     * Creates a mapping from variables to a List of filters based on
+	 * the expression.
+     * 
+     * @param node the expression to extract filters from
+	 * @param literalFilters a map from variables to a List of filters (of any type
+	 *                       supported by the underlying AdvancedRdfSource).
+     */
+	protected void extractLiteralFilters(ExpressionLogic node, Map literalFilters) {
+		if (node instanceof AndLogic) {
+			extractLiteralFilters(((AndLogic)node).getLeftExpression(), literalFilters);
+			extractLiteralFilters(((AndLogic)node).getRightExpression(), literalFilters);
+		}
+	}
+	
+	protected void addLiteralFilter(Variable variable, Object filter, Map literalFilters) {
+		List list = (List)literalFilters.get(variable);
+		if (list == null) {
+			list = new java.util.ArrayList();
+			literalFilters.put(variable, list);
+		}
+		list.add(filter);
+	}
+	
+	private void extractVariableFunctions(Map knownValues) {
+        for (Iterator cons = data.getConstraints().iterator(); cons.hasNext();) {
+            ConstraintLogic c = (ConstraintLogic) cons.next();
+            if (c instanceof FilterConstraintData) {
+				FilterConstraintData f = (FilterConstraintData)c;
+				extractVariableFunctions(f.getExpression(), knownValues);
+			}
+		}
+	}
+	
+	private void extractVariableFunctions(ExpressionLogic node, Map knownValues) {
+		if (node instanceof AndLogic) {
+			extractVariableFunctions(((AndLogic)node).getLeftExpression(), knownValues);
+			extractVariableFunctions(((AndLogic)node).getRightExpression(), knownValues);
+		}
+		if (node instanceof OrLogic) {
+			Map a = new HashMap();
+			Map b = new HashMap();
+			extractVariableFunctions(((OrLogic)node).getLeftExpression(), a);
+			extractVariableFunctions(((OrLogic)node).getRightExpression(), b);
+			for (Iterator i = a.keySet().iterator(); i.hasNext(); ) {
+				Variable v = (Variable)i.next();
+				if (b.containsKey(v)) {
+					Set av = (Set)a.get(v);
+					Set bv = (Set)b.get(v);
+					av.addAll(bv);
+					if (knownValues.containsKey(v)) {
+						((Set)knownValues.get(v)).retainAll(av);
+					} else {
+						knownValues.put(v, av);
+					}
+				}
+			}
+		}
+		if (node instanceof EqualsLogic) {
+			extractVariableFunctions(((EqualsLogic)node).getLeftExpression(), ((EqualsLogic)node).getRightExpression(), knownValues);
+			extractVariableFunctions(((EqualsLogic)node).getRightExpression(), ((EqualsLogic)node).getLeftExpression(), knownValues);
+		}
+	}
+	
+	private void extractVariableFunctions(ExpressionLogic a, ExpressionLogic b, Map knownValues) {
+		if (!(a instanceof Variable)) return;
+		if (knownValues.containsKey(a)) return; // we could intersect with existing values, but be sure not to do this for values we just inserted into the hash
+		
+		if (b instanceof Variable && knownValues.containsKey(b)) {
+			knownValues.put(a, knownValues.get(b));
+		
+		} else if (b instanceof ExternalFunctionLogic) {
+			// if this is a function of one variable, get the values by applying the function
+			// to all of the variables values.  (if it's of more than one variable, we could
+			// permute through the variables...)
+			ExternalFunctionLogic f = (ExternalFunctionLogic)b;
+			Set varargs =  f.getVariables();
+			
+			if (varargs.size() == 0) { // a constant, ok
+				Value v = f.evaluate(new MyBindingRow(new HashMap()));
+				HashSet vs = new HashSet();
+				vs.add(v);
+				knownValues.put(a, vs);
+				return;
+			}
+			
+			if (varargs.size() > 1) return;
+			
+			for (Iterator i = varargs.iterator(); i.hasNext(); ) {
+				Variable var = (Variable)i.next();
+				if (!knownValues.containsKey(var))
+					return;
+				
+				Set varvalues = (Set)knownValues.get(var);
+				Set newvalues = new HashSet();
+				Map bindings = new HashMap();
+				for (Iterator j = varvalues.iterator(); j.hasNext(); ) {
+					bindings.put(var, j.next());
+					newvalues.add( f.evaluate(new MyBindingRow(bindings)) );
+				}
+				
+				knownValues.put(a, newvalues);
+			}
+		}
+		
+		
+		// TODO: if b is a function whose arguments are all constants or known values, evaluate the function
+	}
+	
+	private class MyBindingRow extends AbstractRdfBindingRow {
+		Map values;
+		public MyBindingRow(Map values) { super(null); this.values = values; }
+		public List getVariables() { return new java.util.ArrayList(values.keySet()); }
+		public Value getValue(Variable v) { return (Value)values.get(v); }
+	}
+	
+    /**
+     * Returns the complexity of the triple constraint, given a set of
+	 * variables that already have known values.  The return value is a
+	 * measure of the number of statements that we expect to match the
+	 * filter, on a nonsensical scale.
+     * 
+     * @param variablesKnown a set of variables whose values are known
+     */
+	private float getComplexity(TripleConstraint triple, Set variablesKnown, Set cheapVariables, Map knownFilters, RdfSource source) {
+		Object subject = triple.getSubjectExpression();
+		Object predicate = triple.getPredicateExpression();
+		Object object = triple.getObjectExpression();
+		
+		boolean isFunctional = predicate instanceof URI && isFunctional((URI)predicate, source, true);
+		boolean isInverseFunctional = predicate instanceof URI && isFunctional((URI)predicate, source, false);
+		
+		// Properties in RDF tend to be many-to-few.  That is, lots of people
+		// may have a particular foaf:name, and one person has very few foaf:names.
+		// Thus, we give a penalty when a new variable occurs in subject position.
+		// Predicate variables have a *low* penality because all things being equal,
+		// we would prefer a variable in predicate position than in the other positions.
+		
+		float subjComplexity = getComplexity2(subject, variablesKnown, cheapVariables, knownFilters, 4);
+		float predComplexity = getComplexity2(predicate, variablesKnown, cheapVariables, knownFilters, 2);
+		float objComplexity = getComplexity2(object, variablesKnown, cheapVariables, knownFilters, 3);
+
+		// If this is a functional or inverse functional statement, then we reduce the
+		// complexity of the object because we know it is in a 1-to-1 relation with
+		// the subject (or the other way around).  (And, in these cases the predicate
+		// isn't a variable, so its complexity is zero anyway.)  Note that these
+		// computations are based on the 1 + maximum possible complexity for the
+		// subject and object, so *modifications to the getComplexity2 function and
+		// the penalities should be reflected here.
+		
+		if (isFunctional) objComplexity /= (7 - subjComplexity);
+		if (isInverseFunctional) subjComplexity /= (6 - objComplexity);
+		// If both functional and inverse functional, then does this make sense?
+		
+		return subjComplexity + predComplexity + objComplexity;
+	}
+	
+	private int getComplexity2(Object thing, Set variablesKnown, Set cheapVariables, Map knownFilters, int penalty) {
+		int ret = 0;
+		if (thing instanceof Variable && !cheapVariables.contains(thing)) {
+			ret++;
+			if (!knownFilters.containsKey(thing)) ret++;
+			if (!variablesKnown.contains(thing)) ret += penalty;
+		}
+		return ret;
+	}
+	
+	private boolean isFunctional(URI predicate, RdfSource source, boolean forward) {
+		Map map = forward ? isFunctional : isInverseFunctional;
+		if (map.containsKey(predicate)) return ((Boolean)map.get(predicate)).booleanValue();
+	
+		URI rdftype = valueFactory.createURI("http://www.w3.org/1999/02/22-rdf-syntax-ns#type");
+		String typeuri = "http://www.w3.org/2002/07/owl#" +
+			( forward ? "FunctionalProperty" : "InverseFunctionalProperty");
+		boolean ret = source.hasDefaultGraphStatement(predicate, rdftype, valueFactory.createURI(typeuri));
+		map.put(predicate, new Boolean(ret));
+		return ret;
+	}
+
+    /**
+     * Adds the variables in the constraint into the set.
+     * 
+     * @param variablesKnown a set of variables whose values are known
+     */
+	private void getVariables(TripleConstraint triple, Set variablesKnown) {
+		if (triple.getSubjectExpression() instanceof Variable) variablesKnown.add(triple.getSubjectExpression());
+		if (triple.getPredicateExpression() instanceof Variable) variablesKnown.add(triple.getPredicateExpression());
+		if (triple.getObjectExpression() instanceof Variable) variablesKnown.add(triple.getObjectExpression());
+	}
+	
+   /**
+     * Gets a variable for the filter.  If the filter is a EqualsLogic,
+	 * return the variable on the left hand side.  If the filter is a
+	 * OrLogic, return the variable if its the same on both sides,
+	 * or else null.
+     */
+	private Variable getFilterPrimaryVariable(BinaryLogic expr) {
+		if (expr instanceof OrLogic
+			&& expr.getLeftExpression() instanceof BinaryLogic
+			&& expr.getRightExpression() instanceof BinaryLogic) {
+			Variable left = getFilterPrimaryVariable((BinaryLogic)expr.getLeftExpression());
+			Variable right = getFilterPrimaryVariable((BinaryLogic)expr.getRightExpression());
+			if (left != null && right != null && left.equals(right)) return left;
+		} else if (expr instanceof EqualsLogic
+			&& expr.getLeftExpression() instanceof Variable && (expr.getRightExpression() instanceof URI || expr.getRightExpression() instanceof BNode || expr.getRightExpression() instanceof Literal)) {
+			return (Variable)expr.getLeftExpression(); 
+		}
+		return null;
+	}
+	
+   /**
+     * Gets the values for a filter.  For an ASTEqualsNode, returns
+	 * the right hand side.  For an ASTOrNode, returns the values of its parts.
+     */
+	private void getFilterValues(BinaryLogic expr, Set set) {
+		if (expr instanceof OrLogic) {
+			getFilterValues((BinaryLogic)expr.getLeftExpression(), set);
+			getFilterValues((BinaryLogic)expr.getRightExpression(), set);
+		} else if (expr instanceof EqualsLogic && (expr.getRightExpression() instanceof URI || expr.getRightExpression() instanceof BNode || expr.getRightExpression() instanceof Literal)) {
+			set.add(expr.getRightExpression());
+		}
+	}
+
+}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetIntersectLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetIntersectLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetIntersectLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetIntersectLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -64,7 +64,7 @@
         final List variables;
 
         final List commonVariables;
-
+		
         RdfBindingIntersect(RdfBindingSet set1, RdfBindingSet set2) {
             this.set1 = set1;
             this.set2 = set2;
@@ -259,10 +259,11 @@
             }
 
             public Value getValue(Variable variable) {
-                Value returnValue = this.row1.getValue(variable);
-                if (returnValue == null) {
+				Value returnValue = null;
+				if (set1.getVariables().contains(variable))
+					returnValue = this.row1.getValue(variable);
+                if (returnValue == null && set2.getVariables().contains(variable))
                     returnValue = this.row2.getValue(variable);
-                }
                 return returnValue;
             }
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetJoinLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetJoinLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetJoinLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/IndexedSetJoinLogic.java	2008-02-05 17:40:48.000000000 -0500
@@ -10,6 +10,7 @@
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -81,7 +82,7 @@
 		final List variables;
 
 		final List commonVariables;
-
+		
 		RdfBindingJoin(RdfBindingSet set1, RdfBindingSet set2, Collection filters) {
 			this.set1 = set1;
 			this.set2 = set2;
@@ -206,7 +207,7 @@
 									retainedMatches.addAll((Collection) this.indexMap[varPos].get(null));
 								}
 							} else {
-								ArrayList matchesWithNull = new ArrayList();
+								HashSet matchesWithNull = new HashSet();
 								if (this.indexMap[varPos].containsKey(value)) {
 									matchesWithNull.addAll((Collection) this.indexMap[varPos].get(value));
 								}
@@ -293,14 +294,11 @@
 			}
 
 			public Value getValue(Variable variable) {
-				Value returnValue = this.row1.getValue(variable);
-				if (returnValue == null) {
-					if (this.row2 == null) {
-						returnValue = null;
-					} else {
-						returnValue = this.row2.getValue(variable);
-					}
-				}
+				Value returnValue = null;
+				if (set1.getVariables().contains(variable))
+					returnValue = this.row1.getValue(variable);
+				if (returnValue == null && this.row2 != null && set2.getVariables().contains(variable))
+					returnValue = this.row2.getValue(variable);
 				return returnValue;
 			}
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedFilterConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedFilterConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedFilterConstraintLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedFilterConstraintLogic.java	2008-08-13 15:38:25.000000000 -0400
@@ -10,6 +10,7 @@
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -69,16 +70,10 @@
 	 * Filters the passed in binding set, only adding those rows that return a
 	 * true boolean value to the returned binding set.
 	 * 
-	 * @param bindings the current bound values
-	 * @param source the RDF source, not used in this constraint
-	 * @param defaultDatasets the datasets to query, not used in this constraint
-	 * @param namedDatasets the named datasets for graph queries, not used in
-	 *            this constraint
 	 * @return a binding set with values that pass through the filter expression
 	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
-		return new FilterBindingSet(bindings, this.data.getExpression());
+	public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+		return new FilterBindingSet(p.bindings, this.data.getExpression());
 	}
 
 	private class FilterBindingSet extends AbstractRdfBindingSet implements StackedRdfBindingSet {
@@ -139,6 +134,9 @@
 						}
 					} catch (TypeError e) {
 						// Ignore and don't return
+					} catch (RuntimeException e) {
+						// Ignore and don't return
+						// This could come from wrapping the exception thrown by an external function, including cast functions
 					}
 				}
 				return null;
@@ -155,16 +153,4 @@
 
 
 	}
-
-	/**
-	 * Currently does nothing, as I'm not even sure what this method is used for
-	 * and the filter constraint doesn't really change the variable bindings at
-	 * all.
-	 * 
-	 * @return an empty list always
-	 */
-	public Collection getVariables() {
-		return new LinkedList();
-	}
-
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedGraphConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedGraphConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedGraphConstraintLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedGraphConstraintLogic.java	2008-08-13 17:42:00.000000000 -0400
@@ -7,9 +7,12 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collection;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -38,14 +41,6 @@
  * @version 1.0
  */
 public class StreamedGraphConstraintLogic implements ConstraintLogic {
-
-    /**
-     * This dummy variable is used to bind in inner triples and then be matched
-     * in this constraint.
-     */
-    public static final Variable CONTEXT_VARIABLE = new VariableImpl(
-            StreamedGraphConstraintLogic.class.getName());
-
     /**
      * The data that holds the group constraint and the URI/variable list of
      * named graphs.
@@ -74,288 +69,35 @@
      * Does the constraining of the binding set, by returning a binding set of
      * variables bound in the named graphs by the subconstraints. It is expected
      * to be intersected with the previous constraints in the containing group
-     * constraint.
-     * 
-     * @param bindings the current bindings, not used in this constraint
-     * @param source the source, passed on to the group constraint
-     * @param defaultDatasets the datasets to use in the query, not used in this
-     *            constraint
-     * @param namedDatasets the named datasets, used in case the graph variable
-     *            is not bound
+     * constraint.
+     *
      * @return a binding set of values bound in the named graphs, potentially
      *         with a bound graph variable
      */
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source,
-            Collection defaultDatasets, Collection namedDatasets) {
-
-        RdfBindingSet fullSet = new RdfBindingSetImpl();
-        if (bindings != null && bindings.iterator().hasNext()) {
-            for (Iterator i = bindings.iterator(); i.hasNext();) {
-                RdfBindingRow row = (RdfBindingRow) i.next();
-                Object evaluation = this.data.getGraph().evaluate(row);
-                // If this evaluates to an un-bound variable, assume we want to
-                // apply the group to any named dataset
-                if (evaluation instanceof Variable) {
-                    if (namedDatasets.isEmpty()) {
-                        // Here we want to use any named dataset in the data
-                        RdfBindingSet namedResults = this.data.getConstraint().constrain(
-                                bindings, source, null, namedDatasets);
-
-                        RdfBindingSet sourcedSet = changeSource(
-                                (Variable) evaluation, namedResults);
-
-                        fullSet = this.unionLogic.union(fullSet, sourcedSet);
-                    } else {
-                        // If there are named datasets, only use those
-                        for (Iterator j = namedDatasets.iterator(); j.hasNext();) {
-                            URI namedSet = (URI) j.next();
-                            Collection datasets = Arrays.asList(new Object[] { namedSet });
-
-                            RdfBindingSet namedResults = this.data.getConstraint().constrain(
-                                    bindings, source, datasets, namedDatasets);
-
-                            RdfBindingSet sourcedSet = addSource(
-                                    (Variable) evaluation, namedSet,
-                                    namedResults);
-
-                            fullSet = this.unionLogic.union(fullSet, sourcedSet);
-                        }
-                    }
-                } else if (this.data.getGraph() instanceof Variable) {
-                    Collection datasets = Arrays.asList(new Object[] { evaluation });
-                    RdfBindingSet namedResults = this.data.getConstraint().constrain(
-                            bindings, source, datasets, namedDatasets);
-                    fullSet = this.unionLogic.union(fullSet, addSource(
-                            (Variable) this.data.getGraph(), (URI) evaluation,
-                            namedResults));
-                } else {
-                    Collection datasets = Arrays.asList(new Object[] { evaluation });
-                    fullSet = this.unionLogic.union(fullSet,
-                            this.data.getConstraint().constrain(bindings,
-                                    source, datasets, namedDatasets));
-                }
-            }
-        } else {
-            if (this.data.getGraph() instanceof Variable) {
-                if (namedDatasets.isEmpty()) {
-                    // Here we want to use any named dataset in the data
-                    RdfBindingSet namedResults = this.data.getConstraint().constrain(
-                            bindings, source, null, namedDatasets);
-
-                    RdfBindingSet sourcedSet = changeSource(
-                            (Variable) this.data.getGraph(), namedResults);
-
-                    fullSet = this.unionLogic.union(fullSet, sourcedSet);
-                } else {
-                    // If there are named datasets, only use those
-                    for (Iterator j = namedDatasets.iterator(); j.hasNext();) {
-                        URI namedSet = (URI) j.next();
-                        Collection datasets = Arrays.asList(new Object[] { namedSet });
-
-                        RdfBindingSet namedResults = this.data.getConstraint().constrain(
-                                bindings, source, datasets, namedDatasets);
-
-                        RdfBindingSet sourcedSet = addSource(
-                                (Variable) this.data.getGraph(), namedSet,
-                                namedResults);
-
-                        fullSet = this.unionLogic.union(fullSet, sourcedSet);
-                    }
-                }
-            } else {
-                Collection datasets = Arrays.asList(new Object[] { this.data.getGraph() });
-                fullSet = this.unionLogic.union(fullSet,
-                        this.data.getConstraint().constrain(bindings, source,
-                                datasets, namedDatasets));
-            }
-        }
-        return fullSet;
-    }
-
-    /**
-     * Adds the source column to a value binding set, when variables are
-     * specified in the graph name list. This helper method refactors out some
-     * logic from the constraint method.
-     * 
-     * @param variable the variable to bind the source to
-     * @param source the source that will be the value in the column for the
-     *            rows
-     * @param set the set to add the source column to
-     * @return a set with the source value added to each row under a variable
-     *         header
-     */
-    private RdfBindingSet addSource(Variable variable, URI source,
-            RdfBindingSet set) {
-        return new VariableAddSourceSet(set, variable, source);
-    }
-
-    /**
-     * Changes the source column to have the appropriate variable name as
-     * defined in a GRAPH ?var query.
-     * 
-     * @param variable the variable that will be the new header
-     * @param set the set to modify the column in
-     */
-    private RdfBindingSet changeSource(Variable variable, RdfBindingSet set) {
-        return new VariableNameChangeSet(set, variable);
-    }
-    
-    private class VariableNameChangeSet extends AbstractRdfBindingSet implements StackedRdfBindingSet {
-
-        final RdfBindingSet set;
-
-        final Variable newVar;
-
-        VariableNameChangeSet(RdfBindingSet set, Variable newVar) {
-            this.set = set;
-            this.newVar = newVar;
-        }
-
-        public Iterator iterator() {
-            return new VariableNameChangeIterator();
-        }
-
-        public List getVariables() {
-            List setVars = new ArrayList(this.set.getVariables());
-            setVars.remove(CONTEXT_VARIABLE);
-            setVars.add(this.newVar);
-            return setVars;
-        }
-
-        private class VariableNameChangeIterator implements Iterator {
-
-            private Iterator setIterator = VariableNameChangeSet.this.set.iterator();
-
-            public void remove() {
-                this.setIterator.remove();
-            }
-
-            public boolean hasNext() {
-                return this.setIterator.hasNext();
-            }
-
-            public Object next() {
-                return new VariableNameChangeRow(
-                        (RdfBindingRow) this.setIterator.next());
-            }
-
-            private class VariableNameChangeRow extends AbstractRdfBindingRow {
-
-                private RdfBindingRow row;
-
-                VariableNameChangeRow(RdfBindingRow row) {
-                    super(VariableNameChangeSet.this);
-                    this.row = row;
-                }
-
-                public Value getValue(Variable variable) {
-                    if (variable.equals(VariableNameChangeSet.this.newVar)) {
-                        return this.row.getValue(CONTEXT_VARIABLE);
-                    } else {
-                        return this.row.getValue(variable);
-                    }
-                }
-
-                public List getVariables() {
-                    return VariableNameChangeSet.this.getVariables();
-                }
-            }
-        }
-
-        public String describeSet() {
-            return "SET GRAPH VARIABLE";
-        }
-
-		public void setSource(RdfSource source) {
-			if (this.set instanceof SourcedRdfBindingSet) {
-				((SourcedRdfBindingSet) this.set).setSource(source);
-			}
-		}
-
-		public void accept(StreamedBindingSetVisitor setVisitor) {
-			setVisitor.visit(this);
-		}
-		public Collection getDependencies() {
-			return Arrays.asList(new RdfBindingSet[] { this.set });
-		}
-
-    }
-
-    private class VariableAddSourceSet extends AbstractRdfBindingSet implements StackedRdfBindingSet {
-
-        RdfBindingSet set;
-
-        Variable newVar;
-
-        URI source;
-
-        VariableAddSourceSet(RdfBindingSet set, Variable newVar, URI source) {
-            this.set = set;
-            this.newVar = newVar;
-            this.source = source;
-        }
-
-        public Iterator iterator() {
-            return new VariableAddSourceIterator();
-        }
-
-        public List getVariables() {
-            List setVars = new ArrayList(this.set.getVariables());
-            setVars.add(this.newVar);
-            return setVars;
-        }
-
-        private class VariableAddSourceIterator implements Iterator {
-
-            private Iterator setIterator = VariableAddSourceSet.this.set.iterator();
-
-            public void remove() {
-                this.setIterator.remove();
-            }
-
-            public boolean hasNext() {
-                return this.setIterator.hasNext();
-            }
-
-            public Object next() {
-                return new VariableAddSourceRow(
-                        (RdfBindingRow) this.setIterator.next());
-            }
-
-            private class VariableAddSourceRow extends AbstractRdfBindingRow {
-
-                private RdfBindingRow row;
-
-                VariableAddSourceRow(RdfBindingRow row) {
-                    super(VariableAddSourceSet.this);
-                    this.row = row;
-                }
-
-                public Value getValue(Variable variable) {
-                    if (variable.equals(VariableAddSourceSet.this.newVar)) {
-                        return VariableAddSourceSet.this.source;
-                    } else {
-                        return this.row.getValue(variable);
-                    }
-                }
-
-                public List getVariables() {
-                    return VariableAddSourceSet.this.getVariables();
-                }
-            }
-        }
-
-        public String describeSet() {
-            return "ADD STATEMENT SOURCE";
-        }
-
-		public void accept(StreamedBindingSetVisitor setVisitor) {
-			setVisitor.visit(this);
-		}
-		public Collection getDependencies() {
-			return Arrays.asList(new RdfBindingSet[] { this.set });
-		}
-
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        ConstraintLogic.CallParams p2 = p.clone();
+        
+        // If this graph binds a variable, then when evaluating statements within
+        // this constraint, graph variables are set to bind to this variable.
+        // If we know the value of this variable from previous graph statements,
+        // then we say that the graphs for triple constraints down below comes from
+        // those values. If not, then we say that the graphs come from the query's
+        // FROM NAMED set.
+        if (this.data.getGraph() instanceof Variable) {
+        	p2.graphVariable = (Variable)this.data.getGraph();
+            p2.sourceDatasets = (Collection)p.knownValues.get(this.data.getGraph());
+            if (p2.sourceDatasets == null)
+            	p2.sourceDatasets = p.namedDatasets;
+            if (p2.distinguishedVariables == null)
+            	p2.distinguishedVariables = new HashSet();
+            p2.distinguishedVariables.add(this.data.getGraph());
+        } else {
+        	HashSet c = new HashSet();
+        	c.add(this.data.getGraph());
+        	p2.sourceDatasets = c;
+        }
+        
+		return this.data.getConstraint().constrain(p2);
     }
 
     /**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedSetProjectionLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedSetProjectionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedSetProjectionLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedSetProjectionLogic.java	2007-10-21 12:35:15.000000000 -0400
@@ -130,8 +130,10 @@
 			}
 
 			public Value getValue(Variable variable) {
-				return ((ExpressionLogic) RdfBindingProjection.this.variableExpressions.get(variable))
-						.evaluate(this.row);
+				ExpressionLogic expr = (ExpressionLogic) RdfBindingProjection.this.variableExpressions.get(variable);
+				if (expr == null)
+					throw new IllegalArgumentException("Variable " + variable + " is not bound in this row.");
+				return expr.evaluate(this.row);
 			}
 
 			public List getVariables() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedTripleConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedTripleConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedTripleConstraintLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/streamed/StreamedTripleConstraintLogic.java	1969-12-31 19:00:00.000000000 -0500
@@ -1,443 +0,0 @@
-/*
- * SPARQL Engine
- * Copyright (C) 2005 Ryan Levering, All rights reserved.
- * See LICENSE for full license information
- */
-package name.levering.ryan.sparql.logic.streamed;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.NoSuchElementException;
-
-import name.levering.ryan.sparql.common.GraphStatement;
-import name.levering.ryan.sparql.common.RdfBindingRow;
-import name.levering.ryan.sparql.common.RdfBindingSet;
-import name.levering.ryan.sparql.common.RdfSource;
-import name.levering.ryan.sparql.common.URI;
-import name.levering.ryan.sparql.common.Value;
-import name.levering.ryan.sparql.common.Variable;
-import name.levering.ryan.sparql.common.impl.AbstractRdfBindingRow;
-import name.levering.ryan.sparql.common.impl.AbstractRdfBindingSet;
-import name.levering.ryan.sparql.common.impl.StatementImpl;
-import name.levering.ryan.sparql.model.data.TripleConstraintData;
-import name.levering.ryan.sparql.model.logic.ConstraintLogic;
-import name.levering.ryan.sparql.model.logic.ExpressionLogic;
-
-/**
- * This is the logic that handles most of the interaction with the end
- * RdfSource. Most other constraints pass the source down to triple constraints,
- * which provide the core bound values to manipulate. This is responsible for
- * querying the defaultDatasets for statements with wildcard placeholders.
- * 
- * @author Ryan Levering
- * @version 1.1
- */
-public class StreamedTripleConstraintLogic implements ConstraintLogic {
-
-	/**
-	 * The data containing the possible subject, predicate, and object to find.
-	 */
-	final TripleConstraintData data;
-
-	/**
-	 * Creates a new triple constraint logic that constrains a database to match
-	 * particular statement criteria.
-	 * 
-	 * @param data the data holding the statement data to match
-	 */
-	public StreamedTripleConstraintLogic(TripleConstraintData data) {
-		this.data = data;
-	}
-
-	/**
-	 * Returns a binding set of bound values matching a particular subject,
-	 * predicate, and object where one or more of them is a wildcard.
-	 * 
-	 * @param bindings the current bindings, not used in this constraint
-	 * @param source the source to query for the statement constraints
-	 * @param defaultDatasets the datasets to query, if non-default graphs are
-	 *            being used
-	 * @param namedDatasets the named datasets to use in graph constraints, not
-	 *            used in this constraint
-	 */
-	public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets,
-			Collection namedDatasets) {
-
-		ExpressionLogic subExpr = this.data.getSubjectExpression();
-		ExpressionLogic predExpr = this.data.getPredicateExpression();
-		ExpressionLogic objExpr = this.data.getObjectExpression();
-
-		int[] flags = new int[3];
-		List variables = new ArrayList();
-		Value subject = null;
-		if (subExpr instanceof Variable) {
-			variables.add(subExpr);
-			flags[0] = 1;
-			if (subExpr.equals(predExpr)) {
-				flags[1] = 1;
-			}
-			if (subExpr.equals(objExpr)) {
-				flags[2] = 1;
-			}
-		} else {
-			subject = (Value) subExpr;
-		}
-
-		URI verb = null;
-		if (predExpr instanceof Variable && flags[1] == 0) {
-			variables.add(predExpr);
-			flags[1] = 2;
-			if (predExpr.equals(objExpr)) {
-				flags[2] = 2;
-			}
-		} else {
-			verb = (URI) predExpr;
-		}
-
-		Value object = null;
-		if (objExpr instanceof Variable && flags[2] == 0) {
-			variables.add(objExpr);
-			flags[2] = 3;
-		} else if (flags[2] == 0) {
-			object = (Value) objExpr;
-		}
-
-		if (defaultDatasets == null) {
-			// This adds an extra column to the returned set for the GRAPH
-			// constraint to process
-			if (source != null) {
-				StatementBindingSet bindingSet = new StatementBindingSet(source, variables, flags, true);
-				bindingSet.addIterator(new StatementImpl(subject, verb, object));
-				return bindingSet;
-			} else {
-				StreamedTripleBindingSet bindingSet = new StreamedTripleBindingSet(variables, flags, true);
-				bindingSet.addIterator(new StatementImpl(subject, verb, object));
-				return bindingSet;
-			}
-		} else {
-			if (source != null) {
-				StatementBindingSet bindingSet = new StatementBindingSet(source, variables, flags, false);
-				if (defaultDatasets.isEmpty()) {
-					// This is if no FROM graphs are specified
-					bindingSet.addIterator(new StatementImpl(subject, verb, object));
-				} else {
-					// This is if FROM graphs are specified or FROM NAMED and
-					// we're in a GRAPH constraint
-					for (Iterator i = defaultDatasets.iterator(); i.hasNext();) {
-						bindingSet.addIterator(new StatementImpl(subject, verb, object, (URI) i.next()));
-					}
-				}
-				return bindingSet;
-			} else {
-				StreamedTripleBindingSet bindingSet = new StreamedTripleBindingSet(variables, flags, false);
-				if (defaultDatasets.isEmpty()) {
-					// This is if no FROM graphs are specified
-					bindingSet.addIterator(new StatementImpl(subject, verb, object));
-				} else {
-					// This is if FROM graphs are specified or FROM NAMED and
-					// we're in a GRAPH constraint
-					for (Iterator i = defaultDatasets.iterator(); i.hasNext();) {
-						bindingSet.addIterator(new StatementImpl(subject, verb, object, (URI) i.next()));
-					}
-				}
-				return bindingSet;
-			}
-		}
-	}
-
-	/**
-	 * This set is the lowest level binding set that wraps a request to an
-	 * RdfSource. It returns an iterator that uses the row iterators from the
-	 * RdfSource getStatement call to check if returned rows match the equality
-	 * criteria in the passed in flags.
-	 * 
-	 * @author Ryan Levering
-	 * @version 1.1
-	 */
-	private class StatementBindingSet extends AbstractRdfBindingSet {
-
-		/**
-		 * The RDF source that's being queried.
-		 */
-		final RdfSource source;
-
-		/**
-		 * The variables that are being bound to values in the RDF source.
-		 */
-		final List variables;
-
-		/**
-		 * Flags that allow a shortcut to checking for the equality of two
-		 * equivalent variables.
-		 */
-		final int[] flags;
-
-		/**
-		 * The statements that are matched against the RDF source.
-		 */
-		final List statementIterators = new ArrayList();
-
-		/**
-		 * Whether or not to include the graph name in the returned bindings.
-		 */
-		final boolean includeSource;
-
-		/**
-		 * Creates a new binding set that queries a particular RdfSource,
-		 * binding particular variables using shortcut flags and potentially
-		 * including the source graph name in the output bound variables.
-		 * 
-		 * @param source the source to get the data from
-		 * @param variables the variables being bound in the binding set
-		 * @param flags indicates the presence of variable equivalency
-		 * @param includeSource whether to bind the graph name as well
-		 */
-		private StatementBindingSet(RdfSource source, List variables, int[] flags, boolean includeSource) {
-			this.source = source;
-			this.variables = variables;
-			this.flags = flags;
-			this.includeSource = includeSource;
-		}
-
-		void addIterator(GraphStatement statementIterator) {
-			this.statementIterators.add(statementIterator);
-		}
-
-		public Iterator iterator() {
-			return new BoundStatementIterator();
-		}
-
-		public List getVariables() {
-			List extVariables = new ArrayList(this.variables);
-			if (this.includeSource) {
-				extVariables.add(StreamedGraphConstraintLogic.CONTEXT_VARIABLE);
-			}
-			return extVariables;
-		}
-
-		private class BoundStatementIterator implements Iterator {
-
-			private final Iterator itIterator = StatementBindingSet.this.statementIterators.iterator();
-
-			private Iterator statementIterator = null;
-
-			private GraphStatement nextStatement = null;
-
-			private BoundStatementIterator() {
-				if (this.itIterator.hasNext()) {
-					this.statementIterator = getStatements((GraphStatement) this.itIterator.next());
-				}
-
-				this.nextStatement = nextStatement();
-			}
-
-			private GraphStatement nextStatement() {
-				while (this.statementIterator != null) {
-
-					// Only come out of this loop if statementIterator is null
-					// (doomed)
-					// or we have a good statementIterator
-					while (this.statementIterator != null && !this.statementIterator.hasNext()) {
-						if (this.itIterator.hasNext()) {
-							this.statementIterator = getStatements((GraphStatement) this.itIterator.next());
-						} else {
-							// This is one end condition, there are no more
-							// iterators
-							this.statementIterator = null;
-							return null;
-						}
-					}
-
-					if (this.statementIterator != null) {
-						// We've found a statement iterator that has elements
-						GraphStatement statement = (GraphStatement) this.statementIterator.next();
-						while (statement != null && !this.checkStatement(statement)) {
-							if (this.statementIterator.hasNext()) {
-								statement = (GraphStatement) this.statementIterator.next();
-							} else {
-								// We ran out of statements here, go back for
-								// another iterator
-								statement = null;
-							}
-						}
-						if (statement != null) {
-							// This is another end condition, we found a match
-							return statement;
-						}
-					}
-				}
-
-				// We should only get here if there was never a chance
-				return null;
-			}
-
-			private Iterator getStatements(GraphStatement statement) {
-				if (statement.getGraphName() == null) {
-					if (StatementBindingSet.this.includeSource) {
-						return StatementBindingSet.this.source.getStatements(statement.getSubject(), statement
-								.getPredicate(), statement.getObject());
-					} else {
-						return StatementBindingSet.this.source.getDefaultStatements(statement.getSubject(), statement
-								.getPredicate(), statement.getObject());
-					}
-				} else {
-					return StatementBindingSet.this.source.getStatements(statement.getSubject(), statement
-							.getPredicate(), statement.getObject(), statement.getGraphName());
-				}
-			}
-
-			private boolean checkStatement(GraphStatement statement) {
-				int[] localFlags = StatementBindingSet.this.flags;
-
-				if (localFlags[0] != 0 && localFlags[0] == localFlags[2]) {
-					if (!statement.getSubject().equals(statement.getObject())) {
-						return false;
-					}
-				}
-				if (localFlags[0] != 0 && localFlags[0] == localFlags[1]) {
-					if (!statement.getSubject().equals(statement.getPredicate())) {
-						return false;
-					}
-				}
-				if (localFlags[1] != 0 && localFlags[1] == localFlags[2]) {
-					if (!statement.getPredicate().equals(statement.getObject())) {
-						return false;
-					}
-				}
-				return true;
-			}
-
-			public void remove() {
-				throw new UnsupportedOperationException();
-			}
-
-			public boolean hasNext() {
-				return this.nextStatement != null;
-			}
-
-			public Object next() {
-				if (this.nextStatement == null) {
-					throw new NoSuchElementException();
-				}
-				RdfBindingRow row = new StatementBindingRow(this.nextStatement);
-				this.nextStatement = nextStatement();
-				return row;
-			}
-
-			private class StatementBindingRow extends AbstractRdfBindingRow {
-
-				private final GraphStatement statement;
-
-				StatementBindingRow(GraphStatement statement) {
-					super(StatementBindingSet.this);
-					this.statement = statement;
-				}
-
-				public Value getValue(Variable variable) {
-					// Special case for the source
-					if (StatementBindingSet.this.includeSource
-							&& variable.equals(StreamedGraphConstraintLogic.CONTEXT_VARIABLE)) {
-						return this.statement.getGraphName();
-					}
-					// First get the index
-					int index = getIndex(variable);
-
-					int[] localFlags = StatementBindingSet.this.flags;
-					if (index == 2) {
-						// If the variable is in the last spot, it's got to be
-						// the object
-						return this.statement.getObject();
-					} else if (index == 1) {
-						// If the variable is the second one, it's either the
-						// pred or object
-						if (localFlags[1] != 0 && localFlags[0] != 0) {
-							// It's the predicate if the subject and predicate
-							// are variables
-							return this.statement.getPredicate();
-						} else {
-							return this.statement.getObject();
-						}
-					} else if (index == 0) {
-						// If the variable is the first, it could be any
-						if (localFlags[0] != 0) {
-							return this.statement.getSubject();
-						} else if (localFlags[1] != 0) {
-							return this.statement.getPredicate();
-						} else {
-							return this.statement.getObject();
-						}
-					}
-					return null;
-				}
-
-				private int getIndex(Variable variable) {
-					int index = 0;
-					for (Iterator vars = StatementBindingSet.this.variables.iterator(); vars.hasNext(); index++) {
-						Variable var = (Variable) vars.next();
-						if (variable.equals(var)) {
-							return index;
-						}
-					}
-					return -1;
-				}
-
-				public List getVariables() {
-					return StatementBindingSet.this.getVariables();
-				}
-
-			}
-		}
-
-		public String describeSet() {
-			return "FETCH TRIPLES FOR [" + StreamedTripleConstraintLogic.this.data.getSubjectExpression() + ","
-					+ StreamedTripleConstraintLogic.this.data.getPredicateExpression() + ","
-					+ StreamedTripleConstraintLogic.this.data.getObjectExpression() + "]";
-		}
-
-		public void accept(StreamedBindingSetVisitor setVisitor) {
-			setVisitor.visit(this);
-		}
-
-	}
-
-	private class StreamedTripleBindingSet extends VirtualRdfBindingSet {
-
-		private final List variables;
-
-		private final int[] flags;
-
-		private final boolean includeSource;
-
-		private final List statementIterators = new ArrayList();
-
-		public StreamedTripleBindingSet(List variables, int[] flags, boolean includeSource) {
-			this.variables = variables;
-			this.flags = flags;
-			this.includeSource = includeSource;
-		}
-
-		public void setSource(RdfSource source) {
-			StatementBindingSet set = new StatementBindingSet(source, this.variables, this.flags, this.includeSource);
-			for (Iterator statementIt = statementIterators.iterator(); statementIt.hasNext();) {
-				set.addIterator((GraphStatement) statementIt.next());
-			}
-			setSourcedSet(set);
-		}
-
-		public String describeSet() {
-			return "FETCH TRIPLES FOR [" + StreamedTripleConstraintLogic.this.data.getSubjectExpression() + ","
-					+ StreamedTripleConstraintLogic.this.data.getPredicateExpression() + ","
-					+ StreamedTripleConstraintLogic.this.data.getObjectExpression() + "]";
-		}
-
-		void addIterator(GraphStatement statement) {
-			this.statementIterators.add(statement);
-		}
-
-		public void accept(StreamedBindingSetVisitor setVisitor) {
-			setVisitor.visit(this);
-		}
-	}
-}
\ No newline at end of file
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/StreamedLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/StreamedLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/StreamedLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/StreamedLogic.java	2008-08-13 16:43:14.000000000 -0400
@@ -65,6 +65,7 @@
 import name.levering.ryan.sparql.logic.function.StringCastFunction;
 import name.levering.ryan.sparql.logic.naive.DefaultGroupConstraintLogic;
 import name.levering.ryan.sparql.logic.naive.DefaultOptionalConstraintLogic;
+import name.levering.ryan.sparql.logic.naive.DefaultTripleConstraintLogic;
 import name.levering.ryan.sparql.logic.naive.DefaultUnionConstraintLogic;
 import name.levering.ryan.sparql.logic.naive.StaticGraphDistinctionLogic;
 import name.levering.ryan.sparql.logic.streamed.IndexedSetDistinctionLogic;
@@ -75,7 +76,6 @@
 import name.levering.ryan.sparql.logic.streamed.StreamedSetProjectionLogic;
 import name.levering.ryan.sparql.logic.streamed.StreamedSetRangeLogic;
 import name.levering.ryan.sparql.logic.streamed.StreamedSetUnionLogic;
-import name.levering.ryan.sparql.logic.streamed.StreamedTripleConstraintLogic;
 import name.levering.ryan.sparql.model.data.AskQueryData;
 import name.levering.ryan.sparql.model.data.CallExpressionData;
 import name.levering.ryan.sparql.model.data.ConstructQueryData;
@@ -151,7 +151,7 @@
 		registerExternalFunction(SPARQLConstants.DOUBLE_TYPE, DoubleCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.DECIMAL_TYPE, DecimalCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.INTEGER_TYPE, IntegerCastFunction.getFactory());
-		registerExternalFunction(SPARQLConstants.DATE_TYPE, DateTimeCastFunction.getFactory());
+		registerExternalFunction(SPARQLConstants.DATETIME_TYPE, DateTimeCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.BOOLEAN_TYPE, BooleanCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.IRI_TYPE, IRICastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.LITERAL_TYPE, LiteralCastFunction.getFactory());
@@ -248,7 +248,7 @@
 	 * @return the logic handling the ask query
 	 */
 	public AskQueryLogic getAskQueryLogic(AskQueryData data) {
-		return new DefaultAskQueryLogic(data);
+		return new DefaultAskQueryLogic(data, new StreamedSetRangeLogic());
 	}
 
 	/**
@@ -257,8 +257,8 @@
 	 * @param data the data containing the query constraint and transformations
 	 * @return the logic handling the describe query
 	 */
-	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data) {
-		return new DefaultDescribeQueryLogic(data, new StreamedSetProjectionLogic(), new StreamedSetRangeLogic());
+	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data, SPARQLValueFactory valueFactory) {
+		return new DefaultDescribeQueryLogic(data, new StreamedSetProjectionLogic(), new StreamedSetRangeLogic(), valueFactory);
 	}
 
 	/**
@@ -319,7 +319,7 @@
 						.getPredicateExpression()), data);
 			}
 		}
-		return new StreamedTripleConstraintLogic(data);
+		return new DefaultTripleConstraintLogic(data);
 	}
 
 	/**
@@ -339,9 +339,7 @@
 	 * @return the logic handling the OPTIONAL constraint
 	 */
 	public ConstraintLogic getOptionalConstraintLogic(OptionalConstraintData data, SPARQLValueFactory valueFactory) {
-		return new DefaultOptionalConstraintLogic(data, new IndexedSetIntersectLogic(), new DefaultIntersectOrderLogic(
-				new IndexedSetIntersectLogic()), new IndexedSetJoinLogic(getValueConversionLogic(valueFactory),
-				getEffectiveBooleanLogic(valueFactory)));
+		return new DefaultOptionalConstraintLogic(data, new IndexedSetJoinLogic(getValueConversionLogic(valueFactory), getEffectiveBooleanLogic(valueFactory)), this);
 	}
 
 	/**
@@ -377,8 +375,8 @@
 	 *            direction
 	 * @return the logic handling the ordering of an expression
 	 */
-	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data) {
-		return new DefaultOrderExpressionLogic(data, getValueOrderingLogic());
+	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data, SPARQLValueFactory valueFactory) {
+		return new DefaultOrderExpressionLogic(data, getValueOrderingLogic(valueFactory));
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/logic/StreamedStrictLogic.java work-copy/src/main/name/levering/ryan/sparql/logic/StreamedStrictLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/logic/StreamedStrictLogic.java	2007-10-07 07:19:19.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/logic/StreamedStrictLogic.java	2008-08-13 16:43:33.000000000 -0400
@@ -32,6 +32,7 @@
 import name.levering.ryan.sparql.logic.naive.DefaultGroupConstraintLogic;
 import name.levering.ryan.sparql.logic.naive.DefaultOptionalConstraintLogic;
 import name.levering.ryan.sparql.logic.naive.DefaultUnionConstraintLogic;
+import name.levering.ryan.sparql.logic.naive.DefaultTripleConstraintLogic;
 import name.levering.ryan.sparql.logic.streamed.IndexedSetDistinctionLogic;
 import name.levering.ryan.sparql.logic.streamed.IndexedSetIntersectLogic;
 import name.levering.ryan.sparql.logic.streamed.IndexedSetJoinLogic;
@@ -40,7 +41,6 @@
 import name.levering.ryan.sparql.logic.streamed.StreamedSetProjectionLogic;
 import name.levering.ryan.sparql.logic.streamed.StreamedSetRangeLogic;
 import name.levering.ryan.sparql.logic.streamed.StreamedSetUnionLogic;
-import name.levering.ryan.sparql.logic.streamed.StreamedTripleConstraintLogic;
 import name.levering.ryan.sparql.model.data.AskQueryData;
 import name.levering.ryan.sparql.model.data.CallExpressionData;
 import name.levering.ryan.sparql.model.data.ConstructQueryData;
@@ -100,7 +100,7 @@
 		registerExternalFunction(SPARQLConstants.DOUBLE_TYPE, DoubleCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.DECIMAL_TYPE, DecimalCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.INTEGER_TYPE, IntegerCastFunction.getFactory());
-		registerExternalFunction(SPARQLConstants.DATE_TYPE, DateTimeCastFunction.getFactory());
+		registerExternalFunction(SPARQLConstants.DATETIME_TYPE, DateTimeCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.BOOLEAN_TYPE, BooleanCastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.IRI_TYPE, IRICastFunction.getFactory());
 		registerExternalFunction(SPARQLConstants.LITERAL_TYPE, LiteralCastFunction.getFactory());
@@ -140,7 +140,7 @@
 	 * @return the logic handling the ask query
 	 */
 	public AskQueryLogic getAskQueryLogic(AskQueryData data) {
-		return new DefaultAskQueryLogic(data);
+		return new DefaultAskQueryLogic(data, new StreamedSetRangeLogic());
 	}
 
 	/**
@@ -149,8 +149,8 @@
 	 * @param data the data containing the query constraint and transformations
 	 * @return the logic handling the describe query
 	 */
-	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data) {
-		return new DefaultDescribeQueryLogic(data, new StreamedSetProjectionLogic(), new StreamedSetRangeLogic());
+	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data, SPARQLValueFactory valueFactory) {
+		return new DefaultDescribeQueryLogic(data, new StreamedSetProjectionLogic(), new StreamedSetRangeLogic(), valueFactory);
 	}
 
 	/**
@@ -211,7 +211,7 @@
 	 * @return the logic handling the triple constraint
 	 */
 	public ConstraintLogic getTripleConstraintLogic(TripleConstraintData data) {
-		return new StreamedTripleConstraintLogic(data);
+		return new DefaultTripleConstraintLogic(data);
 	}
 
 	/**
@@ -231,9 +231,8 @@
 	 * @return the logic handling the OPTIONAL constraint
 	 */
 	public ConstraintLogic getOptionalConstraintLogic(OptionalConstraintData data, SPARQLValueFactory valueFactory) {
-		return new DefaultOptionalConstraintLogic(data, new IndexedSetIntersectLogic(), new DefaultIntersectOrderLogic(
-				new IndexedSetIntersectLogic()), new IndexedSetJoinLogic(getValueConversionLogic(valueFactory),
-				getEffectiveBooleanLogic(valueFactory)));
+		return new DefaultOptionalConstraintLogic(data, new IndexedSetJoinLogic(getValueConversionLogic(valueFactory),
+				getEffectiveBooleanLogic(valueFactory)), this);
 	}
 
 	/**
@@ -269,8 +268,8 @@
 	 *            direction
 	 * @return the logic handling the ordering of an expression
 	 */
-	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data) {
-		return new DefaultOrderExpressionLogic(data, getValueOrderingLogic());
+	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data, SPARQLValueFactory valueFactory) {
+		return new DefaultOrderExpressionLogic(data, getValueOrderingLogic(valueFactory));
 	}
 
 	/**
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/model/data/SelectQueryData.java work-copy/src/main/name/levering/ryan/sparql/model/data/SelectQueryData.java
--- work-copy/src/main/name/levering/ryan/sparql/model/data/SelectQueryData.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/model/data/SelectQueryData.java	2007-10-21 12:35:15.000000000 -0400
@@ -8,9 +8,9 @@
 import java.util.List;
 
 /**
- * Represents the interface for the data accessors for a SELECT query. A SELECT
- * query has extra information for modifying the solutions as well as a list of
- * variables to project the value binding set onto.
+ * Represents the interface for the data accessors for a SELECT query. A
+ * SELECT query has extra information for modifying the solutions as well as a
+ * list of variables to project the value binding set onto.
  * 
  * @author Ryan Levering
  * @version 1.0
@@ -26,14 +26,6 @@
     public boolean getDistinct();
 
     /**
-     * Returns whether the query should possibly return distinct values in the
-     * resulting binding set.
-     * 
-     * @return true if the reduced keyword was included in the query
-     */
-    public boolean getReduced();
-
-    /**
      * Gets the variable list to project the value bindings onto. This limits
      * the columns returned in the value binding table.
      * 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/model/logic/ConstraintLogic.java work-copy/src/main/name/levering/ryan/sparql/model/logic/ConstraintLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/model/logic/ConstraintLogic.java	2006-08-20 20:00:59.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/model/logic/ConstraintLogic.java	2008-08-13 17:43:33.000000000 -0400
@@ -6,9 +6,18 @@
 package name.levering.ryan.sparql.model.logic;
 
 import java.util.Collection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
-import name.levering.ryan.sparql.common.RdfSource;
+import name.levering.ryan.sparql.common.RdfSource;
+import name.levering.ryan.sparql.common.Variable;
+
+import name.levering.ryan.sparql.model.logic.helper.SetRangeLogic;
+import name.levering.ryan.sparql.model.logic.helper.SetProjectionLogic;
+import name.levering.ryan.sparql.model.logic.helper.SetDistinctionLogic;
 
 /**
  * The logic that every constraint satisfies. It currently can be used two ways.
@@ -27,16 +36,165 @@
      * Constrains the value bindings by either constraining the current value
      * bindings or returning a set that will be constrained via intersection
      * with the current set.
-     * 
-     * @param bindings the set of current bindings to evaluate against
-     * @param source the RDF source, which is dealt with by the triple
-     *            constraint
-     * @param defaultDatasets the datasets that are currently being used for
-     *            binding
-     * @param namedDatasets the datasets that are used in the GRAPH constraint
-     *            for unbound variables
      */
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source,
-            Collection defaultDatasets, Collection namedDatasets);
+    public RdfBindingSet constrain(CallParams p);
+	 
+	 public static class CallParams {
+		 /**
+		  * The set of current bindings to evaluate against, for
+		  * ConstraintLogics where it is used (like filters).
+		  */
+		 public RdfBindingSet bindings;
+		 
+		 /**
+		  * The RDF data source, which is dealt with by the triple constraint
+		  */
+		 public RdfSource source;
+		 
+		 /**
+		  * The FROM datasets used in group constraints outside of a GRAPH constraint.
+		  */
+		 public Collection defaultDatasets;
+		 
+		 /**
+		  * The FROM NAMED datasets used in the GRAPH constraint with unbound variables.
+		  */
+		 public Collection namedDatasets;
+		 
+		 /**
+		  * The current set of graph URIs that constraints are being evaluated against.
+		  * If null, then defaultDatasets should be used. Inside a GRAPH
+		  * constraint with a variable, this becomes namedDatasets. Inside a GRAPH
+		  * constraint with a URI, this becomes a singleton set containing that URI.
+		  */
+		 public Collection sourceDatasets;
+		 
+		 /**
+		  * When evaluating a triple constraint, a variable to bind to the graph URI
+		  * containing each triple, or null to discard graph information in the
+		  * resulting bindings.
+		  */
+		 public Variable graphVariable;
+
+		 /**
+		  * A List of OrderExpressionLogic objects that control how the
+		  * results should be ordered, or null if no order is specified.
+		  */
+		 public List orderExpressions;
+		
+		 /**
+		  * The most number of binding rows that is being requested, or -1
+		  * if all rows are requested. If set to something other than -1,
+		  * rangeLogic must be set.
+		  */
+		 public int limit = -1;
+		 
+		 /**
+		  * The first row of results to be returned. Zero means the first row
+		  * from the data set. If set to something other than set, rangeLogic
+		  * must also be set.
+		  */
+		 public int offset = 0;
+
+		 public static class DistinctType {
+			 public static final int ALL_BINDINGS = 0;
+			 public static final int REDUCED = 1;
+			 public static final int DISTINCT = 2;
+		 }
+		 
+		 /**
+		  * Whether REDUCED or DISTINCT results are requested.
+		  * A value from DistinctType. If something other than
+		  * ALL_BINDINGS is used, distinctionLogic must be set.
+		  */
+		 public int distinct = DistinctType.ALL_BINDINGS;
+		 
+		 /**
+		  * A set of distinguished variables: variables whose bindings are
+		  * to be returned to the caller. If null, all variables whose scope
+		  * is larger than the ConstraintLogic are to be returned. If this
+		  * field is not null, projectionLogic must be set.
+		  */
+		 public Set distinguishedVariables;
+
+		 /**
+		  * A mapping from variables to Sets of values that the variable must be drawn from
+		  */
+		 public Map knownValues;
+		 
+		 /**
+		  * A mapping from variables to Lists of filters that the variable must satisfy.
+		  * A filter's type is determined by API implementors.
+		  */
+		 public Map knownFilters;
+		 
+		 public SetRangeLogic rangeLogic;
+		 public SetProjectionLogic projectionLogic;
+		 public SetDistinctionLogic distinctionLogic;
+		 
+		public Set getOrderVariables() {
+			Set ret = new HashSet();
+			if (orderExpressions != null) {
+				for (int i = orderExpressions.size() - 1; i >= 0; i--) {
+					OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
+					ret.addAll(orderer.getVariables());
+				}
+			}
+			return ret;
+		 }
+		 
+		 public CallParams clone() {
+			 CallParams p = new CallParams();
+			 p.bindings = bindings;
+			 p.source = source;
+			 p.defaultDatasets = defaultDatasets;
+			 p.namedDatasets = namedDatasets;
+			 p.sourceDatasets = sourceDatasets;
+			 p.graphVariable = graphVariable;
+			 p.distinguishedVariables = distinguishedVariables == null ? null : new java.util.HashSet(distinguishedVariables);
+			 p.orderExpressions = orderExpressions == null ? null : new java.util.ArrayList(orderExpressions);
+			 p.limit = limit;
+			 p.offset = offset;
+			 p.distinct = distinct;
+			 p.knownValues = knownValues == null ? null : new java.util.HashMap(knownValues);
+			 p.knownFilters = knownFilters == null ? null : new java.util.HashMap(knownFilters);
+			 p.rangeLogic = rangeLogic;
+			 p.projectionLogic = projectionLogic;
+			 p.distinctionLogic = distinctionLogic;
+			 return p;
+		 }
 
+		public RdfBindingSet projectOrderDistinctLimit(RdfBindingSet results) {
+			// Ordering must be done before projection because the ordering may
+			// make use of variables that are not distinguished.
+			if (orderExpressions != null && !results.isOrdered()) {
+				// Apply ordering in reverse order to give priority to the first
+				// variable.
+				for (int i = orderExpressions.size() - 1; i >= 0; i--) {
+					OrderExpressionLogic orderer = (OrderExpressionLogic) orderExpressions.get(i);
+					results = orderer.order(results);
+				}
+			}
+			
+			if (distinguishedVariables != null) {
+				Set select = new HashSet(distinguishedVariables);
+				select.retainAll(results.getVariables());
+				results = projectionLogic.project(results, select);
+			}
+			
+			// It would be nice to do the distinct logic before ordering, but we have to do
+			// it after the projection.
+			if (distinct == CallParams.DistinctType.DISTINCT && !results.isDistinct())
+			results = this.distinctionLogic.makeDistinct(results);
+			
+			// Now apply limiting and offsetting
+			if (offset > 0)
+				results = rangeLogic.offset(results, offset);
+			if (limit >= 0)
+				results = rangeLogic.limit(results, limit);
+			
+			return results;
+		}
+	
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/model/logic/ExpressionLogic.java work-copy/src/main/name/levering/ryan/sparql/model/logic/ExpressionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/model/logic/ExpressionLogic.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/model/logic/ExpressionLogic.java	2008-05-03 17:39:06.000000000 -0400
@@ -5,6 +5,8 @@
  */
 package name.levering.ryan.sparql.model.logic;
 
+import java.util.Set;
+
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.Value;
 
@@ -29,4 +31,9 @@
      */
     public Value evaluate(RdfBindingRow bindings);
 
+    /**
+     * Returns a Set of variables used by the expression.
+     * @return a Set of variables used by the expression
+     */
+    public Set getVariables();
 }
\ No newline at end of file
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/model/logic/helper/ValueConversionLogic.java work-copy/src/main/name/levering/ryan/sparql/model/logic/helper/ValueConversionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/model/logic/helper/ValueConversionLogic.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/model/logic/helper/ValueConversionLogic.java	2008-07-11 15:28:33.000000000 -0400
@@ -95,22 +95,22 @@
     public Literal convertDouble(double value);
 
     /**
-     * Converts a xsd:integer literal to a int primitive value.
+     * Converts a xsd:integer literal to a java.math.BigInteger value.
      * 
      * @param literal a literal of xsd:integer datatype
-     * @return a int value representing the value in the literal
+     * @return a java.math.BigInteger value representing the value in the literal
      * @throws ConversionException if the literal isn't a integer
      */
-    public int convertInteger(Literal literal);
+    public java.math.BigInteger convertInteger(Literal literal);
 
     /**
-     * Converts a int primitive value to an xsd:integer literal.
+     * Converts a java.math.BigInteger value to an xsd:integer literal.
      * 
-     * @param value the int value to convert to a literal
+     * @param value the java.math.BigInteger value to convert to a literal
      * @return a literal of type xsd:integer representing the value of the
      *         primitive
      */
-    public Literal convertInteger(int value);
+    public Literal convertInteger(java.math.BigInteger value);
 
     /**
      * Converts a xsd:dateTime literal to a DateTime primitive value.
@@ -149,21 +149,21 @@
     public Literal convertFloat(float value);
 
     /**
-     * Converts a xsd:decimal literal to a long primitive value.
+     * Converts a xsd:decimal literal to a java.math.BigDecimal value.
      * 
      * @param literal a literal of xsd:decimal datatype
-     * @return a long value representing the value in the literal
+     * @return a java.math.BigDecimal value representing the value in the literal
      * @throws ConversionException if the literal isn't a decimal
      */
-    public long convertDecimal(Literal literal);
+    public java.math.BigDecimal convertDecimal(Literal literal);
 
     /**
-     * Converts a long primitive value to an xsd:decimal literal.
+     * Converts a java.math.BigDecimal value to an xsd:decimal literal.
      * 
-     * @param value the long value to convert to a literal
+     * @param value the java.math.BigDecimal value to convert to a literal
      * @return a literal of type xsd:decimal representing the value of the
      *         primitive
      */
-    public Literal convertDecimal(long value);
+    public Literal convertDecimal(java.math.BigDecimal value);
 
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/model/logic/LogicFactory.java work-copy/src/main/name/levering/ryan/sparql/model/logic/LogicFactory.java
--- work-copy/src/main/name/levering/ryan/sparql/model/logic/LogicFactory.java	2007-10-07 07:19:17.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/model/logic/LogicFactory.java	2008-07-11 15:31:54.000000000 -0400
@@ -47,7 +47,7 @@
 
 	public AskQueryLogic getAskQueryLogic(AskQueryData data);
 
-	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data);
+	public DescribeQueryLogic getDescribeQueryLogic(DescribeQueryData data, SPARQLValueFactory valueFactory);
 
 	public SelectQueryLogic getSelectQueryLogic(SelectQueryData data);
 
@@ -63,7 +63,7 @@
 
 	public ConstraintLogic getOptionalConstraintLogic(OptionalConstraintData data, SPARQLValueFactory valueFactory);
 
-	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data);
+	public OrderExpressionLogic getOrderExpressionLogic(OrderExpressionData data, SPARQLValueFactory valueFactory);
 
 	public ExpressionLogic getAdditionLogic(BinaryExpressionData data, SPARQLValueFactory valueFactory);
 
@@ -109,19 +109,15 @@
 
 	public ExpressionLogic getLangMatchesLogic(CallExpressionData data, SPARQLValueFactory valueFactory);
 
-    public ExpressionLogic getSameTermLogic(CallExpressionData sameTermFuncNode, SPARQLValueFactory valueFactory);
-
 	public ExpressionLogic getRegexLogic(CallExpressionData data, SPARQLValueFactory valueFactory);
 
 	public ExpressionLogic getStringLogic(CallExpressionData data, SPARQLValueFactory valueFactory);
 
 	public ExpressionLogic getExternalFunctionLogic(CallExpressionData data, SPARQLValueFactory valueFactory);
 
-	public ExpressionLogic getVariableLogic(Variable data);
-
 	public ValueConversionLogic getValueConversionLogic(SPARQLValueFactory valueFactory);
 
-	public ValueOrderingLogic getValueOrderingLogic();
+	public ValueOrderingLogic getValueOrderingLogic(SPARQLValueFactory valueFactory);
 
 	public void registerExternalFunction(URI functionIRI, ExternalFunctionFactory functionFactory);
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/model/logic/OrderExpressionLogic.java work-copy/src/main/name/levering/ryan/sparql/model/logic/OrderExpressionLogic.java
--- work-copy/src/main/name/levering/ryan/sparql/model/logic/OrderExpressionLogic.java	2006-08-20 20:00:59.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/model/logic/OrderExpressionLogic.java	2008-04-27 11:14:20.000000000 -0400
@@ -5,6 +5,8 @@
  */
 package name.levering.ryan.sparql.model.logic;
 
+import java.util.Set;
+
 import name.levering.ryan.sparql.common.RdfBindingSet;
 
 /**
@@ -26,4 +28,10 @@
      */
     public RdfBindingSet order(RdfBindingSet set);
 
+    /**
+     * Gets the variables used in the order expression.
+     * 
+     * @return a set of variables
+     */
+    public Set getVariables();
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/JavaCharStream.java work-copy/src/main/name/levering/ryan/sparql/parser/JavaCharStream.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/JavaCharStream.java	2007-10-07 07:19:57.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/JavaCharStream.java	2007-10-21 12:35:16.000000000 -0400
@@ -1,4 +1,4 @@
-/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 3.0 */
+/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 4.0 */
 package name.levering.ryan.sparql.parser;
 
 /**
@@ -76,6 +76,10 @@
   protected int maxNextCharInd = 0;
   protected int nextCharInd = -1;
   protected int inBuf = 0;
+  protected int tabSize = 8;
+
+  protected void setTabSize(int i) { tabSize = i; }
+  protected int getTabSize(int i) { return tabSize; }
 
   protected void ExpandBuff(boolean wrapAround)
   {
@@ -234,7 +238,7 @@
            break;
         case '\t' :
            column--;
-           column += (8 - (column & 07));
+           column += (tabSize - (column % tabSize));
            break;
         default :
            break;
@@ -431,33 +435,66 @@
   {
      ReInit(dstream, 1, 1, 4096);
   }
+  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
   public JavaCharStream(java.io.InputStream dstream, int startline,
   int startcolumn, int buffersize)
   {
      this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
   }
 
+  public JavaCharStream(java.io.InputStream dstream, String encoding, int startline,
+                        int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, startline, startcolumn, 4096);
+  }
+
   public JavaCharStream(java.io.InputStream dstream, int startline,
-                                                           int startcolumn)
+                        int startcolumn)
   {
      this(dstream, startline, startcolumn, 4096);
   }
 
+  public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     this(dstream, encoding, 1, 1, 4096);
+  }
+
   public JavaCharStream(java.io.InputStream dstream)
   {
      this(dstream, 1, 1, 4096);
   }
 
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+  int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize);
+  }
+
   public void ReInit(java.io.InputStream dstream, int startline,
   int startcolumn, int buffersize)
   {
-     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
+     ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize);
+  }
+  public void ReInit(java.io.InputStream dstream, String encoding, int startline,
+                     int startcolumn) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, startline, startcolumn, 4096);
   }
   public void ReInit(java.io.InputStream dstream, int startline,
-                                                           int startcolumn)
+                     int startcolumn)
   {
      ReInit(dstream, startline, startcolumn, 4096);
   }
+  public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException
+  {
+     ReInit(dstream, encoding, 1, 1, 4096);
+  }
+
   public void ReInit(java.io.InputStream dstream)
   {
      ReInit(dstream, 1, 1, 4096);
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTDescribeQuery.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTDescribeQuery.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTDescribeQuery.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTDescribeQuery.java	2008-07-11 15:31:54.000000000 -0400
@@ -138,7 +138,7 @@
     }
     
     public void applyLogic(LogicBinder binder) {
-        this.logic = binder.getLogicFactory().getDescribeQueryLogic(this);
+        this.logic = binder.getLogicFactory().getDescribeQueryLogic(this, binder.getValueFactory());
     }
     
     public Collection getVariables() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFilterConstraint.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFilterConstraint.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFilterConstraint.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFilterConstraint.java	2008-02-09 15:25:05.000000000 -0500
@@ -4,6 +4,7 @@
 
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -21,15 +22,15 @@
     }
 
     public ExpressionLogic getExpression() {
-        return (ExpressionLogic) this.jjtGetChild(0);
+        return ((ExpressionNode) this.jjtGetChild(0)).getExpressionLogic();
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public Set getVariables() {
-        return Collections.EMPTY_SET;
+        return getExpression().getVariables();
     }
     
     public String toString() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFunctionCall.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFunctionCall.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFunctionCall.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTFunctionCall.java	2008-08-06 17:36:25.000000000 -0400
@@ -27,7 +27,7 @@
             Node child = this.jjtGetChild(i);
             if (child instanceof ASTArguments) {
                 for (int j = 0; j < child.jjtGetNumChildren(); j++) {
-                    arguments.add(child.jjtGetChild(j));
+                    arguments.add(((ExpressionNode)child.jjtGetChild(j)).getExpressionLogic());
                 }
             }
         }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGraphConstraint.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGraphConstraint.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGraphConstraint.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGraphConstraint.java	2007-10-21 12:35:16.000000000 -0400
@@ -3,6 +3,7 @@
 package name.levering.ryan.sparql.parser.model;
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -40,8 +41,8 @@
         return null;
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public Set getVariables() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGroupConstraint.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGroupConstraint.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGroupConstraint.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTGroupConstraint.java	2007-10-21 12:35:16.000000000 -0400
@@ -6,6 +6,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -39,9 +40,8 @@
         return constraints;
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source,
-            Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public Set getVariables() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTLiteral.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTLiteral.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTLiteral.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTLiteral.java	2008-02-07 16:52:55.000000000 -0500
@@ -60,4 +60,19 @@
         }
     }
     
+	public int hashCode() {
+		return label.hashCode();
+	}
+	
+	public boolean equals(Object other) {
+		if (!(other instanceof Literal)) return false;
+		Literal lit = (Literal)other;
+		return label.equals(lit.getLabel())
+			&& ((language == null && lit.getLanguage() == null) || (language != null && lit.getLanguage() != null && language.equals(lit.getLanguage())))
+			&& ((datatype == null && lit.getDatatype() == null) || (datatype != null && lit.getDatatype() != null && datatype.equals(lit.getDatatype()))); 
+	}
+	
+	 public java.util.Set getVariables() {
+		 return new java.util.HashSet();
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTOptionalConstraint.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTOptionalConstraint.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTOptionalConstraint.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTOptionalConstraint.java	2007-10-21 12:35:16.000000000 -0400
@@ -3,6 +3,7 @@
 package name.levering.ryan.sparql.parser.model;
 
 import java.util.Collection;
+import java.util.Map;
 import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -24,8 +25,8 @@
         return (GroupConstraint) this.jjtGetChild(0);
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public Set getVariables() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTQName.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTQName.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTQName.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTQName.java	2008-01-20 11:59:40.000000000 -0500
@@ -31,7 +31,7 @@
         } else if (this.namespace != null) {
             resolvedNamespace = this.namespace;
         } else {
-            resolvedNamespace = "";
+        	throw new RuntimeException("The namespace prefix " + this.namespace + " has not been defined.");
         }
         return resolvedNamespace + this.localName;
     }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSameTermFuncNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSameTermFuncNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSameTermFuncNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSameTermFuncNode.java	1969-12-31 19:00:00.000000000 -0500
@@ -1,22 +0,0 @@
-package name.levering.ryan.sparql.parser.model;
-
-import name.levering.ryan.sparql.model.logic.ExpressionLogic;
-
-import name.levering.ryan.sparql.common.SPARQLValueFactory;
-import name.levering.ryan.sparql.common.URI;
-
-public class ASTSameTermFuncNode extends FunctionNode {
-
-    public ASTSameTermFuncNode(int id) {
-        super(id);
-    }
-
-    public ExpressionLogic getLogic(LogicBinder binder) {
-        return binder.getLogicFactory().getSameTermLogic(this, binder.getValueFactory());
-    }
-
-    public URI getName(SPARQLValueFactory factory) {
-        return factory.createURI("fn:sameTerm");
-    }
-
-}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSelectQuery.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSelectQuery.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSelectQuery.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTSelectQuery.java	2007-10-21 12:35:16.000000000 -0400
@@ -22,8 +22,7 @@
     private SelectQueryLogic logic;
 
     private boolean distinct = false;
-    
-    private boolean reduced = false;
+	 private boolean reduced = false;
 
     public ASTSelectQuery(int id) {
         super(id);
@@ -37,10 +36,6 @@
         this.distinct = distinct;
     }
 
-    public boolean getReduced() {
-        return this.reduced;
-    }
-
     public void setReduced(boolean reduced) {
         this.reduced = reduced;
     }
@@ -124,10 +119,6 @@
             output.append("DISTINCT ");
         }
 
-        if (this.getReduced()) {
-            output.append("REDUCED ");
-        }
-
         List selectVars = this.getQueryVariables();
         if (!selectVars.isEmpty()) {
             for (Iterator i = selectVars.iterator(); i.hasNext();) {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTUnionConstraint.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTUnionConstraint.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTUnionConstraint.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTUnionConstraint.java	2007-10-21 12:35:16.000000000 -0400
@@ -6,6 +6,7 @@
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -31,8 +32,8 @@
         return constraints;
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public Set getVariables() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTVar.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTVar.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTVar.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTVar.java	2008-02-09 10:22:11.000000000 -0500
@@ -8,9 +8,8 @@
 
 import name.levering.ryan.sparql.common.Value;
 
-public class ASTVar extends SimpleNode implements Variable {
+public class ASTVar extends SimpleNode implements ExpressionNode, Variable {
     
-    private ExpressionLogic logic;
     private String name;
     
     public ASTVar(int id) {
@@ -20,9 +19,13 @@
     public String getName() {
         return this.name;
     }
+    
+    public ExpressionLogic getExpressionLogic() {
+    	return this;
+    }
 
     public Value evaluate(RdfBindingRow bindings) {
-        return this.logic.evaluate(bindings);
+        return bindings.getValue(this);
     }
     
     public void setName(String name) {
@@ -45,7 +48,11 @@
     }
     
     public void applyLogic(LogicBinder binder) {
-        this.logic = binder.getLogicFactory().getVariableLogic(this);
     }
 
+	 public java.util.Set getVariables() {
+		 java.util.HashSet ret = new java.util.HashSet();
+		 ret.add(this);
+		 return ret;
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTWithExtension.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTWithExtension.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTWithExtension.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ASTWithExtension.java	2007-10-21 12:35:16.000000000 -0400
@@ -6,6 +6,7 @@
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
+import java.util.Map;
 
 import name.levering.ryan.sparql.common.QueryException;
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -25,8 +26,8 @@
         super(id);
     }
     
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public URI getName() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/BinaryExpressionNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/BinaryExpressionNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/BinaryExpressionNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/BinaryExpressionNode.java	2008-02-09 15:10:39.000000000 -0500
@@ -16,7 +16,7 @@
  * @version 1.0
  */
 public abstract class BinaryExpressionNode extends SimpleNode implements
-        BinaryExpressionData,ExpressionLogic {
+        ExpressionNode, BinaryExpressionData {
 
     private ExpressionLogic logic;
     
@@ -25,18 +25,18 @@
     }
 
     public ExpressionLogic getLeftExpression() {
-        return (ExpressionLogic) this.jjtGetChild(0);
+        return ((ExpressionNode) this.jjtGetChild(0)).getExpressionLogic();
     }
 
     public ExpressionLogic getRightExpression() {
-        return (ExpressionLogic) this.jjtGetChild(1);
+        return ((ExpressionNode) this.jjtGetChild(1)).getExpressionLogic();
     }
     
-    public Value evaluate(RdfBindingRow bindings) {
-        return this.logic.evaluate(bindings);
+    public ExpressionLogic getExpressionLogic() {
+        return logic;
     }
     
-    public abstract ExpressionLogic getLogic(LogicBinder binder);
+    protected abstract ExpressionLogic getLogic(LogicBinder binder);
     
     public String toString() {
         return "(" + getLeftExpression() + " " + getOperator() + " " + getRightExpression() + ")";
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/BNodeNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/BNodeNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/BNodeNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/BNodeNode.java	2008-02-07 16:52:14.000000000 -0500
@@ -25,4 +25,10 @@
     public String getName() {
         return getID();
     }
+
+	 public java.util.Set getVariables() {
+		 java.util.HashSet ret = new java.util.HashSet();
+		 ret.add(this);
+		 return ret;
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/DelegatingTripleConstraint.java work-copy/src/main/name/levering/ryan/sparql/parser/model/DelegatingTripleConstraint.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/DelegatingTripleConstraint.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/DelegatingTripleConstraint.java	2007-10-21 12:35:16.000000000 -0400
@@ -7,6 +7,7 @@
 
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.Map;
 import java.util.Set;
 
 import name.levering.ryan.sparql.common.RdfBindingSet;
@@ -39,8 +40,8 @@
         return this.statement.getObjectExpression();
     }
 
-    public RdfBindingSet constrain(RdfBindingSet bindings, RdfSource source, Collection defaultDatasets, Collection namedDatasets) {
-        return this.logic.constrain(bindings, source, defaultDatasets, namedDatasets);
+    public RdfBindingSet constrain(ConstraintLogic.CallParams p) {
+        return this.logic.constrain(p);
     }
 
     public Set getVariables() {
@@ -64,5 +65,5 @@
     public void setLogic(ConstraintLogic logic) {
         this.logic = logic;
     }
-
+	
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ExpressionNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ExpressionNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ExpressionNode.java	1969-12-31 19:00:00.000000000 -0500
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ExpressionNode.java	2008-02-09 10:15:22.000000000 -0500
@@ -0,0 +1,17 @@
+/*
+ * SPARQL Engine
+ */
+package name.levering.ryan.sparql.parser.model;
+
+import name.levering.ryan.sparql.model.logic.ExpressionLogic;
+
+/**
+ * A node that is part of a expression and can return an
+ * ExpressionLogic object that encapsulates how to evaluate
+ * this type of expression.
+ */
+public interface ExpressionNode {
+
+	public ExpressionLogic getExpressionLogic();
+
+}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/FunctionNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/FunctionNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/FunctionNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/FunctionNode.java	2008-02-09 10:29:45.000000000 -0500
@@ -21,8 +21,7 @@
  * @author Ryan Levering
  * @version 1.0
  */
-public abstract class FunctionNode extends SimpleNode implements ExpressionLogic,
-        CallExpressionData {
+public abstract class FunctionNode extends SimpleNode implements ExpressionNode, CallExpressionData {
 
     private ExpressionLogic logic;
     
@@ -32,19 +31,19 @@
         super(i);
     }
 
-    public Value evaluate(RdfBindingRow bindings) {
-        return this.logic.evaluate(bindings);
+    public ExpressionLogic getExpressionLogic() {
+        return logic;
     }
 
     public List getArguments() {
         List arguments = new ArrayList();
         for (int i = 0; i < this.jjtGetNumChildren(); i++) {
-            arguments.add(this.jjtGetChild(i));
+            arguments.add(((ExpressionNode)this.jjtGetChild(i)).getExpressionLogic());
         }
         return arguments;
     }
     
-    public abstract ExpressionLogic getLogic(LogicBinder binder);
+    protected abstract ExpressionLogic getLogic(LogicBinder binder);
     
     public abstract URI getName(SPARQLValueFactory factory);
 
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/JJTSPARQLParserState.java work-copy/src/main/name/levering/ryan/sparql/parser/model/JJTSPARQLParserState.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/JJTSPARQLParserState.java	2006-08-20 20:05:43.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/JJTSPARQLParserState.java	2007-10-21 12:35:16.000000000 -0400
@@ -1,123 +1,123 @@
-/* Generated By:JJTree: Do not edit this line. /home/tauberer/dev/semweb/sparql/src/src/main/name/levering/ryan/sparql/parser/model/JJTSPARQLParserState.java */
-
-package name.levering.ryan.sparql.parser.model;
-
-class JJTSPARQLParserState {
-  private java.util.Stack nodes;
-  private java.util.Stack marks;
-
-  private int sp;		// number of nodes on stack
-  private int mk;		// current mark
-  private boolean node_created;
-
-  JJTSPARQLParserState() {
-    nodes = new java.util.Stack();
-    marks = new java.util.Stack();
-    sp = 0;
-    mk = 0;
-  }
-
-  /* Determines whether the current node was actually closed and
-     pushed.  This should only be called in the final user action of a
-     node scope.  */
-  boolean nodeCreated() {
-    return node_created;
-  }
-
-  /* Call this to reinitialize the node stack.  It is called
-     automatically by the parser's ReInit() method. */
-  void reset() {
-    nodes.removeAllElements();
-    marks.removeAllElements();
-    sp = 0;
-    mk = 0;
-  }
-
-  /* Returns the root node of the AST.  It only makes sense to call
-     this after a successful parse. */
-  Node rootNode() {
-    return (Node)nodes.elementAt(0);
-  }
-
-  /* Pushes a node on to the stack. */
-  void pushNode(Node n) {
-    nodes.push(n);
-    ++sp;
-  }
-
-  /* Returns the node on the top of the stack, and remove it from the
-     stack.  */
-  Node popNode() {
-    if (--sp < mk) {
-      mk = ((Integer)marks.pop()).intValue();
-    }
-    return (Node)nodes.pop();
-  }
-
-  /* Returns the node currently on the top of the stack. */
-  Node peekNode() {
-    return (Node)nodes.peek();
-  }
-
-  /* Returns the number of children on the stack in the current node
-     scope. */
-  int nodeArity() {
-    return sp - mk;
-  }
-
-
-  void clearNodeScope(Node n) {
-    while (sp > mk) {
-      popNode();
-    }
-    mk = ((Integer)marks.pop()).intValue();
-  }
-
-
-  void openNodeScope(Node n) {
-    marks.push(new Integer(mk));
-    mk = sp;
-    n.jjtOpen();
-  }
-
-
-  /* A definite node is constructed from a specified number of
-     children.  That number of nodes are popped from the stack and
-     made the children of the definite node.  Then the definite node
-     is pushed on to the stack. */
-  void closeNodeScope(Node n, int num) {
-    mk = ((Integer)marks.pop()).intValue();
-    while (num-- > 0) {
-      Node c = popNode();
-      c.jjtSetParent(n);
-      n.jjtAddChild(c, num);
-    }
-    n.jjtClose();
-    pushNode(n);
-    node_created = true;
-  }
-
-
-  /* A conditional node is constructed if its condition is true.  All
-     the nodes that have been pushed since the node was opened are
-     made children of the the conditional node, which is then pushed
-     on to the stack.  If the condition is false the node is not
-     constructed and they are left on the stack. */
-  void closeNodeScope(Node n, boolean condition) {
-    if (condition) {
-      int a = nodeArity();
-      mk = ((Integer)marks.pop()).intValue();
-      while (a-- > 0) {
-	Node c = popNode();
-	c.jjtSetParent(n);
-	n.jjtAddChild(c, a);
-      }
-      n.jjtClose();
-      pushNode(n);
-      node_created = true;
-    } else {
-      mk = ((Integer)marks.pop()).intValue();
-      node_created = false;
-    }
-  }
-}
+/* Generated By:JJTree: Do not edit this line. /home/tauberer/dev/semweb/sparql/src/src/main/name/levering/ryan/sparql/parser/model/JJTSPARQLParserState.java */
+
+package name.levering.ryan.sparql.parser.model;
+
+class JJTSPARQLParserState {
+  private java.util.Stack nodes;
+  private java.util.Stack marks;
+
+  private int sp;		// number of nodes on stack
+  private int mk;		// current mark
+  private boolean node_created;
+
+  JJTSPARQLParserState() {
+    nodes = new java.util.Stack();
+    marks = new java.util.Stack();
+    sp = 0;
+    mk = 0;
+  }
+
+  /* Determines whether the current node was actually closed and
+     pushed.  This should only be called in the final user action of a
+     node scope.  */
+  boolean nodeCreated() {
+    return node_created;
+  }
+
+  /* Call this to reinitialize the node stack.  It is called
+     automatically by the parser's ReInit() method. */
+  void reset() {
+    nodes.removeAllElements();
+    marks.removeAllElements();
+    sp = 0;
+    mk = 0;
+  }
+
+  /* Returns the root node of the AST.  It only makes sense to call
+     this after a successful parse. */
+  Node rootNode() {
+    return (Node)nodes.elementAt(0);
+  }
+
+  /* Pushes a node on to the stack. */
+  void pushNode(Node n) {
+    nodes.push(n);
+    ++sp;
+  }
+
+  /* Returns the node on the top of the stack, and remove it from the
+     stack.  */
+  Node popNode() {
+    if (--sp < mk) {
+      mk = ((Integer)marks.pop()).intValue();
+    }
+    return (Node)nodes.pop();
+  }
+
+  /* Returns the node currently on the top of the stack. */
+  Node peekNode() {
+    return (Node)nodes.peek();
+  }
+
+  /* Returns the number of children on the stack in the current node
+     scope. */
+  int nodeArity() {
+    return sp - mk;
+  }
+
+
+  void clearNodeScope(Node n) {
+    while (sp > mk) {
+      popNode();
+    }
+    mk = ((Integer)marks.pop()).intValue();
+  }
+
+
+  void openNodeScope(Node n) {
+    marks.push(new Integer(mk));
+    mk = sp;
+    n.jjtOpen();
+  }
+
+
+  /* A definite node is constructed from a specified number of
+     children.  That number of nodes are popped from the stack and
+     made the children of the definite node.  Then the definite node
+     is pushed on to the stack. */
+  void closeNodeScope(Node n, int num) {
+    mk = ((Integer)marks.pop()).intValue();
+    while (num-- > 0) {
+      Node c = popNode();
+      c.jjtSetParent(n);
+      n.jjtAddChild(c, num);
+    }
+    n.jjtClose();
+    pushNode(n);
+    node_created = true;
+  }
+
+
+  /* A conditional node is constructed if its condition is true.  All
+     the nodes that have been pushed since the node was opened are
+     made children of the the conditional node, which is then pushed
+     on to the stack.  If the condition is false the node is not
+     constructed and they are left on the stack. */
+  void closeNodeScope(Node n, boolean condition) {
+    if (condition) {
+      int a = nodeArity();
+      mk = ((Integer)marks.pop()).intValue();
+      while (a-- > 0) {
+	Node c = popNode();
+	c.jjtSetParent(n);
+	n.jjtAddChild(c, a);
+      }
+      n.jjtClose();
+      pushNode(n);
+      node_created = true;
+    } else {
+      mk = ((Integer)marks.pop()).intValue();
+      node_created = false;
+    }
+  }
+}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/OrderExpressionNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/OrderExpressionNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/OrderExpressionNode.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/OrderExpressionNode.java	2008-04-27 11:17:35.000000000 -0400
@@ -5,6 +5,8 @@
  */
 package name.levering.ryan.sparql.parser.model;
 
+import java.util.Set;
+
 import name.levering.ryan.sparql.common.RdfBindingSet;
 import name.levering.ryan.sparql.model.OrderExpression;
 import name.levering.ryan.sparql.model.logic.ExpressionLogic;
@@ -27,10 +29,14 @@
     }
 
     public ExpressionLogic getExpression() {
-        return (ExpressionLogic) this.jjtGetChild(0);
+        return ((ExpressionNode) this.jjtGetChild(0)).getExpressionLogic();
     }
 
     public void applyLogic(LogicBinder binder) {
-        this.logic = binder.getLogicFactory().getOrderExpressionLogic(this);
+        this.logic = binder.getLogicFactory().getOrderExpressionLogic(this, binder.getValueFactory());
     }
+
+	public Set getVariables() {
+		return this.getExpression().getVariables();
+	}
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/QueryNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/QueryNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/QueryNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/QueryNode.java	2007-10-21 12:35:16.000000000 -0400
@@ -25,6 +25,8 @@
 
 	private static final LogicFactory DEFAULT_LOGIC = new StreamedLogic();
 	
+	boolean didBindValues = false, didBindLogic = false;
+	
 	public QueryNode(int i) {
 		super(i);
 	}
@@ -86,13 +88,21 @@
 	}
 
 	public void bindValues(SPARQLValueFactory valueFactory) {
+		if (didBindValues) return;
+		
 		SPARQLParserVisitor resolver = new ValueBinder(valueFactory, getPrefixExpansions(), getBase());
 		this.jjtAccept(resolver);
+		
+		didBindValues = true;
 	}
 
 	public void bindLogic(LogicFactory currentLogic, SPARQLValueFactory valueFactory) {
+		if (didBindLogic) return;
+		
 		LogicBinder logicBinder = new LogicBinder(currentLogic, valueFactory);
 		this.jjtAccept(logicBinder);
+		
+		didBindLogic = true;
 	}
 
 	public String toString() {
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLBNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLBNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLBNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLBNode.java	2008-02-07 16:48:39.000000000 -0500
@@ -92,4 +92,10 @@
 		return this.baseNode.getNative();
 	}
 
+
+	 public java.util.Set getVariables() {
+		 java.util.HashSet ret = new java.util.HashSet();
+		 ret.add(this);
+		 return ret;
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLLiteral.java work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLLiteral.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLLiteral.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLLiteral.java	2008-02-07 16:48:15.000000000 -0500
@@ -101,4 +101,8 @@
 		return this.baseLiteral.getNative();
 	}
 
+
+	 public java.util.Set getVariables() {
+		 return new java.util.HashSet();
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLParserTreeConstants.java work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLParserTreeConstants.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLParserTreeConstants.java	2007-10-07 07:19:57.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLParserTreeConstants.java	2008-10-08 19:03:13.000000000 -0400
@@ -1,141 +1,139 @@
-/* Generated By:JJTree: Do not edit this line. C:/workspaces/sparql/SPARQL Engine Trunk/src/main/name/levering/ryan/sparql/parser/model\SPARQLParserTreeConstants.java */
-
-package name.levering.ryan.sparql.parser.model;
-
-public interface SPARQLParserTreeConstants
-{
-  public int JJTQUERYCONTAINER = 0;
-  public int JJTVOID = 1;
-  public int JJTBASE = 2;
-  public int JJTPREFIX = 3;
-  public int JJTSELECTQUERY = 4;
-  public int JJTCONSTRUCTQUERY = 5;
-  public int JJTDESCRIBEQUERY = 6;
-  public int JJTASKQUERY = 7;
-  public int JJTDEFAULTGRAPH = 8;
-  public int JJTNAMEDGRAPH = 9;
-  public int JJTORDERCONDITIONS = 10;
-  public int JJTASCORDER = 11;
-  public int JJTDESCORDER = 12;
-  public int JJTDEFAULTORDER = 13;
-  public int JJTLIMIT = 14;
-  public int JJTOFFSET = 15;
-  public int JJTGROUPCONSTRAINT = 16;
-  public int JJTOPTIONALCONSTRAINT = 17;
-  public int JJTGRAPHCONSTRAINT = 18;
-  public int JJTGRAPH = 19;
-  public int JJTUNIONCONSTRAINT = 20;
-  public int JJTFILTERCONSTRAINT = 21;
-  public int JJTFUNCTIONCALL = 22;
-  public int JJTARGUMENTS = 23;
-  public int JJTCONSTRUCTTEMPLATE = 24;
-  public int JJTPROPERTYLIST = 25;
-  public int JJTTRIPLESET = 26;
-  public int JJTNODESET = 27;
-  public int JJTOBJECTLIST = 28;
-  public int JJTVERBOBJECT = 29;
-  public int JJTTYPEVERB = 30;
-  public int JJTBLANKNODEPROPERTYLIST = 31;
-  public int JJTCOLLECTION = 32;
-  public int JJTWITHEXTENSION = 33;
-  public int JJTVAR = 34;
-  public int JJTEMPTYNODE = 35;
-  public int JJTORNODE = 36;
-  public int JJTANDNODE = 37;
-  public int JJTEQUALSNODE = 38;
-  public int JJTNOTEQUALSNODE = 39;
-  public int JJTLESSTHANNODE = 40;
-  public int JJTLESSTHANEQUALSNODE = 41;
-  public int JJTGREATERTHANNODE = 42;
-  public int JJTGREATERTHANEQUALSNODE = 43;
-  public int JJTADDITIONNODE = 44;
-  public int JJTSUBTRACTIONNODE = 45;
-  public int JJTMULTIPLICATIONNODE = 46;
-  public int JJTDIVISIONNODE = 47;
-  public int JJTNOTNODE = 48;
-  public int JJTPLUSNODE = 49;
-  public int JJTMINUSNODE = 50;
-  public int JJTSTRFUNCNODE = 51;
-  public int JJTLANGFUNCNODE = 52;
-  public int JJTLANGMATCHESFUNCNODE = 53;
-  public int JJTDTFUNCNODE = 54;
-  public int JJTBOUNDFUNCNODE = 55;
-  public int JJTURIFUNCNODE = 56;
-  public int JJTBLANKFUNCNODE = 57;
-  public int JJTLITERALFUNCNODE = 58;
-  public int JJTREGEXFUNCNODE = 59;
-  public int JJTLITERAL = 60;
-  public int JJTQNAME = 61;
-  public int JJTLABELEDBLANKNODE = 62;
-  public int JJTGENERICBLANKNODE = 63;
-  public int JJTQUOTEDIRIREF = 64;
-
-
-  public String[] jjtNodeName = {
-    "QueryContainer",
-    "void",
-    "Base",
-    "Prefix",
-    "SelectQuery",
-    "ConstructQuery",
-    "DescribeQuery",
-    "AskQuery",
-    "DefaultGraph",
-    "NamedGraph",
-    "OrderConditions",
-    "AscOrder",
-    "DescOrder",
-    "DefaultOrder",
-    "Limit",
-    "Offset",
-    "GroupConstraint",
-    "OptionalConstraint",
-    "GraphConstraint",
-    "Graph",
-    "UnionConstraint",
-    "FilterConstraint",
-    "FunctionCall",
-    "Arguments",
-    "ConstructTemplate",
-    "PropertyList",
-    "TripleSet",
-    "NodeSet",
-    "ObjectList",
-    "VerbObject",
-    "TypeVerb",
-    "BlankNodePropertyList",
-    "Collection",
-    "WithExtension",
-    "Var",
-    "EmptyNode",
-    "OrNode",
-    "AndNode",
-    "EqualsNode",
-    "NotEqualsNode",
-    "LessThanNode",
-    "LessThanEqualsNode",
-    "GreaterThanNode",
-    "GreaterThanEqualsNode",
-    "AdditionNode",
-    "SubtractionNode",
-    "MultiplicationNode",
-    "DivisionNode",
-    "NotNode",
-    "PlusNode",
-    "MinusNode",
-    "StrFuncNode",
-    "LangFuncNode",
-    "LangMatchesFuncNode",
-    "DTFuncNode",
-    "BoundFuncNode",
-    "URIFuncNode",
-    "BlankFuncNode",
-    "LiteralFuncNode",
-    "RegexFuncNode",
-    "Literal",
-    "QName",
-    "LabeledBlankNode",
-    "GenericBlankNode",
-    "QuotedIRIref",
-  };
-}
+/* Generated By:JJTree: Do not edit this line. /home/tauberer/dev/semweb/sparql/work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLParserTreeConstants.java */
+
+package name.levering.ryan.sparql.parser.model;
+
+public interface SPARQLParserTreeConstants
+{
+  public int JJTQUERYCONTAINER = 0;
+  public int JJTVOID = 1;
+  public int JJTBASE = 2;
+  public int JJTPREFIX = 3;
+  public int JJTSELECTQUERY = 4;
+  public int JJTCONSTRUCTQUERY = 5;
+  public int JJTDESCRIBEQUERY = 6;
+  public int JJTASKQUERY = 7;
+  public int JJTDEFAULTGRAPH = 8;
+  public int JJTNAMEDGRAPH = 9;
+  public int JJTORDERCONDITIONS = 10;
+  public int JJTASCORDER = 11;
+  public int JJTDESCORDER = 12;
+  public int JJTDEFAULTORDER = 13;
+  public int JJTLIMIT = 14;
+  public int JJTOFFSET = 15;
+  public int JJTGROUPCONSTRAINT = 16;
+  public int JJTOPTIONALCONSTRAINT = 17;
+  public int JJTGRAPHCONSTRAINT = 18;
+  public int JJTGRAPH = 19;
+  public int JJTUNIONCONSTRAINT = 20;
+  public int JJTFILTERCONSTRAINT = 21;
+  public int JJTFUNCTIONCALL = 22;
+  public int JJTARGUMENTS = 23;
+  public int JJTCONSTRUCTTEMPLATE = 24;
+  public int JJTPROPERTYLIST = 25;
+  public int JJTTRIPLESET = 26;
+  public int JJTNODESET = 27;
+  public int JJTOBJECTLIST = 28;
+  public int JJTVERBOBJECT = 29;
+  public int JJTTYPEVERB = 30;
+  public int JJTBLANKNODEPROPERTYLIST = 31;
+  public int JJTCOLLECTION = 32;
+  public int JJTVAR = 33;
+  public int JJTEMPTYNODE = 34;
+  public int JJTORNODE = 35;
+  public int JJTANDNODE = 36;
+  public int JJTEQUALSNODE = 37;
+  public int JJTNOTEQUALSNODE = 38;
+  public int JJTLESSTHANNODE = 39;
+  public int JJTLESSTHANEQUALSNODE = 40;
+  public int JJTGREATERTHANNODE = 41;
+  public int JJTGREATERTHANEQUALSNODE = 42;
+  public int JJTADDITIONNODE = 43;
+  public int JJTSUBTRACTIONNODE = 44;
+  public int JJTMULTIPLICATIONNODE = 45;
+  public int JJTDIVISIONNODE = 46;
+  public int JJTNOTNODE = 47;
+  public int JJTPLUSNODE = 48;
+  public int JJTMINUSNODE = 49;
+  public int JJTSTRFUNCNODE = 50;
+  public int JJTLANGFUNCNODE = 51;
+  public int JJTLANGMATCHESFUNCNODE = 52;
+  public int JJTDTFUNCNODE = 53;
+  public int JJTBOUNDFUNCNODE = 54;
+  public int JJTURIFUNCNODE = 55;
+  public int JJTBLANKFUNCNODE = 56;
+  public int JJTLITERALFUNCNODE = 57;
+  public int JJTREGEXFUNCNODE = 58;
+  public int JJTLITERAL = 59;
+  public int JJTQNAME = 60;
+  public int JJTLABELEDBLANKNODE = 61;
+  public int JJTGENERICBLANKNODE = 62;
+  public int JJTQUOTEDIRIREF = 63;
+
+
+  public String[] jjtNodeName = {
+    "QueryContainer",
+    "void",
+    "Base",
+    "Prefix",
+    "SelectQuery",
+    "ConstructQuery",
+    "DescribeQuery",
+    "AskQuery",
+    "DefaultGraph",
+    "NamedGraph",
+    "OrderConditions",
+    "AscOrder",
+    "DescOrder",
+    "DefaultOrder",
+    "Limit",
+    "Offset",
+    "GroupConstraint",
+    "OptionalConstraint",
+    "GraphConstraint",
+    "Graph",
+    "UnionConstraint",
+    "FilterConstraint",
+    "FunctionCall",
+    "Arguments",
+    "ConstructTemplate",
+    "PropertyList",
+    "TripleSet",
+    "NodeSet",
+    "ObjectList",
+    "VerbObject",
+    "TypeVerb",
+    "BlankNodePropertyList",
+    "Collection",
+    "Var",
+    "EmptyNode",
+    "OrNode",
+    "AndNode",
+    "EqualsNode",
+    "NotEqualsNode",
+    "LessThanNode",
+    "LessThanEqualsNode",
+    "GreaterThanNode",
+    "GreaterThanEqualsNode",
+    "AdditionNode",
+    "SubtractionNode",
+    "MultiplicationNode",
+    "DivisionNode",
+    "NotNode",
+    "PlusNode",
+    "MinusNode",
+    "StrFuncNode",
+    "LangFuncNode",
+    "LangMatchesFuncNode",
+    "DTFuncNode",
+    "BoundFuncNode",
+    "URIFuncNode",
+    "BlankFuncNode",
+    "LiteralFuncNode",
+    "RegexFuncNode",
+    "Literal",
+    "QName",
+    "LabeledBlankNode",
+    "GenericBlankNode",
+    "QuotedIRIref",
+  };
+}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLURI.java work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLURI.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLURI.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/SPARQLURI.java	2008-02-07 16:47:59.000000000 -0500
@@ -30,21 +30,12 @@
     }
 
     /**
-     * Delegates this method to return the internal URI's namespace.
+     * Delegates this method to return the internal URI's URI.
      * 
-     * @return the string namespace of the base URI
+     * @return the string URI of the base URI
      */
-    public String getNamespace() {
-        return this.baseURI.getNamespace();
-    }
-
-    /**
-     * Delegates this method to return the internal URI's local name.
-     * 
-     * @return the string local name of the base URI
-     */
-    public String getLocalName() {
-        return this.baseURI.getLocalName();
+    public String getURI() {
+        return this.baseURI.getURI();
     }
 
     /**
@@ -91,4 +82,7 @@
 		return this.baseURI.getNative();
 	}
 
+	 public java.util.Set getVariables() {
+		 return new java.util.HashSet();
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/UnaryExpressionNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/UnaryExpressionNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/UnaryExpressionNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/UnaryExpressionNode.java	2008-02-09 15:10:54.000000000 -0500
@@ -16,7 +16,7 @@
  * @version 1.0
  */
 public abstract class UnaryExpressionNode extends SimpleNode implements
-        UnaryExpressionData, ExpressionLogic {
+        ExpressionNode, UnaryExpressionData {
     
     private ExpressionLogic logic;
     
@@ -25,11 +25,11 @@
     }
 
     public ExpressionLogic getExpression() {
-        return (ExpressionLogic) this.jjtGetChild(0);
+        return ((ExpressionNode) this.jjtGetChild(0)).getExpressionLogic();
     }
 
-    public Value evaluate(RdfBindingRow bindings) {
-        return this.logic.evaluate(bindings);
+    public ExpressionLogic getExpressionLogic() {
+        return logic;
     }
     
     public abstract ExpressionLogic getLogic(LogicBinder binder);
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/URINode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/URINode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/URINode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/URINode.java	2008-02-07 16:49:08.000000000 -0500
@@ -21,15 +21,13 @@
 		super(i);
 	}
 
-	public String getNamespace() {
-		return ((URI) this.boundValue).getNamespace();
+	public String getURI() {
+		if (this.boundValue == null)
+			throw new IllegalStateException("boundValue accessed before being initialized");
+		return ((URI) this.boundValue).getURI();
 	}
 
-	public String getLocalName() {
-		return ((URI) this.boundValue).getLocalName();
-	}
-
-	public ValueExpression getBoundValue(ValueBinder binder) {
+	protected ValueExpression getBoundValue(ValueBinder binder) {
 		try {
 			return new SPARQLURI(binder.getFactory().createURI(this.getURI(binder)));
 		} catch (RuntimeException e) {
@@ -37,6 +35,9 @@
 		}
 	}
 
-	public abstract String getURI(ValueBinder binder);
+	protected abstract String getURI(ValueBinder binder);
 
+	 public java.util.Set getVariables() {
+		 return new java.util.HashSet();
+	 }
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/model/ValueNode.java work-copy/src/main/name/levering/ryan/sparql/parser/model/ValueNode.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/model/ValueNode.java	2007-10-07 07:19:18.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/model/ValueNode.java	2008-02-09 10:15:57.000000000 -0500
@@ -5,15 +5,18 @@
  */
 package name.levering.ryan.sparql.parser.model;
 
+import java.util.Set;
+
 import name.levering.ryan.sparql.common.RdfBindingRow;
 import name.levering.ryan.sparql.common.Value;
 import name.levering.ryan.sparql.common.impl.ValueExpression;
+import name.levering.ryan.sparql.model.logic.ExpressionLogic;
 
 /**
  * @author Ryan Levering
  * @version 1.0
  */
-public abstract class ValueNode extends SimpleNode implements ValueExpression {
+public abstract class ValueNode extends SimpleNode implements ExpressionNode, ValueExpression {
     
     protected ValueExpression boundValue;
     
@@ -21,6 +24,10 @@
         super(i);
     }
 
+    public ExpressionLogic getExpressionLogic() {
+        return this;
+    }
+
     public Value evaluate(RdfBindingRow bindings) {
         return this.boundValue.evaluate(bindings);
     }
@@ -41,7 +48,9 @@
     }
     
     public void applyBinding(ValueBinder binder) {
-        this.boundValue = getBoundValue(binder);
+ 		if (this.boundValue != null)
+			throw new IllegalStateException("boundValue already initialized");
+       this.boundValue = getBoundValue(binder);
     }
     
     public Object getNative() {
@@ -51,4 +60,6 @@
     protected abstract ValueExpression getBoundValue(ValueBinder binder);
     
     protected abstract String toQueryString();
+    
+    public abstract Set getVariables();
 }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/ParseException.java work-copy/src/main/name/levering/ryan/sparql/parser/ParseException.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/ParseException.java	2006-08-20 20:01:00.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/ParseException.java	2008-08-13 14:41:24.000000000 -0400
@@ -29,7 +29,7 @@
                         String[] tokenImageVal
                        )
   {
-    super("");
+    super("");
     specialConstructor = true;
     currentToken = currentTokenVal;
     expectedTokenSequences = expectedTokenSequencesVal;
@@ -100,7 +100,7 @@
     }
     String expected = "";
     int maxSize = 0;
-    for (int i = 0; i < expectedTokenSequences.length; i++) {
+    for (int i = 0; i < expectedTokenSequences.length; i++) {
       if (maxSize < expectedTokenSequences[i].length) {
         maxSize = expectedTokenSequences[i].length;
       }
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParserConstants.java work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParserConstants.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParserConstants.java	2007-10-07 07:19:57.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParserConstants.java	2008-10-08 19:03:14.000000000 -0400
@@ -1,139 +1,136 @@
-/* Generated By:JJTree&JavaCC: Do not edit this line. SPARQLParserConstants.java */
-package name.levering.ryan.sparql.parser;
-
-public interface SPARQLParserConstants {
-
-  int EOF = 0;
-  int SINGLE_LINE_COMMENT = 7;
-  int FUNCTION_PAREN = 9;
-  int Q_IRI_REF = 11;
-  int QNAME_NS = 12;
-  int QNAME = 13;
-  int BNODE_LABEL = 14;
-  int VAR1 = 15;
-  int VAR2 = 16;
-  int LANGTAG = 17;
-  int INTEGER = 18;
-  int DECIMAL = 19;
-  int DOUBLE = 20;
-  int STRING_LITERAL1 = 21;
-  int STRING_LITERAL2 = 22;
-  int STRING_LITERAL_LONG1 = 23;
-  int STRING_LITERAL_LONG2 = 24;
-  int NIL = 25;
-  int ANON = 26;
-  int WS = 27;
-  int VARNAME = 28;
-  int NCCHAR = 29;
-  int NCNAME_PREFIX = 30;
-  int NCNAME = 31;
-  int EXPONENT = 32;
-  int ECHAR = 33;
-  int UCHAR = 34;
-  int HEX = 35;
-  int NCCHAR1 = 36;
-  int NCCHAR1P = 37;
-
-  int DEFAULT = 0;
-  int IN_SINGLE_LINE_COMMENT = 1;
-  int POSSIBLE_FUNCTION = 2;
-
-  String[] tokenImage = {
-    "<EOF>",
-    "\" \"",
-    "\"\\t\"",
-    "\"\\n\"",
-    "\"\\r\"",
-    "\"\\f\"",
-    "\"#\"",
-    "<SINGLE_LINE_COMMENT>",
-    "<token of kind 8>",
-    "\"(\"",
-    "<token of kind 10>",
-    "<Q_IRI_REF>",
-    "<QNAME_NS>",
-    "<QNAME>",
-    "<BNODE_LABEL>",
-    "<VAR1>",
-    "<VAR2>",
-    "<LANGTAG>",
-    "<INTEGER>",
-    "<DECIMAL>",
-    "<DOUBLE>",
-    "<STRING_LITERAL1>",
-    "<STRING_LITERAL2>",
-    "<STRING_LITERAL_LONG1>",
-    "<STRING_LITERAL_LONG2>",
-    "<NIL>",
-    "<ANON>",
-    "<WS>",
-    "<VARNAME>",
-    "<NCCHAR>",
-    "<NCNAME_PREFIX>",
-    "<NCNAME>",
-    "<EXPONENT>",
-    "<ECHAR>",
-    "<UCHAR>",
-    "<HEX>",
-    "<NCCHAR1>",
-    "<NCCHAR1P>",
-    "\"BASE\"",
-    "\"PREFIX\"",
-    "\"SELECT\"",
-    "\"DISTINCT\"",
-    "\"*\"",
-    "\"CONSTRUCT\"",
-    "\"DESCRIBE\"",
-    "\"ASK\"",
-    "\"FROM\"",
-    "\"NAMED\"",
-    "\"WHERE\"",
-    "\"ORDER\"",
-    "\"BY\"",
-    "\"ASC\"",
-    "\"DESC\"",
-    "\"LIMIT\"",
-    "\"OFFSET\"",
-    "\"{\"",
-    "\"}\"",
-    "\".\"",
-    "\"OPTIONAL\"",
-    "\"GRAPH\"",
-    "\"UNION\"",
-    "\"FILTER\"",
-    "\",\"",
-    "\")\"",
-    "\";\"",
-    "\"a\"",
-    "\"[\"",
-    "\"]\"",
-    "\"(\"",
-    "\"WITH\"",
-    "\"+\"",
-    "\"-\"",
-    "\"||\"",
-    "\"&&\"",
-    "\"=\"",
-    "\"!=\"",
-    "\"<\"",
-    "\"<=\"",
-    "\">\"",
-    "\">=\"",
-    "\"/\"",
-    "\"!\"",
-    "\"STR\"",
-    "\"LANG\"",
-    "\"LANGMATCHES\"",
-    "\"DATATYPE\"",
-    "\"BOUND\"",
-    "\"isIRI\"",
-    "\"isURI\"",
-    "\"isBLANK\"",
-    "\"isLITERAL\"",
-    "\"REGEX\"",
-    "\"^^\"",
-    "\"true\"",
-    "\"false\"",
-  };
-
-}
+/* Generated By:JJTree&JavaCC: Do not edit this line. SPARQLParserConstants.java */
+package name.levering.ryan.sparql.parser;
+
+public interface SPARQLParserConstants {
+
+  int EOF = 0;
+  int SINGLE_LINE_COMMENT = 7;
+  int IRI_REF = 9;
+  int PNAME_NS = 10;
+  int QNAME = 11;
+  int BNODE_LABEL = 12;
+  int VAR1 = 13;
+  int VAR2 = 14;
+  int LANGTAG = 15;
+  int INTEGER = 16;
+  int DECIMAL = 17;
+  int DOUBLE = 18;
+  int STRING_LITERAL1 = 19;
+  int STRING_LITERAL2 = 20;
+  int STRING_LITERAL_LONG1 = 21;
+  int STRING_LITERAL_LONG2 = 22;
+  int NIL = 23;
+  int ANON = 24;
+  int WS = 25;
+  int VARNAME = 26;
+  int PN_CHARS = 27;
+  int PN_PREFIX = 28;
+  int PN_LOCAL = 29;
+  int EXPONENT = 30;
+  int ECHAR = 31;
+  int UCHAR = 32;
+  int HEX = 33;
+  int PN_CHARS_U = 34;
+  int PN_CHARS_BASE = 35;
+
+  int DEFAULT = 0;
+  int IN_SINGLE_LINE_COMMENT = 1;
+
+  String[] tokenImage = {
+    "<EOF>",
+    "\" \"",
+    "\"\\t\"",
+    "\"\\n\"",
+    "\"\\r\"",
+    "\"\\f\"",
+    "\"#\"",
+    "<SINGLE_LINE_COMMENT>",
+    "<token of kind 8>",
+    "<IRI_REF>",
+    "<PNAME_NS>",
+    "<QNAME>",
+    "<BNODE_LABEL>",
+    "<VAR1>",
+    "<VAR2>",
+    "<LANGTAG>",
+    "<INTEGER>",
+    "<DECIMAL>",
+    "<DOUBLE>",
+    "<STRING_LITERAL1>",
+    "<STRING_LITERAL2>",
+    "<STRING_LITERAL_LONG1>",
+    "<STRING_LITERAL_LONG2>",
+    "<NIL>",
+    "<ANON>",
+    "<WS>",
+    "<VARNAME>",
+    "<PN_CHARS>",
+    "<PN_PREFIX>",
+    "<PN_LOCAL>",
+    "<EXPONENT>",
+    "<ECHAR>",
+    "<UCHAR>",
+    "<HEX>",
+    "<PN_CHARS_U>",
+    "<PN_CHARS_BASE>",
+    "\"BASE\"",
+    "\"PREFIX\"",
+    "\"SELECT\"",
+    "\"DISTINCT\"",
+    "\"REDUCED\"",
+    "\"*\"",
+    "\"CONSTRUCT\"",
+    "\"DESCRIBE\"",
+    "\"ASK\"",
+    "\"FROM\"",
+    "\"NAMED\"",
+    "\"WHERE\"",
+    "\"ORDER\"",
+    "\"BY\"",
+    "\"ASC\"",
+    "\"DESC\"",
+    "\"LIMIT\"",
+    "\"OFFSET\"",
+    "\"{\"",
+    "\"}\"",
+    "\".\"",
+    "\"OPTIONAL\"",
+    "\"GRAPH\"",
+    "\"UNION\"",
+    "\"FILTER\"",
+    "\"(\"",
+    "\",\"",
+    "\")\"",
+    "\";\"",
+    "\"a\"",
+    "\"[\"",
+    "\"]\"",
+    "\"+\"",
+    "\"-\"",
+    "\"||\"",
+    "\"&&\"",
+    "\"=\"",
+    "\"!=\"",
+    "\"<\"",
+    "\"<=\"",
+    "\">\"",
+    "\">=\"",
+    "\"/\"",
+    "\"!\"",
+    "\"STR\"",
+    "\"LANG\"",
+    "\"LANGMATCHES\"",
+    "\"DATATYPE\"",
+    "\"BOUND\"",
+    "\"sameTerm\"",
+    "\"isIRI\"",
+    "\"isURI\"",
+    "\"isBLANK\"",
+    "\"isLITERAL\"",
+    "\"REGEX\"",
+    "\"^^\"",
+    "\"true\"",
+    "\"false\"",
+  };
+
+}
diff -urN --exclude=.svn --exclude=.settings --exclude=META-INF --exclude='*.jj' --exclude='*.rej' work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParser.java work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParser.java
--- work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParser.java	2007-10-07 07:19:39.000000000 -0400
+++ work-copy/src/main/name/levering/ryan/sparql/parser/SPARQLParser.java	2008-10-08 19:03:14.000000000 -0400
@@ -1,4422 +1,3217 @@
-/* Generated By:JJTree&JavaCC: Do not edit this line. SPARQLParser.java */
-package name.levering.ryan.sparql.parser;
-
-import name.levering.ryan.sparql.parser.model.*;
-import name.levering.ryan.sparql.model.Query;
-
-public class SPARQLParser/*@bgen(jjtree)*/implements SPARQLParserTreeConstants, SPARQLParserConstants {/*@bgen(jjtree)*/
-  protected JJTSPARQLParserState jjtree = new JJTSPARQLParserState();
-        public static Query parse(java.io.Reader reader) throws ParseException {
-                SPARQLParser parser = new SPARQLParser(reader);
-        return (QueryNode) parser.Query();
-        }
-
-        public static Query parse(java.io.InputStream stream) throws ParseException {
-                SPARQLParser parser = new SPARQLParser(stream);
-        return (QueryNode) parser.Query();
-        }
-
-        public static String unescape(String escapedString) {
-                StringBuffer unescapedString = new StringBuffer(escapedString.length());
-                StringBuffer unicodeCache = new StringBuffer(8);
-                boolean escaped = false, isUnicode = false;
-                for (int i = 0; i < escapedString.length(); i++) {
-                        char current = escapedString.charAt(i);
-                        if (isUnicode) {
+/* Generated By:JJTree&JavaCC: Do not edit this line. SPARQLParser.java */
+package name.levering.ryan.sparql.parser;
+
+import name.levering.ryan.sparql.parser.model.*;
+import name.levering.ryan.sparql.model.Query;
+
+public class SPARQLParser/*@bgen(jjtree)*/implements SPARQLParserTreeConstants, SPARQLParserConstants {/*@bgen(jjtree)*/
+  protected JJTSPARQLParserState jjtree = new JJTSPARQLParserState();
+        public static Query parse(java.io.Reader reader) throws ParseException {
+                SPARQLParser parser = new SPARQLParser(reader);
+        return (QueryNode) parser.Query();
+        }
+
+        public static Query parse(java.io.InputStream stream) throws ParseException {
+                SPARQLParser parser = new SPARQLParser(stream);
+        return (QueryNode) parser.Query();
+        }
+
+        public static String unescape(String escapedString) {
+                StringBuffer unescapedString = new StringBuffer(escapedString.length());
+                StringBuffer unicodeCache = new StringBuffer(8);
+                boolean escaped = false, isUnicode = false;
+                for (int i = 0; i < escapedString.length(); i++) {
+                        char current = escapedString.charAt(i);
+                        if (isUnicode) {
                                 // If we just hit a backslash-u
-                                if (Character.isLetterOrDigit(current)) {
-                                        unicodeCache.append(current);
-                                } else {
-                                        unescapedString.append((char) Integer.parseInt(unicodeCache.toString(), 16));
-                                        unicodeCache.setLength(0);
-                                        unicodeCache.setLength(8);
-                                        isUnicode = false;
-                                }
-                        } else if (escaped) {
+                                if (Character.isLetterOrDigit(current)) {
+                                        unicodeCache.append(current);
+                                } else {
+                                        unescapedString.append((char) Integer.parseInt(unicodeCache.toString(), 16));
+                                        unicodeCache.setLength(0);
+                                        unicodeCache.setLength(8);
+                                        isUnicode = false;
+                                }
+                        } else if (escaped) {
                                 // If we just hit a backslash
-                                switch (current) {
-                                        case '\\':
-                                                unescapedString.append('\\');
-                                                break;
-                                        case 't':
-                                                unescapedString.append('\t');
-                                                break;
-                                        case 'b':
-                                                unescapedString.append('\b');
-                                                break;
-                                        case 'n':
-                                                unescapedString.append('\n');
-                                                break;
-                                        case 'r':
-                                                unescapedString.append('\r');
-                                                break;
-                                        case 'f':
-                                                unescapedString.append('\f');
-                                                break;
-                                        case '"':
-                                                unescapedString.append('"');
-                                                break;
-                                        case '\'':
-                                                unescapedString.append('\'');
-                                                break;
-                                        case 'u':
-                                                isUnicode = true;
-                                }
-                                escaped = false;
-                        } else {
+                                switch (current) {
+                                        case '\\':
+                                                unescapedString.append('\\');
+                                                break;
+                                        case 't':
+                                                unescapedString.append('\t');
+                                                break;
+                                        case 'b':
+                                                unescapedString.append('\b');
+                                                break;
+                                        case 'n':
+                                                unescapedString.append('\n');
+                                                break;
+                                        case 'r':
+                                                unescapedString.append('\r');
+                                                break;
+                                        case 'f':
+                                                unescapedString.append('\f');
+                                                break;
+                                        case '"':
+                                                unescapedString.append('"');
+                                                break;
+                                        case '\'':
+                                                unescapedString.append('\'');
+                                                break;
+                                        case 'u':
+                                                isUnicode = true;
+                                }
+                                escaped = false;
+                        } else {
                                 // Normal behavior
-                                switch (current) {
-                                        case '\\':
-                                                escaped = true;
-                                                break;
-                                        default:
-                                                unescapedString.append(current);
-                                }
-                        }
-                }
-                return unescapedString.toString();
-        }
-
-  final public Node Query() throws ParseException {
- /*@bgen(jjtree) QueryContainer */
-  ASTQueryContainer jjtn000 = new ASTQueryContainer(JJTQUERYCONTAINER);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      Prolog();
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 40:
-        SelectQuery();
-        break;
-      case 43:
-        ConstructQuery();
-        break;
-      case 44:
-        DescribeQuery();
-        break;
-      case 45:
-        AskQuery();
-        break;
-      default:
-        jj_la1[0] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-      jj_consume_token(0);
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          {if (true) return jjtn000.jjtGetChild(jjtn000.jjtGetNumChildren() - 1);}
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-    throw new Error("Missing return statement in function");
-  }
-
-  final public void Prolog() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 38:
-      BaseDecl();
-      break;
-    default:
-      jj_la1[1] = jj_gen;
-      ;
-    }
-    label_1:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 39:
-        ;
-        break;
-      default:
-        jj_la1[2] = jj_gen;
-        break label_1;
-      }
-      PrefixDecl();
-    }
-  }
-
-  final public void BaseDecl() throws ParseException {
-                         /*@bgen(jjtree) Base */
-  ASTBase jjtn000 = new ASTBase(JJTBASE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(38);
-      QuotedIRIref();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void PrefixDecl() throws ParseException {
- /*@bgen(jjtree) Prefix */
-        ASTPrefix jjtn000 = new ASTPrefix(JJTPREFIX);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);Token qName;
-    try {
-      jj_consume_token(39);
-      qName = jj_consume_token(QNAME_NS);
-      QuotedIRIref();
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-         jjtn000.setPrefix(qName.image.substring(0, qName.image.indexOf(':')));
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void SelectQuery() throws ParseException {
- /*@bgen(jjtree) SelectQuery */
-  ASTSelectQuery jjtn000 = new ASTSelectQuery(JJTSELECTQUERY);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(40);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 41:
-        jj_consume_token(41);
-                               jjtn000.setDistinct(true);
-        break;
-      default:
-        jj_la1[3] = jj_gen;
-        ;
-      }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case Q_IRI_REF:
-      case QNAME_NS:
-      case QNAME:
-      case VAR1:
-      case VAR2:
-      case 68:
-      case 82:
-      case 83:
-      case 84:
-      case 85:
-      case 86:
-      case 87:
-      case 88:
-      case 89:
-      case 90:
-      case 91:
-        label_2:
-        while (true) {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case VAR1:
-          case VAR2:
-            Var();
-            break;
-          case Q_IRI_REF:
-          case QNAME_NS:
-          case QNAME:
-          case 68:
-          case 82:
-          case 83:
-          case 84:
-          case 85:
-          case 86:
-          case 87:
-          case 88:
-          case 89:
-          case 90:
-          case 91:
-            switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-            case 68:
-              BracketedExpression();
-              break;
-            case 82:
-            case 83:
-            case 84:
-            case 85:
-            case 86:
-            case 87:
-            case 88:
-            case 89:
-            case 90:
-            case 91:
-              BuiltInCall();
-              break;
-            case Q_IRI_REF:
-            case QNAME_NS:
-            case QNAME:
-              FunctionCall();
-              break;
-            default:
-              jj_la1[4] = jj_gen;
-              jj_consume_token(-1);
-              throw new ParseException();
-            }
-            break;
-          default:
-            jj_la1[5] = jj_gen;
-            jj_consume_token(-1);
-            throw new ParseException();
-          }
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case Q_IRI_REF:
-          case QNAME_NS:
-          case QNAME:
-          case VAR1:
-          case VAR2:
-          case 68:
-          case 82:
-          case 83:
-          case 84:
-          case 85:
-          case 86:
-          case 87:
-          case 88:
-          case 89:
-          case 90:
-          case 91:
-            ;
-            break;
-          default:
-            jj_la1[6] = jj_gen;
-            break label_2;
-          }
-        }
-        break;
-      case 42:
-        jj_consume_token(42);
-        break;
-      default:
-        jj_la1[7] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-      label_3:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 46:
-          ;
-          break;
-        default:
-          jj_la1[8] = jj_gen;
-          break label_3;
-        }
-        DatasetClause();
-      }
-      WhereClause();
-      SolutionModifier();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void ConstructQuery() throws ParseException {
- /*@bgen(jjtree) ConstructQuery */
-  ASTConstructQuery jjtn000 = new ASTConstructQuery(JJTCONSTRUCTQUERY);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(43);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 41:
-        jj_consume_token(41);
-                                  jjtn000.setDistinct(true);
-        break;
-      default:
-        jj_la1[9] = jj_gen;
-        ;
-      }
-      ConstructTemplate();
-      label_4:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 46:
-          ;
-          break;
-        default:
-          jj_la1[10] = jj_gen;
-          break label_4;
-        }
-        DatasetClause();
-      }
-      WhereClause();
-      SolutionModifier();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void DescribeQuery() throws ParseException {
- /*@bgen(jjtree) DescribeQuery */
-  ASTDescribeQuery jjtn000 = new ASTDescribeQuery(JJTDESCRIBEQUERY);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(44);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case Q_IRI_REF:
-      case QNAME_NS:
-      case QNAME:
-      case VAR1:
-      case VAR2:
-      case 68:
-      case 82:
-      case 83:
-      case 84:
-      case 85:
-      case 86:
-      case 87:
-      case 88:
-      case 89:
-      case 90:
-      case 91:
-        label_5:
-        while (true) {
-          VarOrIRIref();
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case Q_IRI_REF:
-          case QNAME_NS:
-          case QNAME:
-          case VAR1:
-          case VAR2:
-          case 68:
-          case 82:
-          case 83:
-          case 84:
-          case 85:
-          case 86:
-          case 87:
-          case 88:
-          case 89:
-          case 90:
-          case 91:
-            ;
-            break;
-          default:
-            jj_la1[11] = jj_gen;
-            break label_5;
-          }
-        }
-        break;
-      case 42:
-        jj_consume_token(42);
-        break;
-      default:
-        jj_la1[12] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-      label_6:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 46:
-          ;
-          break;
-        default:
-          jj_la1[13] = jj_gen;
-          break label_6;
-        }
-        DatasetClause();
-      }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 48:
-      case 55:
-        WhereClause();
-        break;
-      default:
-        jj_la1[14] = jj_gen;
-        ;
-      }
-      SolutionModifier();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void AskQuery() throws ParseException {
- /*@bgen(jjtree) AskQuery */
-  ASTAskQuery jjtn000 = new ASTAskQuery(JJTASKQUERY);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(45);
-      label_7:
-      while (true) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 46:
-          ;
-          break;
-        default:
-          jj_la1[15] = jj_gen;
-          break label_7;
-        }
-        DatasetClause();
-      }
-      WhereClause();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void DatasetClause() throws ParseException {
-    jj_consume_token(46);
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-      DefaultGraphClause();
-      break;
-    case 47:
-      NamedGraphClause();
-      break;
-    default:
-      jj_la1[16] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void DefaultGraphClause() throws ParseException {
- /*@bgen(jjtree) DefaultGraph */
-  ASTDefaultGraph jjtn000 = new ASTDefaultGraph(JJTDEFAULTGRAPH);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      SourceSelector();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void NamedGraphClause() throws ParseException {
- /*@bgen(jjtree) NamedGraph */
-  ASTNamedGraph jjtn000 = new ASTNamedGraph(JJTNAMEDGRAPH);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(47);
-      SourceSelector();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void SourceSelector() throws ParseException {
-    IRIref();
-  }
-
-  final public void WhereClause() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 48:
-      jj_consume_token(48);
-      break;
-    default:
-      jj_la1[17] = jj_gen;
-      ;
-    }
-    GroupGraphPattern();
-  }
-
-  final public void SolutionModifier() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 49:
-      OrderClause();
-      break;
-    default:
-      jj_la1[18] = jj_gen;
-      ;
-    }
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 53:
-      LimitClause();
-      break;
-    default:
-      jj_la1[19] = jj_gen;
-      ;
-    }
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 54:
-      OffsetClause();
-      break;
-    default:
-      jj_la1[20] = jj_gen;
-      ;
-    }
-  }
-
-  final public void OrderClause() throws ParseException {
- /*@bgen(jjtree) OrderConditions */
-  ASTOrderConditions jjtn000 = new ASTOrderConditions(JJTORDERCONDITIONS);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(49);
-      jj_consume_token(50);
-      label_8:
-      while (true) {
-        OrderCondition();
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-        case VAR1:
-        case VAR2:
-        case 51:
-        case 52:
-        case 68:
-          ;
-          break;
-        default:
-          jj_la1[21] = jj_gen;
-          break label_8;
-        }
-      }
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void OrderCondition() throws ParseException {
-boolean ascending = true;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 51:
-    case 52:
-            ASTDescOrder jjtn002 = new ASTDescOrder(JJTDESCORDER);
-            boolean jjtc002 = true;
-            jjtree.openNodeScope(jjtn002);
-      try {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 51:
-          jj_consume_token(51);
-          break;
-        case 52:
-          jj_consume_token(52);
-                              ascending = false;
-          break;
-        default:
-          jj_la1[22] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-                                                      ASTAscOrder jjtn001 = new ASTAscOrder(JJTASCORDER);
-                                                      boolean jjtc001 = true;
-                                                      jjtree.openNodeScope(jjtn001);
-        try {
-          BracketedExpression();
-        } catch (Throwable jjte001) {
-                                                      if (jjtc001) {
-                                                        jjtree.clearNodeScope(jjtn001);
-                                                        jjtc001 = false;
-                                                      } else {
-                                                        jjtree.popNode();
-                                                      }
-                                                      if (jjte001 instanceof RuntimeException) {
-                                                        {if (true) throw (RuntimeException)jjte001;}
-                                                      }
-                                                      if (jjte001 instanceof ParseException) {
-                                                        {if (true) throw (ParseException)jjte001;}
-                                                      }
-                                                      {if (true) throw (Error)jjte001;}
-        } finally {
-                                                      if (jjtc001) {
-                                                        jjtree.closeNodeScope(jjtn001,  ascending);
-                                                      }
-        }
-      } catch (Throwable jjte002) {
-            if (jjtc002) {
-              jjtree.clearNodeScope(jjtn002);
-              jjtc002 = false;
-            } else {
-              jjtree.popNode();
-            }
-            if (jjte002 instanceof RuntimeException) {
-              {if (true) throw (RuntimeException)jjte002;}
-            }
-            if (jjte002 instanceof ParseException) {
-              {if (true) throw (ParseException)jjte002;}
-            }
-            {if (true) throw (Error)jjte002;}
-      } finally {
-            if (jjtc002) {
-              jjtree.closeNodeScope(jjtn002,  ! ascending);
-            }
-      }
-      break;
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-    case VAR1:
-    case VAR2:
-    case 68:
-                      ASTDefaultOrder jjtn003 = new ASTDefaultOrder(JJTDEFAULTORDER);
-                      boolean jjtc003 = true;
-                      jjtree.openNodeScope(jjtn003);
-      try {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-          FunctionCall();
-          break;
-        case VAR1:
-        case VAR2:
-          Var();
-          break;
-        case 68:
-          BracketedExpression();
-          break;
-        default:
-          jj_la1[23] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      } catch (Throwable jjte003) {
-                      if (jjtc003) {
-                        jjtree.clearNodeScope(jjtn003);
-                        jjtc003 = false;
-                      } else {
-                        jjtree.popNode();
-                      }
-                      if (jjte003 instanceof RuntimeException) {
-                        {if (true) throw (RuntimeException)jjte003;}
-                      }
-                      if (jjte003 instanceof ParseException) {
-                        {if (true) throw (ParseException)jjte003;}
-                      }
-                      {if (true) throw (Error)jjte003;}
-      } finally {
-                      if (jjtc003) {
-                        jjtree.closeNodeScope(jjtn003, true);
-                      }
-      }
-      break;
-    default:
-      jj_la1[24] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void LimitClause() throws ParseException {
- /*@bgen(jjtree) Limit */
-ASTLimit jjtn000 = new ASTLimit(JJTLIMIT);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token limit;
-    try {
-      jj_consume_token(53);
-      limit = jj_consume_token(INTEGER);
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setLimit(limit.image);
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void OffsetClause() throws ParseException {
- /*@bgen(jjtree) Offset */
-ASTOffset jjtn000 = new ASTOffset(JJTOFFSET);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token offset;
-    try {
-      jj_consume_token(54);
-      offset = jj_consume_token(INTEGER);
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setOffset(offset.image);
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void GroupGraphPattern() throws ParseException {
- /*@bgen(jjtree) GroupConstraint */
-  ASTGroupConstraint jjtn000 = new ASTGroupConstraint(JJTGROUPCONSTRAINT);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(55);
-      GraphPattern();
-      jj_consume_token(56);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void GraphPattern() throws ParseException {
-    FilteredBasicGraphPattern();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 55:
-    case 58:
-    case 59:
-      GraphPatternNotTriples();
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 57:
-        jj_consume_token(57);
-        break;
-      default:
-        jj_la1[25] = jj_gen;
-        ;
-      }
-      GraphPattern();
-      break;
-    default:
-      jj_la1[26] = jj_gen;
-      ;
-    }
-  }
-
-  final public void FilteredBasicGraphPattern() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-    case BNODE_LABEL:
-    case VAR1:
-    case VAR2:
-    case INTEGER:
-    case DECIMAL:
-    case DOUBLE:
-    case STRING_LITERAL1:
-    case STRING_LITERAL2:
-    case STRING_LITERAL_LONG1:
-    case STRING_LITERAL_LONG2:
-    case NIL:
-    case ANON:
-    case 66:
-    case 68:
-    case 69:
-    case 70:
-    case 71:
-    case 82:
-    case 83:
-    case 84:
-    case 85:
-    case 86:
-    case 87:
-    case 88:
-    case 89:
-    case 90:
-    case 91:
-    case 93:
-    case 94:
-      BlockOfTriples();
-      break;
-    default:
-      jj_la1[27] = jj_gen;
-      ;
-    }
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 61:
-      Constraint();
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 57:
-        jj_consume_token(57);
-        break;
-      default:
-        jj_la1[28] = jj_gen;
-        ;
-      }
-      FilteredBasicGraphPattern();
-      break;
-    default:
-      jj_la1[29] = jj_gen;
-      ;
-    }
-  }
-
-  final public void BlockOfTriples() throws ParseException {
-    TriplesSameSubject();
-    label_9:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 57:
-        ;
-        break;
-      default:
-        jj_la1[30] = jj_gen;
-        break label_9;
-      }
-      jj_consume_token(57);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case Q_IRI_REF:
-      case QNAME_NS:
-      case QNAME:
-      case BNODE_LABEL:
-      case VAR1:
-      case VAR2:
-      case INTEGER:
-      case DECIMAL:
-      case DOUBLE:
-      case STRING_LITERAL1:
-      case STRING_LITERAL2:
-      case STRING_LITERAL_LONG1:
-      case STRING_LITERAL_LONG2:
-      case NIL:
-      case ANON:
-      case 66:
-      case 68:
-      case 69:
-      case 70:
-      case 71:
-      case 82:
-      case 83:
-      case 84:
-      case 85:
-      case 86:
-      case 87:
-      case 88:
-      case 89:
-      case 90:
-      case 91:
-      case 93:
-      case 94:
-        TriplesSameSubject();
-        break;
-      default:
-        jj_la1[31] = jj_gen;
-        ;
-      }
-    }
-  }
-
-  final public void GraphPatternNotTriples() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 58:
-      OptionalGraphPattern();
-      break;
-    case 55:
-      GroupOrUnionGraphPattern();
-      break;
-    case 59:
-      GraphGraphPattern();
-      break;
-    default:
-      jj_la1[32] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void OptionalGraphPattern() throws ParseException {
- /*@bgen(jjtree) OptionalConstraint */
-  ASTOptionalConstraint jjtn000 = new ASTOptionalConstraint(JJTOPTIONALCONSTRAINT);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(58);
-      GroupGraphPattern();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void GraphGraphPattern() throws ParseException {
- /*@bgen(jjtree) GraphConstraint */
-  ASTGraphConstraint jjtn000 = new ASTGraphConstraint(JJTGRAPHCONSTRAINT);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(59);
-                  ASTGraph jjtn001 = new ASTGraph(JJTGRAPH);
-                  boolean jjtc001 = true;
-                  jjtree.openNodeScope(jjtn001);
-      try {
-        VarOrBlankNodeOrIRIref();
-      } catch (Throwable jjte001) {
-                  if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                  } else {
-                    jjtree.popNode();
-                  }
-                  if (jjte001 instanceof RuntimeException) {
-                    {if (true) throw (RuntimeException)jjte001;}
-                  }
-                  if (jjte001 instanceof ParseException) {
-                    {if (true) throw (ParseException)jjte001;}
-                  }
-                  {if (true) throw (Error)jjte001;}
-      } finally {
-                  if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001,  1);
-                  }
-      }
-      GroupGraphPattern();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void GroupOrUnionGraphPattern() throws ParseException {
-    GroupGraphPattern();
-    label_10:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 60:
-        ;
-        break;
-      default:
-        jj_la1[33] = jj_gen;
-        break label_10;
-      }
-      jj_consume_token(60);
-                                       ASTUnionConstraint jjtn001 = new ASTUnionConstraint(JJTUNIONCONSTRAINT);
-                                       boolean jjtc001 = true;
-                                       jjtree.openNodeScope(jjtn001);
-      try {
-        GroupGraphPattern();
-      } catch (Throwable jjte001) {
-                                       if (jjtc001) {
-                                         jjtree.clearNodeScope(jjtn001);
-                                         jjtc001 = false;
-                                       } else {
-                                         jjtree.popNode();
-                                       }
-                                       if (jjte001 instanceof RuntimeException) {
-                                         {if (true) throw (RuntimeException)jjte001;}
-                                       }
-                                       if (jjte001 instanceof ParseException) {
-                                         {if (true) throw (ParseException)jjte001;}
-                                       }
-                                       {if (true) throw (Error)jjte001;}
-      } finally {
-                                       if (jjtc001) {
-                                         jjtree.closeNodeScope(jjtn001,  2);
-                                       }
-      }
-    }
-  }
-
-  final public void Constraint() throws ParseException {
- /*@bgen(jjtree) FilterConstraint */
-  ASTFilterConstraint jjtn000 = new ASTFilterConstraint(JJTFILTERCONSTRAINT);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(61);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 68:
-        BracketedExpression();
-        break;
-      case 82:
-      case 83:
-      case 84:
-      case 85:
-      case 86:
-      case 87:
-      case 88:
-      case 89:
-      case 90:
-      case 91:
-        BuiltInCall();
-        break;
-      case Q_IRI_REF:
-      case QNAME_NS:
-      case QNAME:
-        FunctionCall();
-        break;
-      default:
-        jj_la1[34] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void FunctionCall() throws ParseException {
- /*@bgen(jjtree) FunctionCall */
-  ASTFunctionCall jjtn000 = new ASTFunctionCall(JJTFUNCTIONCALL);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      IRIref();
-      ArgList();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void ArgList() throws ParseException {
- /*@bgen(jjtree) Arguments */
-  ASTArguments jjtn000 = new ASTArguments(JJTARGUMENTS);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(FUNCTION_PAREN);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case Q_IRI_REF:
-      case QNAME_NS:
-      case QNAME:
-      case BNODE_LABEL:
-      case VAR1:
-      case VAR2:
-      case INTEGER:
-      case DECIMAL:
-      case DOUBLE:
-      case STRING_LITERAL1:
-      case STRING_LITERAL2:
-      case STRING_LITERAL_LONG1:
-      case STRING_LITERAL_LONG2:
-      case ANON:
-      case 68:
-      case 70:
-      case 71:
-      case 81:
-      case 82:
-      case 83:
-      case 84:
-      case 85:
-      case 86:
-      case 87:
-      case 88:
-      case 89:
-      case 90:
-      case 91:
-      case 93:
-      case 94:
-        Expression();
-        label_11:
-        while (true) {
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case 62:
-            ;
-            break;
-          default:
-            jj_la1[35] = jj_gen;
-            break label_11;
-          }
-          jj_consume_token(62);
-          Expression();
-        }
-        break;
-      default:
-        jj_la1[36] = jj_gen;
-        ;
-      }
-      jj_consume_token(63);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void ConstructTemplate() throws ParseException {
- /*@bgen(jjtree) ConstructTemplate */
-  ASTConstructTemplate jjtn000 = new ASTConstructTemplate(JJTCONSTRUCTTEMPLATE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(55);
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 42:
-        jj_consume_token(42);
-        break;
-      default:
-        jj_la1[37] = jj_gen;
-        ConstructTriples();
-      }
-      jj_consume_token(56);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void ConstructTriples() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-    case BNODE_LABEL:
-    case VAR1:
-    case VAR2:
-    case INTEGER:
-    case DECIMAL:
-    case DOUBLE:
-    case STRING_LITERAL1:
-    case STRING_LITERAL2:
-    case STRING_LITERAL_LONG1:
-    case STRING_LITERAL_LONG2:
-    case NIL:
-    case ANON:
-    case 66:
-    case 68:
-    case 69:
-    case 70:
-    case 71:
-    case 82:
-    case 83:
-    case 84:
-    case 85:
-    case 86:
-    case 87:
-    case 88:
-    case 89:
-    case 90:
-    case 91:
-    case 93:
-    case 94:
-      TriplesSameSubject();
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 57:
-        jj_consume_token(57);
-        ConstructTriples();
-        break;
-      default:
-        jj_la1[38] = jj_gen;
-        ;
-      }
-      break;
-    default:
-      jj_la1[39] = jj_gen;
-      ;
-    }
-  }
-
-  final public void TriplesSameSubject() throws ParseException {
-    if (jj_2_1(3)) {
-                                                                                   ASTTripleSet jjtn002 = new ASTTripleSet(JJTTRIPLESET);
-                                                                                   boolean jjtc002 = true;
-                                                                                   jjtree.openNodeScope(jjtn002);
-      try {
-        VarOrTerm();
-                                                                                                 ASTPropertyList jjtn001 = new ASTPropertyList(JJTPROPERTYLIST);
-                                                                                                 boolean jjtc001 = true;
-                                                                                                 jjtree.openNodeScope(jjtn001);
-        try {
-          PropertyListNotEmpty();
-        } catch (Throwable jjte001) {
-                                                                                                 if (jjtc001) {
-                                                                                                   jjtree.clearNodeScope(jjtn001);
-                                                                                                   jjtc001 = false;
-                                                                                                 } else {
-                                                                                                   jjtree.popNode();
-                                                                                                 }
-                                                                                                 if (jjte001 instanceof RuntimeException) {
-                                                                                                   {if (true) throw (RuntimeException)jjte001;}
-                                                                                                 }
-                                                                                                 if (jjte001 instanceof ParseException) {
-                                                                                                   {if (true) throw (ParseException)jjte001;}
-                                                                                                 }
-                                                                                                 {if (true) throw (Error)jjte001;}
-        } finally {
-                                                                                                 if (jjtc001) {
-                                                                                                   jjtree.closeNodeScope(jjtn001, true);
-                                                                                                 }
-        }
-      } catch (Throwable jjte002) {
-                                                                                   if (jjtc002) {
-                                                                                     jjtree.clearNodeScope(jjtn002);
-                                                                                     jjtc002 = false;
-                                                                                   } else {
-                                                                                     jjtree.popNode();
-                                                                                   }
-                                                                                   if (jjte002 instanceof RuntimeException) {
-                                                                                     {if (true) throw (RuntimeException)jjte002;}
-                                                                                   }
-                                                                                   if (jjte002 instanceof ParseException) {
-                                                                                     {if (true) throw (ParseException)jjte002;}
-                                                                                   }
-                                                                                   {if (true) throw (Error)jjte002;}
-      } finally {
-                                                                                   if (jjtc002) {
-                                                                                     jjtree.closeNodeScope(jjtn002, true);
-                                                                                   }
-      }
-    } else {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 66:
-      case 68:
-      case 69:
-                    ASTNodeSet jjtn004 = new ASTNodeSet(JJTNODESET);
-                    boolean jjtc004 = true;
-                    jjtree.openNodeScope(jjtn004);
-        try {
-          TriplesNode();
-          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-          case Q_IRI_REF:
-          case QNAME_NS:
-          case QNAME:
-          case VAR1:
-          case VAR2:
-          case 65:
-          case 68:
-          case 82:
-          case 83:
-          case 84:
-          case 85:
-          case 86:
-          case 87:
-          case 88:
-          case 89:
-          case 90:
-          case 91:
-                                    ASTPropertyList jjtn003 = new ASTPropertyList(JJTPROPERTYLIST);
-                                    boolean jjtc003 = true;
-                                    jjtree.openNodeScope(jjtn003);
-            try {
-              PropertyListNotEmpty();
-            } catch (Throwable jjte003) {
-                                    if (jjtc003) {
-                                      jjtree.clearNodeScope(jjtn003);
-                                      jjtc003 = false;
-                                    } else {
-                                      jjtree.popNode();
-                                    }
-                                    if (jjte003 instanceof RuntimeException) {
-                                      {if (true) throw (RuntimeException)jjte003;}
-                                    }
-                                    if (jjte003 instanceof ParseException) {
-                                      {if (true) throw (ParseException)jjte003;}
-                                    }
-                                    {if (true) throw (Error)jjte003;}
-            } finally {
-                                    if (jjtc003) {
-                                      jjtree.closeNodeScope(jjtn003, true);
-                                    }
-            }
-            break;
-          default:
-            jj_la1[40] = jj_gen;
-            ;
-          }
-        } catch (Throwable jjte004) {
-                    if (jjtc004) {
-                      jjtree.clearNodeScope(jjtn004);
-                      jjtc004 = false;
-                    } else {
-                      jjtree.popNode();
-                    }
-                    if (jjte004 instanceof RuntimeException) {
-                      {if (true) throw (RuntimeException)jjte004;}
-                    }
-                    if (jjte004 instanceof ParseException) {
-                      {if (true) throw (ParseException)jjte004;}
-                    }
-                    {if (true) throw (Error)jjte004;}
-        } finally {
-                    if (jjtc004) {
-                      jjtree.closeNodeScope(jjtn004, true);
-                    }
-        }
-        break;
-      default:
-        jj_la1[41] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-    }
-  }
-
-  final public void PropertyList() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-    case VAR1:
-    case VAR2:
-    case 65:
-    case 68:
-    case 82:
-    case 83:
-    case 84:
-    case 85:
-    case 86:
-    case 87:
-    case 88:
-    case 89:
-    case 90:
-    case 91:
-      PropertyListNotEmpty();
-      break;
-    default:
-      jj_la1[42] = jj_gen;
-      ;
-    }
-  }
-
-  final public void PropertyListNotEmpty() throws ParseException {
-          ASTVerbObject jjtn002 = new ASTVerbObject(JJTVERBOBJECT);
-          boolean jjtc002 = true;
-          jjtree.openNodeScope(jjtn002);
-    try {
-      Verb();
-                  ASTObjectList jjtn001 = new ASTObjectList(JJTOBJECTLIST);
-                  boolean jjtc001 = true;
-                  jjtree.openNodeScope(jjtn001);
-      try {
-        ObjectList();
-      } catch (Throwable jjte001) {
-                  if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                  } else {
-                    jjtree.popNode();
-                  }
-                  if (jjte001 instanceof RuntimeException) {
-                    {if (true) throw (RuntimeException)jjte001;}
-                  }
-                  if (jjte001 instanceof ParseException) {
-                    {if (true) throw (ParseException)jjte001;}
-                  }
-                  {if (true) throw (Error)jjte001;}
-      } finally {
-                  if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001, true);
-                  }
-      }
-    } catch (Throwable jjte002) {
-          if (jjtc002) {
-            jjtree.clearNodeScope(jjtn002);
-            jjtc002 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte002 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte002;}
-          }
-          if (jjte002 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte002;}
-          }
-          {if (true) throw (Error)jjte002;}
-    } finally {
-          if (jjtc002) {
-            jjtree.closeNodeScope(jjtn002,  true);
-          }
-    }
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 64:
-      jj_consume_token(64);
-      PropertyList();
-      break;
-    default:
-      jj_la1[43] = jj_gen;
-      ;
-    }
-  }
-
-  final public void ObjectList() throws ParseException {
-    GraphNode();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 62:
-      jj_consume_token(62);
-      ObjectList();
-      break;
-    default:
-      jj_la1[44] = jj_gen;
-      ;
-    }
-  }
-
-  final public void Verb() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-    case VAR1:
-    case VAR2:
-    case 68:
-    case 82:
-    case 83:
-    case 84:
-    case 85:
-    case 86:
-    case 87:
-    case 88:
-    case 89:
-    case 90:
-    case 91:
-      VarOrIRIref();
-      break;
-    case 65:
-                          ASTTypeVerb jjtn001 = new ASTTypeVerb(JJTTYPEVERB);
-                          boolean jjtc001 = true;
-                          jjtree.openNodeScope(jjtn001);
-      try {
-        jj_consume_token(65);
-      } finally {
-                          if (jjtc001) {
-                            jjtree.closeNodeScope(jjtn001,  0);
-                          }
-      }
-      break;
-    default:
-      jj_la1[45] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void TriplesNode() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 68:
-      Collection();
-      break;
-    case 66:
-      BlankNodePropertyList();
-      break;
-    case 69:
-      WithExtension();
-      break;
-    default:
-      jj_la1[46] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void BlankNodePropertyList() throws ParseException {
- /*@bgen(jjtree) BlankNodePropertyList */
-  ASTBlankNodePropertyList jjtn000 = new ASTBlankNodePropertyList(JJTBLANKNODEPROPERTYLIST);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(66);
-              ASTPropertyList jjtn001 = new ASTPropertyList(JJTPROPERTYLIST);
-              boolean jjtc001 = true;
-              jjtree.openNodeScope(jjtn001);
-      try {
-        PropertyListNotEmpty();
-      } catch (Throwable jjte001) {
-              if (jjtc001) {
-                jjtree.clearNodeScope(jjtn001);
-                jjtc001 = false;
-              } else {
-                jjtree.popNode();
-              }
-              if (jjte001 instanceof RuntimeException) {
-                {if (true) throw (RuntimeException)jjte001;}
-              }
-              if (jjte001 instanceof ParseException) {
-                {if (true) throw (ParseException)jjte001;}
-              }
-              {if (true) throw (Error)jjte001;}
-      } finally {
-              if (jjtc001) {
-                jjtree.closeNodeScope(jjtn001, true);
-              }
-      }
-      jj_consume_token(67);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void Collection() throws ParseException {
- /*@bgen(jjtree) Collection */
-  ASTCollection jjtn000 = new ASTCollection(JJTCOLLECTION);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(68);
-      label_12:
-      while (true) {
-        GraphNode();
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-        case BNODE_LABEL:
-        case VAR1:
-        case VAR2:
-        case INTEGER:
-        case DECIMAL:
-        case DOUBLE:
-        case STRING_LITERAL1:
-        case STRING_LITERAL2:
-        case STRING_LITERAL_LONG1:
-        case STRING_LITERAL_LONG2:
-        case NIL:
-        case ANON:
-        case 66:
-        case 68:
-        case 69:
-        case 70:
-        case 71:
-        case 82:
-        case 83:
-        case 84:
-        case 85:
-        case 86:
-        case 87:
-        case 88:
-        case 89:
-        case 90:
-        case 91:
-        case 93:
-        case 94:
-          ;
-          break;
-        default:
-          jj_la1[47] = jj_gen;
-          break label_12;
-        }
-      }
-      jj_consume_token(63);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void WithExtension() throws ParseException {
- /*@bgen(jjtree) WithExtension */
-  ASTWithExtension jjtn000 = new ASTWithExtension(JJTWITHEXTENSION);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(69);
-      FunctionCall();
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void GraphNode() throws ParseException {
-    if (jj_2_2(3)) {
-      VarOrTerm();
-    } else {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 66:
-      case 68:
-      case 69:
-        TriplesNode();
-        break;
-      default:
-        jj_la1[48] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-    }
-  }
-
-  final public void VarOrTerm() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case VAR1:
-    case VAR2:
-      Var();
-      break;
-    default:
-      jj_la1[50] = jj_gen;
-      if (jj_2_3(2)) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 68:
-          BracketedExpression();
-          break;
-        case 82:
-        case 83:
-        case 84:
-        case 85:
-        case 86:
-        case 87:
-        case 88:
-        case 89:
-        case 90:
-        case 91:
-          BuiltInCall();
-          break;
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-          FunctionCall();
-          break;
-        default:
-          jj_la1[49] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      } else {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-        case BNODE_LABEL:
-        case INTEGER:
-        case DECIMAL:
-        case DOUBLE:
-        case STRING_LITERAL1:
-        case STRING_LITERAL2:
-        case STRING_LITERAL_LONG1:
-        case STRING_LITERAL_LONG2:
-        case NIL:
-        case ANON:
-        case 70:
-        case 71:
-        case 93:
-        case 94:
-          GraphTerm();
-          break;
-        default:
-          jj_la1[51] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      }
-    }
-  }
-
-  final public void VarOrIRIref() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case VAR1:
-    case VAR2:
-      Var();
-      break;
-    default:
-      jj_la1[53] = jj_gen;
-      if (jj_2_4(2)) {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case 68:
-          BracketedExpression();
-          break;
-        case 82:
-        case 83:
-        case 84:
-        case 85:
-        case 86:
-        case 87:
-        case 88:
-        case 89:
-        case 90:
-        case 91:
-          BuiltInCall();
-          break;
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-          FunctionCall();
-          break;
-        default:
-          jj_la1[52] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      } else {
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case Q_IRI_REF:
-        case QNAME_NS:
-        case QNAME:
-          IRIref();
-          break;
-        default:
-          jj_la1[54] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-      }
-    }
-  }
-
-  final public void VarOrBlankNodeOrIRIref() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case VAR1:
-    case VAR2:
-      Var();
-      break;
-    case BNODE_LABEL:
-    case ANON:
-      BlankNode();
-      break;
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-      IRIref();
-      break;
-    default:
-      jj_la1[55] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void Var() throws ParseException {
- /*@bgen(jjtree) Var */
-        ASTVar jjtn000 = new ASTVar(JJTVAR);
-        boolean jjtc000 = true;
-        jjtree.openNodeScope(jjtn000);Token varName;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case VAR1:
-        varName = jj_consume_token(VAR1);
-        break;
-      case VAR2:
-        varName = jj_consume_token(VAR2);
-        break;
-      default:
-        jj_la1[56] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setName(varName.image.substring(1));
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void GraphTerm() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-      IRIref();
-      break;
-    case STRING_LITERAL1:
-    case STRING_LITERAL2:
-    case STRING_LITERAL_LONG1:
-    case STRING_LITERAL_LONG2:
-      RDFLiteral();
-      break;
-    case INTEGER:
-    case DECIMAL:
-    case DOUBLE:
-      PositiveLiteral();
-      break;
-    case 70:
-      jj_consume_token(70);
-      PositiveLiteral();
-      break;
-    case 71:
-      jj_consume_token(71);
-      NegativeLiteral();
-      break;
-    case 93:
-    case 94:
-      BooleanLiteral();
-      break;
-    case BNODE_LABEL:
-    case ANON:
-      BlankNode();
-      break;
-    case NIL:
-                      ASTEmptyNode jjtn001 = new ASTEmptyNode(JJTEMPTYNODE);
-                      boolean jjtc001 = true;
-                      jjtree.openNodeScope(jjtn001);
-      try {
-        jj_consume_token(NIL);
-      } finally {
-                      if (jjtc001) {
-                        jjtree.closeNodeScope(jjtn001,  1);
-                      }
-      }
-      break;
-    default:
-      jj_la1[57] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void Expression() throws ParseException {
-    ConditionalOrExpression();
-  }
-
-  final public void ConditionalOrExpression() throws ParseException {
-    ConditionalAndExpression();
-    label_13:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 72:
-        ;
-        break;
-      default:
-        jj_la1[58] = jj_gen;
-        break label_13;
-      }
-      jj_consume_token(72);
-                                             ASTOrNode jjtn001 = new ASTOrNode(JJTORNODE);
-                                             boolean jjtc001 = true;
-                                             jjtree.openNodeScope(jjtn001);
-      try {
-        ConditionalAndExpression();
-      } catch (Throwable jjte001) {
-                                             if (jjtc001) {
-                                               jjtree.clearNodeScope(jjtn001);
-                                               jjtc001 = false;
-                                             } else {
-                                               jjtree.popNode();
-                                             }
-                                             if (jjte001 instanceof RuntimeException) {
-                                               {if (true) throw (RuntimeException)jjte001;}
-                                             }
-                                             if (jjte001 instanceof ParseException) {
-                                               {if (true) throw (ParseException)jjte001;}
-                                             }
-                                             {if (true) throw (Error)jjte001;}
-      } finally {
-                                             if (jjtc001) {
-                                               jjtree.closeNodeScope(jjtn001,  2);
-                                             }
-      }
-    }
-  }
-
-  final public void ConditionalAndExpression() throws ParseException {
-    ValueLogical();
-    label_14:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 73:
-        ;
-        break;
-      default:
-        jj_la1[59] = jj_gen;
-        break label_14;
-      }
-      jj_consume_token(73);
-                               ASTAndNode jjtn001 = new ASTAndNode(JJTANDNODE);
-                               boolean jjtc001 = true;
-                               jjtree.openNodeScope(jjtn001);
-      try {
-        ValueLogical();
-      } catch (Throwable jjte001) {
-                               if (jjtc001) {
-                                 jjtree.clearNodeScope(jjtn001);
-                                 jjtc001 = false;
-                               } else {
-                                 jjtree.popNode();
-                               }
-                               if (jjte001 instanceof RuntimeException) {
-                                 {if (true) throw (RuntimeException)jjte001;}
-                               }
-                               if (jjte001 instanceof ParseException) {
-                                 {if (true) throw (ParseException)jjte001;}
-                               }
-                               {if (true) throw (Error)jjte001;}
-      } finally {
-                               if (jjtc001) {
-                                 jjtree.closeNodeScope(jjtn001,  2);
-                               }
-      }
-    }
-  }
-
-  final public void ValueLogical() throws ParseException {
-    RelationalExpression();
-  }
-
-  final public void RelationalExpression() throws ParseException {
-    NumericExpression();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 74:
-    case 75:
-    case 76:
-    case 77:
-    case 78:
-    case 79:
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 74:
-        jj_consume_token(74);
-                        ASTEqualsNode jjtn001 = new ASTEqualsNode(JJTEQUALSNODE);
-                        boolean jjtc001 = true;
-                        jjtree.openNodeScope(jjtn001);
-        try {
-          NumericExpression();
-        } catch (Throwable jjte001) {
-                        if (jjtc001) {
-                          jjtree.clearNodeScope(jjtn001);
-                          jjtc001 = false;
-                        } else {
-                          jjtree.popNode();
-                        }
-                        if (jjte001 instanceof RuntimeException) {
-                          {if (true) throw (RuntimeException)jjte001;}
-                        }
-                        if (jjte001 instanceof ParseException) {
-                          {if (true) throw (ParseException)jjte001;}
-                        }
-                        {if (true) throw (Error)jjte001;}
-        } finally {
-                        if (jjtc001) {
-                          jjtree.closeNodeScope(jjtn001,  2);
-                        }
-        }
-        break;
-      case 75:
-        jj_consume_token(75);
-                                   ASTNotEqualsNode jjtn002 = new ASTNotEqualsNode(JJTNOTEQUALSNODE);
-                                   boolean jjtc002 = true;
-                                   jjtree.openNodeScope(jjtn002);
-        try {
-          NumericExpression();
-        } catch (Throwable jjte002) {
-                                   if (jjtc002) {
-                                     jjtree.clearNodeScope(jjtn002);
-                                     jjtc002 = false;
-                                   } else {
-                                     jjtree.popNode();
-                                   }
-                                   if (jjte002 instanceof RuntimeException) {
-                                     {if (true) throw (RuntimeException)jjte002;}
-                                   }
-                                   if (jjte002 instanceof ParseException) {
-                                     {if (true) throw (ParseException)jjte002;}
-                                   }
-                                   {if (true) throw (Error)jjte002;}
-        } finally {
-                                   if (jjtc002) {
-                                     jjtree.closeNodeScope(jjtn002,  2);
-                                   }
-        }
-        break;
-      case 76:
-        jj_consume_token(76);
-                                  ASTLessThanNode jjtn003 = new ASTLessThanNode(JJTLESSTHANNODE);
-                                  boolean jjtc003 = true;
-                                  jjtree.openNodeScope(jjtn003);
-        try {
-          NumericExpression();
-        } catch (Throwable jjte003) {
-                                  if (jjtc003) {
-                                    jjtree.clearNodeScope(jjtn003);
-                                    jjtc003 = false;
-                                  } else {
-                                    jjtree.popNode();
-                                  }
-                                  if (jjte003 instanceof RuntimeException) {
-                                    {if (true) throw (RuntimeException)jjte003;}
-                                  }
-                                  if (jjte003 instanceof ParseException) {
-                                    {if (true) throw (ParseException)jjte003;}
-                                  }
-                                  {if (true) throw (Error)jjte003;}
-        } finally {
-                                  if (jjtc003) {
-                                    jjtree.closeNodeScope(jjtn003,  2);
-                                  }
-        }
-        break;
-      case 77:
-        jj_consume_token(77);
-                                   ASTLessThanEqualsNode jjtn004 = new ASTLessThanEqualsNode(JJTLESSTHANEQUALSNODE);
-                                   boolean jjtc004 = true;
-                                   jjtree.openNodeScope(jjtn004);
-        try {
-          NumericExpression();
-        } catch (Throwable jjte004) {
-                                   if (jjtc004) {
-                                     jjtree.clearNodeScope(jjtn004);
-                                     jjtc004 = false;
-                                   } else {
-                                     jjtree.popNode();
-                                   }
-                                   if (jjte004 instanceof RuntimeException) {
-                                     {if (true) throw (RuntimeException)jjte004;}
-                                   }
-                                   if (jjte004 instanceof ParseException) {
-                                     {if (true) throw (ParseException)jjte004;}
-                                   }
-                                   {if (true) throw (Error)jjte004;}
-        } finally {
-                                   if (jjtc004) {
-                                     jjtree.closeNodeScope(jjtn004,  2);
-                                   }
-        }
-        break;
-      case 78:
-        jj_consume_token(78);
-                                  ASTGreaterThanNode jjtn005 = new ASTGreaterThanNode(JJTGREATERTHANNODE);
-                                  boolean jjtc005 = true;
-                                  jjtree.openNodeScope(jjtn005);
-        try {
-          NumericExpression();
-        } catch (Throwable jjte005) {
-                                  if (jjtc005) {
-                                    jjtree.clearNodeScope(jjtn005);
-                                    jjtc005 = false;
-                                  } else {
-                                    jjtree.popNode();
-                                  }
-                                  if (jjte005 instanceof RuntimeException) {
-                                    {if (true) throw (RuntimeException)jjte005;}
-                                  }
-                                  if (jjte005 instanceof ParseException) {
-                                    {if (true) throw (ParseException)jjte005;}
-                                  }
-                                  {if (true) throw (Error)jjte005;}
-        } finally {
-                                  if (jjtc005) {
-                                    jjtree.closeNodeScope(jjtn005,  2);
-                                  }
-        }
-        break;
-      case 79:
-        jj_consume_token(79);
-                                   ASTGreaterThanEqualsNode jjtn006 = new ASTGreaterThanEqualsNode(JJTGREATERTHANEQUALSNODE);
-                                   boolean jjtc006 = true;
-                                   jjtree.openNodeScope(jjtn006);
-        try {
-          NumericExpression();
-        } catch (Throwable jjte006) {
-                                   if (jjtc006) {
-                                     jjtree.clearNodeScope(jjtn006);
-                                     jjtc006 = false;
-                                   } else {
-                                     jjtree.popNode();
-                                   }
-                                   if (jjte006 instanceof RuntimeException) {
-                                     {if (true) throw (RuntimeException)jjte006;}
-                                   }
-                                   if (jjte006 instanceof ParseException) {
-                                     {if (true) throw (ParseException)jjte006;}
-                                   }
-                                   {if (true) throw (Error)jjte006;}
-        } finally {
-                                   if (jjtc006) {
-                                     jjtree.closeNodeScope(jjtn006,  2);
-                                   }
-        }
-        break;
-      default:
-        jj_la1[60] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-      break;
-    default:
-      jj_la1[61] = jj_gen;
-      ;
-    }
-  }
-
-  final public void NumericExpression() throws ParseException {
-    AdditiveExpression();
-  }
-
-  final public void AdditiveExpression() throws ParseException {
-    MultiplicativeExpression();
-    label_15:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 70:
-      case 71:
-        ;
-        break;
-      default:
-        jj_la1[62] = jj_gen;
-        break label_15;
-      }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 70:
-        jj_consume_token(70);
-                  ASTAdditionNode jjtn001 = new ASTAdditionNode(JJTADDITIONNODE);
-                  boolean jjtc001 = true;
-                  jjtree.openNodeScope(jjtn001);
-        try {
-          MultiplicativeExpression();
-        } catch (Throwable jjte001) {
-                  if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                  } else {
-                    jjtree.popNode();
-                  }
-                  if (jjte001 instanceof RuntimeException) {
-                    {if (true) throw (RuntimeException)jjte001;}
-                  }
-                  if (jjte001 instanceof ParseException) {
-                    {if (true) throw (ParseException)jjte001;}
-                  }
-                  {if (true) throw (Error)jjte001;}
-        } finally {
-                  if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001,  2);
-                  }
-        }
-        break;
-      case 71:
-        jj_consume_token(71);
-                          ASTSubtractionNode jjtn002 = new ASTSubtractionNode(JJTSUBTRACTIONNODE);
-                          boolean jjtc002 = true;
-                          jjtree.openNodeScope(jjtn002);
-        try {
-          MultiplicativeExpression();
-        } catch (Throwable jjte002) {
-                          if (jjtc002) {
-                            jjtree.clearNodeScope(jjtn002);
-                            jjtc002 = false;
-                          } else {
-                            jjtree.popNode();
-                          }
-                          if (jjte002 instanceof RuntimeException) {
-                            {if (true) throw (RuntimeException)jjte002;}
-                          }
-                          if (jjte002 instanceof ParseException) {
-                            {if (true) throw (ParseException)jjte002;}
-                          }
-                          {if (true) throw (Error)jjte002;}
-        } finally {
-                          if (jjtc002) {
-                            jjtree.closeNodeScope(jjtn002,  2);
-                          }
-        }
-        break;
-      default:
-        jj_la1[63] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-    }
-  }
-
-  final public void MultiplicativeExpression() throws ParseException {
-    UnaryExpression();
-    label_16:
-    while (true) {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 42:
-      case 80:
-        ;
-        break;
-      default:
-        jj_la1[64] = jj_gen;
-        break label_16;
-      }
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 42:
-        jj_consume_token(42);
-                  ASTMultiplicationNode jjtn001 = new ASTMultiplicationNode(JJTMULTIPLICATIONNODE);
-                  boolean jjtc001 = true;
-                  jjtree.openNodeScope(jjtn001);
-        try {
-          UnaryExpression();
-        } catch (Throwable jjte001) {
-                  if (jjtc001) {
-                    jjtree.clearNodeScope(jjtn001);
-                    jjtc001 = false;
-                  } else {
-                    jjtree.popNode();
-                  }
-                  if (jjte001 instanceof RuntimeException) {
-                    {if (true) throw (RuntimeException)jjte001;}
-                  }
-                  if (jjte001 instanceof ParseException) {
-                    {if (true) throw (ParseException)jjte001;}
-                  }
-                  {if (true) throw (Error)jjte001;}
-        } finally {
-                  if (jjtc001) {
-                    jjtree.closeNodeScope(jjtn001,  2);
-                  }
-        }
-        break;
-      case 80:
-        jj_consume_token(80);
-                          ASTDivisionNode jjtn002 = new ASTDivisionNode(JJTDIVISIONNODE);
-                          boolean jjtc002 = true;
-                          jjtree.openNodeScope(jjtn002);
-        try {
-          UnaryExpression();
-        } catch (Throwable jjte002) {
-                          if (jjtc002) {
-                            jjtree.clearNodeScope(jjtn002);
-                            jjtc002 = false;
-                          } else {
-                            jjtree.popNode();
-                          }
-                          if (jjte002 instanceof RuntimeException) {
-                            {if (true) throw (RuntimeException)jjte002;}
-                          }
-                          if (jjte002 instanceof ParseException) {
-                            {if (true) throw (ParseException)jjte002;}
-                          }
-                          {if (true) throw (Error)jjte002;}
-        } finally {
-                          if (jjtc002) {
-                            jjtree.closeNodeScope(jjtn002,  2);
-                          }
-        }
-        break;
-      default:
-        jj_la1[65] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-    }
-  }
-
-  final public void UnaryExpression() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 81:
-      jj_consume_token(81);
-              ASTNotNode jjtn001 = new ASTNotNode(JJTNOTNODE);
-              boolean jjtc001 = true;
-              jjtree.openNodeScope(jjtn001);
-      try {
-        PrimaryExpression();
-      } catch (Throwable jjte001) {
-              if (jjtc001) {
-                jjtree.clearNodeScope(jjtn001);
-                jjtc001 = false;
-              } else {
-                jjtree.popNode();
-              }
-              if (jjte001 instanceof RuntimeException) {
-                {if (true) throw (RuntimeException)jjte001;}
-              }
-              if (jjte001 instanceof ParseException) {
-                {if (true) throw (ParseException)jjte001;}
-              }
-              {if (true) throw (Error)jjte001;}
-      } finally {
-              if (jjtc001) {
-                jjtree.closeNodeScope(jjtn001,  1);
-              }
-      }
-      break;
-    case 70:
-      jj_consume_token(70);
-                        ASTPlusNode jjtn002 = new ASTPlusNode(JJTPLUSNODE);
-                        boolean jjtc002 = true;
-                        jjtree.openNodeScope(jjtn002);
-      try {
-        PrimaryExpression();
-      } catch (Throwable jjte002) {
-                        if (jjtc002) {
-                          jjtree.clearNodeScope(jjtn002);
-                          jjtc002 = false;
-                        } else {
-                          jjtree.popNode();
-                        }
-                        if (jjte002 instanceof RuntimeException) {
-                          {if (true) throw (RuntimeException)jjte002;}
-                        }
-                        if (jjte002 instanceof ParseException) {
-                          {if (true) throw (ParseException)jjte002;}
-                        }
-                        {if (true) throw (Error)jjte002;}
-      } finally {
-                        if (jjtc002) {
-                          jjtree.closeNodeScope(jjtn002,  1);
-                        }
-      }
-      break;
-    case 71:
-      jj_consume_token(71);
-                        ASTMinusNode jjtn003 = new ASTMinusNode(JJTMINUSNODE);
-                        boolean jjtc003 = true;
-                        jjtree.openNodeScope(jjtn003);
-      try {
-        PrimaryExpression();
-      } catch (Throwable jjte003) {
-                        if (jjtc003) {
-                          jjtree.clearNodeScope(jjtn003);
-                          jjtc003 = false;
-                        } else {
-                          jjtree.popNode();
-                        }
-                        if (jjte003 instanceof RuntimeException) {
-                          {if (true) throw (RuntimeException)jjte003;}
-                        }
-                        if (jjte003 instanceof ParseException) {
-                          {if (true) throw (ParseException)jjte003;}
-                        }
-                        {if (true) throw (Error)jjte003;}
-      } finally {
-                        if (jjtc003) {
-                          jjtree.closeNodeScope(jjtn003,  1);
-                        }
-      }
-      break;
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-    case BNODE_LABEL:
-    case VAR1:
-    case VAR2:
-    case INTEGER:
-    case DECIMAL:
-    case DOUBLE:
-    case STRING_LITERAL1:
-    case STRING_LITERAL2:
-    case STRING_LITERAL_LONG1:
-    case STRING_LITERAL_LONG2:
-    case ANON:
-    case 68:
-    case 82:
-    case 83:
-    case 84:
-    case 85:
-    case 86:
-    case 87:
-    case 88:
-    case 89:
-    case 90:
-    case 91:
-    case 93:
-    case 94:
-      PrimaryExpression();
-      break;
-    default:
-      jj_la1[66] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void PrimaryExpression() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 68:
-      BracketedExpression();
-      break;
-    case 82:
-    case 83:
-    case 84:
-    case 85:
-    case 86:
-    case 87:
-    case 88:
-    case 89:
-    case 90:
-    case 91:
-      BuiltInCall();
-      break;
-    case Q_IRI_REF:
-    case QNAME_NS:
-    case QNAME:
-      IRIrefOrFunction();
-      break;
-    case STRING_LITERAL1:
-    case STRING_LITERAL2:
-    case STRING_LITERAL_LONG1:
-    case STRING_LITERAL_LONG2:
-      RDFLiteral();
-      break;
-    case INTEGER:
-    case DECIMAL:
-    case DOUBLE:
-      PositiveLiteral();
-      break;
-    case 93:
-    case 94:
-      BooleanLiteral();
-      break;
-    case BNODE_LABEL:
-    case ANON:
-      BlankNode();
-      break;
-    case VAR1:
-    case VAR2:
-      Var();
-      break;
-    default:
-      jj_la1[67] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void BracketedExpression() throws ParseException {
-    jj_consume_token(68);
-    Expression();
-    jj_consume_token(63);
-  }
-
-  final public void BuiltInCall() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case 82:
-      jj_consume_token(82);
-      jj_consume_token(68);
-      Expression();
-                                 ASTStrFuncNode jjtn001 = new ASTStrFuncNode(JJTSTRFUNCNODE);
-                                 boolean jjtc001 = true;
-                                 jjtree.openNodeScope(jjtn001);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                 if (jjtc001) {
-                                   jjtree.closeNodeScope(jjtn001,  1);
-                                 }
-      }
-      break;
-    case 83:
-      jj_consume_token(83);
-      jj_consume_token(68);
-      Expression();
-                                            ASTLangFuncNode jjtn002 = new ASTLangFuncNode(JJTLANGFUNCNODE);
-                                            boolean jjtc002 = true;
-                                            jjtree.openNodeScope(jjtn002);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                            if (jjtc002) {
-                                              jjtree.closeNodeScope(jjtn002,  1);
-                                            }
-      }
-      break;
-    case 84:
-      jj_consume_token(84);
-      jj_consume_token(68);
-      Expression();
-      jj_consume_token(62);
-      Expression();
-                                                                    ASTLangMatchesFuncNode jjtn003 = new ASTLangMatchesFuncNode(JJTLANGMATCHESFUNCNODE);
-                                                                    boolean jjtc003 = true;
-                                                                    jjtree.openNodeScope(jjtn003);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                                                    if (jjtc003) {
-                                                                      jjtree.closeNodeScope(jjtn003,  1);
-                                                                    }
-      }
-      break;
-    case 85:
-      jj_consume_token(85);
-      jj_consume_token(68);
-      Expression();
-                                                ASTDTFuncNode jjtn004 = new ASTDTFuncNode(JJTDTFUNCNODE);
-                                                boolean jjtc004 = true;
-                                                jjtree.openNodeScope(jjtn004);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                                if (jjtc004) {
-                                                  jjtree.closeNodeScope(jjtn004,  1);
-                                                }
-      }
-      break;
-    case 86:
-      jj_consume_token(86);
-      jj_consume_token(68);
-      Var();
-                                      ASTBoundFuncNode jjtn005 = new ASTBoundFuncNode(JJTBOUNDFUNCNODE);
-                                      boolean jjtc005 = true;
-                                      jjtree.openNodeScope(jjtn005);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                      if (jjtc005) {
-                                        jjtree.closeNodeScope(jjtn005,  1);
-                                      }
-      }
-      break;
-    case 87:
-      jj_consume_token(87);
-      jj_consume_token(68);
-      Expression();
-                                             ASTURIFuncNode jjtn006 = new ASTURIFuncNode(JJTURIFUNCNODE);
-                                             boolean jjtc006 = true;
-                                             jjtree.openNodeScope(jjtn006);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                             if (jjtc006) {
-                                               jjtree.closeNodeScope(jjtn006,  1);
-                                             }
-      }
-      break;
-    case 88:
-      jj_consume_token(88);
-      jj_consume_token(68);
-      Expression();
-                                             ASTURIFuncNode jjtn007 = new ASTURIFuncNode(JJTURIFUNCNODE);
-                                             boolean jjtc007 = true;
-                                             jjtree.openNodeScope(jjtn007);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                             if (jjtc007) {
-                                               jjtree.closeNodeScope(jjtn007,  1);
-                                             }
-      }
-      break;
-    case 89:
-      jj_consume_token(89);
-      jj_consume_token(68);
-      Expression();
-                                               ASTBlankFuncNode jjtn008 = new ASTBlankFuncNode(JJTBLANKFUNCNODE);
-                                               boolean jjtc008 = true;
-                                               jjtree.openNodeScope(jjtn008);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                               if (jjtc008) {
-                                                 jjtree.closeNodeScope(jjtn008,  1);
-                                               }
-      }
-      break;
-    case 90:
-      jj_consume_token(90);
-      jj_consume_token(68);
-      Expression();
-                                                 ASTLiteralFuncNode jjtn009 = new ASTLiteralFuncNode(JJTLITERALFUNCNODE);
-                                                 boolean jjtc009 = true;
-                                                 jjtree.openNodeScope(jjtn009);
-      try {
-        jj_consume_token(63);
-      } finally {
-                                                 if (jjtc009) {
-                                                   jjtree.closeNodeScope(jjtn009,  1);
-                                                 }
-      }
-      break;
-    case 91:
-      RegexExpression();
-      break;
-    default:
-      jj_la1[68] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void RegexExpression() throws ParseException {
- /*@bgen(jjtree) RegexFuncNode */
-  ASTRegexFuncNode jjtn000 = new ASTRegexFuncNode(JJTREGEXFUNCNODE);
-  boolean jjtc000 = true;
-  jjtree.openNodeScope(jjtn000);
-    try {
-      jj_consume_token(91);
-      jj_consume_token(68);
-      Expression();
-      jj_consume_token(62);
-      Expression();
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 62:
-        jj_consume_token(62);
-        Expression();
-        break;
-      default:
-        jj_la1[69] = jj_gen;
-        ;
-      }
-      jj_consume_token(63);
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void IRIrefOrFunction() throws ParseException {
-    IRIref();
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case FUNCTION_PAREN:
-                    ASTFunctionCall jjtn001 = new ASTFunctionCall(JJTFUNCTIONCALL);
-                    boolean jjtc001 = true;
-                    jjtree.openNodeScope(jjtn001);
-      try {
-        ArgList();
-      } catch (Throwable jjte001) {
-                    if (jjtc001) {
-                      jjtree.clearNodeScope(jjtn001);
-                      jjtc001 = false;
-                    } else {
-                      jjtree.popNode();
-                    }
-                    if (jjte001 instanceof RuntimeException) {
-                      {if (true) throw (RuntimeException)jjte001;}
-                    }
-                    if (jjte001 instanceof ParseException) {
-                      {if (true) throw (ParseException)jjte001;}
-                    }
-                    {if (true) throw (Error)jjte001;}
-      } finally {
-                    if (jjtc001) {
-                      jjtree.closeNodeScope(jjtn001,  2);
-                    }
-      }
-      break;
-    default:
-      jj_la1[70] = jj_gen;
-      ;
-    }
-  }
-
-  final public void RDFLiteral() throws ParseException {
- /*@bgen(jjtree) Literal */
-ASTLiteral jjtn000 = new ASTLiteral(JJTLITERAL);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token label, language;
-String literal;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case STRING_LITERAL1:
-        label = jj_consume_token(STRING_LITERAL1);
-                                                literal = label.image.substring(1, label.image.length() - 1);
-        break;
-      case STRING_LITERAL2:
-        label = jj_consume_token(STRING_LITERAL2);
-                                            literal = label.image.substring(1, label.image.length() - 1);
-        break;
-      case STRING_LITERAL_LONG1:
-        label = jj_consume_token(STRING_LITERAL_LONG1);
-                                                 literal = label.image.substring(3, label.image.length() - 3);
-        break;
-      case STRING_LITERAL_LONG2:
-        label = jj_consume_token(STRING_LITERAL_LONG2);
-                                                 literal = label.image.substring(3, label.image.length() - 3);
-        break;
-      default:
-        jj_la1[71] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-                                        // Escape all the escape characters
-                                        jjtn000.setLabel(SPARQLParser.unescape(literal));
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case LANGTAG:
-      case 92:
-        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-        case LANGTAG:
-          language = jj_consume_token(LANGTAG);
-                                       jjtn000.setLanguage(language.image.substring(1));
-          break;
-        case 92:
-          jj_consume_token(92);
-          IRIref();
-          break;
-        default:
-          jj_la1[72] = jj_gen;
-          jj_consume_token(-1);
-          throw new ParseException();
-        }
-        break;
-      default:
-        jj_la1[73] = jj_gen;
-        ;
-      }
-    } catch (Throwable jjte000) {
-          if (jjtc000) {
-            jjtree.clearNodeScope(jjtn000);
-            jjtc000 = false;
-          } else {
-            jjtree.popNode();
-          }
-          if (jjte000 instanceof RuntimeException) {
-            {if (true) throw (RuntimeException)jjte000;}
-          }
-          if (jjte000 instanceof ParseException) {
-            {if (true) throw (ParseException)jjte000;}
-          }
-          {if (true) throw (Error)jjte000;}
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void NegativeLiteral() throws ParseException {
- /*@bgen(jjtree) Literal */
-ASTLiteral jjtn000 = new ASTLiteral(JJTLITERAL);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token number;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case INTEGER:
-        number = jj_consume_token(INTEGER);
-                  jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#integer");
-        break;
-      case DECIMAL:
-        number = jj_consume_token(DECIMAL);
-                  jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#decimal");
-        break;
-      case DOUBLE:
-        number = jj_consume_token(DOUBLE);
-                  jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#double");
-        break;
-      default:
-        jj_la1[74] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setLabel("-" + number.image);
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void PositiveLiteral() throws ParseException {
- /*@bgen(jjtree) Literal */
-ASTLiteral jjtn000 = new ASTLiteral(JJTLITERAL);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token number;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case INTEGER:
-        number = jj_consume_token(INTEGER);
-                  jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#integer");
-        break;
-      case DECIMAL:
-        number = jj_consume_token(DECIMAL);
-                  jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#decimal");
-        break;
-      case DOUBLE:
-        number = jj_consume_token(DOUBLE);
-                  jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#double");
-        break;
-      default:
-        jj_la1[75] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setLabel(number.image);
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void BooleanLiteral() throws ParseException {
- /*@bgen(jjtree) Literal */
-ASTLiteral jjtn000 = new ASTLiteral(JJTLITERAL);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token bool;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case 93:
-        bool = jj_consume_token(93);
-        break;
-      case 94:
-        bool = jj_consume_token(94);
-        break;
-      default:
-        jj_la1[76] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setLabel(bool.image);
-                jjtn000.setDatatype("http://www.w3.org/2001/XMLSchema#boolean");
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void IRIref() throws ParseException {
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case Q_IRI_REF:
-      QuotedIRIref();
-      break;
-    case QNAME_NS:
-    case QNAME:
-      QName();
-      break;
-    default:
-      jj_la1[77] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void QName() throws ParseException {
- /*@bgen(jjtree) QName */
-ASTQName jjtn000 = new ASTQName(JJTQNAME);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token qName;
-    try {
-      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-      case QNAME:
-        qName = jj_consume_token(QNAME);
-        break;
-      case QNAME_NS:
-        qName = jj_consume_token(QNAME_NS);
-        break;
-      default:
-        jj_la1[78] = jj_gen;
-        jj_consume_token(-1);
-        throw new ParseException();
-      }
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setNamespace(qName.image.substring(0, qName.image.indexOf(':')));
-                jjtn000.setLocalName(qName.image.substring(qName.image.indexOf(':') + 1));
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final public void BlankNode() throws ParseException {
-Token nodeLabel;
-    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
-    case BNODE_LABEL:
-          ASTLabeledBlankNode jjtn001 = new ASTLabeledBlankNode(JJTLABELEDBLANKNODE);
-          boolean jjtc001 = true;
-          jjtree.openNodeScope(jjtn001);
-      try {
-        nodeLabel = jj_consume_token(BNODE_LABEL);
-                                      jjtree.closeNodeScope(jjtn001, true);
-                                      jjtc001 = false;
-                                     jjtn001.setID(nodeLabel.image.substring(2));
-      } finally {
-          if (jjtc001) {
-            jjtree.closeNodeScope(jjtn001, true);
-          }
-      }
-      break;
-    case ANON:
-          ASTGenericBlankNode jjtn002 = new ASTGenericBlankNode(JJTGENERICBLANKNODE);
-          boolean jjtc002 = true;
-          jjtree.openNodeScope(jjtn002);
-      try {
-        jj_consume_token(ANON);
-      } finally {
-          if (jjtc002) {
-            jjtree.closeNodeScope(jjtn002, true);
-          }
-      }
-      break;
-    default:
-      jj_la1[79] = jj_gen;
-      jj_consume_token(-1);
-      throw new ParseException();
-    }
-  }
-
-  final public void QuotedIRIref() throws ParseException {
- /*@bgen(jjtree) QuotedIRIref */
-ASTQuotedIRIref jjtn000 = new ASTQuotedIRIref(JJTQUOTEDIRIREF);
-boolean jjtc000 = true;
-jjtree.openNodeScope(jjtn000);Token qRef;
-    try {
-      qRef = jj_consume_token(Q_IRI_REF);
-          jjtree.closeNodeScope(jjtn000, true);
-          jjtc000 = false;
-          jjtn000.setQRef(qRef.image.substring(1, qRef.image.length() - 1));
-    } finally {
-          if (jjtc000) {
-            jjtree.closeNodeScope(jjtn000, true);
-          }
-    }
-  }
-
-  final private boolean jj_2_1(int xla) {
-    jj_la = xla; jj_lastpos = jj_scanpos = token;
-    try { return !jj_3_1(); }
-    catch(LookaheadSuccess ls) { return true; }
-    finally { jj_save(0, xla); }
-  }
-
-  final private boolean jj_2_2(int xla) {
-    jj_la = xla; jj_lastpos = jj_scanpos = token;
-    try { return !jj_3_2(); }
-    catch(LookaheadSuccess ls) { return true; }
-    finally { jj_save(1, xla); }
-  }
-
-  final private boolean jj_2_3(int xla) {
-    jj_la = xla; jj_lastpos = jj_scanpos = token;
-    try { return !jj_3_3(); }
-    catch(LookaheadSuccess ls) { return true; }
-    finally { jj_save(2, xla); }
-  }
-
-  final private boolean jj_2_4(int xla) {
-    jj_la = xla; jj_lastpos = jj_scanpos = token;
-    try { return !jj_3_4(); }
-    catch(LookaheadSuccess ls) { return true; }
-    finally { jj_save(3, xla); }
-  }
-
-  final private boolean jj_3R_128() {
-    if (jj_3R_67()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_127() {
-    if (jj_3R_65()) return true;
-    return false;
-  }
-
-  final private boolean jj_3_1() {
-    if (jj_3R_17()) return true;
-    if (jj_3R_18()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_75() {
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_126() {
-    if (jj_3R_64()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_29() {
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    if (jj_scan_token(63)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_125() {
-    if (jj_3R_131()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_124() {
-    if (jj_3R_30()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_116() {
-    if (jj_3R_120()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_115() {
-    if (jj_scan_token(71)) return true;
-    if (jj_3R_120()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_114() {
-    if (jj_scan_token(70)) return true;
-    if (jj_3R_120()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_123() {
-    if (jj_3R_29()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_120() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_123()) {
-    jj_scanpos = xsp;
-    if (jj_3R_124()) {
-    jj_scanpos = xsp;
-    if (jj_3R_125()) {
-    jj_scanpos = xsp;
-    if (jj_3R_126()) {
-    jj_scanpos = xsp;
-    if (jj_3R_127()) {
-    jj_scanpos = xsp;
-    if (jj_3R_128()) {
-    jj_scanpos = xsp;
-    if (jj_3R_129()) {
-    jj_scanpos = xsp;
-    if (jj_3R_130()) return true;
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_24() {
-    if (jj_3R_31()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_49() {
-    if (jj_scan_token(FUNCTION_PAREN)) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_75()) jj_scanpos = xsp;
-    if (jj_scan_token(63)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_122() {
-    if (jj_scan_token(80)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_113() {
-    if (jj_scan_token(81)) return true;
-    if (jj_3R_120()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_111() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_113()) {
-    jj_scanpos = xsp;
-    if (jj_3R_114()) {
-    jj_scanpos = xsp;
-    if (jj_3R_115()) {
-    jj_scanpos = xsp;
-    if (jj_3R_116()) return true;
-    }
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_31() {
-    if (jj_3R_48()) return true;
-    if (jj_3R_49()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_21() {
-    if (jj_3R_31()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_121() {
-    if (jj_scan_token(42)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_119() {
-    if (jj_scan_token(71)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_117() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_121()) {
-    jj_scanpos = xsp;
-    if (jj_3R_122()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_104() {
-    if (jj_3R_111()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_117()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_23() {
-    if (jj_3R_30()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_110() {
-    if (jj_scan_token(79)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_109() {
-    if (jj_scan_token(78)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_118() {
-    if (jj_scan_token(70)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_112() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_118()) {
-    jj_scanpos = xsp;
-    if (jj_3R_119()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_108() {
-    if (jj_scan_token(77)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_107() {
-    if (jj_scan_token(76)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_106() {
-    if (jj_scan_token(75)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_20() {
-    if (jj_3R_30()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_102() {
-    if (jj_3R_104()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_112()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_101() {
-    if (jj_3R_102()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_93() {
-    if (jj_scan_token(72)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_105() {
-    if (jj_scan_token(74)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_103() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_105()) {
-    jj_scanpos = xsp;
-    if (jj_3R_106()) {
-    jj_scanpos = xsp;
-    if (jj_3R_107()) {
-    jj_scanpos = xsp;
-    if (jj_3R_108()) {
-    jj_scanpos = xsp;
-    if (jj_3R_109()) {
-    jj_scanpos = xsp;
-    if (jj_3R_110()) return true;
-    }
-    }
-    }
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_22() {
-    if (jj_3R_29()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_100() {
-    if (jj_scan_token(73)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_73() {
-    if (jj_scan_token(Q_IRI_REF)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_99() {
-    if (jj_3R_101()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_103()) jj_scanpos = xsp;
-    return false;
-  }
-
-  final private boolean jj_3R_19() {
-    if (jj_3R_29()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_88() {
-    if (jj_scan_token(ANON)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_92() {
-    if (jj_3R_99()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_87() {
-    if (jj_scan_token(BNODE_LABEL)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_68() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_87()) {
-    jj_scanpos = xsp;
-    if (jj_3R_88()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_63() {
-    if (jj_3R_74()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_72() {
-    if (jj_3R_92()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_100()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_74() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(13)) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(12)) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_60() {
-    if (jj_3R_72()) return true;
-    Token xsp;
-    while (true) {
-      xsp = jj_scanpos;
-      if (jj_3R_93()) { jj_scanpos = xsp; break; }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_57() {
-    if (jj_scan_token(NIL)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_56() {
-    if (jj_3R_68()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_55() {
-    if (jj_3R_67()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_54() {
-    if (jj_scan_token(71)) return true;
-    if (jj_3R_66()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_37() {
-    if (jj_3R_60()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_53() {
-    if (jj_scan_token(70)) return true;
-    if (jj_3R_65()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_48() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_62()) {
-    jj_scanpos = xsp;
-    if (jj_3R_63()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_62() {
-    if (jj_3R_73()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_52() {
-    if (jj_3R_65()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_51() {
-    if (jj_3R_64()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_67() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(93)) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(94)) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_33() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_50()) {
-    jj_scanpos = xsp;
-    if (jj_3R_51()) {
-    jj_scanpos = xsp;
-    if (jj_3R_52()) {
-    jj_scanpos = xsp;
-    if (jj_3R_53()) {
-    jj_scanpos = xsp;
-    if (jj_3R_54()) {
-    jj_scanpos = xsp;
-    if (jj_3R_55()) {
-    jj_scanpos = xsp;
-    if (jj_3R_56()) {
-    jj_scanpos = xsp;
-    if (jj_3R_57()) return true;
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_50() {
-    if (jj_3R_48()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_83() {
-    if (jj_scan_token(DOUBLE)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_82() {
-    if (jj_scan_token(DECIMAL)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_81() {
-    if (jj_scan_token(INTEGER)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_32() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_scan_token(15)) {
-    jj_scanpos = xsp;
-    if (jj_scan_token(16)) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_70() {
-    if (jj_3R_48()) return true;
-    return false;
-  }
-
-  final private boolean jj_3_4() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_22()) {
-    jj_scanpos = xsp;
-    if (jj_3R_23()) {
-    jj_scanpos = xsp;
-    if (jj_3R_24()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_65() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_81()) {
-    jj_scanpos = xsp;
-    if (jj_3R_82()) {
-    jj_scanpos = xsp;
-    if (jj_3R_83()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_86() {
-    if (jj_scan_token(DOUBLE)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_26() {
-    if (jj_3R_33()) return true;
-    return false;
-  }
-
-  final private boolean jj_3_3() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_19()) {
-    jj_scanpos = xsp;
-    if (jj_3R_20()) {
-    jj_scanpos = xsp;
-    if (jj_3R_21()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_91() {
-    if (jj_3R_98()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_85() {
-    if (jj_scan_token(DECIMAL)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_58() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_69()) {
-    jj_scanpos = xsp;
-    if (jj_3_4()) {
-    jj_scanpos = xsp;
-    if (jj_3R_70()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_69() {
-    if (jj_3R_32()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_84() {
-    if (jj_scan_token(INTEGER)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_59() {
-    if (jj_3R_71()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_17() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_25()) {
-    jj_scanpos = xsp;
-    if (jj_3_3()) {
-    jj_scanpos = xsp;
-    if (jj_3R_26()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_25() {
-    if (jj_3R_32()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_66() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_84()) {
-    jj_scanpos = xsp;
-    if (jj_3R_85()) {
-    jj_scanpos = xsp;
-    if (jj_3R_86()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_95() {
-    if (jj_scan_token(92)) return true;
-    if (jj_3R_48()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_94() {
-    if (jj_scan_token(LANGTAG)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_80() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_94()) {
-    jj_scanpos = xsp;
-    if (jj_3R_95()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_36() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3_2()) {
-    jj_scanpos = xsp;
-    if (jj_3R_59()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3_2() {
-    if (jj_3R_17()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_79() {
-    if (jj_scan_token(STRING_LITERAL_LONG2)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_98() {
-    if (jj_scan_token(69)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_78() {
-    if (jj_scan_token(STRING_LITERAL_LONG1)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_90() {
-    if (jj_3R_97()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_77() {
-    if (jj_scan_token(STRING_LITERAL2)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_76() {
-    if (jj_scan_token(STRING_LITERAL1)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_96() {
-    if (jj_scan_token(68)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_35() {
-    if (jj_scan_token(65)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_132() {
-    if (jj_3R_49()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_97() {
-    if (jj_scan_token(66)) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_64() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_76()) {
-    jj_scanpos = xsp;
-    if (jj_3R_77()) {
-    jj_scanpos = xsp;
-    if (jj_3R_78()) {
-    jj_scanpos = xsp;
-    if (jj_3R_79()) return true;
-    }
-    }
-    }
-    xsp = jj_scanpos;
-    if (jj_3R_80()) jj_scanpos = xsp;
-    return false;
-  }
-
-  final private boolean jj_3R_89() {
-    if (jj_3R_96()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_71() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_89()) {
-    jj_scanpos = xsp;
-    if (jj_3R_90()) {
-    jj_scanpos = xsp;
-    if (jj_3R_91()) return true;
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_131() {
-    if (jj_3R_48()) return true;
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_132()) jj_scanpos = xsp;
-    return false;
-  }
-
-  final private boolean jj_3R_34() {
-    if (jj_3R_58()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_27() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_34()) {
-    jj_scanpos = xsp;
-    if (jj_3R_35()) return true;
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_47() {
-    if (jj_3R_61()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_46() {
-    if (jj_scan_token(90)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_45() {
-    if (jj_scan_token(89)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_44() {
-    if (jj_scan_token(88)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_43() {
-    if (jj_scan_token(87)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_61() {
-    if (jj_scan_token(91)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_28() {
-    if (jj_3R_36()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_42() {
-    if (jj_scan_token(86)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_32()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_41() {
-    if (jj_scan_token(85)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_40() {
-    if (jj_scan_token(84)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_39() {
-    if (jj_scan_token(83)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_18() {
-    if (jj_3R_27()) return true;
-    if (jj_3R_28()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_38() {
-    if (jj_scan_token(82)) return true;
-    if (jj_scan_token(68)) return true;
-    if (jj_3R_37()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_30() {
-    Token xsp;
-    xsp = jj_scanpos;
-    if (jj_3R_38()) {
-    jj_scanpos = xsp;
-    if (jj_3R_39()) {
-    jj_scanpos = xsp;
-    if (jj_3R_40()) {
-    jj_scanpos = xsp;
-    if (jj_3R_41()) {
-    jj_scanpos = xsp;
-    if (jj_3R_42()) {
-    jj_scanpos = xsp;
-    if (jj_3R_43()) {
-    jj_scanpos = xsp;
-    if (jj_3R_44()) {
-    jj_scanpos = xsp;
-    if (jj_3R_45()) {
-    jj_scanpos = xsp;
-    if (jj_3R_46()) {
-    jj_scanpos = xsp;
-    if (jj_3R_47()) return true;
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    }
-    return false;
-  }
-
-  final private boolean jj_3R_130() {
-    if (jj_3R_32()) return true;
-    return false;
-  }
-
-  final private boolean jj_3R_129() {
-    if (jj_3R_68()) return true;
-    return false;
-  }
-
-  public SPARQLParserTokenManager token_source;
-  JavaCharStream jj_input_stream;
-  public Token token, jj_nt;
-  private int jj_ntk;
-  private Token jj_scanpos, jj_lastpos;
-  private int jj_la;
-  public boolean lookingAhead = false;
-  private boolean jj_semLA;
-  private int jj_gen;
-  final private int[] jj_la1 = new int[80];
-  static private int[] jj_la1_0;
-  static private int[] jj_la1_1;
-  static private int[] jj_la1_2;
-  static {
-      jj_la1_0();
-      jj_la1_1();
-      jj_la1_2();
-   }
-   private static void jj_la1_0() {
-      jj_la1_0 = new int[] {0x0,0x0,0x0,0x0,0x3800,0x1b800,0x1b800,0x1b800,0x0,0x0,0x0,0x1b800,0x1b800,0x0,0x0,0x0,0x3800,0x0,0x0,0x0,0x0,0x1b800,0x0,0x1b800,0x1b800,0x0,0x0,0x7fdf800,0x0,0x0,0x0,0x7fdf800,0x0,0x0,0x3800,0x0,0x5fdf800,0x0,0x0,0x7fdf800,0x1b800,0x0,0x1b800,0x0,0x0,0x1b800,0x0,0x7fdf800,0x0,0x3800,0x18000,0x7fc7800,0x3800,0x18000,0x3800,0x401f800,0x18000,0x7fc7800,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x5fdf800,0x5fdf800,0x0,0x0,0x200,0x1e00000,0x20000,0x20000,0x1c0000,0x1c0000,0x0,0x3800,0x3000,0x4004000,};
-   }
-   private static void jj_la1_1() {
-      jj_la1_1 = new int[] {0x3900,0x40,0x80,0x200,0x0,0x0,0x0,0x400,0x4000,0x200,0x4000,0x0,0x400,0x4000,0x810000,0x4000,0x8000,0x10000,0x20000,0x200000,0x400000,0x180000,0x180000,0x0,0x180000,0x2000000,0xc800000,0x0,0x2000000,0x20000000,0x2000000,0x0,0xc800000,0x10000000,0x0,0x40000000,0x0,0x400,0x2000000,0x0,0x0,0x0,0x0,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x400,0x400,0x0,0x0,0x0,0x40000000,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,};
-   }
-   private static void jj_la1_2() {
-      jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0xffc0010,0xffc0010,0xffc0010,0xffc0010,0x0,0x0,0x0,0xffc0010,0xffc0010,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x10,0x0,0x10,0x10,0x0,0x0,0x6ffc00f4,0x0,0x0,0x0,0x6ffc00f4,0x0,0x0,0xffc0010,0x0,0x6ffe00d0,0x0,0x0,0x6ffc00f4,0xffc0012,0x34,0xffc0012,0x1,0x0,0xffc0012,0x34,0x6ffc00f4,0x34,0xffc0010,0x0,0x600000c0,0xffc0010,0x0,0x0,0x0,0x0,0x600000c0,0x100,0x200,0xfc00,0xfc00,0xc0,0xc0,0x10000,0x10000,0x6ffe00d0,0x6ffc0010,0xffc0000,0x0,0x0,0x0,0x10000000,0x10000000,0x0,0x0,0x60000000,0x0,0x0,0x0,};
-   }
-  final private JJCalls[] jj_2_rtns = new JJCalls[4];
-  private boolean jj_rescan = false;
-  private int jj_gc = 0;
-
-  public SPARQLParser(java.io.InputStream stream) {
-    jj_input_stream = new JavaCharStream(stream, 1, 1);
-    token_source = new SPARQLParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 80; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public void ReInit(java.io.InputStream stream) {
-    jj_input_stream.ReInit(stream, 1, 1);
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 80; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public SPARQLParser(java.io.Reader stream) {
-    jj_input_stream = new JavaCharStream(stream, 1, 1);
-    token_source = new SPARQLParserTokenManager(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 80; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public void ReInit(java.io.Reader stream) {
-    jj_input_stream.ReInit(stream, 1, 1);
-    token_source.ReInit(jj_input_stream);
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 80; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public SPARQLParser(SPARQLParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jj_gen = 0;
-    for (int i = 0; i < 80; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  public void ReInit(SPARQLParserTokenManager tm) {
-    token_source = tm;
-    token = new Token();
-    jj_ntk = -1;
-    jjtree.reset();
-    jj_gen = 0;
-    for (int i = 0; i < 80; i++) jj_la1[i] = -1;
-    for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
-  }
-
-  final private Token jj_consume_token(int kind) throws ParseException {
-    Token oldToken;
-    if ((oldToken = token).next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    if (token.kind == kind) {
-      jj_gen++;
-      if (++jj_gc > 100) {
-        jj_gc = 0;
-        for (int i = 0; i < jj_2_rtns.length; i++) {
-          JJCalls c = jj_2_rtns[i];
-          while (c != null) {
-            if (c.gen < jj_gen) c.first = null;
-            c = c.next;
-          }
-        }
-      }
-      return token;
-    }
-    token = oldToken;
-    jj_kind = kind;
-    throw generateParseException();
-  }
-
-  static private final class LookaheadSuccess extends java.lang.Error { }
-  final private LookaheadSuccess jj_ls = new LookaheadSuccess();
-  final private boolean jj_scan_token(int kind) {
-    if (jj_scanpos == jj_lastpos) {
-      jj_la--;
-      if (jj_scanpos.next == null) {
-        jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
-      } else {
-        jj_lastpos = jj_scanpos = jj_scanpos.next;
-      }
-    } else {
-      jj_scanpos = jj_scanpos.next;
-    }
-    if (jj_rescan) {
-      int i = 0; Token tok = token;
-      while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
-      if (tok != null) jj_add_error_token(kind, i);
-    }
-    if (jj_scanpos.kind != kind) return true;
-    if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
-    return false;
-  }
-
-  final public Token getNextToken() {
-    if (token.next != null) token = token.next;
-    else token = token.next = token_source.getNextToken();
-    jj_ntk = -1;
-    jj_gen++;
-    return token;
-  }
-
-  final public Token getToken(int index) {
-    Token t = lookingAhead ? jj_scanpos : token;
-    for (int i = 0; i < index; i++) {
-      if (t.next != null) t = t.next;
-      else t = t.next = token_source.getNextToken();
-    }
-    return t;
-  }
-
-  final private int jj_ntk() {
-    if ((jj_nt=token.next) == null)
-      return (jj_ntk = (token.next=token_source.getNextToken()).kind);
-    else
-      return (jj_ntk = jj_nt.kind);
-  }
-
-  private java.util.Vector jj_expentries = new java.util.Vector();
-  private int[] jj_expentry;
-  private int jj_kind = -1;
-  private int[] jj_lasttokens = new int[100];
-  private int jj_endpos;
-
-  private void jj_add_error_token(int kind, int pos) {
-    if (pos >= 100) return;
-    if (pos == jj_endpos + 1) {
-      jj_lasttokens[jj_endpos++] = kind;
-    } else if (jj_endpos != 0) {
-      jj_expentry = new int[jj_endpos];
-      for (int i = 0; i < jj_endpos; i++) {
-        jj_expentry[i] = jj_lasttokens[i];
-      }
-      boolean exists = false;
-      for (java.util.Enumeration e = jj_expentries.elements(); e.hasMoreElements();) {
-        int[] oldentry = (int[])(e.nextElement());
-        if (oldentry.length == jj_expentry.length) {
-          exists = true;
-          for (int i = 0; i < jj_expentry.length; i++) {
-            if (oldentry[i] != jj_expentry[i]) {
-              exists = false;
-              break;
-            }
-          }
-          if (exists) break;
-        }
-      }
-      if (!exists) jj_expentries.addElement(jj_expentry);
-      if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
-    }
-  }
-
-  public ParseException generateParseException() {
-    jj_expentries.removeAllElements();
-    boolean[] la1tokens = new boolean[95];
-    for (int i = 0; i < 95; i++) {
-      la1tokens[i] = false;
-    }
-    if (jj_kind >= 0) {
-      la1tokens[jj_kind] = true;
-      jj_kind = -1;
-    }
-    for (int i = 0; i < 80; i++) {
-      if (jj_la1[i] == jj_gen) {
-        for (int j = 0; j < 32; j++) {
-          if ((jj_la1_0[i] & (1<<j)) != 0) {
-            la1tokens[j] = true;
-          }
-          if ((jj_la1_1[i] & (1<<j)) != 0) {
-            la1tokens[32+j] = true;
-          }
-          if ((jj_la1_2[i] & (1<<j)) != 0) {
-            la1tokens[64+j] = true;
-          }
-        }
-      }
-    }
-    for (int i = 0; i < 95; i++) {
-      if (la1tokens[i]) {
-        jj_expentry = new int[1];
-        jj_expentry[0] = i;
-        jj_expentries.addElement(jj_expentry);
-      }
-    }
-    jj_endpos = 0;
-    jj_rescan_token();
-    jj_add_error_token(0, 0);
-    int[][] exptokseq = new int[jj_expentries.size()][];
-    for (int i = 0; i < jj_expentries.size(); i++) {
-      exptokseq[i] = (int[])jj_expentries.elementAt(i);
-    }
-    return new ParseException(token, exptokseq, tokenImage);
-  }
-
-  final public void enable_tracing() {
-  }
-
-  final public void disable_tracing() {
-  }
-
-  final private void jj_rescan_token() {
-    jj_rescan = true;
-    for (int i = 0; i < 4; i++) {
-      JJCalls p = jj_2_rtns[i];
-      do {
-        if (p.gen > jj_gen) {
-          jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
-          switch (i) {
-            case 0: jj_3_1(); break;
-            case 1: jj_3_2(); break;
-            case 2: jj_3_3(); break;
-            case 3: jj_3_4(); break;
-          }
-        }
-        p = p.next;
-      } while (p != null);
-    }
-    jj_rescan = false;
-  }
-
-  final private void jj_save(int index, int xla) {
-    JJCalls p = jj_2_rtns[index];
-    while (p.gen > jj_gen) {
-      if (p.next == null) { p = p.next = new JJCalls(); break; }
-      p = p.next;
-    }
-    p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
-  }
-
-  static final class JJCalls {
-    int gen;
-    Token first;
-    int arg;
-    JJCalls next;
-  }
-
-}
+                                switch (current) {
+                                        case '\\':
+                                                escaped = true;
+                                                break;
+                                        default:
+                                                unescapedString.append(current);
+                                }
+                        }
+                }
+                return unescapedString.toString();
+        }
+
+  final public Node Query() throws ParseException {
+ /*@bgen(jjtree) QueryContainer */
+  ASTQueryContainer jjtn000 = new ASTQueryContainer(JJTQUERYCONTAINER);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      Prologue();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 38:
+        SelectQuery();
+        break;
+      case 42:
+        ConstructQuery();
+        break;
+      case 43:
+        DescribeQuery();
+        break;
+      case 44:
+        AskQuery();
+        break;
+      default:
+        jj_la1[0] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      jj_consume_token(0);
+          jjtree.closeNodeScope(jjtn000, true);
+          jjtc000 = false;
+          {if (true) return jjtn000.jjtGetChild(jjtn000.jjtGetNumChildren() - 1);}
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+    throw new Error("Missing return statement in function");
+  }
+
+  final public void Prologue() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 36:
+      BaseDecl();
+      break;
+    default:
+      jj_la1[1] = jj_gen;
+      ;
+    }
+    label_1:
+    while (true) {
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 37:
+        ;
+        break;
+      default:
+        jj_la1[2] = jj_gen;
+        break label_1;
+      }
+      PrefixDecl();
+    }
+  }
+
+  final public void BaseDecl() throws ParseException {
+                         /*@bgen(jjtree) Base */
+  ASTBase jjtn000 = new ASTBase(JJTBASE);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(36);
+      QuotedIRIref();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void PrefixDecl() throws ParseException {
+ /*@bgen(jjtree) Prefix */
+        ASTPrefix jjtn000 = new ASTPrefix(JJTPREFIX);
+        boolean jjtc000 = true;
+        jjtree.openNodeScope(jjtn000);Token qName;
+    try {
+      jj_consume_token(37);
+      qName = jj_consume_token(PNAME_NS);
+      QuotedIRIref();
+          jjtree.closeNodeScope(jjtn000, true);
+          jjtc000 = false;
+         jjtn000.setPrefix(qName.image.substring(0, qName.image.indexOf(':')));
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void SelectQuery() throws ParseException {
+ /*@bgen(jjtree) SelectQuery */
+  ASTSelectQuery jjtn000 = new ASTSelectQuery(JJTSELECTQUERY);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(38);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 39:
+      case 40:
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 39:
+          jj_consume_token(39);
+                               jjtn000.setDistinct(true);
+          break;
+        case 40:
+          jj_consume_token(40);
+                                                                          jjtn000.setReduced(true);
+          break;
+        default:
+          jj_la1[3] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+        break;
+      default:
+        jj_la1[4] = jj_gen;
+        ;
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case VAR1:
+      case VAR2:
+        label_2:
+        while (true) {
+          Var();
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case VAR1:
+          case VAR2:
+            ;
+            break;
+          default:
+            jj_la1[5] = jj_gen;
+            break label_2;
+          }
+        }
+        break;
+      case 41:
+        jj_consume_token(41);
+        break;
+      default:
+        jj_la1[6] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      label_3:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 45:
+          ;
+          break;
+        default:
+          jj_la1[7] = jj_gen;
+          break label_3;
+        }
+        DatasetClause();
+      }
+      WhereClause();
+      SolutionModifier();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void ConstructQuery() throws ParseException {
+ /*@bgen(jjtree) ConstructQuery */
+  ASTConstructQuery jjtn000 = new ASTConstructQuery(JJTCONSTRUCTQUERY);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(42);
+      ConstructTemplate();
+      label_4:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 45:
+          ;
+          break;
+        default:
+          jj_la1[8] = jj_gen;
+          break label_4;
+        }
+        DatasetClause();
+      }
+      WhereClause();
+      SolutionModifier();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void DescribeQuery() throws ParseException {
+ /*@bgen(jjtree) DescribeQuery */
+  ASTDescribeQuery jjtn000 = new ASTDescribeQuery(JJTDESCRIBEQUERY);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(43);
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case IRI_REF:
+      case PNAME_NS:
+      case QNAME:
+      case VAR1:
+      case VAR2:
+        label_5:
+        while (true) {
+          VarOrIRIref();
+          switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+          case IRI_REF:
+          case PNAME_NS:
+          case QNAME:
+          case VAR1:
+          case VAR2:
+            ;
+            break;
+          default:
+            jj_la1[9] = jj_gen;
+            break label_5;
+          }
+        }
+        break;
+      case 41:
+        jj_consume_token(41);
+        break;
+      default:
+        jj_la1[10] = jj_gen;
+        jj_consume_token(-1);
+        throw new ParseException();
+      }
+      label_6:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 45:
+          ;
+          break;
+        default:
+          jj_la1[11] = jj_gen;
+          break label_6;
+        }
+        DatasetClause();
+      }
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 47:
+      case 54:
+        WhereClause();
+        break;
+      default:
+        jj_la1[12] = jj_gen;
+        ;
+      }
+      SolutionModifier();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void AskQuery() throws ParseException {
+ /*@bgen(jjtree) AskQuery */
+  ASTAskQuery jjtn000 = new ASTAskQuery(JJTASKQUERY);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(44);
+      label_7:
+      while (true) {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 45:
+          ;
+          break;
+        default:
+          jj_la1[13] = jj_gen;
+          break label_7;
+        }
+        DatasetClause();
+      }
+      WhereClause();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void DatasetClause() throws ParseException {
+    jj_consume_token(45);
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case IRI_REF:
+    case PNAME_NS:
+    case QNAME:
+      DefaultGraphClause();
+      break;
+    case 46:
+      NamedGraphClause();
+      break;
+    default:
+      jj_la1[14] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+  final public void DefaultGraphClause() throws ParseException {
+ /*@bgen(jjtree) DefaultGraph */
+  ASTDefaultGraph jjtn000 = new ASTDefaultGraph(JJTDEFAULTGRAPH);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      SourceSelector();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void NamedGraphClause() throws ParseException {
+ /*@bgen(jjtree) NamedGraph */
+  ASTNamedGraph jjtn000 = new ASTNamedGraph(JJTNAMEDGRAPH);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(46);
+      SourceSelector();
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void SourceSelector() throws ParseException {
+    IRIref();
+  }
+
+  final public void WhereClause() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 47:
+      jj_consume_token(47);
+      break;
+    default:
+      jj_la1[15] = jj_gen;
+      ;
+    }
+    GroupGraphPattern();
+  }
+
+  final public void SolutionModifier() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 48:
+      OrderClause();
+      break;
+    default:
+      jj_la1[16] = jj_gen;
+      ;
+    }
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 52:
+    case 53:
+      LimitOffsetClauses();
+      break;
+    default:
+      jj_la1[17] = jj_gen;
+      ;
+    }
+  }
+
+  final public void LimitOffsetClauses() throws ParseException {
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 52:
+      LimitClause();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 53:
+        OffsetClause();
+        break;
+      default:
+        jj_la1[18] = jj_gen;
+        ;
+      }
+      break;
+    case 53:
+      OffsetClause();
+      switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+      case 52:
+        LimitClause();
+        break;
+      default:
+        jj_la1[19] = jj_gen;
+        ;
+      }
+      break;
+    default:
+      jj_la1[20] = jj_gen;
+      jj_consume_token(-1);
+      throw new ParseException();
+    }
+  }
+
+  final public void OrderClause() throws ParseException {
+ /*@bgen(jjtree) OrderConditions */
+  ASTOrderConditions jjtn000 = new ASTOrderConditions(JJTORDERCONDITIONS);
+  boolean jjtc000 = true;
+  jjtree.openNodeScope(jjtn000);
+    try {
+      jj_consume_token(48);
+      jj_consume_token(49);
+      label_8:
+      while (true) {
+        OrderCondition();
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case IRI_REF:
+        case PNAME_NS:
+        case QNAME:
+        case VAR1:
+        case VAR2:
+        case 50:
+        case 51:
+        case 61:
+        case 80:
+        case 81:
+        case 82:
+        case 83:
+        case 84:
+        case 85:
+        case 86:
+        case 87:
+        case 88:
+        case 89:
+        case 90:
+          ;
+          break;
+        default:
+          jj_la1[21] = jj_gen;
+          break label_8;
+        }
+      }
+    } catch (Throwable jjte000) {
+          if (jjtc000) {
+            jjtree.clearNodeScope(jjtn000);
+            jjtc000 = false;
+          } else {
+            jjtree.popNode();
+          }
+          if (jjte000 instanceof RuntimeException) {
+            {if (true) throw (RuntimeException)jjte000;}
+          }
+          if (jjte000 instanceof ParseException) {
+            {if (true) throw (ParseException)jjte000;}
+          }
+          {if (true) throw (Error)jjte000;}
+    } finally {
+          if (jjtc000) {
+            jjtree.closeNodeScope(jjtn000, true);
+          }
+    }
+  }
+
+  final public void OrderCondition() throws ParseException {
+boolean ascending = true;
+    switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+    case 50:
+    case 51:
+            ASTDescOrder jjtn002 = new ASTDescOrder(JJTDESCORDER);
+            boolean jjtc002 = true;
+            jjtree.openNodeScope(jjtn002);
+      try {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 50:
+          jj_consume_token(50);
+          break;
+        case 51:
+          jj_consume_token(51);
+                              ascending = false;
+          break;
+        default:
+          jj_la1[22] = jj_gen;
+          jj_consume_token(-1);
+          throw new ParseException();
+        }
+                                                      ASTAscOrder jjtn001 = new ASTAscOrder(JJTASCORDER);
+                                                      boolean jjtc001 = true;
+                                                      jjtree.openNodeScope(jjtn001);
+        try {
+          BracketedExpression();
+        } catch (Throwable jjte001) {
+                                                      if (jjtc001) {
+                                                        jjtree.clearNodeScope(jjtn001);
+                                                        jjtc001 = false;
+                                                      } else {
+                                                        jjtree.popNode();
+                                                      }
+                                                      if (jjte001 instanceof RuntimeException) {
+                                                        {if (true) throw (RuntimeException)jjte001;}
+                                                      }
+                                                      if (jjte001 instanceof ParseException) {
+                                                        {if (true) throw (ParseException)jjte001;}
+                                                      }
+                                                      {if (true) throw (Error)jjte001;}
+        } finally {
+                                                      if (jjtc001) {
+                                                        jjtree.closeNodeScope(jjtn001,  ascending);
+                                                      }
+        }
+      } catch (Throwable jjte002) {
+            if (jjtc002) {
+              jjtree.clearNodeScope(jjtn002);
+              jjtc002 = false;
+            } else {
+              jjtree.popNode();
+            }
+            if (jjte002 instanceof RuntimeException) {
+              {if (true) throw (RuntimeException)jjte002;}
+            }
+            if (jjte002 instanceof ParseException) {
+              {if (true) throw (ParseException)jjte002;}
+            }
+            {if (true) throw (Error)jjte002;}
+      } finally {
+            if (jjtc002) {
+              jjtree.closeNodeScope(jjtn002,  ! ascending);
+            }
+      }
+      break;
+    case IRI_REF:
+    case PNAME_NS:
+    case QNAME:
+    case VAR1:
+    case VAR2:
+    case 61:
+    case 80:
+    case 81:
+    case 82:
+    case 83:
+    case 84:
+    case 85:
+    case 86:
+    case 87:
+    case 88:
+    case 89:
+    case 90:
+                      ASTDefaultOrder jjtn003 = new ASTDefaultOrder(JJTDEFAULTORDER);
+                      boolean jjtc003 = true;
+                      jjtree.openNodeScope(jjtn003);
+      try {
+        switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
+        case 80:
+        case 81:
+        