[Mulgara-svn] r856 - in trunk: . lib src/jar src/jar/itql src/jar/krule/java/org/mulgara/krule src/jar/parser src/jar/query/java/org/mulgara/connection src/jar/query/java/org/mulgara/query src/jar/query/java/org/mulgara/query/filter src/jar/query/java/org/mulgara/query/filter/arithmetic src/jar/query/java/org/mulgara/query/filter/value src/jar/query/java/org/mulgara/query/rdf src/jar/resolver/java/org/mulgara/resolver src/jar/resolver-spi/java/org/mulgara/resolver/spi src/jar/sparql-interpreter src/jar/sparql-interpreter/java src/jar/sparql-interpreter/java/org src/jar/sparql-interpreter/java/org/mulgara src/jar/sparql-interpreter/java/org/mulgara/sparql src/jar/tuples/java/org/mulgara/store/tuples

pag at mulgara.org pag at mulgara.org
Sat Apr 26 02:17:59 UTC 2008


Author: pag
Date: 2008-04-25 19:17:54 -0700 (Fri, 25 Apr 2008)
New Revision: 856

Added:
   trunk/lib/mulgara-sparql-0.0.1.jar
   trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintOptionalJoin.java
   trunk/src/jar/query/java/org/mulgara/query/ModelVariable.java
   trunk/src/jar/query/java/org/mulgara/query/filter/
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/And.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Context.java
   trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java
   trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java
   trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Not.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Or.java
   trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java
   trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java
   trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/
   trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesContext.java
   trunk/src/jar/sparql-interpreter/
   trunk/src/jar/sparql-interpreter/build.xml
   trunk/src/jar/sparql-interpreter/java/
   trunk/src/jar/sparql-interpreter/java/org/
   trunk/src/jar/sparql-interpreter/java/org/mulgara/
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java
   trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoinUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/PartialColumnComparator.java
Removed:
   trunk/src/jar/parser/java/
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/And.java
   trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Context.java
   trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java
   trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java
   trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Not.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Or.java
   trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java
   trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java
   trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java
   trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/
   trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java
   trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java
   trunk/src/jar/sparql-interpreter/build.xml
   trunk/src/jar/sparql-interpreter/java/
   trunk/src/jar/sparql-interpreter/java/org/
   trunk/src/jar/sparql-interpreter/java/org/mulgara/
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java
   trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java
   trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties
Modified:
   trunk/.classpath
   trunk/build.properties
   trunk/build.xml
   trunk/common.xml
   trunk/src/jar/itql/build.xml
   trunk/src/jar/krule/java/org/mulgara/krule/Rule.java
   trunk/src/jar/query/java/org/mulgara/connection/CommandExecutor.java
   trunk/src/jar/query/java/org/mulgara/query/Variable.java
   trunk/src/jar/query/java/org/mulgara/query/rdf/XSD.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/ConstraintOperations.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
Log:
Added SPARQL support! This is a merge of branch mgr-61-sparql. Several features are still needed for Mulgara to fully support SPARQL, but most of the functionality is present. The main area of work is in Mulgara's storage and handling of LiteralImpl, with some other work needed for the default and empty graphs. Also a scripting framework is needed to run the SPARQL test suite.

Modified: trunk/.classpath
===================================================================
--- trunk/.classpath	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/.classpath	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,138 +1,140 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
-	<classpathentry path="src/jar/ant-task/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-distributed/java" kind="src"/>
-	<classpathentry path="src/war/webui/java" kind="src"/>
-	<classpathentry path="src/jar/descriptor/src/java" kind="src"/>
-	<classpathentry path="src/jar/client-jrdf/java" kind="src"/>
-	<classpathentry path="src/jar/content-mbox/java" kind="src"/>
-	<classpathentry path="src/jar/content-mp3/java" kind="src"/>
-	<classpathentry path="src/jar/content-n3/java" kind="src"/>
-	<classpathentry path="src/jar/content-rdfxml/java" kind="src"/>
-	<classpathentry path="src/jar/content-rio/java" kind="src"/>
-	<classpathentry path="src/jar/demo-mp3/java" kind="src"/>
-	<classpathentry path="src/jar/driver/java" kind="src"/>
-	<classpathentry path="src/jar/dtd/java" kind="src"/>
-	<classpathentry path="src/jar/itql/java" kind="src"/>
-	<classpathentry path="src/jar/itql/sablecc" kind="src"/>
-	<classpathentry path="src/jar/jrdf/java" kind="src"/>
-	<classpathentry path="src/jar/krule/java" kind="src"/>
-	<classpathentry path="src/jar/query/java" kind="src"/>
-	<classpathentry path="src/jar/resolver/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-file/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-filesystem/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-gis/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-http/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-jar/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-lucene/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-memory/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-nodetype/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-prefix/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-relational/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-spi/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-store/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-test/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-url/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-view/java" kind="src"/>
-	<classpathentry path="src/jar/resolver-xsd/java" kind="src"/>
-	<classpathentry path="src/jar/rules/java" kind="src"/>
-	<classpathentry path="src/jar/server/java" kind="src"/>
-	<classpathentry path="src/jar/server-beep/java" kind="src"/>
-	<classpathentry path="src/jar/server-http/java" kind="src"/>
-	<classpathentry path="src/jar/server-local/java" kind="src"/>
-	<classpathentry path="src/jar/server-rmi/java" kind="src"/>
-	<classpathentry path="src/jar/sofa/java" kind="src"/>
-	<classpathentry path="src/jar/sparql-protocol/java" kind="src"/>
-	<classpathentry path="src/jar/store/java" kind="src"/>
-	<classpathentry path="src/jar/store-nodepool/java" kind="src"/>
-	<classpathentry path="src/jar/store-nodepool-memory/java" kind="src"/>
-	<classpathentry path="src/jar/store-nodepool-xa/java" kind="src"/>
-	<classpathentry path="src/jar/store-stringpool/java" kind="src"/>
-	<classpathentry path="src/jar/store-stringpool-memory/java" kind="src"/>
-	<classpathentry path="src/jar/store-stringpool-xa/java" kind="src"/>
-	<classpathentry path="src/jar/store-xa/java" kind="src"/>
-	<classpathentry path="src/jar/tag/java" kind="src"/>
-	<classpathentry path="src/jar/tuples/java" kind="src"/>
-	<classpathentry path="src/jar/tuples-hybrid/java" kind="src"/>
-	<classpathentry path="src/jar/util/java" kind="src"/>
-	<classpathentry path="src/jar/util-xa/java" kind="src"/>
-	<classpathentry path="src/jar/parser/java" kind="src"/>
-	<classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"/>
-	<classpathentry path="lib/xom-1.0d21.jar" kind="lib"/>
-	<classpathentry path="lib/xmlParserAPIs.jar" kind="lib"/>
-	<classpathentry path="lib/xmlc-xerces.jar" kind="lib"/>
-	<classpathentry path="lib/xmlc-taskdef-2.2.jar" kind="lib"/>
-	<classpathentry path="lib/xmlc-all-runtime-2.2.jar" kind="lib"/>
-	<classpathentry path="lib/xercesImpl.jar" kind="lib"/>
-	<classpathentry path="lib/wsdl4j-1.5.1.jar" kind="lib"/>
-	<classpathentry path="lib/trove-1.0.2.jar" kind="lib"/>
-	<classpathentry path="lib/sofa-1.0-alpha.jar" kind="lib"/>
-	<classpathentry path="lib/sablecc-2.18.2.jar" kind="lib"/>
-	<classpathentry path="lib/saaj-1.4.jar" kind="lib"/>
-	<classpathentry path="lib/Quick4util.jar" kind="lib"/>
-	<classpathentry path="lib/Quick4rt.jar" kind="lib"/>
-	<classpathentry path="lib/plankton-1.2.6.jar" kind="lib"/>
-	<classpathentry path="lib/org.mortbay.jetty-4.2.19.jar" kind="lib"/>
-	<classpathentry path="lib/org.mortbay.jetty.plus-4.2.19.jar" kind="lib"/>
-	<classpathentry path="lib/mail-1.3.jar" kind="lib"/>
-	<classpathentry path="lib/log4j-1.2.15.jar" kind="lib"/>
-	<classpathentry path="lib/jxunit3.jar" kind="lib"/>
-	<classpathentry path="lib/junit-3.8.1.jar" kind="lib"/>
-	<classpathentry path="lib/jtidy-r7-xmlc-2.2.jar" kind="lib"/>
-	<classpathentry path="lib/jta-spec1_0_1.jar" kind="lib"/>
-	<classpathentry path="lib/jsr173_07_ri.jar" kind="lib"/>
-	<classpathentry path="lib/jsr173_07_api.jar" kind="lib"/>
-	<classpathentry path="lib/js-1.5r3.jar" kind="lib"/>
-	<classpathentry path="lib/jotm-2.0.10.jar" kind="lib"/>
-	<classpathentry path="lib/jotm_jrmp_stubs-2.0.10.jar" kind="lib"/>
-	<classpathentry path="lib/carol-2.0.5.jar" kind="lib"/>
-	<classpathentry path="lib/howl-logger-0.1.11.jar" kind="lib"/>
-	<classpathentry path="lib/jl1.0.jar" kind="lib"/>
-	<classpathentry path="lib/jid3-0.34.jar" kind="lib"/>
-	<classpathentry path="lib/jboss-j2ee.jar" kind="lib"/>
-	<classpathentry path="lib/jaxrpc-1.4.jar" kind="lib"/>
-	<classpathentry path="lib/javax.servlet-2.3.jar" kind="lib"/>
-	<classpathentry path="lib/javacc.jar" kind="lib"/>
-	<classpathentry path="lib/jasper-runtime-4.2.29.jar" kind="lib"/>
-	<classpathentry path="lib/jasper-compiler-4.2.29.jar" kind="lib"/>
-	<classpathentry path="lib/jargs-0.2.jar" kind="lib"/>
-	<classpathentry path="lib/jakarta-oro-2.0.5.jar" kind="lib"/>
-	<classpathentry path="lib/icu4j.jar" kind="lib"/>
-	<classpathentry path="lib/gnu-regexp-1.1.4.jar" kind="lib"/>
-	<classpathentry path="lib/connector-1_5.jar" kind="lib"/>
-	<classpathentry path="lib/concurrent-1.3.4.jar" kind="lib"/>
-	<classpathentry path="lib/commons-logging-1.0.3.jar" kind="lib"/>
-	<classpathentry path="lib/commons-discovery-1.2.jar" kind="lib"/>
-	<classpathentry path="lib/bsh-2.0b1.jar" kind="lib"/>
-	<classpathentry path="lib/bsf-2.3.0.jar" kind="lib"/>
-	<classpathentry path="lib/beepcore-0.9.08.jar" kind="lib"/>
-	<classpathentry path="lib/barracuda-ant-1.2.6.jar" kind="lib"/>
-	<classpathentry path="lib/barracuda-1.2.6.jar" kind="lib"/>
-	<classpathentry path="lib/axis-ant-1.4.jar" kind="lib"/>
-	<classpathentry path="lib/axis-1.4.jar" kind="lib"/>
-	<classpathentry path="lib/aspectjrt-1.2.jar" kind="lib"/>
-	<classpathentry path="lib/apache-soap-2.2.jar" kind="lib"/>
-	<classpathentry path="lib/antlr.jar" kind="lib"/>
-	<classpathentry path="lib/activation-1.0.2.jar" kind="lib"/>
-	<classpathentry path="lib/jena-2.1.jar" kind="lib"/>
-	<classpathentry path="dist/ideSupport.jar" kind="lib"/>
-	<classpathentry path="lib/xalan-2.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/lucene-2.0.0.jar" kind="lib"/>
-	<classpathentry path="lib/jrdf-0.3.4.3.jar" kind="lib"/>
-	<classpathentry path="lib/ant-trax-1.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/ant-nodeps-1.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/ant-launcher-1.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/ant-junit-1.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/ant-apache-bsf-1.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/ant-1.7.0.jar" kind="lib"/>
-	<classpathentry path="lib/DateUtils1.jar" kind="lib"/>
-	<classpathentry path="lib/commons-httpclient-3.0.1.jar" kind="lib"/>
-	<classpathentry path="lib/commons-codec-1.3.jar" kind="lib"/>
-	<classpathentry path="lib/castor-1.2-codegen.jar" kind="lib"/>
-	<classpathentry path="lib/castor-1.2-xml.jar" kind="lib"/>
-	<classpathentry path="lib/castor-1.2-xml-schema.jar" kind="lib"/>
-	<classpathentry path="lib/derby.jar" kind="lib"/>
-	<classpathentry path="lib/velocity-1.5.jar" kind="lib"/>
-	<classpathentry path="lib/emory-util-2.1-remote.jar" kind="lib"/>
-	<classpathentry path="obj/jar" kind="output"/>
-</classpath>
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/jar/ant-task/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-distributed/java"/>
+	<classpathentry kind="src" path="src/war/webui/java"/>
+	<classpathentry kind="src" path="src/jar/descriptor/src/java"/>
+	<classpathentry kind="src" path="src/jar/client-jrdf/java"/>
+	<classpathentry kind="src" path="src/jar/content-mbox/java"/>
+	<classpathentry kind="src" path="src/jar/content-mp3/java"/>
+	<classpathentry kind="src" path="src/jar/content-n3/java"/>
+	<classpathentry kind="src" path="src/jar/content-rdfxml/java"/>
+	<classpathentry kind="src" path="src/jar/content-rio/java"/>
+	<classpathentry kind="src" path="src/jar/demo-mp3/java"/>
+	<classpathentry kind="src" path="src/jar/driver/java"/>
+	<classpathentry kind="src" path="src/jar/dtd/java"/>
+	<classpathentry kind="src" path="src/jar/itql/java"/>
+	<classpathentry kind="src" path="src/jar/itql/sablecc"/>
+	<classpathentry kind="src" path="src/jar/jrdf/java"/>
+	<classpathentry kind="src" path="src/jar/krule/java"/>
+	<classpathentry kind="src" path="src/jar/query/java"/>
+	<classpathentry kind="src" path="src/jar/resolver/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-file/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-filesystem/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-gis/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-http/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-jar/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-lucene/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-memory/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-nodetype/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-prefix/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-relational/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-spi/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-store/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-test/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-url/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-view/java"/>
+	<classpathentry kind="src" path="src/jar/resolver-xsd/java"/>
+	<classpathentry kind="src" path="src/jar/rules/java"/>
+	<classpathentry kind="src" path="src/jar/server/java"/>
+	<classpathentry kind="src" path="src/jar/server-beep/java"/>
+	<classpathentry kind="src" path="src/jar/server-http/java"/>
+	<classpathentry kind="src" path="src/jar/server-local/java"/>
+	<classpathentry kind="src" path="src/jar/server-rmi/java"/>
+	<classpathentry kind="src" path="src/jar/sofa/java"/>
+	<classpathentry kind="src" path="src/jar/sparql-protocol/java"/>
+	<classpathentry kind="src" path="src/jar/store/java"/>
+	<classpathentry kind="src" path="src/jar/store-nodepool/java"/>
+	<classpathentry kind="src" path="src/jar/store-nodepool-memory/java"/>
+	<classpathentry kind="src" path="src/jar/store-nodepool-xa/java"/>
+	<classpathentry kind="src" path="src/jar/store-stringpool/java"/>
+	<classpathentry kind="src" path="src/jar/store-stringpool-memory/java"/>
+	<classpathentry kind="src" path="src/jar/store-stringpool-xa/java"/>
+	<classpathentry kind="src" path="src/jar/store-xa/java"/>
+	<classpathentry kind="src" path="src/jar/tag/java"/>
+	<classpathentry kind="src" path="src/jar/tuples/java"/>
+	<classpathentry kind="src" path="src/jar/tuples-hybrid/java"/>
+	<classpathentry kind="src" path="src/jar/util/java"/>
+	<classpathentry kind="src" path="src/jar/util-xa/java"/>
+	<classpathentry kind="src" path="src/jar/parser/java"/>
+	<classpathentry kind="src" path="src/jar/sparql-interpreter/java"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="lib/xom-1.0d21.jar"/>
+	<classpathentry kind="lib" path="lib/xmlParserAPIs.jar"/>
+	<classpathentry kind="lib" path="lib/xmlc-xerces.jar"/>
+	<classpathentry kind="lib" path="lib/xmlc-taskdef-2.2.jar"/>
+	<classpathentry kind="lib" path="lib/xmlc-all-runtime-2.2.jar"/>
+	<classpathentry kind="lib" path="lib/xercesImpl.jar"/>
+	<classpathentry kind="lib" path="lib/wsdl4j-1.5.1.jar"/>
+	<classpathentry kind="lib" path="lib/trove-1.0.2.jar"/>
+	<classpathentry kind="lib" path="lib/sofa-1.0-alpha.jar"/>
+	<classpathentry kind="lib" path="lib/sablecc-2.18.2.jar"/>
+	<classpathentry kind="lib" path="lib/saaj-1.4.jar"/>
+	<classpathentry kind="lib" path="lib/Quick4util.jar"/>
+	<classpathentry kind="lib" path="lib/Quick4rt.jar"/>
+	<classpathentry kind="lib" path="lib/plankton-1.2.6.jar"/>
+	<classpathentry kind="lib" path="lib/org.mortbay.jetty-4.2.19.jar"/>
+	<classpathentry kind="lib" path="lib/org.mortbay.jetty.plus-4.2.19.jar"/>
+	<classpathentry kind="lib" path="lib/mail-1.3.jar"/>
+	<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
+	<classpathentry kind="lib" path="lib/jxunit3.jar"/>
+	<classpathentry kind="lib" path="lib/junit-3.8.1.jar"/>
+	<classpathentry kind="lib" path="lib/jtidy-r7-xmlc-2.2.jar"/>
+	<classpathentry kind="lib" path="lib/jta-spec1_0_1.jar"/>
+	<classpathentry kind="lib" path="lib/jsr173_07_ri.jar"/>
+	<classpathentry kind="lib" path="lib/jsr173_07_api.jar"/>
+	<classpathentry kind="lib" path="lib/js-1.5r3.jar"/>
+	<classpathentry kind="lib" path="lib/jotm-2.0.10.jar"/>
+	<classpathentry kind="lib" path="lib/jotm_jrmp_stubs-2.0.10.jar"/>
+	<classpathentry kind="lib" path="lib/carol-2.0.5.jar"/>
+	<classpathentry kind="lib" path="lib/howl-logger-0.1.11.jar"/>
+	<classpathentry kind="lib" path="lib/jl1.0.jar"/>
+	<classpathentry kind="lib" path="lib/jid3-0.34.jar"/>
+	<classpathentry kind="lib" path="lib/jboss-j2ee.jar"/>
+	<classpathentry kind="lib" path="lib/jaxrpc-1.4.jar"/>
+	<classpathentry kind="lib" path="lib/javax.servlet-2.3.jar"/>
+	<classpathentry kind="lib" path="lib/javacc.jar"/>
+	<classpathentry kind="lib" path="lib/jasper-runtime-4.2.29.jar"/>
+	<classpathentry kind="lib" path="lib/jasper-compiler-4.2.29.jar"/>
+	<classpathentry kind="lib" path="lib/jargs-0.2.jar"/>
+	<classpathentry kind="lib" path="lib/jakarta-oro-2.0.5.jar"/>
+	<classpathentry kind="lib" path="lib/icu4j.jar"/>
+	<classpathentry kind="lib" path="lib/gnu-regexp-1.1.4.jar"/>
+	<classpathentry kind="lib" path="lib/connector-1_5.jar"/>
+	<classpathentry kind="lib" path="lib/concurrent-1.3.4.jar"/>
+	<classpathentry kind="lib" path="lib/commons-logging-1.0.3.jar"/>
+	<classpathentry kind="lib" path="lib/commons-discovery-1.2.jar"/>
+	<classpathentry kind="lib" path="lib/bsh-2.0b1.jar"/>
+	<classpathentry kind="lib" path="lib/bsf-2.3.0.jar"/>
+	<classpathentry kind="lib" path="lib/beepcore-0.9.08.jar"/>
+	<classpathentry kind="lib" path="lib/barracuda-ant-1.2.6.jar"/>
+	<classpathentry kind="lib" path="lib/barracuda-1.2.6.jar"/>
+	<classpathentry kind="lib" path="lib/axis-ant-1.4.jar"/>
+	<classpathentry kind="lib" path="lib/axis-1.4.jar"/>
+	<classpathentry kind="lib" path="lib/aspectjrt-1.2.jar"/>
+	<classpathentry kind="lib" path="lib/apache-soap-2.2.jar"/>
+	<classpathentry kind="lib" path="lib/antlr.jar"/>
+	<classpathentry kind="lib" path="lib/activation-1.0.2.jar"/>
+	<classpathentry kind="lib" path="lib/jena-2.1.jar"/>
+	<classpathentry kind="lib" path="dist/ideSupport.jar"/>
+	<classpathentry kind="lib" path="lib/xalan-2.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/lucene-2.0.0.jar"/>
+	<classpathentry kind="lib" path="lib/jrdf-0.3.4.3.jar"/>
+	<classpathentry kind="lib" path="lib/ant-trax-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/ant-nodeps-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/ant-launcher-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/ant-junit-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/ant-apache-bsf-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/ant-1.7.0.jar"/>
+	<classpathentry kind="lib" path="lib/DateUtils1.jar"/>
+	<classpathentry kind="lib" path="lib/commons-httpclient-3.0.1.jar"/>
+	<classpathentry kind="lib" path="lib/commons-codec-1.3.jar"/>
+	<classpathentry kind="lib" path="lib/castor-1.2-codegen.jar"/>
+	<classpathentry kind="lib" path="lib/castor-1.2-xml.jar"/>
+	<classpathentry kind="lib" path="lib/castor-1.2-xml-schema.jar"/>
+	<classpathentry kind="lib" path="lib/derby.jar"/>
+	<classpathentry kind="lib" path="lib/velocity-1.5.jar"/>
+	<classpathentry kind="lib" path="lib/emory-util-2.1-remote.jar"/>
+	<classpathentry kind="lib" path="lib/mulgara-sparql-0.0.1.jar"/>
+	<classpathentry kind="output" path="obj/jar"/>
+</classpath>

Modified: trunk/build.properties
===================================================================
--- trunk/build.properties	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/build.properties	2008-04-26 02:17:54 UTC (rev 856)
@@ -151,10 +151,7 @@
 xerces.jar               =xercesImpl.jar
 xmlParserAPIs.jar        =xmlParserAPIs.jar
 xom.jar                  =xom-1.0d21.jar
+beaver.jar               =beaver-0.9.6.1.jar
+mulgara-sparql.jar       =mulgara-sparql-0.0.1.jar
+velocity.jar             =velocity-1.5.jar
 
-drools-version  =2.0-beta-15
-drools-base.jar =drools-base-${drools-version}.jar
-drools-core.jar =drools-core-${drools-version}.jar
-drools-io.jar   =drools-io-${drools-version}.jar
-drools-java.jar =drools-java-${drools-version}.jar
-drools-smf.jar  =drools-smf-${drools-version}.jar

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/build.xml	2008-04-26 02:17:54 UTC (rev 856)
@@ -56,6 +56,7 @@
   <property file="${jar.src.dir}/krule/krule-build.properties"/>
   <property file="${jar.src.dir}/rules/rules-build.properties"/>
   <property file="${jar.src.dir}/sparql-protocol/sparql-protocol-build.properties"/>
+  <property file="${jar.src.dir}/sparql-interpreter/sparql-interpreter-build.properties"/>
   <property file="${jar.src.dir}/store/store-build.properties"/>
   <property file="${jar.src.dir}/store-xa/store-xa-build.properties"/>
   <property file="${jar.src.dir}/store-nodepool/store-nodepool-build.properties"/>
@@ -125,6 +126,7 @@
   <import file="${jar.src.dir}/krule/build.xml"/>
   <import file="${jar.src.dir}/rules/build.xml"/>
   <import file="${jar.src.dir}/sparql-protocol/build.xml"/>
+  <import file="${jar.src.dir}/sparql-interpreter/build.xml"/>
   <import file="${jar.src.dir}/store/build.xml"/>
   <import file="${jar.src.dir}/store-xa/build.xml"/>
   <import file="${jar.src.dir}/store-nodepool/build.xml"/>
@@ -322,7 +324,7 @@
                    resolver-url-dist, resolver-view-dist, resolver-xsd-dist,
                    resolver-jar-dist, resolver-test-dist,
                    server-dist, server-beep-dist, server-http-dist, server-local-dist,
-                   server-rmi-dist, sofa-dist, krule-dist, rules-dist,
+                   server-rmi-dist, sofa-dist, sparql-int-dist, krule-dist, rules-dist,
                    store-stringpool-dist, store-stringpool-memory-dist,
                    store-stringpool-xa-dist, tag-dist,
                    tuples-dist, tuples-hybrid-dist,
@@ -469,7 +471,8 @@
 
       <attribute name="Main-Class" value="org.mulgara.util.Bootstrap"/>
       <attribute name="Embedded-Jar" value="
-          lib/${query.jar}, lib/${driver.jar}, lib/${itql.jar}, lib/${rmi.jar},
+          lib/${query.jar}, lib/${driver.jar}, lib/${itql.jar}, lib/${sparql-int.jar},
+          lib/${rmi.jar},
           lib/${server.jar}, lib/${server-beep.jar}, lib/${server-rmi.jar},
           lib/${util.jar}, lib/${config.jar}, lib/${descriptor.jar}, lib/${server-local.jar},
           lib/${resolver.jar}, lib/${resolver-spi.jar}, lib/${resolver-filesystem.jar},
@@ -491,7 +494,7 @@
           lib/${jetty.jar}, lib/${jetty.plus.jar}, lib/${jasper.compiler.jar}, lib/${servlet.jar}, lib/jargs-0.2.jar,
           lib/${castor-xml.jar}, lib/${castor-codegen.jar}, lib/${castor-xml-schema.jar}, lib/trove-1.0.2.jar, lib/${jrdf.jar}, lib/${saaj.jar},
           lib/${jakarta-oro.jar}, lib/jta-spec1_0_1.jar, lib/${jotm.jar}, lib/${jotm.jrmp.jar}, lib/${carol.jar}, lib/${howl.jar},
-          lib/${httpclient.jar}, lib/${commons-codec.jar}"/>
+          lib/${jca.jar}, lib/${httpclient.jar}, lib/${commons-codec.jar}, lib/${mulgara-sparql.jar}"/>
       <attribute name="Embedded-Main-Class" value="org.mulgara.server.EmbeddedMulgaraServer"/>
     </manifest>
   </target>
@@ -500,7 +503,7 @@
   <!-- Creates the lite distribution file for the Embedded Mulgara server   -->
   <!-- =================================================================== -->
   <target name="lite-dist"
-          depends="driver-jar, itql-jar, query-jar, rmi-jar,
+          depends="driver-jar, itql-jar, sparql-int-jar, rules-jar, query-jar, rmi-jar,
                    server-jar, server-local-jar, server-beep-jar,
                    server-rmi-jar, util-jar, config-jar, dtd-jar, jrdf-jar, ant-task-jar,
                    store-dist, store-xa-dist, store-nodepool-dist,
@@ -545,7 +548,7 @@
         ${servlet.jar}, ${jasper.runtime.jar}, ${jasper.compiler.jar},
         ${lucene.jar}, ${mail.jar}, ${castor-xml.jar}, ${castor-xml-schema.jar}, ${castor-codegen.jar}, ${trove.jar},
         ${date-utils.jar}, ${commons-logging.jar}, ${commons-httpclient.jar},
-        ${commons-codec.jar}, ${emory-util.jar},
+        ${commons-codec.jar}, ${emory-util.jar}, ${mulgara-sparql.jar}
         ${jotm.jar}, ${jotm.jrmp.jar}, ${carol.jar}, ${howl.jar}, ${jta.jar},
         ${jsr.173.api.jar}, ${jsr.173.ri.jar}, ${jca.jar}, ${saaj.jar},
         ${axis.jar}, ${commons-discovery.jar}, ${jaxrpc.jar}, ${wsdl4j.jar},
@@ -554,7 +557,8 @@
                        ${axis.jar}, ${commons-discovery.jar},
                        ${jaxrpc.jar}, ${wsdl4j.jar}"/>
       <zipfileset dir="${bin.dir}" prefix="lib" includes="
-        ${query.jar}, ${driver.jar}, ${itql.jar}, ${rules.jar}, ${rmi.jar},
+          ${query.jar}, ${driver.jar}, ${itql.jar}, ${sparql-int.jar},
+          ${rules.jar}, ${rmi.jar},
           ${server.jar}, ${server-beep.jar}, ${server-rmi.jar},
           ${util.jar}, ${config.jar}, ${descriptor.jar}, ${server-local.jar},
           ${resolver.jar}, ${resolver-spi.jar}, ${resolver-filesystem.jar},
@@ -728,7 +732,8 @@
              ant-task-jar, client-jrdf-jar, config-jar,
              content-mbox-jar, content-mp3-jar,
              content-n3-jar, content-rdfxml-jar, content-rio-jar,
-             doclet.jar, itql-jar, jrdf-jar, store-jar,
+             itql-jar, sparql-int-jar,
+             doclet.jar, jrdf-jar, store-jar,
              store-xa-jar,
              store-nodepool-jar, store-nodepool-memory-jar,
              store-nodepool-xa-jar, query-jar,
@@ -738,7 +743,8 @@
              resolver-url-jar, resolver-view-jar, resolver-xsd-jar,
              resolver-test-jar,
              server-jar, server-beep-jar, server-rmi-jar,
-             sofa-jar, krule-jar, rules-jar, sparql-protocol-jar, store-stringpool-jar,
+             sofa-jar, krule-jar, rules-jar, sparql-protocol-jar,
+             store-stringpool-jar,
              store-stringpool-memory-jar, store-stringpool-xa-jar,
              tuples-jar, tuples-hybrid-jar, util-jar, util-xa-jar, webui-war"
     unless="javadoc-uptodate"
@@ -810,8 +816,6 @@
       <classpath path="${lib.dir}/${jid3.jar}"/>
       <classpath path="${lib.dir}/jsr173_07_api.jar"/>
       <classpath path="${lib.dir}/${lucene.jar}"/>
-      <classpath path="${lib.dir}/krule-1.0-alpha.jar"/>
-      <classpath path="${lib.dir}/rules-1.0-alpha.jar"/>
       <classpath path="${lib.dir}/${sofa.jar}"/>
       <classpath path="${lib.dir}/xmlc-all-runtime-2.2.jar"/>
       <classpath path="${lib.dir}/xom-1.0d21.jar"/>
@@ -847,6 +851,7 @@
       <sourcepath path="${server-rmi.src.dir}/java"/>
       <sourcepath path="${sofa.src.dir}/java"/>
       <sourcepath path="${sparql-protocol.src.dir}/java"/>
+      <sourcepath path="${sparql-int.src.dir}/java"/>
       <sourcepath path="${store.src.dir}/java"/>
       <sourcepath path="${store-xa.src.dir}/java"/>
       <sourcepath path="${store-nodepool.src.dir}/java"/>
@@ -888,7 +893,8 @@
                    content-mp3-javadoc, content-n3-javadoc,
                    content-rdfxml-javadoc, content-rio-javadoc,
                    descriptor-javadoc, driver-javadoc, dtd-javadoc,
-                   itql-javadoc, store-javadoc, store-xa-javadoc,
+                   itql-javadoc, sparql-int-javadoc,
+                   store-javadoc, store-xa-javadoc,
                    store-nodepool-javadoc,
                    store-nodepool-memory-javadoc, jrdf-javadoc,
                    store-nodepool-xa-javadoc, query-javadoc,
@@ -901,7 +907,8 @@
                    resolver-test-javadoc, resolver-javadoc, resolver-relational-javadoc,
                    server-beep-javadoc, server-http-javadoc,
                    server-local-javadoc, server-rmi-javadoc, server-javadoc,
-                   sofa-javadoc, rules-javadoc, krule-javadoc, store-stringpool-javadoc,
+                   sofa-javadoc, rules-javadoc, krule-javadoc,
+                   store-stringpool-javadoc,
                    store-stringpool-memory-javadoc, store-stringpool-xa-javadoc,
                    tag-javadoc, tuples-hybrid-javadoc, tuples-javadoc,
                    util-xa-javadoc, util-javadoc"
@@ -1370,7 +1377,7 @@
   <!-- =================================================================== -->
   <target name="mulgara-war"
       description="Builds the Mulgara Semantic Store (Mulgara) WAR"
-      depends="driver-jar, itql-jar, query-jar, rmi-jar, server-jar,
+      depends="driver-jar, itql-jar, sparql-int-jar, query-jar, rmi-jar, server-jar,
       server-beep-jar, server-rmi-jar, util-jar, config-jar, descriptor-jar, dtd-compile,
       set.host.name, mulgara.war-uptodate"
       unless="mulgara.war-uptodate">
@@ -1396,7 +1403,7 @@
       <lib dir="${lib.dir}" includes="log4j-core-*.jar, icu4j.jar, jena-*.jar, antlr*.jar, beepcore-*.jar,
           lucene*.jar, apache-soap-*.jar, ${jrdf.jar}, ${date-utils.jar}, ${commons-logging.jar}"/>
       <lib dir="${bin.dir}" includes="${query.jar},
-        ${driver.jar}, ${itql.jar}, ${rules.jar}, ${rmi.jar},
+        ${driver.jar}, ${itql.jar}, ${sparql-int.jar}, ${rules.jar}, ${rmi.jar},
           ${server.jar}, ${server-beep.jar}, ${server-rmi.jar},
           ${util.jar}, ${config.jar}"/>
       <lib dir="${dist.dir}" includes="expires.txt"/>
@@ -1410,6 +1417,7 @@
 
       <srcfiles dir="${bin.dir}" includes="${query.jar},
           ${driver.jar}, ${itql.jar}, ${rules.jar}, ${rmi.jar},
+          ${sparql-int.jar},
           ${server.jar}, ${server-beep.jar}, ${server-rmi.jar},
           ${util.jar}, ${config.jar}, ${descriptor.jar}"/>
       <srcfiles dir="${dist.dir}" includes="expires.txt"/>
@@ -1685,7 +1693,8 @@
           depends="client-jrdf-jar, config-jar,
              content-mbox-jar, content-mp3-jar, content-n3-jar,
              content-rdfxml-jar, content-rio-jar,
-             create-manifest, demo-jar, dtd-jar, driver-jar, dtd-jar, itql-jar,
+             create-manifest, demo-jar, dtd-jar, driver-jar, dtd-jar,
+             itql-jar, sparql-int-jar,
              javadoc-dist, jrdf-jar, store-jar, store-xa-jar,
              store-nodepool-jar,
              store-nodepool-memory-jar, store-nodepool-xa-jar,
@@ -1736,6 +1745,7 @@
       <zipfileset src="${lib.dir}/${jasper.compiler.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${lucene.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${mail.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${lib.dir}/${mulgara-sparql.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${castor-xml.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${castor-xml-schema.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${castor-codegen.jar}" excludes="META-INF/**"/>
@@ -1766,6 +1776,7 @@
       <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${itql.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${bin.dir}/${sparql-int.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**"/>
       <zipfileset src="${bin.dir}/${server-beep.jar}" excludes="META-INF/**"/>
@@ -1933,8 +1944,7 @@
   </target>
 
   <target name="utils-test"
-    depends="ant-task-test, dtd-test, sofa-test, rules-test, krule-test, tag-test, util-test,
-             util-xa-test"
+    depends="ant-task-test, dtd-test, sofa-test, rules-test, krule-test, tag-test, util-test, util-xa-test"
     description="Runs miscellaneous utility tests">
   </target>
 

Modified: trunk/common.xml
===================================================================
--- trunk/common.xml	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/common.xml	2008-04-26 02:17:54 UTC (rev 856)
@@ -152,7 +152,8 @@
                        jotm*.jar, commons-logging-*.jar, Quick4rt.jar,
                        commons-discovery-*.jar, commons-httpclient-*.jar,
                        commons-codec-*.jar, connector-*.jar, jaxrpc-*.jar,
-                       carol*.jar, howl-logger*.jar, ${date-utils.jar}"
+                       carol*.jar, howl-logger*.jar, ${date-utils.jar},
+                       mulgara-sparql*.jar"
              excludes="jboss-j2ee.jar"/>
   </path>
 

Copied: trunk/lib/mulgara-sparql-0.0.1.jar (from rev 855, branches/mgr-61-sparql/lib/mulgara-sparql-0.0.1.jar)
===================================================================
(Binary files differ)

Modified: trunk/src/jar/itql/build.xml
===================================================================
--- trunk/src/jar/itql/build.xml	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/itql/build.xml	2008-04-26 02:17:54 UTC (rev 856)
@@ -107,7 +107,7 @@
   </target>
 
   <target name="itql-dist"
-          depends="itql-uptodate, itql-jar, server-beep-jar, server-rmi-jar"
+          depends="itql-uptodate, itql-jar, server-beep-jar, server-rmi-jar, sparql-int-jar"
           unless="itql.uptodate"
           description="Performs all tasks related to finalising this itql and readying it for distribution">
 
@@ -131,6 +131,7 @@
       <zipfileset src="${server-rmi.dist.dir}/${server-rmi.jar}" excludes="META-INF/**"/>
       <zipfileset src="${util.dist.dir}/${util.jar}" excludes="META-INF/**"/>
       <zipfileset src="${rules.dist.dir}/${rules.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${sparql-int.dist.dir}/${sparql-int.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/beepcore-0.9.08.jar" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${commons-logging.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/concurrent-1.3.4.jar" excludes="META-INF/**"/>
@@ -143,6 +144,7 @@
       <zipfileset src="${lib.dir}/${emory-util.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${jta.jar}" excludes="META-INF/**"/>
       <zipfileset src="${lib.dir}/${axis.jar}" excludes="META-INF/**"/>
+      <zipfileset src="${lib.dir}/${mulgara-sparql.jar}" excludes="META-INF/**"/>
     </jar>
   </target>
 
@@ -154,6 +156,7 @@
       <srcfiles dir="${itql.dist.dir}" includes="${itql.jar}"/>
       <srcfiles dir="${driver.dist.dir}" includes="${driver.jar}"/>
       <srcfiles dir="${query.dist.dir}" includes="${query.jar}"/>
+      <srcfiles dir="${sparql-int.dist.dir}" includes="${query.jar}"/>
       <srcfiles dir="${server-beep.dist.dir}" includes="${server-beep.jar}"/>
       <srcfiles dir="${server-rmi.dist.dir}" includes="${server-rmi.jar}"/>
       <srcfiles dir="${util.dist.dir}" includes="${util.jar}"/>

Modified: trunk/src/jar/krule/java/org/mulgara/krule/Rule.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/Rule.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/krule/java/org/mulgara/krule/Rule.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -68,7 +68,7 @@
   /** The rules to be triggered when this rule generates statements.*/
   private Set<Rule> triggerSet;
 
-  /** The query for this rule. */
+  /** The query for this rule. This contains the information for the base model. */
   private Query query;
 
   /** The graph receiving the inferred data. */
@@ -219,9 +219,7 @@
    */
   private void scheduleTriggeredRules() {
   	Iterator<Rule> it = triggerSet.iterator();
-  	while (it.hasNext()) {
-  	  ruleStruct.schedule(it.next());
-  	}
+  	while (it.hasNext()) ruleStruct.schedule(it.next());
   }
 
 

Modified: trunk/src/jar/query/java/org/mulgara/connection/CommandExecutor.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/connection/CommandExecutor.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/connection/CommandExecutor.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -33,7 +33,7 @@
    * @see org.mulgara.connection.Connection#execute(org.mulgara.query.operation.Command)
    */
   public String execute(Command cmd) throws Exception {
-    return (String)cmd.execute(this);
+    return cmd.execute(this).toString();
   }
 
   /**

Copied: trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/ConstraintFilter.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,107 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.query;
+
+import java.util.Set;
+
+import org.mulgara.query.filter.Filter;
+
+// Third party packages
+import org.apache.log4j.Logger;
+
+/**
+ * A constraint expression comprised of filtering the subexpression according
+ * to an abstract formula specified as a {@link org.mulgara.query.filter.Filter}.
+ *
+ * @created Mar 24, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ConstraintFilter implements ConstraintExpression {
+
+  @SuppressWarnings("unused")
+  /** The logger */
+  private final static Logger logger = Logger.getLogger(ConstraintFilter.class.getName());
+
+  /**
+   * Allow newer compiled version of the stub to operate when changes
+   * have not occurred with the class.
+   * NOTE : update this serialVersionUID when a method or a public member is
+   * deleted.
+   */
+  private static final long serialVersionUID = -816733883358318430L;
+
+  /** The filtered expression. */
+  private ConstraintExpression constraintExpr;
+
+  /** The filter construct. */
+  private Filter filter;
+
+  /**
+   * Construct a filtered constraint.
+   * @param constraintExpr a non-<code>null</code> constraint
+   * @throws IllegalArgumentException if <var>constraint</var> is <code>null</code>
+   */
+  public ConstraintFilter(ConstraintExpression constraintExpr, Filter filter) {
+    if (constraintExpr == null) throw new IllegalArgumentException("Null \"constraint expression\" parameter");
+    if (filter == null) throw new IllegalArgumentException("Null \"filter\" parameter");
+    this.constraintExpr = constraintExpr;
+    this.filter = filter;
+  }
+  
+  /**
+   * Retrieve the internal filter expression. This constraint returns data whenever the filter
+   * returns <code>true</code>.
+   * @return the filter for this constraint.
+   */
+  public Filter getFilter() {
+    return filter;
+  }
+
+  /**
+   * Gets the constraint being filtered by this constraint.
+   * @return The original constraint expression.
+   */
+  public ConstraintExpression getUnfilteredConstraint() {
+    return constraintExpr;
+  }
+
+  /** {@inheritDoc} */
+  public Set<Variable> getVariables() {
+    return constraintExpr.getVariables();
+  }
+
+  /** {@inheritDoc} */
+  public String toString() {
+    return "filter " + constraintExpr + " by ";
+  }
+
+  /** {@inheritDoc} */
+  public int hashCode() {
+    return constraintExpr.hashCode() * -1;
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(Object object) {
+    if (object == null) return false;
+    if (object == this) return true;
+
+    // Check that the given object is the correct class.
+    if (!ConstraintFilter.class.equals(object.getClass())) return false;
+    // check each element.
+    ConstraintFilter other = (ConstraintFilter)object;
+    // can't do an equals() on filter, as this evaluates the filter in context
+    return constraintExpr.equals(other.constraintExpr) && filter == other.filter;
+  }
+}

Copied: trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/ConstraintIn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,116 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.query;
+
+// Java 2 standard packages
+import java.util.*;
+
+// Third party packages
+// import org.apache.log4j.Logger;
+
+// Local packages
+import org.apache.log4j.Logger;
+
+/**
+ * A constraint expression for setting the GRAPHs of all child expressions.
+ *
+ * @created Apr 22, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ConstraintIn implements ConstraintExpression {
+
+  /** Serialization ID for marshalling */
+  private static final long serialVersionUID = 1248304769395263538L;
+
+  /** Logger. */
+  @SuppressWarnings("unused")
+  private final static Logger logger = Logger.getLogger(ConstraintIn.class);
+
+  /** The filtered expression. */
+  private ConstraintExpression constraint;
+
+  /** The IN element to set subconstraints to. */
+  private ConstraintElement graph;
+
+  /**
+   * Construct a filtered constraint.
+   * @param constraint a non-<code>null</code> constraint.
+   * @param graph the value to set all the graphs of all sub-constraints to.
+   * @throws IllegalArgumentException if <var>constraint</var> is <code>null</code>
+   */
+  public ConstraintIn(ConstraintExpression constraint, ConstraintElement graph) {
+    if (constraint == null) throw new IllegalArgumentException("Null \"constraint\" parameter");
+    if (graph == null) throw new IllegalArgumentException("Null graph parameter");
+    this.constraint = constraint;
+    this.graph = graph;
+  }
+  
+  /**
+   * Retrieve the graph to use.
+   * @return the graph value for this constraint.
+   */
+  public ConstraintElement getGraph() {
+    return graph;
+  }
+
+  /**
+   * Gets the constraint being modified by this constraint.
+   * @return The original constraint expression.
+   */
+  public ConstraintExpression getConstraintParam() {
+    return constraint;
+  }
+
+  /** {@inheritDoc} */
+  public ConstraintElement getModel() {
+    return graph;
+  }
+
+
+  /** {@inheritDoc} */
+  public Set<Variable> getVariables() {
+    return constraint.getVariables();
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean isInnerConstraintIs() {
+    return constraint instanceof ConstraintIs;
+  }
+
+  /** {@inheritDoc} */
+  public String toString() {
+    return "GRAPH " + graph + " { " + constraint + " }";
+  }
+
+  /** {@inheritDoc} */
+  public int hashCode() {
+    return constraint.hashCode() * -7;
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(Object object) {
+    if (object == null) return false;
+    if (object == this) return true;
+
+    // Check that the given object is the correct class.
+    if (!ConstraintIn.class.equals(object.getClass())) return false;
+    // check each element.
+    ConstraintIn other = (ConstraintIn)object;
+    // can't do an equals() on filter, as this evaluates the filter in context
+    return constraint.equals(other.constraint) && graph.equals(other.graph);
+  }
+
+}

Copied: trunk/src/jar/query/java/org/mulgara/query/ConstraintOptionalJoin.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/ConstraintOptionalJoin.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintOptionalJoin.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintOptionalJoin.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,65 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is the Kowari Metadata Store.
+ *
+ * The Initial Developer of the Original Code is Plugged In Software Pty
+ * Ltd (http://www.pisoftware.com, mailto:info at pisoftware.com). Portions
+ * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
+ * Plugged In Software Pty Ltd. All Rights Reserved.
+ *
+ * Contributor(s): N/A.
+ *
+ * [NOTE: The text of this Exhibit A may differ slightly from the text
+ * of the notices in the Source Code files of the Original Code. You
+ * should use the text of this Exhibit A rather than the text found in the
+ * Original Code Source Code for Your Modifications.]
+ *
+ */
+
+package org.mulgara.query;
+
+/**
+ * A constraint expression composed of a left-out-join conjunction of two subexpressions
+ *
+ * @created Apr 2, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2007 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+
+public class ConstraintOptionalJoin extends ConstraintOperation {
+
+  /**
+   * Allow newer compiled version of the stub to operate when changes
+   * have not occurred with the class.
+   * NOTE : update this serialVersionUID when a method or a public member is
+   * deleted.
+   */
+  private static final long serialVersionUID = 4059489277371655516L;
+
+  /**
+   * Construct a constraint left-outer-join.
+   * @param lhs a non-<code>null</code> constraint expression
+   * @param rhs another non-<code>null</code> constraint expression
+   */
+  public ConstraintOptionalJoin(ConstraintExpression lhs, ConstraintExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * Gets the Name attribute of the ConstraintOptionalJoin object
+   * @return The Name value
+   */
+  String getName() {
+    return " optional ";
+  }
+}

Copied: trunk/src/jar/query/java/org/mulgara/query/ModelVariable.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/ModelVariable.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ModelVariable.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/ModelVariable.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,134 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.query;
+
+// Java 2 standard packages
+import java.net.*;
+import java.util.*;
+
+// Third party packages
+import org.apache.log4j.Logger;
+
+/**
+ * A leaf expression containing a variable that is used for the model expression.
+ *
+ * @created Apr 22, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ModelVariable implements Model {
+
+  /** Used for serializing. */
+  static final long serialVersionUID = 5132086338306266830L;
+
+  /** Logger. */
+  @SuppressWarnings("unused")
+  private final static Logger logger = Logger.getLogger(ModelVariable.class);
+
+  /** The variable for the graph */
+  private Variable variable;
+
+  //
+  // Constructors
+  //
+
+  /**
+   * Construct a model from a {@link URL}.
+   *
+   * @param uri the {@link URI} of the model to query
+   * @throws IllegalArgumentException if <var>url</var> is <code>null</code>
+   */
+  public ModelVariable(Variable variable) {
+    if (variable == null) throw new IllegalArgumentException("Null variable parameter");
+    this.variable = variable;
+  }
+
+  //
+  // Methods implementing ModelExpression
+  //
+
+  /**
+   * Gets a set of database URIs to operate against.
+   * @return We don't know what is in the variable, so return the empty {@link Set}
+   */
+  @SuppressWarnings("unchecked")
+  public Set<URI> getDatabaseURIs() {
+    return (Set<URI>)Collections.EMPTY_SET;
+  }
+
+  //
+  // API methods
+  //
+
+  /**
+   * Accessor for the <var>variable</var> property.
+   * @return a {@link Variable} instance
+   */
+  public Variable getVariable() {
+    return variable;
+  }
+
+  //
+  // Methods extending Object
+  //
+
+  /**
+   * The text representation of the URI.
+   * @return the text representation of the URI.
+   */
+  public String toString() {
+    return variable.toString();
+  }
+
+  //
+  // Methods overriding Object
+  //
+
+  /**
+   * Return true if the variables of a ModelVariable are equal.
+   * @param object ModelVariable to test equality.
+   * @return true if the variables of a ModelVariable are equal.
+   */
+  public boolean equals(Object object) {
+    if (object == null) return false;
+    if (object == this) return true;
+
+    if (!(object instanceof ModelVariable)) return false;
+    ModelVariable modelVar = (ModelVariable)object;
+    return variable.equals(modelVar.variable);
+  }
+
+  /**
+   * Returns the hashCode of a Variable.
+   * @return the hashCode of a Variable.
+   */
+  public int hashCode() {
+    return variable.hashCode();
+  }
+
+  /**
+   * Returns just the default Object clone.
+   * @return just the default Object clone.
+   */
+  public Object clone() {
+    try {
+      ModelVariable cloned = (ModelVariable)super.clone();
+      cloned.variable = variable;
+      return cloned;
+    } catch (CloneNotSupportedException e) {
+      throw new RuntimeException("ModelVariable not cloneable");
+    }
+  }
+
+}

Modified: trunk/src/jar/query/java/org/mulgara/query/Variable.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/Variable.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/Variable.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -34,15 +34,10 @@
  *
  * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
  *
- * @version $Revision: 1.8 $
+ * @maintenanceAuthor <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
  *
- * @modified $Date: 2005/01/05 04:58:20 $ by $Author: newmana $
+ * @copyright &copy;2001-2004 <a href="http://www.pisoftware.com/">Plugged In Software Pty Ltd</a>
  *
- * @maintenanceAuthor $Author: newmana $
- *
- * @copyright &copy;2001-2004
- *   <a href="http://www.pisoftware.com/">Plugged In Software Pty Ltd</a>
- *
  * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
  */
 public class Variable implements SelectElement, ConstraintElement {
@@ -55,106 +50,76 @@
    */
   static final long serialVersionUID = -3242803845875986693L;
 
-  /**
-   * Description of the Field
-   */
+  /** Description of the Field */
   public final static Variable FROM = new Variable("_from");
 
-  /**
-   * The <var>name</var> property.
-   */
+  /** The <var>name</var> property. */
   private String name;
 
+
   /**
    * Create a new variable.
-   *
    * @param name the variable name (no leading <code>$</code> character)
    * @throws IllegalArgumentException if <var>name</var> is <code>null</code>
    */
   public Variable(String name) {
-
     // Validate "name" parameter
-    if (name == null) {
+    if (name == null) throw new IllegalArgumentException("Null \"name\" parameter");
+    if (name.indexOf(" ") != -1)  throw new IllegalArgumentException("\"" + name + "\" is a not a variable name");
 
-      throw new IllegalArgumentException("Null \"name\" parameter");
-    }
-
-    if (name.indexOf(" ") != -1) {
-
-      throw new IllegalArgumentException("\"" + name +
-          "\" is a not a variable name");
-    }
-
-    // Initialize fields
     this.name = name;
   }
 
+
   /**
    * Accessor for the <var>name</var> property.
-   *
-   * @return The Name value
+   * @return The value of the Name
    */
   public String getName() {
-
     return name;
   }
 
+
   /**
-   * METHOD TO DO
-   *
-   * @return RETURNED VALUE TO DO
+   * Clones this variable.
+   * @return A new variable that will compare as equal to this one.
    */
   public Object clone() {
-
-    if (name.equals("_from")) {
-
-      return FROM;
-    }
+    if (name.equals("_from")) return FROM;
     else {
-
       try {
         return super.clone();
+      } catch (CloneNotSupportedException e) {
+        throw new InternalError(e.toString());  // Should not happen
       }
-      catch (CloneNotSupportedException e) {
-        // Should never happen
-        throw new InternalError(e.toString());
-      }
     }
   }
 
+
   /**
    * Variables are equal by <var>name</var> .
    *
-   * @param object PARAMETER TO DO
-   * @return RETURNED VALUE TO DO
+   * @param object The other variable to compare to
+   * @return <code>true</code> if object is a Variable, and has the same name.
    */
   public boolean equals(Object object) {
-
-    if ( (object == null) || !Variable.class.equals(object.getClass())) {
-
-      return false;
-    }
-
-    return (object == this) || name.equals( ( (Variable) object).name);
+    if ((object == null) || !Variable.class.equals(object.getClass())) return false;
+    return (object == this) || name.equals(((Variable)object).name);
   }
 
   /**
-   * METHOD TO DO
-   *
-   * @return RETURNED VALUE TO DO
+   * Calculate a hash code that is relatively unique for this variable.
+   * @return An int encoded from this variable's name.
    */
   public int hashCode() {
-
     return name.hashCode();
   }
 
   /**
    * Legible representation of the variable.
-   *
    * @return a <q>$</q> prefixed to the <var>name</var>
    */
   public String toString() {
-
     return "$" + name;
   }
 }

Copied: trunk/src/jar/query/java/org/mulgara/query/filter (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter)

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,59 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-
-
-/**
- * Describes a test function on an RDFTerm.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractBooleanFn extends AbstractFilterValue implements Filter {
-
-  /** The variable to test */
-  RDFTerm operand;
-
-  /**
-   * Create a function for testing a term
-   * @param The term to test
-   */
-  public AbstractBooleanFn(RDFTerm operand) {
-    super(operand);
-    this.operand = operand;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.Filter#test()
-   */
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    return fnTest();
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
-  protected RDFTerm resolve() throws QueryException {
-    return fnTest() ? Bool.TRUE : Bool.FALSE;
-  }
-
-  /**
-   * An implementation specific test
-   * @return <code>true</code> when this test passes.
-   * @throws QueryException Thrown when an error occurs while trying to resolve the value of the operand.
-   */
-  abstract boolean fnTest() throws QueryException;
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractBooleanFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,59 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+
+
+/**
+ * Describes a test function on an RDFTerm.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractBooleanFn extends AbstractFilterValue implements Filter {
+
+  /** The variable to test */
+  RDFTerm operand;
+
+  /**
+   * Create a function for testing a term
+   * @param The term to test
+   */
+  public AbstractBooleanFn(RDFTerm operand) {
+    super(operand);
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.Filter#test()
+   */
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    return fnTest();
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
+  protected RDFTerm resolve() throws QueryException {
+    return fnTest() ? Bool.TRUE : Bool.FALSE;
+  }
+
+  /**
+   * An implementation specific test
+   * @return <code>true</code> when this test passes.
+   * @throws QueryException Thrown when an error occurs while trying to resolve the value of the operand.
+   */
+  abstract boolean fnTest() throws QueryException;
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,40 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-
-/**
- * Defines how to set and retrieve context
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractContextOwner implements ContextOwner {
-
-  /** The more recent context */
-  private Context context = null;
-
-  /**
-   * Set the current context. This *must* be run at the start of every test else the underlying
-   * values will not resolve correctly.
-   * @param context The context for this test.
-   */
-  public void setCurrentContext(Context context) { this.context = context; }
-  
-  /**
-   * Get the current context. This is a callback that is used during a test.
-   * @return The context of the currently running test, or the most recent context if not in a test.
-   */
-  public Context getCurrentContext() { return context; }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractContextOwner.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,40 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+
+/**
+ * Defines how to set and retrieve context
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractContextOwner implements ContextOwner {
+
+  /** The more recent context */
+  private Context context = null;
+
+  /**
+   * Set the current context. This *must* be run at the start of every test else the underlying
+   * values will not resolve correctly.
+   * @param context The context for this test.
+   */
+  public void setCurrentContext(Context context) { this.context = context; }
+  
+  /**
+   * Get the current context. This is a callback that is used during a test.
+   * @return The context of the currently running test, or the most recent context if not in a test.
+   */
+  public Context getCurrentContext() { return context; }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,153 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.ComparableExpression;
-import org.mulgara.query.filter.value.IRI;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-
-/**
- * A root for most values, for setting the context and giving default responses to many items.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractFilterValue extends AbstractContextOwner implements Filter, ValueLiteral {
-
-  /** The operands for the operation */
-  RDFTerm[] operands;
-
-  /** The owner of the current context */
-  private ContextOwner contextOwner = null;
-
-  public AbstractFilterValue(RDFTerm... operands) {
-    this.operands = operands;
-    for (RDFTerm op: operands) op.setContextOwner(this);
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
-   * @throws QueryException if this function does not resolve to a literal
-   */
-  public SimpleLiteral getLang() throws QueryException { return SimpleLiteral.EMPTY; }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
-  public IRI getType() throws QueryException { return Bool.IRI_TYPE; }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
-  public boolean isSimple() throws QueryException { return false; }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
-   * @throws QueryException if this function does not resolve to a literal
-   */
-  public String getLexical() throws QueryException { return getValue().toString(); }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getValue()
-   * @return an object, for the result.  Never null.
-   * @throws QueryException if this function does not resolve to a literal
-   */
-  public Object getValue() throws QueryException { return resolve().getValue(); }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#test(org.mulgara.query.filter.Context) */
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    RDFTerm term = resolve();
-    if (term.isLiteral()) {
-      return ((ValueLiteral)term).test(context);
-    } else if (term instanceof Filter) {
-      return ((Filter)term).test(context);
-    }
-    throw new QueryException("Type error. Cannot get a boolean from a: " + term.getClass().getSimpleName());
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#equals(org.mulgara.query.filter.RDFTerm) */
-  public boolean equals(RDFTerm v) throws QueryException { return resolve().equals(v); }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isBlank() */
-  public boolean isBlank() throws QueryException { return false; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isIRI() */
-  public boolean isIRI() throws QueryException { return false; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isLiteral() */
-  public boolean isLiteral() throws QueryException { return true; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isURI() */
-  public boolean isURI() throws QueryException { return isIRI(); }
-
-  /** @see org.mulgara.query.filter.RDFTerm#notEquals(org.mulgara.query.filter.RDFTerm) */
-  public boolean notEquals(RDFTerm v) throws QueryException { return !resolve().equals(v); }
-
-  /** @see org.mulgara.query.filter.RDFTerm#sameTerm(org.mulgara.query.filter.RDFTerm) */
-  public boolean sameTerm(RDFTerm v) throws QueryException { return resolve().sameTerm(v); }
-
-  /////////////////////////////////////////////////////////////////
-  // The following all implement the ComparableExpression interface
-  /////////////////////////////////////////////////////////////////
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThan(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean greaterThan(ComparableExpression v) throws QueryException {
-    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
-    return ((ValueLiteral)resolve()).greaterThan(v);
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
-    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
-    return ((ValueLiteral)resolve()).greaterThanEqualTo(v);
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThan(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean lessThan(ComparableExpression v) throws QueryException {
-    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
-    return ((ValueLiteral)resolve()).lessThan(v);
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
-    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
-    return ((ValueLiteral)resolve()).lessThanEqualTo(v);
-  }
-
-  /////////////////////////////////////////////////////////////////
-  // End of the ComparableExpression interface
-  /////////////////////////////////////////////////////////////////
-
-  /** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
-  public ContextOwner getContextOwner() { return contextOwner; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner) */
-  public void setContextOwner(ContextOwner owner) { contextOwner = owner; }
-
-  /** @see org.mulgara.query.filter.ContextOwner#getCurrentContext() */
-  public Context getCurrentContext() { return contextOwner.getCurrentContext(); }
-
-  /** @see org.mulgara.query.filter.ContextOwner#setCurrentContext(org.mulgara.query.filter.Context) */
-  public void setCurrentContext(Context context) {
-    if (!(context.equals(contextOwner.getCurrentContext()))) throw new AssertionError("Filter context being set differently to initial calling context.");
-  }
-
-  /**
-   * Resolves this function into whatever the return type should be (Literal or URI).
-   * @return The resolved value for the function.
-   * @throws QueryException There was an error resolving the value against the context.
-   */
-  protected abstract RDFTerm resolve() throws QueryException;
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractFilterValue.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,153 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.ComparableExpression;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+
+/**
+ * A root for most values, for setting the context and giving default responses to many items.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractFilterValue extends AbstractContextOwner implements Filter, ValueLiteral {
+
+  /** The operands for the operation */
+  RDFTerm[] operands;
+
+  /** The owner of the current context */
+  private ContextOwner contextOwner = null;
+
+  public AbstractFilterValue(RDFTerm... operands) {
+    this.operands = operands;
+    for (RDFTerm op: operands) op.setContextOwner(this);
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
+   * @throws QueryException if this function does not resolve to a literal
+   */
+  public SimpleLiteral getLang() throws QueryException { return SimpleLiteral.EMPTY; }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
+  public IRI getType() throws QueryException { return Bool.IRI_TYPE; }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+  public boolean isSimple() throws QueryException { return false; }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
+   * @throws QueryException if this function does not resolve to a literal
+   */
+  public String getLexical() throws QueryException { return getValue().toString(); }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getValue()
+   * @return an object, for the result.  Never null.
+   * @throws QueryException if this function does not resolve to a literal
+   */
+  public Object getValue() throws QueryException { return resolve().getValue(); }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#test(org.mulgara.query.filter.Context) */
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    RDFTerm term = resolve();
+    if (term.isLiteral()) {
+      return ((ValueLiteral)term).test(context);
+    } else if (term instanceof Filter) {
+      return ((Filter)term).test(context);
+    }
+    throw new QueryException("Type error. Cannot get a boolean from a: " + term.getClass().getSimpleName());
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#equals(org.mulgara.query.filter.RDFTerm) */
+  public boolean equals(RDFTerm v) throws QueryException { return resolve().equals(v); }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isBlank() */
+  public boolean isBlank() throws QueryException { return false; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isIRI() */
+  public boolean isIRI() throws QueryException { return false; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isLiteral() */
+  public boolean isLiteral() throws QueryException { return true; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isURI() */
+  public boolean isURI() throws QueryException { return isIRI(); }
+
+  /** @see org.mulgara.query.filter.RDFTerm#notEquals(org.mulgara.query.filter.RDFTerm) */
+  public boolean notEquals(RDFTerm v) throws QueryException { return !resolve().equals(v); }
+
+  /** @see org.mulgara.query.filter.RDFTerm#sameTerm(org.mulgara.query.filter.RDFTerm) */
+  public boolean sameTerm(RDFTerm v) throws QueryException { return resolve().sameTerm(v); }
+
+  /////////////////////////////////////////////////////////////////
+  // The following all implement the ComparableExpression interface
+  /////////////////////////////////////////////////////////////////
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThan(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean greaterThan(ComparableExpression v) throws QueryException {
+    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+    return ((ValueLiteral)resolve()).greaterThan(v);
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
+    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+    return ((ValueLiteral)resolve()).greaterThanEqualTo(v);
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThan(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean lessThan(ComparableExpression v) throws QueryException {
+    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+    return ((ValueLiteral)resolve()).lessThan(v);
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
+    if (!isLiteral()) throw new QueryException("Type Error: cannot compare a: " + getClass().getSimpleName());
+    return ((ValueLiteral)resolve()).lessThanEqualTo(v);
+  }
+
+  /////////////////////////////////////////////////////////////////
+  // End of the ComparableExpression interface
+  /////////////////////////////////////////////////////////////////
+
+  /** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
+  public ContextOwner getContextOwner() { return contextOwner; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner) */
+  public void setContextOwner(ContextOwner owner) { contextOwner = owner; }
+
+  /** @see org.mulgara.query.filter.ContextOwner#getCurrentContext() */
+  public Context getCurrentContext() { return contextOwner.getCurrentContext(); }
+
+  /** @see org.mulgara.query.filter.ContextOwner#setCurrentContext(org.mulgara.query.filter.Context) */
+  public void setCurrentContext(Context context) {
+    if (!(context.equals(contextOwner.getCurrentContext()))) throw new AssertionError("Filter context being set differently to initial calling context.");
+  }
+
+  /**
+   * Resolves this function into whatever the return type should be (Literal or URI).
+   * @return The resolved value for the function.
+   * @throws QueryException There was an error resolving the value against the context.
+   */
+  protected abstract RDFTerm resolve() throws QueryException;
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,94 +0,0 @@
-package org.mulgara.query.filter;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.IRI;
-import org.mulgara.query.filter.value.Var;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Tests the isURI and isIRI functions.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractIsIriFnUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  public AbstractIsIriFnUnitTest(String name) {
-    super(name);
-  }
-
-  public static Test suite() {
-    return new TestSuite();
-  }
-
-  abstract public AbstractFilterValue createFn(RDFTerm arg);
-
-  public void testLiteral() throws Exception {
-    AbstractFilterValue fn = createFn(t);
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-  
-    fn = createFn(new IRI(URI.create("foo:bar")));
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-  
-    fn = createFn(t.getType());
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    AbstractFilterValue fn = createFn(x);
-  
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Node[][] rows = {
-      new Node[] {seven},
-      new Node[] {null},
-      new Node[] {new URIReferenceImpl(xsdInt)}
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-  
-    // check the context setting
-    fn.setCurrentContext(c);
-  
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-  
-    assertTrue(c.next());
-    try {
-      assertTrue(f.equals(fn));
-      fail("No exception when testing an unbound value");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Unbound column"));
-    }
-  
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-  
-    assertFalse(c.next());
-  }
-
-}
\ No newline at end of file

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractIsIriFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,94 @@
+package org.mulgara.query.filter;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.Var;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests the isURI and isIRI functions.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractIsIriFnUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  public AbstractIsIriFnUnitTest(String name) {
+    super(name);
+  }
+
+  public static Test suite() {
+    return new TestSuite();
+  }
+
+  abstract public AbstractFilterValue createFn(RDFTerm arg);
+
+  public void testLiteral() throws Exception {
+    AbstractFilterValue fn = createFn(t);
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+  
+    fn = createFn(new IRI(URI.create("foo:bar")));
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+  
+    fn = createFn(t.getType());
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    AbstractFilterValue fn = createFn(x);
+  
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Node[][] rows = {
+      new Node[] {seven},
+      new Node[] {null},
+      new Node[] {new URIReferenceImpl(xsdInt)}
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+  
+    // check the context setting
+    fn.setCurrentContext(c);
+  
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+  
+    assertTrue(c.next());
+    try {
+      assertTrue(f.equals(fn));
+      fail("No exception when testing an unbound value");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Unbound column"));
+    }
+  
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+  
+    assertFalse(c.next());
+  }
+
+}
\ No newline at end of file

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,56 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import java.net.URI;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.SimpleLiteral;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-/**
- * Tests binary logic operations.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractLogicUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  protected URI xsdBool = URI.create(XSD_NS + "boolean");
-
-  public AbstractLogicUnitTest(String name) {
-    super(name);
-  }
-
-  public static Test suite() {
-    return new TestSuite();
-  }
-
-  protected void basicTest(AbstractFilterValue op, Bool result) throws Exception {
-    op.setContextOwner(new TestContextOwner(new TestContext()));
-    assertTrue(op.equals(result));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(result.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-  }
-}
\ No newline at end of file

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AbstractLogicUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,56 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import java.net.URI;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.SimpleLiteral;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+/**
+ * Tests binary logic operations.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractLogicUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  protected URI xsdBool = URI.create(XSD_NS + "boolean");
+
+  public AbstractLogicUnitTest(String name) {
+    super(name);
+  }
+
+  public static Test suite() {
+    return new TestSuite();
+  }
+
+  protected void basicTest(AbstractFilterValue op, Bool result) throws Exception {
+    op.setContextOwner(new TestContextOwner(new TestContext()));
+    assertTrue(op.equals(result));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(result.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+  }
+}
\ No newline at end of file

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/And.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/And.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/And.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,61 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.util.List;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * A product of filters.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class And extends NAryOperatorFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -8652610238525527869L;
-
-  /**
-   * Create a product of other filters.
-   * @param operands The operands of the product
-   */
-  public And(Filter... operands) {
-    super(operands);
-  }
-
-  /**
-   * Returns the head of the list ANDed with the product of the remainder of the list.
-   * <code>false</code> and Exception is <code>false</code>.
-   * <code>true</code> and Exception is Exception.
-   * @see org.mulgara.query.filter.Filter#test()
-   */
-  boolean testList(Context context, List<Filter> filters) throws QueryException {
-    Filter head = filters.get(0);
-    if (filters.size() == 1) return head.test(context);
-
-    boolean result = false;
-    try {
-      result = head.test(context);
-    } catch (QueryException e) {
-      // false on the remainder gives false
-      if (!testList(context, tail(filters))) return false;
-      throw e;
-    }
-    return result && testList(context, tail(filters));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/And.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/And.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/And.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/And.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,61 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.util.List;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * A product of filters.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class And extends NAryOperatorFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -8652610238525527869L;
+
+  /**
+   * Create a product of other filters.
+   * @param operands The operands of the product
+   */
+  public And(Filter... operands) {
+    super(operands);
+  }
+
+  /**
+   * Returns the head of the list ANDed with the product of the remainder of the list.
+   * <code>false</code> and Exception is <code>false</code>.
+   * <code>true</code> and Exception is Exception.
+   * @see org.mulgara.query.filter.Filter#test()
+   */
+  boolean testList(Context context, List<Filter> filters) throws QueryException {
+    Filter head = filters.get(0);
+    if (filters.size() == 1) return head.test(context);
+
+    boolean result = false;
+    try {
+      result = head.test(context);
+    } catch (QueryException e) {
+      // false on the remainder gives false
+      if (!testList(context, tail(filters))) return false;
+      throw e;
+    }
+    return result && testList(context, tail(filters));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,180 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the AND operation.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class AndUnitTest extends AbstractLogicUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public AndUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new AndUnitTest("testLiteral"));
-    suite.addTest(new AndUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    Bool t = Bool.TRUE;
-    Bool f = Bool.FALSE;
-    basicTest(t, t, t);
-    basicTest(f, t, f);
-    basicTest(t, f, f);
-    basicTest(f, f, f);
-
-    basicTest(new NumericLiteral(7), t, t);
-    basicTest(new NumericLiteral(0), t, f);
-    basicTest(new NumericLiteral(7), f, f);
-    basicTest(new NumericLiteral(0), f, f);
-
-    basicTest(TypedLiteral.newLiteral("foo"), t, t);
-    basicTest(TypedLiteral.newLiteral(""), t, f);
-    basicTest(TypedLiteral.newLiteral("foo"), f, f);
-    basicTest(TypedLiteral.newLiteral(""), f, f);
-  }
-
-  void basicTest(Filter lhs, Filter rhs, Bool result) throws Exception {
-    basicTest(new And(lhs, rhs), result);
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    Var y = new Var("y");
-    And fn = new And(x, y);
-
-    URI fooBar = URI.create("foo:bar");
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Literal zero = new LiteralImpl("0", xsdInt);
-    Literal trueLiteral = new LiteralImpl("true", xsdBool);
-    Literal falseLiteral = new LiteralImpl("false", xsdBool);
-    Node[][] rows = {
-      new Node[] {seven, seven},
-      new Node[] {seven, zero},
-      new Node[] {seven, trueLiteral},
-      new Node[] {seven, falseLiteral},
-
-      new Node[] {falseLiteral, new LiteralImpl("foo", "en")},
-      new Node[] {trueLiteral, new LiteralImpl("foo", fooBar)},
-      new Node[] {new LiteralImpl(""), trueLiteral},
-      new Node[] {new LiteralImpl(""), falseLiteral},
-      new Node[] {trueLiteral, new URIReferenceImpl(fooBar)},
-      new Node[] {falseLiteral, new URIReferenceImpl(fooBar)},
-      new Node[] {trueLiteral, new BlankNodeImpl(1001)},
-      new Node[] {falseLiteral, new BlankNodeImpl(1002)},
-      new Node[] {trueLiteral, null},
-      new Node[] {falseLiteral, null}
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    Bool t = Bool.TRUE;
-    Bool f = Bool.FALSE;
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("EBV on an unknown type of literal");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on a URI");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on a blank node");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on an unbound");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/AndUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,180 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the AND operation.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class AndUnitTest extends AbstractLogicUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public AndUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new AndUnitTest("testLiteral"));
+    suite.addTest(new AndUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    Bool t = Bool.TRUE;
+    Bool f = Bool.FALSE;
+    basicTest(t, t, t);
+    basicTest(f, t, f);
+    basicTest(t, f, f);
+    basicTest(f, f, f);
+
+    basicTest(new NumericLiteral(7), t, t);
+    basicTest(new NumericLiteral(0), t, f);
+    basicTest(new NumericLiteral(7), f, f);
+    basicTest(new NumericLiteral(0), f, f);
+
+    basicTest(TypedLiteral.newLiteral("foo"), t, t);
+    basicTest(TypedLiteral.newLiteral(""), t, f);
+    basicTest(TypedLiteral.newLiteral("foo"), f, f);
+    basicTest(TypedLiteral.newLiteral(""), f, f);
+  }
+
+  void basicTest(Filter lhs, Filter rhs, Bool result) throws Exception {
+    basicTest(new And(lhs, rhs), result);
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    Var y = new Var("y");
+    And fn = new And(x, y);
+
+    URI fooBar = URI.create("foo:bar");
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Literal zero = new LiteralImpl("0", xsdInt);
+    Literal trueLiteral = new LiteralImpl("true", xsdBool);
+    Literal falseLiteral = new LiteralImpl("false", xsdBool);
+    Node[][] rows = {
+      new Node[] {seven, seven},
+      new Node[] {seven, zero},
+      new Node[] {seven, trueLiteral},
+      new Node[] {seven, falseLiteral},
+
+      new Node[] {falseLiteral, new LiteralImpl("foo", "en")},
+      new Node[] {trueLiteral, new LiteralImpl("foo", fooBar)},
+      new Node[] {new LiteralImpl(""), trueLiteral},
+      new Node[] {new LiteralImpl(""), falseLiteral},
+      new Node[] {trueLiteral, new URIReferenceImpl(fooBar)},
+      new Node[] {falseLiteral, new URIReferenceImpl(fooBar)},
+      new Node[] {trueLiteral, new BlankNodeImpl(1001)},
+      new Node[] {falseLiteral, new BlankNodeImpl(1002)},
+      new Node[] {trueLiteral, null},
+      new Node[] {falseLiteral, null}
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    Bool t = Bool.TRUE;
+    Bool f = Bool.FALSE;
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("EBV on an unknown type of literal");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on a URI");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on a blank node");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on an unbound");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,66 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.ComparableExpression;
-
-
-/**
- * A comparison operation.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class BinaryComparisonFilter extends AbstractFilterValue implements Filter {
-
-  /** The first operand */
-  protected ComparableExpression lhs;
-
-  /** The second operand */
-  protected ComparableExpression rhs;
-
-  /**
-   * Creates a binary comparison, and registers this filter as the context owner
-   * @param lhs The left comparison expression
-   * @param rhs The right comparison expression
-   */
-  BinaryComparisonFilter(ComparableExpression lhs, ComparableExpression rhs) {
-    super(lhs, rhs);
-    this.lhs = lhs;
-    this.rhs = rhs;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.Filter#test()
-   */
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    return testCmp();
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
-  protected RDFTerm resolve() throws QueryException {
-    return testCmp() ? Bool.TRUE : Bool.FALSE;
-  }
-
-  /**
-   * A comparison specific function.
-   * @return <code>true</code> iff the comparison passes.
-   * @throws QueryException If there was an error resolving the parameters of the comparison.
-   */
-  abstract boolean testCmp() throws QueryException;
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,66 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.ComparableExpression;
+
+
+/**
+ * A comparison operation.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class BinaryComparisonFilter extends AbstractFilterValue implements Filter {
+
+  /** The first operand */
+  protected ComparableExpression lhs;
+
+  /** The second operand */
+  protected ComparableExpression rhs;
+
+  /**
+   * Creates a binary comparison, and registers this filter as the context owner
+   * @param lhs The left comparison expression
+   * @param rhs The right comparison expression
+   */
+  BinaryComparisonFilter(ComparableExpression lhs, ComparableExpression rhs) {
+    super(lhs, rhs);
+    this.lhs = lhs;
+    this.rhs = rhs;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.Filter#test()
+   */
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    return testCmp();
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
+  protected RDFTerm resolve() throws QueryException {
+    return testCmp() ? Bool.TRUE : Bool.FALSE;
+  }
+
+  /**
+   * A comparison specific function.
+   * @return <code>true</code> iff the comparison passes.
+   * @throws QueryException If there was an error resolving the parameters of the comparison.
+   */
+  abstract boolean testCmp() throws QueryException;
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,365 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-import java.util.Date;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.ComparableExpression;
-import org.mulgara.query.filter.value.DateTime;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the inequality functions.
- *
- * @created Apr 16, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class BinaryComparisonUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  protected URI xsdFloat = URI.create(XSD_NS + "float");
-  protected URI xsdString = URI.create(XSD_NS + "string");
-  protected URI xsdDate = URI.create(XSD_NS + "dateTime");
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public BinaryComparisonUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new BinaryComparisonUnitTest("testLiteral"));
-    suite.addTest(new BinaryComparisonUnitTest("testVarCompatible"));
-    suite.addTest(new BinaryComparisonUnitTest("testVarInCompatible"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    // integers
-    ComparableExpression smaller = TypedLiteral.newLiteral(7);
-    ComparableExpression larger = TypedLiteral.newLiteral(8);
-    compatibleTest(smaller, larger);
-    // floats
-    smaller = TypedLiteral.newLiteral(7.0);
-    larger = TypedLiteral.newLiteral(8.0);
-    compatibleTest(smaller, larger);
-    // float/integer
-    larger = TypedLiteral.newLiteral(8);
-    compatibleTest(smaller, larger);
-
-    // simple literals
-    smaller = TypedLiteral.newLiteral("foo", null, null);
-    larger = TypedLiteral.newLiteral("goo", null, null);
-    compatibleTest(smaller, larger);
-    // simple literals, with language codes
-    smaller = TypedLiteral.newLiteral("foo", null, "en");
-    larger = TypedLiteral.newLiteral("foo", null, "fr");
-    compatibleTest(smaller, larger);
-    larger = TypedLiteral.newLiteral("goo", null, "en");
-    compatibleTest(smaller, larger);
-    // typed literal strings
-    smaller = TypedLiteral.newLiteral("foo");
-    larger = TypedLiteral.newLiteral("goo");
-    compatibleTest(smaller, larger);
-
-    // booleans
-    smaller = f;
-    larger = t;
-    compatibleTest(smaller, larger);
-
-    // typed literal strings
-    Date time = new Date();
-    smaller = new DateTime(time);
-    time = new Date();
-    time.setTime(time.getTime() + 100);
-    larger = new DateTime(time);
-    compatibleTest(smaller, larger);
-
-    // compare unequal literal types starting with an int
-    smaller = TypedLiteral.newLiteral(7);
-    larger = TypedLiteral.newLiteral("7", null, null);
-    incompatibleTest(smaller, larger);
-    larger = TypedLiteral.newLiteral("foo", null, "en");
-    incompatibleTest(smaller, larger);
-    larger = TypedLiteral.newLiteral("foo");
-    incompatibleTest(smaller, larger);
-    larger = t;
-    incompatibleTest(smaller, larger);
-    larger = new DateTime(time);
-    incompatibleTest(smaller, larger);
-
-    // compare unequal literal types starting with a float
-    smaller = TypedLiteral.newLiteral(7.0);
-    larger = TypedLiteral.newLiteral("7", null, null);
-    incompatibleTest(smaller, larger);
-    larger = TypedLiteral.newLiteral("foo", null, "en");
-    incompatibleTest(smaller, larger);
-    larger = TypedLiteral.newLiteral("foo");
-    incompatibleTest(smaller, larger);
-    larger = t;
-    incompatibleTest(smaller, larger);
-    larger = new DateTime(time);
-    incompatibleTest(smaller, larger);
-
-    // compare unequal literal types starting with a simple literal
-    smaller = TypedLiteral.newLiteral("foo", null, null);
-    larger = TypedLiteral.newLiteral("foo");
-    incompatibleTest(smaller, larger);
-    larger = t;
-    incompatibleTest(smaller, larger);
-    larger = new DateTime(time);
-    incompatibleTest(smaller, larger);
-
-    // compare unequal literal types starting with a language coded simple literal
-    smaller = TypedLiteral.newLiteral("foo", null, "en");
-    larger = TypedLiteral.newLiteral("foo");
-    incompatibleTest(smaller, larger);
-    larger = t;
-    incompatibleTest(smaller, larger);
-    larger = new DateTime(time);
-    incompatibleTest(smaller, larger);
-
-    // compare unequal literal types starting with a string literal
-    smaller = TypedLiteral.newLiteral("foo");
-    larger = t;
-    incompatibleTest(smaller, larger);
-    larger = new DateTime(time);
-    incompatibleTest(smaller, larger);
-
-    // compare unequal literal types
-    smaller = t;
-    larger = new DateTime(time);
-    incompatibleTest(smaller, larger);
-
-    
-    smaller = TypedLiteral.newLiteral("foo", null, null);
-    larger = TypedLiteral.newLiteral("foo", xsdString, null);
-    incompatibleTest(smaller, larger);
-
-  }
-
-  private void compatibleTest(ComparableExpression smaller, ComparableExpression larger) throws Exception {
-    assertTrue(t.equals(new LessThan(smaller, larger)));
-    assertTrue(f.equals(new LessThan(larger, smaller)));
-    assertTrue(f.equals(new GreaterThan(smaller, larger)));
-    assertTrue(t.equals(new GreaterThan(larger, smaller)));
-    assertTrue(t.equals(new LessThanEqualTo(smaller, larger)));
-    assertTrue(f.equals(new LessThanEqualTo(larger, smaller)));
-    assertTrue(t.equals(new LessThanEqualTo(smaller, smaller)));
-    assertTrue(f.equals(new GreaterThanEqualTo(smaller, larger)));
-    assertTrue(t.equals(new GreaterThanEqualTo(larger, smaller)));
-    assertTrue(t.equals(new GreaterThanEqualTo(smaller, smaller)));
-  }
-
-  private void checkIncompatible(BinaryComparisonFilter op) throws Exception {
-    try {
-      op.getValue();
-      fail("Successfully compared incompatible types");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-  }
-
-  private void incompatibleTest(ComparableExpression lhs, ComparableExpression rhs) throws Exception {
-    checkIncompatible(new LessThan(lhs, rhs));
-    checkIncompatible(new LessThan(rhs, lhs));
-    checkIncompatible(new GreaterThan(lhs, rhs));
-    checkIncompatible(new GreaterThan(rhs, lhs));
-    checkIncompatible(new LessThanEqualTo(lhs, rhs));
-    checkIncompatible(new LessThanEqualTo(rhs, lhs));
-    checkIncompatible(new GreaterThanEqualTo(lhs, rhs));
-    checkIncompatible(new GreaterThanEqualTo(rhs, lhs));
-  }
-
-  public void testVarCompatible() throws Exception {
-    Var x = new Var("x");
-    Var y = new Var("y");
-    BinaryComparisonFilter ltT = new LessThan(x, y);
-    BinaryComparisonFilter ltF = new LessThan(y, x);
-    BinaryComparisonFilter gtT = new GreaterThan(x, y);
-    BinaryComparisonFilter gtF = new GreaterThan(y, x);
-
-    BinaryComparisonFilter lteT = new LessThanEqualTo(x, y);
-    BinaryComparisonFilter lteF = new LessThanEqualTo(y, x);
-    BinaryComparisonFilter lteE = new LessThanEqualTo(x, x);
-    BinaryComparisonFilter gteT = new GreaterThanEqualTo(x, y);
-    BinaryComparisonFilter gteF = new GreaterThanEqualTo(y, x);
-    BinaryComparisonFilter gteE = new GreaterThanEqualTo(x, x);
-
-    BinaryComparisonFilter[] comps  = new BinaryComparisonFilter[] { ltT, ltF, gtT, gtF, lteT, lteF, lteE, gteT, gteF, gteE };
-    
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Literal eight = new LiteralImpl("8", xsdInt);
-    Literal sevenF = new LiteralImpl("7.0", xsdFloat);
-    Literal eightF = new LiteralImpl("8.0", xsdFloat);
-    Literal simpleFoo = new LiteralImpl("foo");
-    Literal simpleGoo = new LiteralImpl("goo");
-    Literal simpleFooEn = new LiteralImpl("foo", "en");
-    Literal simpleFooFr = new LiteralImpl("foo", "fr");
-    Literal simpleGooEn = new LiteralImpl("goo", "en");
-    Literal foo = new LiteralImpl("foo", xsdString);
-    Literal goo = new LiteralImpl("goo", xsdString);
-    Literal litFalse = new LiteralImpl("false", t.getType().getValue());
-    Literal litTrue = new LiteralImpl("true", t.getType().getValue());
-    Literal now = new LiteralImpl("2008-04-16T21:57:00Z", xsdDate);
-    Literal soon = new LiteralImpl("2008-04-16T21:58:01Z", xsdDate);
-    Node[][] rows = {
-      new Node[] {seven, eight},
-      new Node[] {sevenF, eightF},
-
-      new Node[] {simpleFoo, simpleGoo},
-      new Node[] {simpleFooEn, simpleFooFr},
-      new Node[] {simpleFooEn, simpleGooEn},
-      new Node[] {foo, goo},
-      new Node[] {litFalse, litTrue},
-      new Node[] {now, soon}
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    TestContextOwner ctxOwner = new TestContextOwner(c);
-    for (BinaryComparisonFilter f: comps) f.setContextOwner(ctxOwner);
-
-    // check the context setting
-    for (BinaryComparisonFilter f: comps) f.setCurrentContext(c);
-
-    // run the tests
-    while (c.next()) compatibleTest(c, comps);
-  }
-
-  private void compatibleTest(TestContext c, BinaryComparisonFilter[] comps) throws Exception {
-    assertTrue(t.equals(comps[0]));
-    assertTrue(f.equals(comps[1]));
-    assertTrue(f.equals(comps[2]));
-    assertTrue(t.equals(comps[3]));
-    assertTrue(t.equals(comps[4]));
-    assertTrue(f.equals(comps[5]));
-    assertTrue(t.equals(comps[6]));
-    assertTrue(f.equals(comps[7]));
-    assertTrue(t.equals(comps[8]));
-    assertTrue(t.equals(comps[9]));
-  }
-
-  public void testVarInCompatible() throws Exception {
-    Var x = new Var("x");
-    Var y = new Var("y");
-    BinaryComparisonFilter ltT = new LessThan(x, y);
-    BinaryComparisonFilter ltF = new LessThan(y, x);
-    BinaryComparisonFilter gtT = new GreaterThan(x, y);
-    BinaryComparisonFilter gtF = new GreaterThan(y, x);
-    BinaryComparisonFilter lteT = new LessThanEqualTo(x, y);
-    BinaryComparisonFilter lteF = new LessThanEqualTo(y, x);
-    BinaryComparisonFilter gteT = new GreaterThanEqualTo(x, y);
-    BinaryComparisonFilter gteF = new GreaterThanEqualTo(y, x);
-
-    BinaryComparisonFilter[] comps  = new BinaryComparisonFilter[] { ltT, ltF, gtT, gtF, lteT, lteF, gteT, gteF };
-    
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Literal sevenSimple = new LiteralImpl("7");
-    Literal sevenF = new LiteralImpl("7.0", xsdFloat);
-    Literal simpleFoo = new LiteralImpl("foo");
-    Literal simpleFooEn = new LiteralImpl("foo", "en");
-    Literal foo = new LiteralImpl("foo", xsdString);
-    Literal litTrue = new LiteralImpl("true", t.getType().getValue());
-    Literal now = new LiteralImpl("2008-04-16T21:57:00Z", xsdDate);
-    URIReferenceImpl intRef = new URIReferenceImpl(xsdInt);
-    BlankNodeImpl bn = new BlankNodeImpl(101);
-    Node[][] rows = {
-      new Node[] {seven, sevenSimple},
-      new Node[] {seven, simpleFooEn},
-      new Node[] {seven, foo},
-      new Node[] {seven, litTrue},
-      new Node[] {seven, now},
-      new Node[] {sevenF, sevenSimple},
-      new Node[] {sevenF, simpleFooEn},
-      new Node[] {sevenF, foo},
-      new Node[] {sevenF, litTrue},
-      new Node[] {sevenF, now},
-      new Node[] {simpleFoo, foo},
-      new Node[] {simpleFoo, litTrue},
-      new Node[] {simpleFoo, now},
-      new Node[] {simpleFooEn, foo},
-      new Node[] {simpleFooEn, litTrue},
-      new Node[] {simpleFooEn, now},
-      new Node[] {foo, litTrue},
-      new Node[] {foo, now},  // 17
-      new Node[] {litTrue, now},
-      new Node[] {seven, intRef},  //19
-      new Node[] {sevenF, intRef},
-      new Node[] {simpleFoo, intRef},
-      new Node[] {simpleFooEn, intRef},
-      new Node[] {foo, intRef},
-      new Node[] {litTrue, intRef},
-      new Node[] {now, intRef},
-      new Node[] {seven, bn},
-      new Node[] {sevenF, bn},
-      new Node[] {simpleFoo, bn},
-      new Node[] {simpleFooEn, bn},
-      new Node[] {foo, bn},
-      new Node[] {litTrue, bn},
-      new Node[] {now, bn}
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    TestContextOwner ctxOwner = new TestContextOwner(c);
-    for (BinaryComparisonFilter f: comps) f.setContextOwner(ctxOwner);
-
-    // check the context setting
-    for (BinaryComparisonFilter f: comps) f.setCurrentContext(c);
-
-    // run the tests
-    int r = 0;
-    while (c.next()) {
-      int test = 0;
-      try {
-        for (BinaryComparisonFilter f: comps) {
-          checkIncompatible(f);
-          test++;
-        }
-      } catch (Error e) {
-        System.err.println("Failed on row: " + r + "  test=" + test);
-        throw e;
-      }
-      r++;
-    }
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryComparisonUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,365 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+import java.util.Date;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.ComparableExpression;
+import org.mulgara.query.filter.value.DateTime;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the inequality functions.
+ *
+ * @created Apr 16, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class BinaryComparisonUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  protected URI xsdFloat = URI.create(XSD_NS + "float");
+  protected URI xsdString = URI.create(XSD_NS + "string");
+  protected URI xsdDate = URI.create(XSD_NS + "dateTime");
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public BinaryComparisonUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new BinaryComparisonUnitTest("testLiteral"));
+    suite.addTest(new BinaryComparisonUnitTest("testVarCompatible"));
+    suite.addTest(new BinaryComparisonUnitTest("testVarInCompatible"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    // integers
+    ComparableExpression smaller = TypedLiteral.newLiteral(7);
+    ComparableExpression larger = TypedLiteral.newLiteral(8);
+    compatibleTest(smaller, larger);
+    // floats
+    smaller = TypedLiteral.newLiteral(7.0);
+    larger = TypedLiteral.newLiteral(8.0);
+    compatibleTest(smaller, larger);
+    // float/integer
+    larger = TypedLiteral.newLiteral(8);
+    compatibleTest(smaller, larger);
+
+    // simple literals
+    smaller = TypedLiteral.newLiteral("foo", null, null);
+    larger = TypedLiteral.newLiteral("goo", null, null);
+    compatibleTest(smaller, larger);
+    // simple literals, with language codes
+    smaller = TypedLiteral.newLiteral("foo", null, "en");
+    larger = TypedLiteral.newLiteral("foo", null, "fr");
+    compatibleTest(smaller, larger);
+    larger = TypedLiteral.newLiteral("goo", null, "en");
+    compatibleTest(smaller, larger);
+    // typed literal strings
+    smaller = TypedLiteral.newLiteral("foo");
+    larger = TypedLiteral.newLiteral("goo");
+    compatibleTest(smaller, larger);
+
+    // booleans
+    smaller = f;
+    larger = t;
+    compatibleTest(smaller, larger);
+
+    // typed literal strings
+    Date time = new Date();
+    smaller = new DateTime(time);
+    time = new Date();
+    time.setTime(time.getTime() + 100);
+    larger = new DateTime(time);
+    compatibleTest(smaller, larger);
+
+    // compare unequal literal types starting with an int
+    smaller = TypedLiteral.newLiteral(7);
+    larger = TypedLiteral.newLiteral("7", null, null);
+    incompatibleTest(smaller, larger);
+    larger = TypedLiteral.newLiteral("foo", null, "en");
+    incompatibleTest(smaller, larger);
+    larger = TypedLiteral.newLiteral("foo");
+    incompatibleTest(smaller, larger);
+    larger = t;
+    incompatibleTest(smaller, larger);
+    larger = new DateTime(time);
+    incompatibleTest(smaller, larger);
+
+    // compare unequal literal types starting with a float
+    smaller = TypedLiteral.newLiteral(7.0);
+    larger = TypedLiteral.newLiteral("7", null, null);
+    incompatibleTest(smaller, larger);
+    larger = TypedLiteral.newLiteral("foo", null, "en");
+    incompatibleTest(smaller, larger);
+    larger = TypedLiteral.newLiteral("foo");
+    incompatibleTest(smaller, larger);
+    larger = t;
+    incompatibleTest(smaller, larger);
+    larger = new DateTime(time);
+    incompatibleTest(smaller, larger);
+
+    // compare unequal literal types starting with a simple literal
+    smaller = TypedLiteral.newLiteral("foo", null, null);
+    larger = TypedLiteral.newLiteral("foo");
+    incompatibleTest(smaller, larger);
+    larger = t;
+    incompatibleTest(smaller, larger);
+    larger = new DateTime(time);
+    incompatibleTest(smaller, larger);
+
+    // compare unequal literal types starting with a language coded simple literal
+    smaller = TypedLiteral.newLiteral("foo", null, "en");
+    larger = TypedLiteral.newLiteral("foo");
+    incompatibleTest(smaller, larger);
+    larger = t;
+    incompatibleTest(smaller, larger);
+    larger = new DateTime(time);
+    incompatibleTest(smaller, larger);
+
+    // compare unequal literal types starting with a string literal
+    smaller = TypedLiteral.newLiteral("foo");
+    larger = t;
+    incompatibleTest(smaller, larger);
+    larger = new DateTime(time);
+    incompatibleTest(smaller, larger);
+
+    // compare unequal literal types
+    smaller = t;
+    larger = new DateTime(time);
+    incompatibleTest(smaller, larger);
+
+    
+    smaller = TypedLiteral.newLiteral("foo", null, null);
+    larger = TypedLiteral.newLiteral("foo", xsdString, null);
+    incompatibleTest(smaller, larger);
+
+  }
+
+  private void compatibleTest(ComparableExpression smaller, ComparableExpression larger) throws Exception {
+    assertTrue(t.equals(new LessThan(smaller, larger)));
+    assertTrue(f.equals(new LessThan(larger, smaller)));
+    assertTrue(f.equals(new GreaterThan(smaller, larger)));
+    assertTrue(t.equals(new GreaterThan(larger, smaller)));
+    assertTrue(t.equals(new LessThanEqualTo(smaller, larger)));
+    assertTrue(f.equals(new LessThanEqualTo(larger, smaller)));
+    assertTrue(t.equals(new LessThanEqualTo(smaller, smaller)));
+    assertTrue(f.equals(new GreaterThanEqualTo(smaller, larger)));
+    assertTrue(t.equals(new GreaterThanEqualTo(larger, smaller)));
+    assertTrue(t.equals(new GreaterThanEqualTo(smaller, smaller)));
+  }
+
+  private void checkIncompatible(BinaryComparisonFilter op) throws Exception {
+    try {
+      op.getValue();
+      fail("Successfully compared incompatible types");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+  }
+
+  private void incompatibleTest(ComparableExpression lhs, ComparableExpression rhs) throws Exception {
+    checkIncompatible(new LessThan(lhs, rhs));
+    checkIncompatible(new LessThan(rhs, lhs));
+    checkIncompatible(new GreaterThan(lhs, rhs));
+    checkIncompatible(new GreaterThan(rhs, lhs));
+    checkIncompatible(new LessThanEqualTo(lhs, rhs));
+    checkIncompatible(new LessThanEqualTo(rhs, lhs));
+    checkIncompatible(new GreaterThanEqualTo(lhs, rhs));
+    checkIncompatible(new GreaterThanEqualTo(rhs, lhs));
+  }
+
+  public void testVarCompatible() throws Exception {
+    Var x = new Var("x");
+    Var y = new Var("y");
+    BinaryComparisonFilter ltT = new LessThan(x, y);
+    BinaryComparisonFilter ltF = new LessThan(y, x);
+    BinaryComparisonFilter gtT = new GreaterThan(x, y);
+    BinaryComparisonFilter gtF = new GreaterThan(y, x);
+
+    BinaryComparisonFilter lteT = new LessThanEqualTo(x, y);
+    BinaryComparisonFilter lteF = new LessThanEqualTo(y, x);
+    BinaryComparisonFilter lteE = new LessThanEqualTo(x, x);
+    BinaryComparisonFilter gteT = new GreaterThanEqualTo(x, y);
+    BinaryComparisonFilter gteF = new GreaterThanEqualTo(y, x);
+    BinaryComparisonFilter gteE = new GreaterThanEqualTo(x, x);
+
+    BinaryComparisonFilter[] comps  = new BinaryComparisonFilter[] { ltT, ltF, gtT, gtF, lteT, lteF, lteE, gteT, gteF, gteE };
+    
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Literal eight = new LiteralImpl("8", xsdInt);
+    Literal sevenF = new LiteralImpl("7.0", xsdFloat);
+    Literal eightF = new LiteralImpl("8.0", xsdFloat);
+    Literal simpleFoo = new LiteralImpl("foo");
+    Literal simpleGoo = new LiteralImpl("goo");
+    Literal simpleFooEn = new LiteralImpl("foo", "en");
+    Literal simpleFooFr = new LiteralImpl("foo", "fr");
+    Literal simpleGooEn = new LiteralImpl("goo", "en");
+    Literal foo = new LiteralImpl("foo", xsdString);
+    Literal goo = new LiteralImpl("goo", xsdString);
+    Literal litFalse = new LiteralImpl("false", t.getType().getValue());
+    Literal litTrue = new LiteralImpl("true", t.getType().getValue());
+    Literal now = new LiteralImpl("2008-04-16T21:57:00Z", xsdDate);
+    Literal soon = new LiteralImpl("2008-04-16T21:58:01Z", xsdDate);
+    Node[][] rows = {
+      new Node[] {seven, eight},
+      new Node[] {sevenF, eightF},
+
+      new Node[] {simpleFoo, simpleGoo},
+      new Node[] {simpleFooEn, simpleFooFr},
+      new Node[] {simpleFooEn, simpleGooEn},
+      new Node[] {foo, goo},
+      new Node[] {litFalse, litTrue},
+      new Node[] {now, soon}
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    TestContextOwner ctxOwner = new TestContextOwner(c);
+    for (BinaryComparisonFilter f: comps) f.setContextOwner(ctxOwner);
+
+    // check the context setting
+    for (BinaryComparisonFilter f: comps) f.setCurrentContext(c);
+
+    // run the tests
+    while (c.next()) compatibleTest(c, comps);
+  }
+
+  private void compatibleTest(TestContext c, BinaryComparisonFilter[] comps) throws Exception {
+    assertTrue(t.equals(comps[0]));
+    assertTrue(f.equals(comps[1]));
+    assertTrue(f.equals(comps[2]));
+    assertTrue(t.equals(comps[3]));
+    assertTrue(t.equals(comps[4]));
+    assertTrue(f.equals(comps[5]));
+    assertTrue(t.equals(comps[6]));
+    assertTrue(f.equals(comps[7]));
+    assertTrue(t.equals(comps[8]));
+    assertTrue(t.equals(comps[9]));
+  }
+
+  public void testVarInCompatible() throws Exception {
+    Var x = new Var("x");
+    Var y = new Var("y");
+    BinaryComparisonFilter ltT = new LessThan(x, y);
+    BinaryComparisonFilter ltF = new LessThan(y, x);
+    BinaryComparisonFilter gtT = new GreaterThan(x, y);
+    BinaryComparisonFilter gtF = new GreaterThan(y, x);
+    BinaryComparisonFilter lteT = new LessThanEqualTo(x, y);
+    BinaryComparisonFilter lteF = new LessThanEqualTo(y, x);
+    BinaryComparisonFilter gteT = new GreaterThanEqualTo(x, y);
+    BinaryComparisonFilter gteF = new GreaterThanEqualTo(y, x);
+
+    BinaryComparisonFilter[] comps  = new BinaryComparisonFilter[] { ltT, ltF, gtT, gtF, lteT, lteF, gteT, gteF };
+    
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Literal sevenSimple = new LiteralImpl("7");
+    Literal sevenF = new LiteralImpl("7.0", xsdFloat);
+    Literal simpleFoo = new LiteralImpl("foo");
+    Literal simpleFooEn = new LiteralImpl("foo", "en");
+    Literal foo = new LiteralImpl("foo", xsdString);
+    Literal litTrue = new LiteralImpl("true", t.getType().getValue());
+    Literal now = new LiteralImpl("2008-04-16T21:57:00Z", xsdDate);
+    URIReferenceImpl intRef = new URIReferenceImpl(xsdInt);
+    BlankNodeImpl bn = new BlankNodeImpl(101);
+    Node[][] rows = {
+      new Node[] {seven, sevenSimple},
+      new Node[] {seven, simpleFooEn},
+      new Node[] {seven, foo},
+      new Node[] {seven, litTrue},
+      new Node[] {seven, now},
+      new Node[] {sevenF, sevenSimple},
+      new Node[] {sevenF, simpleFooEn},
+      new Node[] {sevenF, foo},
+      new Node[] {sevenF, litTrue},
+      new Node[] {sevenF, now},
+      new Node[] {simpleFoo, foo},
+      new Node[] {simpleFoo, litTrue},
+      new Node[] {simpleFoo, now},
+      new Node[] {simpleFooEn, foo},
+      new Node[] {simpleFooEn, litTrue},
+      new Node[] {simpleFooEn, now},
+      new Node[] {foo, litTrue},
+      new Node[] {foo, now},  // 17
+      new Node[] {litTrue, now},
+      new Node[] {seven, intRef},  //19
+      new Node[] {sevenF, intRef},
+      new Node[] {simpleFoo, intRef},
+      new Node[] {simpleFooEn, intRef},
+      new Node[] {foo, intRef},
+      new Node[] {litTrue, intRef},
+      new Node[] {now, intRef},
+      new Node[] {seven, bn},
+      new Node[] {sevenF, bn},
+      new Node[] {simpleFoo, bn},
+      new Node[] {simpleFooEn, bn},
+      new Node[] {foo, bn},
+      new Node[] {litTrue, bn},
+      new Node[] {now, bn}
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    TestContextOwner ctxOwner = new TestContextOwner(c);
+    for (BinaryComparisonFilter f: comps) f.setContextOwner(ctxOwner);
+
+    // check the context setting
+    for (BinaryComparisonFilter f: comps) f.setCurrentContext(c);
+
+    // run the tests
+    int r = 0;
+    while (c.next()) {
+      int test = 0;
+      try {
+        for (BinaryComparisonFilter f: comps) {
+          checkIncompatible(f);
+          test++;
+        }
+      } catch (Error e) {
+        System.err.println("Failed on row: " + r + "  test=" + test);
+        throw e;
+      }
+      r++;
+    }
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,65 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-
-
-/**
- * A test operation for general RDF Terms, specifically equality or inequality.
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class BinaryTestFilter extends AbstractFilterValue implements Filter {
-
-  /** The first operand */
-  protected RDFTerm lhs;
-
-  /** The second operand */
-  protected RDFTerm rhs;
-
-  /**
-   * Creates a binary test, and registers this filter as the context owner
-   * @param lhs The left expression
-   * @param rhs The right expression
-   */
-  BinaryTestFilter(RDFTerm lhs, RDFTerm rhs) {
-    super(lhs, rhs);
-    this.lhs = lhs;
-    this.rhs = rhs;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.Filter#test()
-   */
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    return testCmp();
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
-  protected RDFTerm resolve() throws QueryException {
-    return testCmp() ? Bool.TRUE : Bool.FALSE;
-  }
-
-  /**
-   * A test specific comparison.
-   * @return <code>true</code> iff the test passes.
-   * @throws QueryException If there was an error resolving the operands
-   */
-  abstract boolean testCmp() throws QueryException;
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,65 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+
+
+/**
+ * A test operation for general RDF Terms, specifically equality or inequality.
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class BinaryTestFilter extends AbstractFilterValue implements Filter {
+
+  /** The first operand */
+  protected RDFTerm lhs;
+
+  /** The second operand */
+  protected RDFTerm rhs;
+
+  /**
+   * Creates a binary test, and registers this filter as the context owner
+   * @param lhs The left expression
+   * @param rhs The right expression
+   */
+  BinaryTestFilter(RDFTerm lhs, RDFTerm rhs) {
+    super(lhs, rhs);
+    this.lhs = lhs;
+    this.rhs = rhs;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.Filter#test()
+   */
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    return testCmp();
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
+  protected RDFTerm resolve() throws QueryException {
+    return testCmp() ? Bool.TRUE : Bool.FALSE;
+  }
+
+  /**
+   * A test specific comparison.
+   * @return <code>true</code> iff the test passes.
+   * @throws QueryException If there was an error resolving the operands
+   */
+  abstract boolean testCmp() throws QueryException;
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BoundFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,44 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Var;
-
-
-/**
- * Tests a variable to see if it is bound.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class BoundFn extends AbstractBooleanFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 1266926199143113812L;
-
-  /**
-   * Create a function for testing a variable
-   * @param The variable to test
-   */
-  public BoundFn(Var operand) {
-    super(operand);
-  }
-
-  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
-  boolean fnTest() throws QueryException {
-    return ((Var)operand).isBound();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BoundFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BoundFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,44 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Var;
+
+
+/**
+ * Tests a variable to see if it is bound.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class BoundFn extends AbstractBooleanFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 1266926199143113812L;
+
+  /**
+   * Create a function for testing a variable
+   * @param The variable to test
+   */
+  public BoundFn(Var operand) {
+    super(operand);
+  }
+
+  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
+  boolean fnTest() throws QueryException {
+    return ((Var)operand).isBound();
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,133 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.Var;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the BOUND function.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class BoundFnUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public BoundFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new BoundFnUnitTest("testVar"));
-    suite.addTest(new BoundFnUnitTest("testGuard"));
-    return suite;
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    BoundFn fn = new BoundFn(x);
-
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Node[][] rows = {
-      new Node[] {seven},
-      new Node[] {null},
-      new Node[] {seven},
-      new Node[] {null},
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertFalse(c.next());
-  }
-  
-  public void testGuard() throws Exception {
-    Var x = new Var("x");
-    AbstractFilterValue fn = new And(new BoundFn(x), new IsBlankFn(x));
-
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Node[][] rows = {
-      new Node[] {seven},
-      new Node[] {null},
-      new Node[] {new BlankNodeImpl(101)},
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BoundFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,133 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the BOUND function.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class BoundFnUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public BoundFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new BoundFnUnitTest("testVar"));
+    suite.addTest(new BoundFnUnitTest("testGuard"));
+    return suite;
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    BoundFn fn = new BoundFn(x);
+
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Node[][] rows = {
+      new Node[] {seven},
+      new Node[] {null},
+      new Node[] {seven},
+      new Node[] {null},
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertFalse(c.next());
+  }
+  
+  public void testGuard() throws Exception {
+    Var x = new Var("x");
+    AbstractFilterValue fn = new And(new BoundFn(x), new IsBlankFn(x));
+
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Node[][] rows = {
+      new Node[] {seven},
+      new Node[] {null},
+      new Node[] {new BlankNodeImpl(101)},
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/Context.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Context.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Context.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,60 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-
-
-/**
- * A context for processing filters and resolving variables. Implementing classes are immutable.
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface Context {
-
-  /** An invalid index to indicate that a variable is not bound */
-  static final int NOT_BOUND = -1;
-
-  /**
-   * Gets the current binding to a local value (a long) for a given internal column number.
-   * @return the value in the column number specified in the current context.
-   */
-  public long getColumnValue(int columnNumber) throws QueryException;
-
-  
-  /**
-   * Tests if a given column is bound in the current context.
-   * @return <code>true</code> iff the column exists and is bound.
-   */
-  public boolean isBound(int columnNumber) throws QueryException;
-
-  
-  /**
-   * Gets the internal column number for a column with the given name
-   * @param name The name of the column to search for.
-   * @return The column number for the column with the given name.
-   */
-  public int getInternalColumnIndex(String name);
-
-  /**
-   * Globalize a gNode into a data object.
-   * @param gNode The graph node to globalize
-   * @return A {@link org.jrdf.graph.Node} for the given graph node.
-   * @throws QueryException If a globalize exception is encountered.
-   */
-  public Node globalize(long gNode) throws QueryException;
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/Context.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Context.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/Context.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Context.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,60 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+
+
+/**
+ * A context for processing filters and resolving variables. Implementing classes are immutable.
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface Context {
+
+  /** An invalid index to indicate that a variable is not bound */
+  static final int NOT_BOUND = -1;
+
+  /**
+   * Gets the current binding to a local value (a long) for a given internal column number.
+   * @return the value in the column number specified in the current context.
+   */
+  public long getColumnValue(int columnNumber) throws QueryException;
+
+  
+  /**
+   * Tests if a given column is bound in the current context.
+   * @return <code>true</code> iff the column exists and is bound.
+   */
+  public boolean isBound(int columnNumber) throws QueryException;
+
+  
+  /**
+   * Gets the internal column number for a column with the given name
+   * @param name The name of the column to search for.
+   * @return The column number for the column with the given name.
+   */
+  public int getInternalColumnIndex(String name);
+
+  /**
+   * Globalize a gNode into a data object.
+   * @param gNode The graph node to globalize
+   * @return A {@link org.jrdf.graph.Node} for the given graph node.
+   * @throws QueryException If a globalize exception is encountered.
+   */
+  public Node globalize(long gNode) throws QueryException;
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,37 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-
-/**
- * Defines how to set and retrieve context
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface ContextOwner {
-
-  /**
-   * Set the current context. This *must* be run at the start of every test else the underlying
-   * values will not resolve correctly.
-   * @param context The context for this test.
-   */
-  public void setCurrentContext(Context context);
-  
-  /**
-   * Get the current context. This is a callback that is used during a test.
-   * @return The context of the currently running test, or the most recent context if not in a test.
-   */
-  public Context getCurrentContext();
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/ContextOwner.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,37 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+
+/**
+ * Defines how to set and retrieve context
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface ContextOwner {
+
+  /**
+   * Set the current context. This *must* be run at the start of every test else the underlying
+   * values will not resolve correctly.
+   * @param context The context for this test.
+   */
+  public void setCurrentContext(Context context);
+  
+  /**
+   * Get the current context. This is a callback that is used during a test.
+   * @return The context of the currently running test, or the most recent context if not in a test.
+   */
+  public Context getCurrentContext();
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,306 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.BlankNodeValue;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.IRI;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the equals, not-equals, and sameTerm functions.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class EqualityComparisonUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  protected URI xsdFloat = URI.create(XSD_NS + "float");
-  protected URI xsdString = URI.create(XSD_NS + "string");
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public EqualityComparisonUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new EqualityComparisonUnitTest("testLiteral"));
-    suite.addTest(new EqualityComparisonUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    // compares two equal literals
-    Equals fn = new Equals(t, t);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-    assertTrue(t.equals(new SameTerm(t, t)));
-    assertTrue(f.equals(new NotEquals(t, t)));
-
-    // compares two other equal literals
-    fn = new Equals(f, f);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-    assertTrue(t.equals(new SameTerm(f, f)));
-    assertTrue(f.equals(new NotEquals(f, f)));
-
-    // compare unequal literals
-    RDFTerm lhs = t;
-    RDFTerm rhs = f;
-    try {
-      assertTrue(f.equals(new Equals(lhs, rhs)));
-      fail("Unequal literals should throw an exception when compared for equality");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error"));
-    }
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare equivalent but different literals
-    lhs = TypedLiteral.newLiteral(7);
-    rhs = TypedLiteral.newLiteral(7.0);
-    try {
-      assertTrue(f.equals(new Equals(lhs, rhs)));
-      fail("Unequal literals should throw an exception when compared for equality");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error"));
-    }
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare unequal literal strings
-    lhs = TypedLiteral.newLiteral("foo", null, null);
-    rhs = TypedLiteral.newLiteral("fool", null, null);
-    try {
-      assertTrue(f.equals(new Equals(lhs, rhs)));
-      fail("Unequal literals should throw an exception when compared for equality");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error"));
-    }
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare unequal literals types
-    lhs = TypedLiteral.newLiteral("foo", null, null);
-    rhs = TypedLiteral.newLiteral("foo", xsdString, null);
-    try {
-      assertTrue(f.equals(new Equals(lhs, rhs)));
-      fail("Unequal literals should throw an exception when compared for equality");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error"));
-    }
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare unequal languages
-    lhs = TypedLiteral.newLiteral("foo", null, "en");
-    rhs = TypedLiteral.newLiteral("foo", null, "fr");
-    try {
-      assertTrue(f.equals(new Equals(lhs, rhs)));
-      fail("Unequal literals should throw an exception when compared for equality");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error"));
-    }
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare equal languages
-    lhs = TypedLiteral.newLiteral("foo", null, "en");
-    rhs = TypedLiteral.newLiteral("foo", null, "en");
-    assertTrue(t.equals(new Equals(lhs, rhs)));
-    assertTrue(t.equals(new SameTerm(lhs, rhs)));
-    assertTrue(f.equals(new NotEquals(lhs, rhs)));
-
-    // compare different URIs
-    lhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
-    rhs = new IRI(URI.create("http://mulgara.org/path/to/../to/data.rdf"));
-    assertTrue(f.equals(new Equals(lhs, rhs)));
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare the same URIs
-    lhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
-    rhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
-    assertTrue(t.equals(new Equals(lhs, rhs)));
-    assertTrue(t.equals(new SameTerm(lhs, rhs)));
-    assertTrue(f.equals(new NotEquals(lhs, rhs)));
-
-    // compare different blank nodes
-    lhs = new BlankNodeValue(new BlankNodeImpl(101));
-    rhs =  new BlankNodeValue(new BlankNodeImpl(102));
-    assertTrue(f.equals(new Equals(lhs, rhs)));
-    assertTrue(f.equals(new SameTerm(lhs, rhs)));
-    assertTrue(t.equals(new NotEquals(lhs, rhs)));
-
-    // compare the same blank nodes
-    lhs = new BlankNodeValue(new BlankNodeImpl(42));
-    rhs =  new BlankNodeValue(new BlankNodeImpl(42));
-    assertTrue(t.equals(new Equals(lhs, rhs)));
-    assertTrue(t.equals(new SameTerm(lhs, rhs)));
-    assertTrue(f.equals(new NotEquals(lhs, rhs)));
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    Var y = new Var("y");
-    AbstractFilterValue eq = new Equals(x, y);
-    AbstractFilterValue same = new SameTerm(x, y);
-    AbstractFilterValue ne = new NotEquals(x, y);
-
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Literal sevenF = new LiteralImpl("7.0", xsdFloat);
-    Literal simple = new LiteralImpl("foo");
-    Literal str = new LiteralImpl("foo", xsdString);
-    Literal strEn = new LiteralImpl("foo", "en");
-    Literal strFr = new LiteralImpl("foo", "fr");
-    Node[][] rows = {
-      new Node[] {seven, seven},
-      new Node[] {seven, sevenF},
-
-      new Node[] {simple, simple},
-      new Node[] {simple, str},
-      new Node[] {simple, strEn},
-      new Node[] {simple, strFr},
-
-      new Node[] {str, str},
-      new Node[] {str, strEn},
-      new Node[] {strEn, strEn},
-      new Node[] {strEn, strFr},
-
-      new Node[] {str, new URIReferenceImpl(xsdInt)},
-      new Node[] {str, new BlankNodeImpl(101)},
-
-      new Node[] {new URIReferenceImpl(xsdInt), new URIReferenceImpl(xsdInt)},
-      new Node[] {new URIReferenceImpl(xsdInt), new URIReferenceImpl(xsdFloat)},
-      new Node[] {new URIReferenceImpl(xsdInt), new BlankNodeImpl(100)},
-
-      new Node[] {null, str},
-
-      new Node[] {new BlankNodeImpl(101), new BlankNodeImpl(101)},
-      new Node[] {new BlankNodeImpl(101), new BlankNodeImpl(102)}
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    eq.setContextOwner(new TestContextOwner(c));
-    same.setContextOwner(new TestContextOwner(c));
-    ne.setContextOwner(new TestContextOwner(c));
-    // check the context setting
-    eq.setCurrentContext(c);
-    same.setCurrentContext(c);
-    ne.setCurrentContext(c);
-
-    String results = "tl tlll tltl ff tff x tf";
-    runTests(c, eq, same, ne, results);
-
-  }
-  
-  private void runTests(TestContext c, AbstractFilterValue eq, AbstractFilterValue same, AbstractFilterValue ne, String results) throws Exception {
-    c.beforeFirst();
-    for (char result: results.toCharArray()) {
-      if (result == ' ') continue;
-      assertTrue(c.next());
-      switch (result) {
-      case 't':  // equal
-        assertTrue(t.equals(eq));
-        assertTrue(t.equals(same));
-        assertTrue(f.equals(ne));
-        break;
-
-      case 'f':  // unequal
-        assertTrue(f.equals(eq));
-        assertTrue(f.equals(same));
-        assertTrue(t.equals(ne));
-        break;
-
-      case 'l':  // unequal literals
-        assertTrue(f.equals(same));
-        assertTrue(t.equals(ne));
-        try {
-          assertTrue(f.equals(eq));
-          fail("Unequal literals should throw an exception when compared for equality");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Type Error"));
-        }
-        break;
-
-      case 'e':  // equivalent but unequal
-        assertTrue(t.equals(same));
-        assertTrue(t.equals(ne));
-        try {
-          assertTrue(f.equals(eq));
-          fail("Unequal literals should throw an exception when compared for equality");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Type Error"));
-        }
-        break;
-
-      case 'x':  // exception due to unbound
-        try {
-          assertTrue(f.equals(eq));
-          fail("No exception when testing an unbound value for equality");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Unbound column"));
-        }
-        try {
-          assertTrue(f.equals(same));
-          fail("No exception when testing an unbound value for equivalency");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Unbound column"));
-        }
-        try {
-          assertTrue(f.equals(ne));
-          fail("No exception when testing an unbound value for inequality");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Unbound column"));
-        }
-        break;
-        
-      default:
-        fail("Bad test data");
-      }
-    }
-    assertFalse(c.next());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/EqualityComparisonUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,306 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.BlankNodeValue;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the equals, not-equals, and sameTerm functions.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class EqualityComparisonUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  protected URI xsdFloat = URI.create(XSD_NS + "float");
+  protected URI xsdString = URI.create(XSD_NS + "string");
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public EqualityComparisonUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new EqualityComparisonUnitTest("testLiteral"));
+    suite.addTest(new EqualityComparisonUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    // compares two equal literals
+    Equals fn = new Equals(t, t);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+    assertTrue(t.equals(new SameTerm(t, t)));
+    assertTrue(f.equals(new NotEquals(t, t)));
+
+    // compares two other equal literals
+    fn = new Equals(f, f);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+    assertTrue(t.equals(new SameTerm(f, f)));
+    assertTrue(f.equals(new NotEquals(f, f)));
+
+    // compare unequal literals
+    RDFTerm lhs = t;
+    RDFTerm rhs = f;
+    try {
+      assertTrue(f.equals(new Equals(lhs, rhs)));
+      fail("Unequal literals should throw an exception when compared for equality");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error"));
+    }
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare equivalent but different literals
+    lhs = TypedLiteral.newLiteral(7);
+    rhs = TypedLiteral.newLiteral(7.0);
+    try {
+      assertTrue(f.equals(new Equals(lhs, rhs)));
+      fail("Unequal literals should throw an exception when compared for equality");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error"));
+    }
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare unequal literal strings
+    lhs = TypedLiteral.newLiteral("foo", null, null);
+    rhs = TypedLiteral.newLiteral("fool", null, null);
+    try {
+      assertTrue(f.equals(new Equals(lhs, rhs)));
+      fail("Unequal literals should throw an exception when compared for equality");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error"));
+    }
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare unequal literals types
+    lhs = TypedLiteral.newLiteral("foo", null, null);
+    rhs = TypedLiteral.newLiteral("foo", xsdString, null);
+    try {
+      assertTrue(f.equals(new Equals(lhs, rhs)));
+      fail("Unequal literals should throw an exception when compared for equality");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error"));
+    }
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare unequal languages
+    lhs = TypedLiteral.newLiteral("foo", null, "en");
+    rhs = TypedLiteral.newLiteral("foo", null, "fr");
+    try {
+      assertTrue(f.equals(new Equals(lhs, rhs)));
+      fail("Unequal literals should throw an exception when compared for equality");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error"));
+    }
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare equal languages
+    lhs = TypedLiteral.newLiteral("foo", null, "en");
+    rhs = TypedLiteral.newLiteral("foo", null, "en");
+    assertTrue(t.equals(new Equals(lhs, rhs)));
+    assertTrue(t.equals(new SameTerm(lhs, rhs)));
+    assertTrue(f.equals(new NotEquals(lhs, rhs)));
+
+    // compare different URIs
+    lhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
+    rhs = new IRI(URI.create("http://mulgara.org/path/to/../to/data.rdf"));
+    assertTrue(f.equals(new Equals(lhs, rhs)));
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare the same URIs
+    lhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
+    rhs = new IRI(URI.create("http://mulgara.org/path/to/data.rdf"));
+    assertTrue(t.equals(new Equals(lhs, rhs)));
+    assertTrue(t.equals(new SameTerm(lhs, rhs)));
+    assertTrue(f.equals(new NotEquals(lhs, rhs)));
+
+    // compare different blank nodes
+    lhs = new BlankNodeValue(new BlankNodeImpl(101));
+    rhs =  new BlankNodeValue(new BlankNodeImpl(102));
+    assertTrue(f.equals(new Equals(lhs, rhs)));
+    assertTrue(f.equals(new SameTerm(lhs, rhs)));
+    assertTrue(t.equals(new NotEquals(lhs, rhs)));
+
+    // compare the same blank nodes
+    lhs = new BlankNodeValue(new BlankNodeImpl(42));
+    rhs =  new BlankNodeValue(new BlankNodeImpl(42));
+    assertTrue(t.equals(new Equals(lhs, rhs)));
+    assertTrue(t.equals(new SameTerm(lhs, rhs)));
+    assertTrue(f.equals(new NotEquals(lhs, rhs)));
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    Var y = new Var("y");
+    AbstractFilterValue eq = new Equals(x, y);
+    AbstractFilterValue same = new SameTerm(x, y);
+    AbstractFilterValue ne = new NotEquals(x, y);
+
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Literal sevenF = new LiteralImpl("7.0", xsdFloat);
+    Literal simple = new LiteralImpl("foo");
+    Literal str = new LiteralImpl("foo", xsdString);
+    Literal strEn = new LiteralImpl("foo", "en");
+    Literal strFr = new LiteralImpl("foo", "fr");
+    Node[][] rows = {
+      new Node[] {seven, seven},
+      new Node[] {seven, sevenF},
+
+      new Node[] {simple, simple},
+      new Node[] {simple, str},
+      new Node[] {simple, strEn},
+      new Node[] {simple, strFr},
+
+      new Node[] {str, str},
+      new Node[] {str, strEn},
+      new Node[] {strEn, strEn},
+      new Node[] {strEn, strFr},
+
+      new Node[] {str, new URIReferenceImpl(xsdInt)},
+      new Node[] {str, new BlankNodeImpl(101)},
+
+      new Node[] {new URIReferenceImpl(xsdInt), new URIReferenceImpl(xsdInt)},
+      new Node[] {new URIReferenceImpl(xsdInt), new URIReferenceImpl(xsdFloat)},
+      new Node[] {new URIReferenceImpl(xsdInt), new BlankNodeImpl(100)},
+
+      new Node[] {null, str},
+
+      new Node[] {new BlankNodeImpl(101), new BlankNodeImpl(101)},
+      new Node[] {new BlankNodeImpl(101), new BlankNodeImpl(102)}
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    eq.setContextOwner(new TestContextOwner(c));
+    same.setContextOwner(new TestContextOwner(c));
+    ne.setContextOwner(new TestContextOwner(c));
+    // check the context setting
+    eq.setCurrentContext(c);
+    same.setCurrentContext(c);
+    ne.setCurrentContext(c);
+
+    String results = "tl tlll tltl ff tff x tf";
+    runTests(c, eq, same, ne, results);
+
+  }
+  
+  private void runTests(TestContext c, AbstractFilterValue eq, AbstractFilterValue same, AbstractFilterValue ne, String results) throws Exception {
+    c.beforeFirst();
+    for (char result: results.toCharArray()) {
+      if (result == ' ') continue;
+      assertTrue(c.next());
+      switch (result) {
+      case 't':  // equal
+        assertTrue(t.equals(eq));
+        assertTrue(t.equals(same));
+        assertTrue(f.equals(ne));
+        break;
+
+      case 'f':  // unequal
+        assertTrue(f.equals(eq));
+        assertTrue(f.equals(same));
+        assertTrue(t.equals(ne));
+        break;
+
+      case 'l':  // unequal literals
+        assertTrue(f.equals(same));
+        assertTrue(t.equals(ne));
+        try {
+          assertTrue(f.equals(eq));
+          fail("Unequal literals should throw an exception when compared for equality");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Type Error"));
+        }
+        break;
+
+      case 'e':  // equivalent but unequal
+        assertTrue(t.equals(same));
+        assertTrue(t.equals(ne));
+        try {
+          assertTrue(f.equals(eq));
+          fail("Unequal literals should throw an exception when compared for equality");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Type Error"));
+        }
+        break;
+
+      case 'x':  // exception due to unbound
+        try {
+          assertTrue(f.equals(eq));
+          fail("No exception when testing an unbound value for equality");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Unbound column"));
+        }
+        try {
+          assertTrue(f.equals(same));
+          fail("No exception when testing an unbound value for equivalency");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Unbound column"));
+        }
+        try {
+          assertTrue(f.equals(ne));
+          fail("No exception when testing an unbound value for inequality");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Unbound column"));
+        }
+        break;
+        
+      default:
+        fail("Bad test data");
+      }
+    }
+    assertFalse(c.next());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Equals.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,44 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * The equality comparison for Values.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class Equals extends BinaryTestFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -7289754671291518073L;
-
-  /**
-   * Creates an equality test operation
-   * @param lhs The first term to compare
-   * @param rhs The second term to compare
-   */
-  public Equals(RDFTerm lhs, RDFTerm rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.equals(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Equals.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,44 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * The equality comparison for Values.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Equals extends BinaryTestFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -7289754671291518073L;
+
+  /**
+   * Creates an equality test operation
+   * @param lhs The first term to compare
+   * @param rhs The second term to compare
+   */
+  public Equals(RDFTerm lhs, RDFTerm rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.equals(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Filter.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,54 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * Filters the iteration of a Constraint.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface Filter extends ContextOwner, RDFTerm {
-
-  /**
-   * Tests a binding according to the filter.
-   * @param context The context to resolve the filter in.
-   * @return <code>true</code> when the filter is matched.
-   * @throws QueryException The filter found an error during testing.
-   */
-  public boolean test(Context context) throws QueryException;
-
-  /** A filter that does no filtering. */
-  public static final Filter NULL = new Filter() {
-    private static final long serialVersionUID = -1561779107566375359L;
-    public boolean test(Context context) { return true; }
-    public void setCurrentContext(Context context) { }
-    public Context getCurrentContext() { return null; }
-    // RDFTerm methods
-    public boolean equals(RDFTerm v) throws QueryException { return v == this; }
-    public ContextOwner getContextOwner() { return null; }
-    public Object getValue() throws QueryException { return true; }
-    public boolean isBlank() throws QueryException { return false; }
-    public boolean isIRI() throws QueryException { return false; }
-    public boolean isLiteral() throws QueryException { return true; }
-    public boolean isURI() throws QueryException { return false; }
-    public boolean notEquals(RDFTerm v) throws QueryException { return !equals(v); }
-    public boolean sameTerm(RDFTerm v) throws QueryException { return equals(v); }
-    public void setContextOwner(ContextOwner owner) { }
-  };
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Filter.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Filter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,54 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Filters the iteration of a Constraint.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface Filter extends ContextOwner, RDFTerm {
+
+  /**
+   * Tests a binding according to the filter.
+   * @param context The context to resolve the filter in.
+   * @return <code>true</code> when the filter is matched.
+   * @throws QueryException The filter found an error during testing.
+   */
+  public boolean test(Context context) throws QueryException;
+
+  /** A filter that does no filtering. */
+  public static final Filter NULL = new Filter() {
+    private static final long serialVersionUID = -1561779107566375359L;
+    public boolean test(Context context) { return true; }
+    public void setCurrentContext(Context context) { }
+    public Context getCurrentContext() { return null; }
+    // RDFTerm methods
+    public boolean equals(RDFTerm v) throws QueryException { return v == this; }
+    public ContextOwner getContextOwner() { return null; }
+    public Object getValue() throws QueryException { return true; }
+    public boolean isBlank() throws QueryException { return false; }
+    public boolean isIRI() throws QueryException { return false; }
+    public boolean isLiteral() throws QueryException { return true; }
+    public boolean isURI() throws QueryException { return false; }
+    public boolean notEquals(RDFTerm v) throws QueryException { return !equals(v); }
+    public boolean sameTerm(RDFTerm v) throws QueryException { return equals(v); }
+    public void setContextOwner(ContextOwner owner) { }
+  };
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,40 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.ComparableExpression;
-
-
-/**
- * The GreaterThan comparison for Values.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class GreaterThan extends BinaryComparisonFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -6430563875011786239L;
-
-  public GreaterThan(ComparableExpression lhs, ComparableExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.greaterThan(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThan.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,40 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.ComparableExpression;
+
+
+/**
+ * The GreaterThan comparison for Values.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class GreaterThan extends BinaryComparisonFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -6430563875011786239L;
+
+  public GreaterThan(ComparableExpression lhs, ComparableExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.greaterThan(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,40 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.ComparableExpression;
-
-
-/**
- * The GreaterThanEqualTo comparison for Values.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class GreaterThanEqualTo extends BinaryComparisonFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -8340079905014464794L;
-
-  public GreaterThanEqualTo(ComparableExpression lhs, ComparableExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.greaterThanEqualTo(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/GreaterThanEqualTo.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,40 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.ComparableExpression;
+
+
+/**
+ * The GreaterThanEqualTo comparison for Values.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class GreaterThanEqualTo extends BinaryComparisonFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -8340079905014464794L;
+
+  public GreaterThanEqualTo(ComparableExpression lhs, ComparableExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.greaterThanEqualTo(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,43 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * Tests an element to see if it represents a blank node.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsBlankFn extends AbstractBooleanFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -8213550084849442081L;
-
-  /**
-   * Create a function for testing a variable
-   * @param The variable to test
-   */
-  public IsBlankFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
-  boolean fnTest() throws QueryException {
-    return operand.isBlank();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,43 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Tests an element to see if it represents a blank node.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsBlankFn extends AbstractBooleanFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -8213550084849442081L;
+
+  /**
+   * Create a function for testing a variable
+   * @param The variable to test
+   */
+  public IsBlankFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
+  boolean fnTest() throws QueryException {
+    return operand.isBlank();
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,114 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-
-import org.mulgara.query.filter.value.BlankNodeValue;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.Var;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the isBlank function.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsBlankFnUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public IsBlankFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new NotUnitTest("testLiteral"));
-    suite.addTest(new IsBlankFnUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    IsBlankFn fn = new IsBlankFn(t);
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    fn = new IsBlankFn(new BlankNodeValue(new BlankNodeImpl(101)));
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    IsBlankFn fn = new IsBlankFn(x);
-
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Node[][] rows = {
-      new Node[] {seven},
-      new Node[] {null},
-      new Node[] {new BlankNodeImpl(101)}
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    assertTrue(c.next());
-    try {
-      assertTrue(f.equals(fn));
-      fail("No exception when testing an unbound value");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Unbound column"));
-    }
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsBlankFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,114 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+
+import org.mulgara.query.filter.value.BlankNodeValue;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the isBlank function.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsBlankFnUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public IsBlankFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new NotUnitTest("testLiteral"));
+    suite.addTest(new IsBlankFnUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    IsBlankFn fn = new IsBlankFn(t);
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    fn = new IsBlankFn(new BlankNodeValue(new BlankNodeImpl(101)));
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    IsBlankFn fn = new IsBlankFn(x);
+
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Node[][] rows = {
+      new Node[] {seven},
+      new Node[] {null},
+      new Node[] {new BlankNodeImpl(101)}
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    assertTrue(c.next());
+    try {
+      assertTrue(f.equals(fn));
+      fail("No exception when testing an unbound value");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Unbound column"));
+    }
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,51 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the isIRI function.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsIRIFnUnitTest extends AbstractIsIriFnUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public IsIRIFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new NotUnitTest("testLiteral"));
-    suite.addTest(new IsIRIFnUnitTest("testVar"));
-    return suite;
-  }
-
-  public AbstractFilterValue createFn(RDFTerm arg) {
-    return new IsIriFn(arg);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsIRIFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,51 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the isIRI function.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsIRIFnUnitTest extends AbstractIsIriFnUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public IsIRIFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new NotUnitTest("testLiteral"));
+    suite.addTest(new IsIRIFnUnitTest("testVar"));
+    return suite;
+  }
+
+  public AbstractFilterValue createFn(RDFTerm arg) {
+    return new IsIriFn(arg);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,43 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * Tests an element to see if it conforms to being an IRI.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsIriFn extends AbstractBooleanFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 3963044750471218296L;
-
-  /**
-   * Create a function for testing a variable
-   * @param The variable to test
-   */
-  public IsIriFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
-  boolean fnTest() throws QueryException {
-    return operand.isIRI();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsIriFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,43 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Tests an element to see if it conforms to being an IRI.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsIriFn extends AbstractBooleanFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 3963044750471218296L;
+
+  /**
+   * Create a function for testing a variable
+   * @param The variable to test
+   */
+  public IsIriFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
+  boolean fnTest() throws QueryException {
+    return operand.isIRI();
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,43 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * Tests an element to see if it is an RDF Literal value.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsLiteralFn extends AbstractBooleanFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 3543119682508127635L;
-
-  /**
-   * Create a function for testing if a value it a Literal
-   * @param The variable to test
-   */
-  public IsLiteralFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
-  boolean fnTest() throws QueryException {
-    return operand.isLiteral();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,43 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Tests an element to see if it is an RDF Literal value.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsLiteralFn extends AbstractBooleanFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 3543119682508127635L;
+
+  /**
+   * Create a function for testing if a value it a Literal
+   * @param The variable to test
+   */
+  public IsLiteralFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
+  boolean fnTest() throws QueryException {
+    return operand.isLiteral();
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,116 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.Var;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the isLiteral function.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsLiteralFnUnitTest extends TestCase {
-
-  protected URI xsdInt = URI.create(XSD_NS + "int");
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public IsLiteralFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new IsLiteralFnUnitTest("testLiteral"));
-    suite.addTest(new IsLiteralFnUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    IsLiteralFn fn = new IsLiteralFn(t);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    fn = new IsLiteralFn(t.getType());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-  }
-
-  public void testVar() throws Exception {
-    IsLiteralFn fn = new IsLiteralFn(new Var("x"));
-
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Node[][] rows = {
-      new Node[] {seven},
-      new Node[] {new URIReferenceImpl(xsdInt)},
-      new Node[] {null},
-      new Node[] {new BlankNodeImpl(101)},
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    assertTrue(c.next());
-    try {
-      assertTrue(f.equals(fn));
-      fail("No exception when testing an unbound value");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Unbound column"));
-    }
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertFalse(c.next());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsLiteralFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,116 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.Var;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the isLiteral function.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsLiteralFnUnitTest extends TestCase {
+
+  protected URI xsdInt = URI.create(XSD_NS + "int");
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public IsLiteralFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new IsLiteralFnUnitTest("testLiteral"));
+    suite.addTest(new IsLiteralFnUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    IsLiteralFn fn = new IsLiteralFn(t);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    fn = new IsLiteralFn(t.getType());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+  }
+
+  public void testVar() throws Exception {
+    IsLiteralFn fn = new IsLiteralFn(new Var("x"));
+
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Node[][] rows = {
+      new Node[] {seven},
+      new Node[] {new URIReferenceImpl(xsdInt)},
+      new Node[] {null},
+      new Node[] {new BlankNodeImpl(101)},
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    assertTrue(c.next());
+    try {
+      assertTrue(f.equals(fn));
+      fail("No exception when testing an unbound value");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Unbound column"));
+    }
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertFalse(c.next());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,55 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-
-
-
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the isURI function.
- *
- * @created Apr 15, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsURIFnUnitTest extends AbstractIsIriFnUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public IsURIFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new NotUnitTest("testLiteral"));
-    suite.addTest(new IsURIFnUnitTest("testVar"));
-    return suite;
-  }
-
-  public AbstractFilterValue createFn(RDFTerm arg) {
-    return new IsUriFn(arg);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsURIFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,55 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+
+
+
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the isURI function.
+ *
+ * @created Apr 15, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsURIFnUnitTest extends AbstractIsIriFnUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public IsURIFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new NotUnitTest("testLiteral"));
+    suite.addTest(new IsURIFnUnitTest("testVar"));
+    return suite;
+  }
+
+  public AbstractFilterValue createFn(RDFTerm arg) {
+    return new IsUriFn(arg);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,43 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * Tests an element to see if it conforms to being a URI.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IsUriFn extends AbstractBooleanFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -1881652122335929516L;
-
-  /**
-   * Create a function for testing a variable
-   * @param The variable to test
-   */
-  public IsUriFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
-  boolean fnTest() throws QueryException {
-    return operand.isURI();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/IsUriFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,43 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Tests an element to see if it conforms to being a URI.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IsUriFn extends AbstractBooleanFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -1881652122335929516L;
+
+  /**
+   * Create a function for testing a variable
+   * @param The variable to test
+   */
+  public IsUriFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /** @see org.mulgara.query.filter.AbstractBooleanFn#fnTest() */
+  boolean fnTest() throws QueryException {
+    return operand.isURI();
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LangMatches.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,64 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-
-/**
- * The lang matches a language pattern.
- * This is a rudimentary implementation that is equivalent to the Jena langMatch test.
- * TODO: fully implement RFC 4647: {@link http://www.ietf.org/rfc/rfc4647.txt}
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class LangMatches extends BinaryTestFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 7483330484341360061L;
-
-  /**
-   * Creates an equality test operation
-   * @param lhs The first term to compare
-   * @param rhs The second term to compare
-   */
-  public LangMatches(ValueLiteral lhs, ValueLiteral rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    testSimple(lhs);
-    testSimple(rhs);
-    String lang = ((ValueLiteral)lhs).getLang().getLexical();
-    String pattern = ((ValueLiteral)rhs).getLexical();
-    // the * pattern matches anything that isn't empty
-    if ("*".equals(pattern)) return lang.length() != 0;
-    // all other patterns are matched by prefix, with case insensitivity
-    return lang.toLowerCase().startsWith(pattern.toLowerCase());
-  }
-
-  /**
-   * Tests if the parameter is a {@link org.mulgara.query.filter.value.SimpleLiteral}.
-   * Throws an exception if it is not.
-   * @param v The parameter to test
-   * @throws QueryException Thrown if v is not a simple literal.
-   */
-  private void testSimple(RDFTerm v) throws QueryException {
-    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: LangMatches requires simple literals");
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LangMatches.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,64 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+
+/**
+ * The lang matches a language pattern.
+ * This is a rudimentary implementation that is equivalent to the Jena langMatch test.
+ * TODO: fully implement RFC 4647: {@link http://www.ietf.org/rfc/rfc4647.txt}
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class LangMatches extends BinaryTestFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 7483330484341360061L;
+
+  /**
+   * Creates an equality test operation
+   * @param lhs The first term to compare
+   * @param rhs The second term to compare
+   */
+  public LangMatches(ValueLiteral lhs, ValueLiteral rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    testSimple(lhs);
+    testSimple(rhs);
+    String lang = ((ValueLiteral)lhs).getLang().getLexical();
+    String pattern = ((ValueLiteral)rhs).getLexical();
+    // the * pattern matches anything that isn't empty
+    if ("*".equals(pattern)) return lang.length() != 0;
+    // all other patterns are matched by prefix, with case insensitivity
+    return lang.toLowerCase().startsWith(pattern.toLowerCase());
+  }
+
+  /**
+   * Tests if the parameter is a {@link org.mulgara.query.filter.value.SimpleLiteral}.
+   * Throws an exception if it is not.
+   * @param v The parameter to test
+   * @throws QueryException Thrown if v is not a simple literal.
+   */
+  private void testSimple(RDFTerm v) throws QueryException {
+    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: LangMatches requires simple literals");
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,203 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the langMatches function.
- *
- * @created Apr 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class LangMatchesUnitTest extends TestCase {
-
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public LangMatchesUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new LangMatchesUnitTest("testLiteral"));
-    suite.addTest(new LangMatchesUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    SimpleLiteral litEn = new SimpleLiteral("foo", "en");
-    SimpleLiteral langEn = new SimpleLiteral("en");
-    SimpleLiteral langEnCaps = new SimpleLiteral("EN");
-    LangMatches fn = new LangMatches(litEn, langEn);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-    fn = new LangMatches(litEn, langEnCaps);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    SimpleLiteral langFr = new SimpleLiteral("fr");
-    fn = new LangMatches(litEn, langFr);
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    SimpleLiteral litEnGB = new SimpleLiteral("en-GB");
-    fn = new LangMatches(litEnGB, langEn);
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-    
-    SimpleLiteral litEmpty = new SimpleLiteral("foo");
-    fn = new LangMatches(litEmpty, langEn);
-    assertTrue(f.equals(fn));
-    SimpleLiteral langAll = new SimpleLiteral("*");
-    fn = new LangMatches(litEmpty, langAll);
-    assertTrue(f.equals(fn));
-    fn = new LangMatches(litEn, langAll);
-    assertTrue(t.equals(fn));
-
-    ValueLiteral lit = TypedLiteral.newLiteral("en");
-    fn = new LangMatches(lit, langEn);
-    try {
-      assertTrue(f.equals(fn));
-      fail("Tested the language on a typed literal");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-    fn = new LangMatches(lit, langAll);
-    try {
-      assertTrue(f.equals(fn));
-      fail("Tested the language on a typed literal");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-    fn = new LangMatches(litEn, lit);
-    try {
-      assertTrue(f.equals(fn));
-      fail("Tested the language on a typed literal");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-}
-
-  public void testVar() throws Exception {
-    LangMatches fn = new LangMatches(new Var("x"), new Var("y"));
-
-    Literal fooEn = new LiteralImpl("foo", "en");
-    Literal fooFr = new LiteralImpl("foo", "fr");
-    Literal fooEnGB = new LiteralImpl("foo", "en-GB");
-    Literal fooSimple = new LiteralImpl("foo");
-    Literal fooTyped = new LiteralImpl("en", SimpleLiteral.STRING_TYPE.getValue());
-    Literal en = new LiteralImpl("en");
-    Literal all = new LiteralImpl("*");
-    URIReferenceImpl xsdString = new URIReferenceImpl(SimpleLiteral.STRING_TYPE.getValue());
-    BlankNodeImpl bn = new BlankNodeImpl(101);
-    Node[][] rows = {
-      new Node[] {fooEn, en},
-      new Node[] {fooFr, en},
-      new Node[] {fooEnGB, en},
-      new Node[] {fooEn, all},
-
-      new Node[] {fooSimple, en},
-      new Node[] {fooSimple, all},
-
-      new Node[] {fooTyped, en},
-      new Node[] {fooEn, fooTyped},
-      new Node[] {fooSimple, fooTyped},
-
-      new Node[] {xsdString, en},
-      new Node[] {xsdString, all},
-
-      new Node[] {null, all},
-      new Node[] {null, en},
-
-      new Node[] {bn, en},
-      new Node[] {bn, all},
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    String results = "tftt ff eee ee xx ee";
-    runTests(c, fn, results);
-  }
-
-  private void runTests(TestContext c, AbstractFilterValue fn, String results) throws Exception {
-    c.beforeFirst();
-    for (char result: results.toCharArray()) {
-      if (result == ' ') continue;
-      assertTrue(c.next());
-      switch (result) {
-      case 't':  // equal
-        assertTrue(t.equals(fn));
-        break;
-
-      case 'f':  // unequal
-        assertTrue(f.equals(fn));
-        break;
-
-      case 'e':  // typing error
-        try {
-          assertTrue(f.equals(fn));
-          fail("Successfully tested values that were not simple literals");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Type Error"));
-        }
-        break;
-
-      case 'x':  // exception due to unbound
-        try {
-          assertTrue(f.equals(fn));
-          fail("No exception when testing an unbound value");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Unbound column"));
-        }
-        break;
-        
-      default:
-        fail("Bad test data");
-      }
-    }
-    assertFalse(c.next());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LangMatchesUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,203 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the langMatches function.
+ *
+ * @created Apr 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class LangMatchesUnitTest extends TestCase {
+
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public LangMatchesUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new LangMatchesUnitTest("testLiteral"));
+    suite.addTest(new LangMatchesUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    SimpleLiteral litEn = new SimpleLiteral("foo", "en");
+    SimpleLiteral langEn = new SimpleLiteral("en");
+    SimpleLiteral langEnCaps = new SimpleLiteral("EN");
+    LangMatches fn = new LangMatches(litEn, langEn);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+    fn = new LangMatches(litEn, langEnCaps);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    SimpleLiteral langFr = new SimpleLiteral("fr");
+    fn = new LangMatches(litEn, langFr);
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    SimpleLiteral litEnGB = new SimpleLiteral("en-GB");
+    fn = new LangMatches(litEnGB, langEn);
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+    
+    SimpleLiteral litEmpty = new SimpleLiteral("foo");
+    fn = new LangMatches(litEmpty, langEn);
+    assertTrue(f.equals(fn));
+    SimpleLiteral langAll = new SimpleLiteral("*");
+    fn = new LangMatches(litEmpty, langAll);
+    assertTrue(f.equals(fn));
+    fn = new LangMatches(litEn, langAll);
+    assertTrue(t.equals(fn));
+
+    ValueLiteral lit = TypedLiteral.newLiteral("en");
+    fn = new LangMatches(lit, langEn);
+    try {
+      assertTrue(f.equals(fn));
+      fail("Tested the language on a typed literal");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+    fn = new LangMatches(lit, langAll);
+    try {
+      assertTrue(f.equals(fn));
+      fail("Tested the language on a typed literal");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+    fn = new LangMatches(litEn, lit);
+    try {
+      assertTrue(f.equals(fn));
+      fail("Tested the language on a typed literal");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+}
+
+  public void testVar() throws Exception {
+    LangMatches fn = new LangMatches(new Var("x"), new Var("y"));
+
+    Literal fooEn = new LiteralImpl("foo", "en");
+    Literal fooFr = new LiteralImpl("foo", "fr");
+    Literal fooEnGB = new LiteralImpl("foo", "en-GB");
+    Literal fooSimple = new LiteralImpl("foo");
+    Literal fooTyped = new LiteralImpl("en", SimpleLiteral.STRING_TYPE.getValue());
+    Literal en = new LiteralImpl("en");
+    Literal all = new LiteralImpl("*");
+    URIReferenceImpl xsdString = new URIReferenceImpl(SimpleLiteral.STRING_TYPE.getValue());
+    BlankNodeImpl bn = new BlankNodeImpl(101);
+    Node[][] rows = {
+      new Node[] {fooEn, en},
+      new Node[] {fooFr, en},
+      new Node[] {fooEnGB, en},
+      new Node[] {fooEn, all},
+
+      new Node[] {fooSimple, en},
+      new Node[] {fooSimple, all},
+
+      new Node[] {fooTyped, en},
+      new Node[] {fooEn, fooTyped},
+      new Node[] {fooSimple, fooTyped},
+
+      new Node[] {xsdString, en},
+      new Node[] {xsdString, all},
+
+      new Node[] {null, all},
+      new Node[] {null, en},
+
+      new Node[] {bn, en},
+      new Node[] {bn, all},
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    String results = "tftt ff eee ee xx ee";
+    runTests(c, fn, results);
+  }
+
+  private void runTests(TestContext c, AbstractFilterValue fn, String results) throws Exception {
+    c.beforeFirst();
+    for (char result: results.toCharArray()) {
+      if (result == ' ') continue;
+      assertTrue(c.next());
+      switch (result) {
+      case 't':  // equal
+        assertTrue(t.equals(fn));
+        break;
+
+      case 'f':  // unequal
+        assertTrue(f.equals(fn));
+        break;
+
+      case 'e':  // typing error
+        try {
+          assertTrue(f.equals(fn));
+          fail("Successfully tested values that were not simple literals");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Type Error"));
+        }
+        break;
+
+      case 'x':  // exception due to unbound
+        try {
+          assertTrue(f.equals(fn));
+          fail("No exception when testing an unbound value");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Unbound column"));
+        }
+        break;
+        
+      default:
+        fail("Bad test data");
+      }
+    }
+    assertFalse(c.next());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LessThan.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,40 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.ComparableExpression;
-
-
-/**
- * The LessThan comparison for Values.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class LessThan extends BinaryComparisonFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -4496342997723195355L;
-
-  public LessThan(ComparableExpression lhs, ComparableExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.lessThan(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LessThan.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LessThan.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,40 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.ComparableExpression;
+
+
+/**
+ * The LessThan comparison for Values.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class LessThan extends BinaryComparisonFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -4496342997723195355L;
+
+  public LessThan(ComparableExpression lhs, ComparableExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.lessThan(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,40 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.ComparableExpression;
-
-
-/**
- * The LessThanEqualTo comparison for Values.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class LessThanEqualTo extends BinaryComparisonFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -293271100023802658L;
-
-  public LessThanEqualTo(ComparableExpression lhs, ComparableExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.lessThanEqualTo(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LessThanEqualTo.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,40 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.ComparableExpression;
+
+
+/**
+ * The LessThanEqualTo comparison for Values.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class LessThanEqualTo extends BinaryComparisonFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -293271100023802658L;
+
+  public LessThanEqualTo(ComparableExpression lhs, ComparableExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryComparisonFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.lessThanEqualTo(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,75 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-
-/**
- * Represents a filter that takes other filters as parameters.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class NAryOperatorFilter extends AbstractFilterValue implements ValueLiteral {
-
-  /**
-   * Creates a multiple operand operation
-   * @param operands The operands for this filter operation.
-   */
-  NAryOperatorFilter(Filter... operands) {
-    super(operands);
-  }
-
-  public RDFTerm resolve() throws QueryException {
-    return testOp(getCurrentContext()) ? Bool.TRUE : Bool.FALSE;
-  }
-
-  /**
-   * Runs the test on all the operands.
-   * @param context The context to resolve the test in.
-   * @return <code>true</code> if the operation passes.
-   * @throws QueryException If there was an <em>unrecoverable</em> error resolving the operands 
-   */
-  boolean testOp(Context context) throws QueryException {
-    // we can cast operands, since it was provided as a Filter[]
-    return testList(context, Arrays.asList((Filter[])operands));
-  }
-
-  /**
-   * An operation specific test. This will apply the test to all operands given in the list,
-   * short circuiting where possible, in order to provide a correct result even in the event
-   * of an exception.
-   * @param context The context to resolve the list in.
-   * @param filters The operands of the operation. These are resolved in the provided context.
-   * @return A boolean value, according to the specifics of the test.
-   * @throws QueryException If there was an <em>unrecoverable</em> error resolving the operands.
-   */
-  abstract boolean testList(Context context, List<Filter> filters) throws QueryException;
-
-  /**
-   * Utility to return the tail of a list. This is the entire list, minus the first entry.
-   * @param l The list to get the tail of.
-   * @return A new list, with a size equal to l.size()-1. ie. all of l except l.get(0)
-   */
-  static List<Filter> tail(List<Filter> l) {
-    return l.subList(1, l.size());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NAryOperatorFilter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,75 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+
+/**
+ * Represents a filter that takes other filters as parameters.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class NAryOperatorFilter extends AbstractFilterValue implements ValueLiteral {
+
+  /**
+   * Creates a multiple operand operation
+   * @param operands The operands for this filter operation.
+   */
+  NAryOperatorFilter(Filter... operands) {
+    super(operands);
+  }
+
+  public RDFTerm resolve() throws QueryException {
+    return testOp(getCurrentContext()) ? Bool.TRUE : Bool.FALSE;
+  }
+
+  /**
+   * Runs the test on all the operands.
+   * @param context The context to resolve the test in.
+   * @return <code>true</code> if the operation passes.
+   * @throws QueryException If there was an <em>unrecoverable</em> error resolving the operands 
+   */
+  boolean testOp(Context context) throws QueryException {
+    // we can cast operands, since it was provided as a Filter[]
+    return testList(context, Arrays.asList((Filter[])operands));
+  }
+
+  /**
+   * An operation specific test. This will apply the test to all operands given in the list,
+   * short circuiting where possible, in order to provide a correct result even in the event
+   * of an exception.
+   * @param context The context to resolve the list in.
+   * @param filters The operands of the operation. These are resolved in the provided context.
+   * @return A boolean value, according to the specifics of the test.
+   * @throws QueryException If there was an <em>unrecoverable</em> error resolving the operands.
+   */
+  abstract boolean testList(Context context, List<Filter> filters) throws QueryException;
+
+  /**
+   * Utility to return the tail of a list. This is the entire list, minus the first entry.
+   * @param l The list to get the tail of.
+   * @return A new list, with a size equal to l.size()-1. ie. all of l except l.get(0)
+   */
+  static List<Filter> tail(List<Filter> l) {
+    return l.subList(1, l.size());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/Not.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Not.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Not.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,56 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.Bool;
-
-
-/**
- * An inversion of a test.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class Not extends AbstractFilterValue implements Filter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 1225895946822519277L;
-
-  /** The filter to invert. Local storage of operands[0]. */
-  Filter operand;
-
-  /**
-   * Create an inversion of a filter
-   * @param filter The filter to invert
-   */
-  public Not(Filter operand) {
-    super(operand);
-    this.operand = operand;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.Filter#test()
-   */
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    return !operand.test(context);
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
-  protected RDFTerm resolve() throws QueryException {
-    return operand.test(getCurrentContext()) ? Bool.FALSE : Bool.TRUE;
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/Not.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Not.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/Not.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Not.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,56 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+
+
+/**
+ * An inversion of a test.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Not extends AbstractFilterValue implements Filter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 1225895946822519277L;
+
+  /** The filter to invert. Local storage of operands[0]. */
+  Filter operand;
+
+  /**
+   * Create an inversion of a filter
+   * @param filter The filter to invert
+   */
+  public Not(Filter operand) {
+    super(operand);
+    this.operand = operand;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.Filter#test()
+   */
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    return !operand.test(context);
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#resolve() */
+  protected RDFTerm resolve() throws QueryException {
+    return operand.test(getCurrentContext()) ? Bool.FALSE : Bool.TRUE;
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotEquals.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,39 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * The LessThan comparison for Values.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class NotEquals extends BinaryTestFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -7091505891438740349L;
-
-  public NotEquals(RDFTerm lhs, RDFTerm rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.notEquals(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotEquals.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,39 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * The LessThan comparison for Values.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class NotEquals extends BinaryTestFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -7091505891438740349L;
+
+  public NotEquals(RDFTerm lhs, RDFTerm rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.notEquals(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,142 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the NOT operation.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class NotUnitTest extends AbstractLogicUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public NotUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new NotUnitTest("testLiteral"));
-    suite.addTest(new NotUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    Bool t = Bool.TRUE;
-    Bool f = Bool.FALSE;
-    basicTest(new Not(t), f);
-    basicTest(new Not(f), t);
-
-    basicTest(new Not(new NumericLiteral(7)), f);
-    basicTest(new Not(new NumericLiteral(0)), t);
-
-    basicTest(new Not(TypedLiteral.newLiteral("foo")), f);
-    basicTest(new Not(TypedLiteral.newLiteral("")), t);
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    Not fn = new Not(x);
-
-    URI fooBar = URI.create("foo:bar");
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Literal zero = new LiteralImpl("0", xsdInt);
-    Literal trueLiteral = new LiteralImpl("true", xsdBool);
-    Literal falseLiteral = new LiteralImpl("false", xsdBool);
-    Node[][] rows = {
-      new Node[] {seven},
-      new Node[] {zero},
-      new Node[] {trueLiteral},
-      new Node[] {falseLiteral},
-
-      new Node[] {new LiteralImpl("foo", "en")},
-      new Node[] {new LiteralImpl("foo", fooBar)},
-      new Node[] {new LiteralImpl("")},
-      new Node[] {new URIReferenceImpl(fooBar)},
-      new Node[] {new BlankNodeImpl(1001)},
-      new Node[] {null},
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    Bool t = Bool.TRUE;
-    Bool f = Bool.FALSE;
-
-    assertTrue(c.next()); assertTrue(f.equals(fn));
-    assertTrue(c.next()); assertTrue(t.equals(fn));
-    assertTrue(c.next()); assertTrue(f.equals(fn));
-    assertTrue(c.next()); assertTrue(t.equals(fn));
-    // literals
-    assertTrue(c.next()); assertTrue(f.equals(fn));
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("EBV on an unknown type of literal");
-    } catch (QueryException qe) { }
-    assertTrue(c.next()); assertTrue(t.equals(fn));
-    // URI
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on a URI");
-    } catch (QueryException qe) { }
-    // blank node
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on a blank node");
-    } catch (QueryException qe) { }
-    // unbound
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on an unbound");
-    } catch (QueryException qe) { }
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NotUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,142 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the NOT operation.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class NotUnitTest extends AbstractLogicUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public NotUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new NotUnitTest("testLiteral"));
+    suite.addTest(new NotUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    Bool t = Bool.TRUE;
+    Bool f = Bool.FALSE;
+    basicTest(new Not(t), f);
+    basicTest(new Not(f), t);
+
+    basicTest(new Not(new NumericLiteral(7)), f);
+    basicTest(new Not(new NumericLiteral(0)), t);
+
+    basicTest(new Not(TypedLiteral.newLiteral("foo")), f);
+    basicTest(new Not(TypedLiteral.newLiteral("")), t);
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    Not fn = new Not(x);
+
+    URI fooBar = URI.create("foo:bar");
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Literal zero = new LiteralImpl("0", xsdInt);
+    Literal trueLiteral = new LiteralImpl("true", xsdBool);
+    Literal falseLiteral = new LiteralImpl("false", xsdBool);
+    Node[][] rows = {
+      new Node[] {seven},
+      new Node[] {zero},
+      new Node[] {trueLiteral},
+      new Node[] {falseLiteral},
+
+      new Node[] {new LiteralImpl("foo", "en")},
+      new Node[] {new LiteralImpl("foo", fooBar)},
+      new Node[] {new LiteralImpl("")},
+      new Node[] {new URIReferenceImpl(fooBar)},
+      new Node[] {new BlankNodeImpl(1001)},
+      new Node[] {null},
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    Bool t = Bool.TRUE;
+    Bool f = Bool.FALSE;
+
+    assertTrue(c.next()); assertTrue(f.equals(fn));
+    assertTrue(c.next()); assertTrue(t.equals(fn));
+    assertTrue(c.next()); assertTrue(f.equals(fn));
+    assertTrue(c.next()); assertTrue(t.equals(fn));
+    // literals
+    assertTrue(c.next()); assertTrue(f.equals(fn));
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("EBV on an unknown type of literal");
+    } catch (QueryException qe) { }
+    assertTrue(c.next()); assertTrue(t.equals(fn));
+    // URI
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on a URI");
+    } catch (QueryException qe) { }
+    // blank node
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on a blank node");
+    } catch (QueryException qe) { }
+    // unbound
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on an unbound");
+    } catch (QueryException qe) { }
+
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/Or.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Or.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Or.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,61 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.util.List;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * A sum of filters.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class Or extends NAryOperatorFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 1062167458998556025L;
-
-  /**
-   * Create a sum of other filters.
-   * @param operands The operands of the sum.
-   */
-  public Or(Filter... operands) {
-    super(operands);
-  }
-
-  /**
-   * Returns the head of the list ORed with the sum of the remainder of the list.
-   * <code>true</code> or Exception is <code>true</code>.
-   * <code>false</code> or Exception is Exception.
-   * @see org.mulgara.query.filter.Filter#test()
-   */
-  boolean testList(Context context, List<Filter> filters) throws QueryException {
-    Filter head = filters.get(0);
-    if (filters.size() == 1) return head.test(context);
-
-    boolean result;
-    try {
-      result = filters.get(0).test(context);
-    } catch (QueryException e) {
-      // true on the RHS gives true
-      if (!testList(context, tail(filters))) return true;
-      throw e;
-    }
-    return result || testList(context, tail(filters));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/Or.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/Or.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/Or.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Or.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,61 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.util.List;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * A sum of filters.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Or extends NAryOperatorFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 1062167458998556025L;
+
+  /**
+   * Create a sum of other filters.
+   * @param operands The operands of the sum.
+   */
+  public Or(Filter... operands) {
+    super(operands);
+  }
+
+  /**
+   * Returns the head of the list ORed with the sum of the remainder of the list.
+   * <code>true</code> or Exception is <code>true</code>.
+   * <code>false</code> or Exception is Exception.
+   * @see org.mulgara.query.filter.Filter#test()
+   */
+  boolean testList(Context context, List<Filter> filters) throws QueryException {
+    Filter head = filters.get(0);
+    if (filters.size() == 1) return head.test(context);
+
+    boolean result;
+    try {
+      result = filters.get(0).test(context);
+    } catch (QueryException e) {
+      // true on the RHS gives true
+      if (!testList(context, tail(filters))) return true;
+      throw e;
+    }
+    return result || testList(context, tail(filters));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,185 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the OR operation.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class OrUnitTest extends AbstractLogicUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public OrUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new OrUnitTest("testLiteral"));
-    suite.addTest(new OrUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    Bool t = Bool.TRUE;
-    Bool f = Bool.FALSE;
-    basicTest(t, t, t);
-    basicTest(f, t, t);
-    basicTest(t, f, t);
-    basicTest(f, f, f);
-
-    basicTest(new NumericLiteral(7), t, t);
-    basicTest(new NumericLiteral(0), t, t);
-    basicTest(new NumericLiteral(7), f, t);
-    basicTest(new NumericLiteral(0), f, f);
-
-    basicTest(TypedLiteral.newLiteral("foo"), t, t);
-    basicTest(TypedLiteral.newLiteral(""), t, t);
-    basicTest(TypedLiteral.newLiteral("foo"), f, t);
-    basicTest(TypedLiteral.newLiteral(""), f, f);
-  }
-
-  void basicTest(Filter lhs, Filter rhs, Bool result) throws Exception {
-    basicTest(new Or(lhs, rhs), result);
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    Var y = new Var("y");
-    Or fn = new Or(x, y);
-
-    URI fooBar = URI.create("foo:bar");
-    Literal seven = new LiteralImpl("7", xsdInt);
-    Literal zero = new LiteralImpl("0", xsdInt);
-    Literal trueLiteral = new LiteralImpl("true", xsdBool);
-    Literal falseLiteral = new LiteralImpl("false", xsdBool);
-    Node[][] rows = {
-      new Node[] {zero, seven},
-      new Node[] {zero, zero},
-      new Node[] {zero, trueLiteral},
-      new Node[] {zero, falseLiteral},
-
-      new Node[] {falseLiteral, new LiteralImpl("foo", "en")},
-      new Node[] {falseLiteral, new LiteralImpl("foo", fooBar)},
-      new Node[] {new LiteralImpl(""), trueLiteral},
-      new Node[] {new LiteralImpl(""), falseLiteral},
-      new Node[] {falseLiteral, new URIReferenceImpl(fooBar)},
-      new Node[] {trueLiteral, new URIReferenceImpl(fooBar)},
-      new Node[] {falseLiteral, new BlankNodeImpl(1001)},
-      new Node[] {trueLiteral, new BlankNodeImpl(1002)},
-      new Node[] {falseLiteral, null},
-      new Node[] {trueLiteral, null}
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    Bool t = Bool.TRUE;
-    Bool f = Bool.FALSE;
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    // now the foo literals
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("EBV on an unknown type of literal");
-    } catch (QueryException qe) { }
-
-    // The zero length string literals
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(f.equals(fn));
-
-    // The URIs
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on a URI");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    // The blank nodes
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on a blank node");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    // The unbounds
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Logic operation on an unbound");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    assertTrue(t.equals(fn));
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/OrUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,185 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the OR operation.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class OrUnitTest extends AbstractLogicUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public OrUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new OrUnitTest("testLiteral"));
+    suite.addTest(new OrUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    Bool t = Bool.TRUE;
+    Bool f = Bool.FALSE;
+    basicTest(t, t, t);
+    basicTest(f, t, t);
+    basicTest(t, f, t);
+    basicTest(f, f, f);
+
+    basicTest(new NumericLiteral(7), t, t);
+    basicTest(new NumericLiteral(0), t, t);
+    basicTest(new NumericLiteral(7), f, t);
+    basicTest(new NumericLiteral(0), f, f);
+
+    basicTest(TypedLiteral.newLiteral("foo"), t, t);
+    basicTest(TypedLiteral.newLiteral(""), t, t);
+    basicTest(TypedLiteral.newLiteral("foo"), f, t);
+    basicTest(TypedLiteral.newLiteral(""), f, f);
+  }
+
+  void basicTest(Filter lhs, Filter rhs, Bool result) throws Exception {
+    basicTest(new Or(lhs, rhs), result);
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    Var y = new Var("y");
+    Or fn = new Or(x, y);
+
+    URI fooBar = URI.create("foo:bar");
+    Literal seven = new LiteralImpl("7", xsdInt);
+    Literal zero = new LiteralImpl("0", xsdInt);
+    Literal trueLiteral = new LiteralImpl("true", xsdBool);
+    Literal falseLiteral = new LiteralImpl("false", xsdBool);
+    Node[][] rows = {
+      new Node[] {zero, seven},
+      new Node[] {zero, zero},
+      new Node[] {zero, trueLiteral},
+      new Node[] {zero, falseLiteral},
+
+      new Node[] {falseLiteral, new LiteralImpl("foo", "en")},
+      new Node[] {falseLiteral, new LiteralImpl("foo", fooBar)},
+      new Node[] {new LiteralImpl(""), trueLiteral},
+      new Node[] {new LiteralImpl(""), falseLiteral},
+      new Node[] {falseLiteral, new URIReferenceImpl(fooBar)},
+      new Node[] {trueLiteral, new URIReferenceImpl(fooBar)},
+      new Node[] {falseLiteral, new BlankNodeImpl(1001)},
+      new Node[] {trueLiteral, new BlankNodeImpl(1002)},
+      new Node[] {falseLiteral, null},
+      new Node[] {trueLiteral, null}
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    Bool t = Bool.TRUE;
+    Bool f = Bool.FALSE;
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    // now the foo literals
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("EBV on an unknown type of literal");
+    } catch (QueryException qe) { }
+
+    // The zero length string literals
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(f.equals(fn));
+
+    // The URIs
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on a URI");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    // The blank nodes
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on a blank node");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    // The unbounds
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Logic operation on an unbound");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    assertTrue(t.equals(fn));
+
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,93 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.io.Serializable;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * Represents data that can appear in an expression, used by filters
- *
- * @created Mar 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface RDFTerm extends Serializable {
-
-  /**
-   * Returns the data represented by this expression.
-   * @return The represented data.
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public Object getValue() throws QueryException;
-
-  /**
-   * A value based equality test.
-   * @param v The object to compare to
-   * @return <code>true</code> iff v has the same value as the current object.
-   * @throws QueryException Resolving the data for this value leads to an error,
-   *                        or the types are incompatible.
-   */
-  public boolean equals(RDFTerm v) throws QueryException;
-
-  /**
-   * A value based inequality test.
-   * @param v The object to compare to
-   * @return <code>false</code> iff v has the same value as the current object.
-   * @throws QueryException Resolving the data for this value leads to an error,
-   *                        or the types are incompatible.
-   */
-  public boolean notEquals(RDFTerm v) throws QueryException;
-
-  /**
-   * Tests if this object is a URI or IRI.
-   * @return <code>true</code> if this object is an IRI.
-   */
-  public boolean isIRI() throws QueryException;
-  
-  /** @see #isIRI() */
-  public boolean isURI() throws QueryException;
-
-  /**
-   * Tests if this value is a blank node
-   * @return <code>true</code> if this expression is a blank node
-   */
-  public boolean isBlank() throws QueryException;
-
-  /**
-   * Tests if this value is a literal
-   * @return <code>true</code> if this expression is a literal
-   */
-  public boolean isLiteral() throws QueryException;
-
-  /**
-   * Tests if this is the same term as another expression
-   * @param v The expression to test against
-   * @return <code>true</code> if the terms are the same
-   */
-  public boolean sameTerm(RDFTerm v) throws QueryException;
-  
-  /**
-   * Sets the object that contains the current context to work in.
-   * @param owner The object that owns this context.
-   */
-  public void setContextOwner(ContextOwner owner);
-  
-  /**
-   * Gets the object that contains the current context to work in.
-   * @return The object that owns this context.
-   */
-  public ContextOwner getContextOwner();
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RDFTerm.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,93 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.io.Serializable;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * Represents data that can appear in an expression, used by filters
+ *
+ * @created Mar 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface RDFTerm extends Serializable {
+
+  /**
+   * Returns the data represented by this expression.
+   * @return The represented data.
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public Object getValue() throws QueryException;
+
+  /**
+   * A value based equality test.
+   * @param v The object to compare to
+   * @return <code>true</code> iff v has the same value as the current object.
+   * @throws QueryException Resolving the data for this value leads to an error,
+   *                        or the types are incompatible.
+   */
+  public boolean equals(RDFTerm v) throws QueryException;
+
+  /**
+   * A value based inequality test.
+   * @param v The object to compare to
+   * @return <code>false</code> iff v has the same value as the current object.
+   * @throws QueryException Resolving the data for this value leads to an error,
+   *                        or the types are incompatible.
+   */
+  public boolean notEquals(RDFTerm v) throws QueryException;
+
+  /**
+   * Tests if this object is a URI or IRI.
+   * @return <code>true</code> if this object is an IRI.
+   */
+  public boolean isIRI() throws QueryException;
+  
+  /** @see #isIRI() */
+  public boolean isURI() throws QueryException;
+
+  /**
+   * Tests if this value is a blank node
+   * @return <code>true</code> if this expression is a blank node
+   */
+  public boolean isBlank() throws QueryException;
+
+  /**
+   * Tests if this value is a literal
+   * @return <code>true</code> if this expression is a literal
+   */
+  public boolean isLiteral() throws QueryException;
+
+  /**
+   * Tests if this is the same term as another expression
+   * @param v The expression to test against
+   * @return <code>true</code> if the terms are the same
+   */
+  public boolean sameTerm(RDFTerm v) throws QueryException;
+  
+  /**
+   * Sets the object that contains the current context to work in.
+   * @param owner The object that owns this context.
+   */
+  public void setContextOwner(ContextOwner owner);
+  
+  /**
+   * Gets the object that contains the current context to work in.
+   * @return The object that owns this context.
+   */
+  public ContextOwner getContextOwner();
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/RegexFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,126 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.util.regex.Pattern;
-import static java.util.regex.Pattern.*;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-
-/**
- * The regular expression test for values.
- * TODO: Move this on to Xalan Regex functions as these are fully compliant with SPARQL,
- * while the Java ones are not.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class RegexFn extends BinaryTestFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 6785353529347360357L;
-
-  /** a cache of the last pattern */ 
-  private Pattern pattern = null;
-
-  /** The expression that resolves flags */
-  private ValueLiteral flagExpression = null;
-
-  /** a cache of the last flag string */
-  private String flagsStr = null;
-
-  /** a cache of the last flags */
-  private int flags = 0;
-
-  /**
-   * Creates an equality test operation with default flags
-   * @param lhs The first term to compare
-   * @param rhs The second term to compare
-   */
-  public RegexFn(ValueLiteral str, ValueLiteral patternStr) {
-    super(str, patternStr);
-  }
-
-  /**
-   * Creates an equality test operation with default flags
-   * @param lhs The first term to compare
-   * @param rhs The second term to compare
-   */
-  public RegexFn(ValueLiteral str, ValueLiteral patternStr, ValueLiteral flagExpression) {
-    super(str, patternStr);
-    this.flagExpression = flagExpression;
-    flagExpression.setContextOwner(this);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return pattern().matcher(str()).matches();
-  }
-
-  /**
-   * Gets the string to be matched in this regular expression.
-   * @return The string to be matched against.
-   * @throws QueryException If the expression for the string cannot be resolved.
-   */
-  private String str() throws QueryException {
-    if (!lhs.isLiteral() || !((ValueLiteral)lhs).isSimple()) throw new QueryException("Type Error: Invalid type in regular expression. Need string, got: " + lhs.getClass().getSimpleName());
-    return ((ValueLiteral)lhs).getLexical();
-  }
-
-  /**
-   * Gets the Pattern to use for the current variable bindings. This will calculate a new pattern
-   * and flags if either change for the current variable bindings.
-   * @return A Pattern for regex matching, using the existing pattern if there was no update.
-   * @throws QueryException If the pattern string or flags string cannot be resolved.
-   */
-  private Pattern pattern() throws QueryException {
-    if (!rhs.isLiteral() || !((ValueLiteral)rhs).isSimple()) throw new QueryException("Type Error: Invalid pattern type in regular expression. Need string, got: " + rhs.getClass().getSimpleName());
-    String patternStr = ((ValueLiteral)rhs).getLexical();
-    int oldFlags = flags;
-    // note that the call to flags has a side-effect
-    if (oldFlags != flags() || pattern == null || !patternStr.equals(pattern.pattern())) {
-      pattern = Pattern.compile(patternStr, flags);
-    }
-    return pattern;
-  }
-
-  /** Characters used for regex flags */
-  private static final String optionChars = "smix";
-  /** Regex flags that correspond to the optionChars */
-  private static final int[] optionFlags = new int[] { DOTALL, MULTILINE, CASE_INSENSITIVE, COMMENTS };
-
-  /**
-   * Gets the flags to use for this regex call. This will calculate new flags is the expression
-   * the flags come from is updated.
-   * @return An int with the flags for the current binding. Returns 0 if no flags are to be used.
-   * @throws QueryException The expression the flags are built on cannot be resolved.
-   */
-  private int flags() throws QueryException {
-    if (flagExpression == null) return 0;
-    if (!flagExpression.isLiteral() || !((ValueLiteral)flagExpression).isSimple()) throw new QueryException("Type Error: Invalid flags in regular expression. Need string, got: " + rhs.getClass().getSimpleName());
-    String currentFlagStr = flagExpression.getLexical();
-    if (flagsStr == null || !flagsStr.equals(currentFlagStr)) {
-      flagsStr = currentFlagStr;
-      // calculate the new flags
-      flags = 0;
-      for (int i = 0; i < optionChars.length(); i++) {
-        if (flagsStr.indexOf(optionChars.charAt(i)) != -1) flags |= optionFlags[i];
-      }
-    }
-    return flags;
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/RegexFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,126 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.util.regex.Pattern;
+import static java.util.regex.Pattern.*;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+
+/**
+ * The regular expression test for values.
+ * TODO: Move this on to Xalan Regex functions as these are fully compliant with SPARQL,
+ * while the Java ones are not.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class RegexFn extends BinaryTestFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 6785353529347360357L;
+
+  /** a cache of the last pattern */ 
+  private Pattern pattern = null;
+
+  /** The expression that resolves flags */
+  private ValueLiteral flagExpression = null;
+
+  /** a cache of the last flag string */
+  private String flagsStr = null;
+
+  /** a cache of the last flags */
+  private int flags = 0;
+
+  /**
+   * Creates an equality test operation with default flags
+   * @param lhs The first term to compare
+   * @param rhs The second term to compare
+   */
+  public RegexFn(ValueLiteral str, ValueLiteral patternStr) {
+    super(str, patternStr);
+  }
+
+  /**
+   * Creates an equality test operation with default flags
+   * @param lhs The first term to compare
+   * @param rhs The second term to compare
+   */
+  public RegexFn(ValueLiteral str, ValueLiteral patternStr, ValueLiteral flagExpression) {
+    super(str, patternStr);
+    this.flagExpression = flagExpression;
+    flagExpression.setContextOwner(this);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return pattern().matcher(str()).matches();
+  }
+
+  /**
+   * Gets the string to be matched in this regular expression.
+   * @return The string to be matched against.
+   * @throws QueryException If the expression for the string cannot be resolved.
+   */
+  private String str() throws QueryException {
+    if (!lhs.isLiteral() || !((ValueLiteral)lhs).isSimple()) throw new QueryException("Type Error: Invalid type in regular expression. Need string, got: " + lhs.getClass().getSimpleName());
+    return ((ValueLiteral)lhs).getLexical();
+  }
+
+  /**
+   * Gets the Pattern to use for the current variable bindings. This will calculate a new pattern
+   * and flags if either change for the current variable bindings.
+   * @return A Pattern for regex matching, using the existing pattern if there was no update.
+   * @throws QueryException If the pattern string or flags string cannot be resolved.
+   */
+  private Pattern pattern() throws QueryException {
+    if (!rhs.isLiteral() || !((ValueLiteral)rhs).isSimple()) throw new QueryException("Type Error: Invalid pattern type in regular expression. Need string, got: " + rhs.getClass().getSimpleName());
+    String patternStr = ((ValueLiteral)rhs).getLexical();
+    int oldFlags = flags;
+    // note that the call to flags has a side-effect
+    if (oldFlags != flags() || pattern == null || !patternStr.equals(pattern.pattern())) {
+      pattern = Pattern.compile(patternStr, flags);
+    }
+    return pattern;
+  }
+
+  /** Characters used for regex flags */
+  private static final String optionChars = "smix";
+  /** Regex flags that correspond to the optionChars */
+  private static final int[] optionFlags = new int[] { DOTALL, MULTILINE, CASE_INSENSITIVE, COMMENTS };
+
+  /**
+   * Gets the flags to use for this regex call. This will calculate new flags is the expression
+   * the flags come from is updated.
+   * @return An int with the flags for the current binding. Returns 0 if no flags are to be used.
+   * @throws QueryException The expression the flags are built on cannot be resolved.
+   */
+  private int flags() throws QueryException {
+    if (flagExpression == null) return 0;
+    if (!flagExpression.isLiteral() || !((ValueLiteral)flagExpression).isSimple()) throw new QueryException("Type Error: Invalid flags in regular expression. Need string, got: " + rhs.getClass().getSimpleName());
+    String currentFlagStr = flagExpression.getLexical();
+    if (flagsStr == null || !flagsStr.equals(currentFlagStr)) {
+      flagsStr = currentFlagStr;
+      // calculate the new flags
+      flags = 0;
+      for (int i = 0; i < optionChars.length(); i++) {
+        if (flagsStr.indexOf(optionChars.charAt(i)) != -1) flags |= optionFlags[i];
+      }
+    }
+    return flags;
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,208 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-import org.mulgara.query.filter.value.Var;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the Regex function.
- *
- * @created Apr 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class RegexFnUnitTest extends TestCase {
-
-  Bool t = Bool.TRUE;
-  Bool f = Bool.FALSE;
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public RegexFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new RegexFnUnitTest("testLiteral"));
-    suite.addTest(new RegexFnUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    SimpleLiteral str = new SimpleLiteral("a foolish test");
-    SimpleLiteral diffStr = new SimpleLiteral("another test");
-    SimpleLiteral pattern = new SimpleLiteral(".*foo.*");
-    SimpleLiteral patternCaps = new SimpleLiteral(".*FOO.*");
-    SimpleLiteral pattern2 = new SimpleLiteral(".*foo.*test.*");
-    SimpleLiteral noTest = new SimpleLiteral("fred");
-    SimpleLiteral caseFlag = new SimpleLiteral("i");
-    ValueLiteral typed = TypedLiteral.newLiteral("a foolish test");
-    ValueLiteral typedPattern = TypedLiteral.newLiteral(".*foo.*");
-
-    RegexFn fn = new RegexFn(str, pattern);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-    fn = new RegexFn(str, pattern2);
-    assertTrue(t.equals(fn));
-    assertTrue(fn.equals(t));
-
-    fn = new RegexFn(diffStr, pattern);
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-    fn = new RegexFn(diffStr, pattern2);
-    assertTrue(f.equals(fn));
-    assertTrue(fn.equals(f));
-
-    fn = new RegexFn(str, noTest);
-    assertTrue(f.equals(fn));
-
-    fn = new RegexFn(str, patternCaps);
-    assertTrue(f.equals(fn));
-    fn = new RegexFn(str, patternCaps, caseFlag);
-    assertTrue(t.equals(fn));
-
-    fn = new RegexFn(typed, pattern);
-    try {
-      assertTrue(f.equals(fn));
-      fail("Tested regex on a typed literal");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-
-    fn = new RegexFn(str, typedPattern);
-    try {
-      assertTrue(f.equals(fn));
-      fail("Tested regex on a typed literal");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-}
-
-  public void testVar() throws Exception {
-    RegexFn fn = new RegexFn(new Var("x"), new Var("y"), new Var("z"));
-
-    Literal noFlags = new LiteralImpl("");
-    Literal caseFlag = new LiteralImpl("i");
-
-    Literal str = new LiteralImpl("a foolish test");
-    Literal diffStr = new LiteralImpl("another test");
-    Literal pattern = new LiteralImpl(".*foo.*");
-    Literal patternCaps = new LiteralImpl(".*FOO.*");
-    Literal pattern2 = new LiteralImpl(".*foo.*test.*");
-    Literal noTest = new LiteralImpl("fred");
-    Literal typed = new LiteralImpl("a foolish test", SimpleLiteral.STRING_TYPE.getValue());
-    Literal typedPattern = new LiteralImpl(".*foo.*", SimpleLiteral.STRING_TYPE.getValue());
-    URIReferenceImpl xsdString = new URIReferenceImpl(SimpleLiteral.STRING_TYPE.getValue());
-    BlankNodeImpl bn = new BlankNodeImpl(101);
-    Node[][] rows = {
-      new Node[] {str, pattern, noFlags},
-      new Node[] {diffStr, pattern, noFlags},
-      new Node[] {str, pattern2, noFlags},
-      new Node[] {diffStr, pattern, noFlags},
-      new Node[] {diffStr, pattern2, noFlags},
-
-      new Node[] {str, noTest, noFlags},
-
-      new Node[] {str, patternCaps, noFlags},
-      new Node[] {str, patternCaps, caseFlag},
-
-      new Node[] {typed, pattern, noFlags},
-      new Node[] {str, typedPattern, caseFlag},
-
-      new Node[] {xsdString, pattern, noFlags},
-      new Node[] {str, xsdString, noFlags},
-      new Node[] {str, pattern, xsdString},
-
-      new Node[] {null, pattern, noFlags},
-      new Node[] {str, null, noFlags},
-      new Node[] {str, pattern, null},
-
-      new Node[] {bn, pattern, noFlags},
-      new Node[] {str, bn, noFlags},
-      new Node[] {str, pattern, bn},
-    };
-    TestContext c = new TestContext(new String[] {"x", "y", "z"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    String results = "tftff f ft ee eee xxx eee";
-    runTests(c, fn, results);
-  }
-
-  private void runTests(TestContext c, AbstractFilterValue fn, String results) throws Exception {
-    c.beforeFirst();
-    for (char result: results.toCharArray()) {
-      if (result == ' ') continue;
-      assertTrue(c.next());
-      switch (result) {
-      case 't':  // equal
-        assertTrue(t.equals(fn));
-        break;
-
-      case 'f':  // unequal
-        assertTrue(f.equals(fn));
-        break;
-
-      case 'e':  // typing error
-        try {
-          assertTrue(f.equals(fn));
-          fail("Successfully tested values that were not simple literals");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Type Error"));
-        }
-        break;
-
-      case 'x':  // exception due to unbound
-        try {
-          assertTrue(f.equals(fn));
-          fail("No exception when testing an unbound value");
-        } catch (QueryException qe) {
-          assertTrue(qe.getMessage().startsWith("Unbound column"));
-        }
-        break;
-        
-      default:
-        fail("Bad test data");
-      }
-    }
-    assertFalse(c.next());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RegexFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,208 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+import org.mulgara.query.filter.value.Var;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the Regex function.
+ *
+ * @created Apr 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class RegexFnUnitTest extends TestCase {
+
+  Bool t = Bool.TRUE;
+  Bool f = Bool.FALSE;
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public RegexFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new RegexFnUnitTest("testLiteral"));
+    suite.addTest(new RegexFnUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    SimpleLiteral str = new SimpleLiteral("a foolish test");
+    SimpleLiteral diffStr = new SimpleLiteral("another test");
+    SimpleLiteral pattern = new SimpleLiteral(".*foo.*");
+    SimpleLiteral patternCaps = new SimpleLiteral(".*FOO.*");
+    SimpleLiteral pattern2 = new SimpleLiteral(".*foo.*test.*");
+    SimpleLiteral noTest = new SimpleLiteral("fred");
+    SimpleLiteral caseFlag = new SimpleLiteral("i");
+    ValueLiteral typed = TypedLiteral.newLiteral("a foolish test");
+    ValueLiteral typedPattern = TypedLiteral.newLiteral(".*foo.*");
+
+    RegexFn fn = new RegexFn(str, pattern);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+    fn = new RegexFn(str, pattern2);
+    assertTrue(t.equals(fn));
+    assertTrue(fn.equals(t));
+
+    fn = new RegexFn(diffStr, pattern);
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+    fn = new RegexFn(diffStr, pattern2);
+    assertTrue(f.equals(fn));
+    assertTrue(fn.equals(f));
+
+    fn = new RegexFn(str, noTest);
+    assertTrue(f.equals(fn));
+
+    fn = new RegexFn(str, patternCaps);
+    assertTrue(f.equals(fn));
+    fn = new RegexFn(str, patternCaps, caseFlag);
+    assertTrue(t.equals(fn));
+
+    fn = new RegexFn(typed, pattern);
+    try {
+      assertTrue(f.equals(fn));
+      fail("Tested regex on a typed literal");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+
+    fn = new RegexFn(str, typedPattern);
+    try {
+      assertTrue(f.equals(fn));
+      fail("Tested regex on a typed literal");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+}
+
+  public void testVar() throws Exception {
+    RegexFn fn = new RegexFn(new Var("x"), new Var("y"), new Var("z"));
+
+    Literal noFlags = new LiteralImpl("");
+    Literal caseFlag = new LiteralImpl("i");
+
+    Literal str = new LiteralImpl("a foolish test");
+    Literal diffStr = new LiteralImpl("another test");
+    Literal pattern = new LiteralImpl(".*foo.*");
+    Literal patternCaps = new LiteralImpl(".*FOO.*");
+    Literal pattern2 = new LiteralImpl(".*foo.*test.*");
+    Literal noTest = new LiteralImpl("fred");
+    Literal typed = new LiteralImpl("a foolish test", SimpleLiteral.STRING_TYPE.getValue());
+    Literal typedPattern = new LiteralImpl(".*foo.*", SimpleLiteral.STRING_TYPE.getValue());
+    URIReferenceImpl xsdString = new URIReferenceImpl(SimpleLiteral.STRING_TYPE.getValue());
+    BlankNodeImpl bn = new BlankNodeImpl(101);
+    Node[][] rows = {
+      new Node[] {str, pattern, noFlags},
+      new Node[] {diffStr, pattern, noFlags},
+      new Node[] {str, pattern2, noFlags},
+      new Node[] {diffStr, pattern, noFlags},
+      new Node[] {diffStr, pattern2, noFlags},
+
+      new Node[] {str, noTest, noFlags},
+
+      new Node[] {str, patternCaps, noFlags},
+      new Node[] {str, patternCaps, caseFlag},
+
+      new Node[] {typed, pattern, noFlags},
+      new Node[] {str, typedPattern, caseFlag},
+
+      new Node[] {xsdString, pattern, noFlags},
+      new Node[] {str, xsdString, noFlags},
+      new Node[] {str, pattern, xsdString},
+
+      new Node[] {null, pattern, noFlags},
+      new Node[] {str, null, noFlags},
+      new Node[] {str, pattern, null},
+
+      new Node[] {bn, pattern, noFlags},
+      new Node[] {str, bn, noFlags},
+      new Node[] {str, pattern, bn},
+    };
+    TestContext c = new TestContext(new String[] {"x", "y", "z"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    String results = "tftff f ft ee eee xxx eee";
+    runTests(c, fn, results);
+  }
+
+  private void runTests(TestContext c, AbstractFilterValue fn, String results) throws Exception {
+    c.beforeFirst();
+    for (char result: results.toCharArray()) {
+      if (result == ' ') continue;
+      assertTrue(c.next());
+      switch (result) {
+      case 't':  // equal
+        assertTrue(t.equals(fn));
+        break;
+
+      case 'f':  // unequal
+        assertTrue(f.equals(fn));
+        break;
+
+      case 'e':  // typing error
+        try {
+          assertTrue(f.equals(fn));
+          fail("Successfully tested values that were not simple literals");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Type Error"));
+        }
+        break;
+
+      case 'x':  // exception due to unbound
+        try {
+          assertTrue(f.equals(fn));
+          fail("No exception when testing an unbound value");
+        } catch (QueryException qe) {
+          assertTrue(qe.getMessage().startsWith("Unbound column"));
+        }
+        break;
+        
+      default:
+        fail("Bad test data");
+      }
+    }
+    assertFalse(c.next());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/SameTerm.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,44 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import org.mulgara.query.QueryException;
-
-
-/**
- * The sameterm comparison for Values.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class SameTerm extends BinaryTestFilter {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -5260593869711335738L;
-
-  /**
-   * Creates a sameterm test operation
-   * @param lhs The first term to compare
-   * @param rhs The second term to compare
-   */
-  public SameTerm(RDFTerm lhs, RDFTerm rhs) {
-    super(lhs, rhs);
-  }
-
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
-  boolean testCmp() throws QueryException {
-    return lhs.sameTerm(rhs);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/SameTerm.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,44 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import org.mulgara.query.QueryException;
+
+
+/**
+ * The sameterm comparison for Values.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SameTerm extends BinaryTestFilter {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -5260593869711335738L;
+
+  /**
+   * Creates a sameterm test operation
+   * @param lhs The first term to compare
+   * @param rhs The second term to compare
+   */
+  public SameTerm(RDFTerm lhs, RDFTerm rhs) {
+    super(lhs, rhs);
+  }
+
+  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  boolean testCmp() throws QueryException {
+    return lhs.sameTerm(rhs);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/TestContext.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,149 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-
-
-/**
- * A simple Context used for testing purposes.
- * This context returns <code>null</code> for unbound values, since it is globalizing.
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class TestContext implements Context {
-  
-  /** The current internal row for the data */
-  private int rowNumber = -1;
-
-  /** The names of the columns */
-  private List<String> columnNames;
-
-  /** The rows of data. Now row can exceed the size of columnNames */
-  private Node[][] rows;
-
-  /** The map for converting IDs into Nodes stored against them */
-  private Map<Long,Node> globalizer = new HashMap<Long,Node>();
-
-  /** The map for converting Nodes into the IDs stored against them */
-  private Map<Node,Long> localizer = new HashMap<Node,Long>();
-
-  /** The pseudo node-pool counter */
-  private long lastNode = 1;
-
-  /**
-   * Empty constructor used for tests which have no data.
-   */
-  public TestContext() {
-    columnNames = Collections.emptyList();
-    rows = new Node[][] { new Node[] {} };
-  }
-
-  /**
-   * Creates a test context.
-   * @param columnNames The names of the columns for the virtual tuples.
-   * @param rows An array of rows, where each row is Node[]. All rows should be
-   *   the same width, which is equal to columnNames.length.
-   */
-  public TestContext(String[] columnNames, Node[][] rows) {
-    this.columnNames = Arrays.asList(columnNames);
-    this.rows = rows;
-    mapGlobalizer(rows);
-  }
-
-  /**
-   * Reset the position to the start.
-   */
-  public void beforeFirst() {
-    rowNumber = -1;
-  }
-
-  /**
-   * Move to the next row of data.
-   * @return <code>true</code> if the new row contains data, or <code>false</code>
-   *   if this object has moved past the last row.
-   */
-  public boolean next() {
-    return ++rowNumber < rows.length;
-  }
-
-  /**@see org.mulgara.query.filter.Context#getColumnValue(int) */
-  public long getColumnValue(int columnNumber) throws QueryException {
-    if (columnNumber >= columnNames.size()) throw new QueryException("Unexpected column: " + columnNumber);
-    Node v = rows[rowNumber][columnNumber];
-    if (v == null) throw new QueryException("Unbound column: " + columnNumber);
-    return localizer.get(v);
-  }
-
-  /** @see org.mulgara.query.filter.Context#getInternalColumnIndex(java.lang.String) */
-  public int getInternalColumnIndex(String name) {
-    return columnNames.contains(name) ? columnNames.indexOf(name) : NOT_BOUND;
-  }
-
-  /** @see org.mulgara.query.filter.Context#globalize(long) */
-  public Node globalize(long node) throws QueryException {
-    Node n = globalizer.get(node);
-    if (n == null) throw new QueryException("Unable to globalize id <" + node + ">");
-    return n != Null.NULL ? n : null;
-  }
-
-  /** @see org.mulgara.query.filter.Context#isBound(int) */
-  public boolean isBound(int columnNumber) throws QueryException {
-    if (columnNumber >= columnNames.size()) throw new QueryException("Unexpected column: " + columnNumber);
-    return rows[rowNumber][columnNumber] != null;
-  }
-
-  /**
-   * Gets a previously unused node ID.
-   * @return a new Node ID.
-   */
-  private long newNodeId() {
-    return lastNode++;
-  }
-
-  /**
-   * Map node IDs to the nodes, and nodes back to their IDs.
-   * @param rows An array of node arrays.
-   */
-  private void mapGlobalizer(Node[][] rows) {
-    for (Node[] row: rows) {
-      assert row.length == columnNames.size();
-      for (Node v: row) {
-        if (v == null) v = Null.NULL;
-        Long storedId = localizer.get(v);
-        if (storedId == null) {
-          storedId = newNodeId();
-          globalizer.put(storedId, v);
-          localizer.put(v, storedId);
-        } else {
-          assert globalizer.get(storedId).equals(v) : "Bidirectional mapping for nodes<->ID failed";
-        }
-      }
-    }
-  }
-
-  /** Testing class used for storing a symbol for <code>null</code> that is disambiguated from a missing value */
-  @SuppressWarnings("serial")
-  private static class Null implements Node {
-    public static final Null NULL = new Null();
-    public int hashCode() { return -1; }
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/TestContext.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/TestContext.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,149 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+
+
+/**
+ * A simple Context used for testing purposes.
+ * This context returns <code>null</code> for unbound values, since it is globalizing.
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TestContext implements Context {
+  
+  /** The current internal row for the data */
+  private int rowNumber = -1;
+
+  /** The names of the columns */
+  private List<String> columnNames;
+
+  /** The rows of data. Now row can exceed the size of columnNames */
+  private Node[][] rows;
+
+  /** The map for converting IDs into Nodes stored against them */
+  private Map<Long,Node> globalizer = new HashMap<Long,Node>();
+
+  /** The map for converting Nodes into the IDs stored against them */
+  private Map<Node,Long> localizer = new HashMap<Node,Long>();
+
+  /** The pseudo node-pool counter */
+  private long lastNode = 1;
+
+  /**
+   * Empty constructor used for tests which have no data.
+   */
+  public TestContext() {
+    columnNames = Collections.emptyList();
+    rows = new Node[][] { new Node[] {} };
+  }
+
+  /**
+   * Creates a test context.
+   * @param columnNames The names of the columns for the virtual tuples.
+   * @param rows An array of rows, where each row is Node[]. All rows should be
+   *   the same width, which is equal to columnNames.length.
+   */
+  public TestContext(String[] columnNames, Node[][] rows) {
+    this.columnNames = Arrays.asList(columnNames);
+    this.rows = rows;
+    mapGlobalizer(rows);
+  }
+
+  /**
+   * Reset the position to the start.
+   */
+  public void beforeFirst() {
+    rowNumber = -1;
+  }
+
+  /**
+   * Move to the next row of data.
+   * @return <code>true</code> if the new row contains data, or <code>false</code>
+   *   if this object has moved past the last row.
+   */
+  public boolean next() {
+    return ++rowNumber < rows.length;
+  }
+
+  /**@see org.mulgara.query.filter.Context#getColumnValue(int) */
+  public long getColumnValue(int columnNumber) throws QueryException {
+    if (columnNumber >= columnNames.size()) throw new QueryException("Unexpected column: " + columnNumber);
+    Node v = rows[rowNumber][columnNumber];
+    if (v == null) throw new QueryException("Unbound column: " + columnNumber);
+    return localizer.get(v);
+  }
+
+  /** @see org.mulgara.query.filter.Context#getInternalColumnIndex(java.lang.String) */
+  public int getInternalColumnIndex(String name) {
+    return columnNames.contains(name) ? columnNames.indexOf(name) : NOT_BOUND;
+  }
+
+  /** @see org.mulgara.query.filter.Context#globalize(long) */
+  public Node globalize(long node) throws QueryException {
+    Node n = globalizer.get(node);
+    if (n == null) throw new QueryException("Unable to globalize id <" + node + ">");
+    return n != Null.NULL ? n : null;
+  }
+
+  /** @see org.mulgara.query.filter.Context#isBound(int) */
+  public boolean isBound(int columnNumber) throws QueryException {
+    if (columnNumber >= columnNames.size()) throw new QueryException("Unexpected column: " + columnNumber);
+    return rows[rowNumber][columnNumber] != null;
+  }
+
+  /**
+   * Gets a previously unused node ID.
+   * @return a new Node ID.
+   */
+  private long newNodeId() {
+    return lastNode++;
+  }
+
+  /**
+   * Map node IDs to the nodes, and nodes back to their IDs.
+   * @param rows An array of node arrays.
+   */
+  private void mapGlobalizer(Node[][] rows) {
+    for (Node[] row: rows) {
+      assert row.length == columnNames.size();
+      for (Node v: row) {
+        if (v == null) v = Null.NULL;
+        Long storedId = localizer.get(v);
+        if (storedId == null) {
+          storedId = newNodeId();
+          globalizer.put(storedId, v);
+          localizer.put(v, storedId);
+        } else {
+          assert globalizer.get(storedId).equals(v) : "Bidirectional mapping for nodes<->ID failed";
+        }
+      }
+    }
+  }
+
+  /** Testing class used for storing a symbol for <code>null</code> that is disambiguated from a missing value */
+  @SuppressWarnings("serial")
+  private static class Null implements Node {
+    public static final Null NULL = new Null();
+    public int hashCode() { return -1; }
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,42 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter;
-
-
-/**
- * A test class for emulating a context ownership.
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class TestContextOwner implements ContextOwner {
-  /** The owned context */
-  private Context ctx;
-  
-  /**
-   * Create the test ownership.
-   * @param ctx The context to own.
-   */
-  public TestContextOwner(Context ctx) { this.ctx = ctx; }
-
-  /**
-   * Updates the owned context.
-   * @param ctx The context to update to.
-   */
-  public void setCurrentContext(Context ctx) { this.ctx = ctx; }
-
-  /** @return the current context. */
-  public Context getCurrentContext() { return ctx; }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/TestContextOwner.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,42 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter;
+
+
+/**
+ * A test class for emulating a context ownership.
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TestContextOwner implements ContextOwner {
+  /** The owned context */
+  private Context ctx;
+  
+  /**
+   * Create the test ownership.
+   * @param ctx The context to own.
+   */
+  public TestContextOwner(Context ctx) { this.ctx = ctx; }
+
+  /**
+   * Updates the owned context.
+   * @param ctx The context to update to.
+   */
+  public void setCurrentContext(Context ctx) { this.ctx = ctx; }
+
+  /** @return the current context. */
+  public Context getCurrentContext() { return ctx; }
+
+}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic)

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,139 +0,0 @@
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.ContextOwner;
-import org.mulgara.query.filter.RDFTerm;
-import org.mulgara.query.filter.value.AbstractComparable;
-import org.mulgara.query.filter.value.IRI;
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-
-/**
- * Implements common functionality for arithmetic operations.
- *
- * @created Apr 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractNumericOperation extends AbstractComparable implements NumericExpression {
-
-  /** The owner of the context for resolving here */
-  private ContextOwner owner = null;
-
-  public AbstractNumericOperation() {
-    super();
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#getValue() */
-  public Number getValue() throws QueryException { return getNumber(); }
-
-  /** @see org.mulgara.query.filter.RDFTerm#equals() */
-  public boolean equals(RDFTerm v) throws QueryException { return compare(getNumber(), v.getValue()) == 0; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isBlank() */
-  public boolean isBlank() throws QueryException { return false; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isIRI() */
-  public boolean isIRI() throws QueryException { return false; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isLiteral() */
-  public boolean isLiteral() throws QueryException { return true; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isURI() */
-  public boolean isURI() throws QueryException { return false; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#notEquals() */
-  public boolean notEquals(RDFTerm v) throws QueryException { return compare(getNumber(), v.getValue()) != 0; }
-
-  /** @see org.mulgara.query.filter.RDFTerm#sameTerm() */
-  public boolean sameTerm(RDFTerm v) throws QueryException { return getNumber().equals(v.getValue()); }
-
-  /** @see org.mulgara.query.filter.Filter#test() */
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    return getNumber().doubleValue() != 0.0;
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner) */
-  public void setContextOwner(ContextOwner owner) {
-    this.owner = owner;
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
-  public ContextOwner getContextOwner() {
-    return owner;
-  }
-
-  /** @see org.mulgara.query.filter.value.NumericExpression#getNumber() */
-  public abstract Number getNumber() throws QueryException;
-
-
-  //////////////////////////////////////////////////////////////
-  // Implementation of AbstractComparable.compare(Object,Object)
-  //////////////////////////////////////////////////////////////
-  
-  /** The set of classes to be compared as floating point */
-  private static Set<Class<? extends Number>> floatUpcast = new HashSet<Class<? extends Number>>();
-  
-  /* Initialize the set of classes to be compared as floating point */
-  static {
-    floatUpcast.add(Double.class);
-    floatUpcast.add(Float.class);
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.AbstractComparable#compare(java.lang.Object, java.lang.Object)
-   */
-  protected int compare(Object left, Object right) throws QueryException {
-    return compare((Number)left, right);
-  }
-
-  /**
-   * Compares 2 numbers of unknown type.  If they are both floating point, then use Double compare,
-   * otherwise use Long compare.
-   * @param left The first number in the comparison.
-   * @param right The second number. This cannot be assumed to be a number due to poorly formed queries.
-   * @return -1 if left<right, +1 if left>right, 0 if left==right
-   * @throws QueryException if right is a type other than {@link java.lang.Number}.
-   */
-  protected int compare(Number left, Object right) throws QueryException {
-    if (!(right instanceof Number)) throw new QueryException("Cannot compare a number to a: " + right.getClass().getSimpleName());
-    if (floatUpcast.contains(left.getClass()) || floatUpcast.contains(right.getClass())) {
-      return Double.valueOf(left.doubleValue()).compareTo(((Number)right).doubleValue());
-    }
-    return Long.valueOf(left.longValue()).compareTo(((Number)right).longValue());
-  }
-
-
-  /////////////////////////////////
-  // Implementation of ValueLiteral
-  /////////////////////////////////
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#getLexical() */
-  public String getLexical() throws QueryException {
-    return getValue().toString();
-  }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#getLang() */
-  public SimpleLiteral getLang() {
-    return SimpleLiteral.EMPTY;
-  }
-
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
-  public IRI getType() throws QueryException {
-    return NumericLiteral.getTypeFor(getValue());
-  }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
-  public boolean isSimple() throws QueryException {
-    return false;
-  }
-
-}
\ No newline at end of file

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractNumericOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,139 @@
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.RDFTerm;
+import org.mulgara.query.filter.value.AbstractComparable;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+
+/**
+ * Implements common functionality for arithmetic operations.
+ *
+ * @created Apr 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractNumericOperation extends AbstractComparable implements NumericExpression {
+
+  /** The owner of the context for resolving here */
+  private ContextOwner owner = null;
+
+  public AbstractNumericOperation() {
+    super();
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#getValue() */
+  public Number getValue() throws QueryException { return getNumber(); }
+
+  /** @see org.mulgara.query.filter.RDFTerm#equals() */
+  public boolean equals(RDFTerm v) throws QueryException { return compare(getNumber(), v.getValue()) == 0; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isBlank() */
+  public boolean isBlank() throws QueryException { return false; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isIRI() */
+  public boolean isIRI() throws QueryException { return false; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isLiteral() */
+  public boolean isLiteral() throws QueryException { return true; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isURI() */
+  public boolean isURI() throws QueryException { return false; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#notEquals() */
+  public boolean notEquals(RDFTerm v) throws QueryException { return compare(getNumber(), v.getValue()) != 0; }
+
+  /** @see org.mulgara.query.filter.RDFTerm#sameTerm() */
+  public boolean sameTerm(RDFTerm v) throws QueryException { return getNumber().equals(v.getValue()); }
+
+  /** @see org.mulgara.query.filter.Filter#test() */
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    return getNumber().doubleValue() != 0.0;
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner) */
+  public void setContextOwner(ContextOwner owner) {
+    this.owner = owner;
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
+  public ContextOwner getContextOwner() {
+    return owner;
+  }
+
+  /** @see org.mulgara.query.filter.value.NumericExpression#getNumber() */
+  public abstract Number getNumber() throws QueryException;
+
+
+  //////////////////////////////////////////////////////////////
+  // Implementation of AbstractComparable.compare(Object,Object)
+  //////////////////////////////////////////////////////////////
+  
+  /** The set of classes to be compared as floating point */
+  private static Set<Class<? extends Number>> floatUpcast = new HashSet<Class<? extends Number>>();
+  
+  /* Initialize the set of classes to be compared as floating point */
+  static {
+    floatUpcast.add(Double.class);
+    floatUpcast.add(Float.class);
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.AbstractComparable#compare(java.lang.Object, java.lang.Object)
+   */
+  protected int compare(Object left, Object right) throws QueryException {
+    return compare((Number)left, right);
+  }
+
+  /**
+   * Compares 2 numbers of unknown type.  If they are both floating point, then use Double compare,
+   * otherwise use Long compare.
+   * @param left The first number in the comparison.
+   * @param right The second number. This cannot be assumed to be a number due to poorly formed queries.
+   * @return -1 if left<right, +1 if left>right, 0 if left==right
+   * @throws QueryException if right is a type other than {@link java.lang.Number}.
+   */
+  protected int compare(Number left, Object right) throws QueryException {
+    if (!(right instanceof Number)) throw new QueryException("Cannot compare a number to a: " + right.getClass().getSimpleName());
+    if (floatUpcast.contains(left.getClass()) || floatUpcast.contains(right.getClass())) {
+      return Double.valueOf(left.doubleValue()).compareTo(((Number)right).doubleValue());
+    }
+    return Long.valueOf(left.longValue()).compareTo(((Number)right).longValue());
+  }
+
+
+  /////////////////////////////////
+  // Implementation of ValueLiteral
+  /////////////////////////////////
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#getLexical() */
+  public String getLexical() throws QueryException {
+    return getValue().toString();
+  }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#getLang() */
+  public SimpleLiteral getLang() {
+    return SimpleLiteral.EMPTY;
+  }
+
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
+  public IRI getType() throws QueryException {
+    return NumericLiteral.getTypeFor(getValue());
+  }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+  public boolean isSimple() throws QueryException {
+    return false;
+  }
+
+}
\ No newline at end of file

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,225 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-import org.mulgara.query.filter.value.Var;
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the numeric operation classes.
- * This uses a convoluted mechanism to let the compiler determine the correct return types
- * in each of the implementing classes.
- *
- * @created Apr 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractOperationUnitTest extends TestCase {
-
-  URI xsdInt = URI.create(XSD_NS + "int");
-  URI xsdLong = URI.create(XSD_NS + "long");
-  URI xsdFloat = URI.create(XSD_NS + "float");
-  URI xsdDouble = URI.create(XSD_NS + "double");
-
-  /** The first operand to use for this test */
-  abstract Number op1();
-
-  /** The second operand to use for this test */
-  abstract Number op2();
-
-  /** Get an instance of the operation for this test */
-  abstract BinaryOperation getOperation(NumericExpression e1, NumericExpression e2);
-
-  /** perform the operation using native data types which are passed in two literals */
-  abstract ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException;
-
-  NumericLiteral doOperation(NumericLiteral l1, NumericLiteral l2) throws QueryException {
-    return (NumericLiteral)doOperation(new LiteralImpl(l1.getLexical(), l1.getType().getValue()), new LiteralImpl(l2.getLexical(), l2.getType().getValue()));
-  }
-
-  enum NumberType { tInt, tLong, tFloat, tDouble };
-
-  /** Gets the type of a URI as one of the defined number types */
-  NumberType getType(Literal l) {
-    URI dt = l.getDatatypeURI();
-    if (dt.equals(xsdInt)) return NumberType.tInt;
-    if (dt.equals(xsdLong)) return NumberType.tLong;
-    if (dt.equals(xsdFloat)) return NumberType.tFloat;
-    if (dt.equals(xsdDouble)) return NumberType.tDouble;
-    throw new Error("Unknown number type: " + dt);
-  }
-
-  /** request that the implementing class do the operation and creates a literal */
-  ValueLiteral getLiteralResult(Node n1, Node n2) throws QueryException {
-    Literal l1 = (Literal)n1;
-    Literal l2 = (Literal)n2;
-    return doOperation(l1, l2);
-  }
-
-  // use compiler dispatch and autoboxing to convert a value to a typed literal
-  ValueLiteral newLiteral(int x) throws QueryException { return TypedLiteral.newLiteral(x); }
-  ValueLiteral newLiteral(long x) throws QueryException { return TypedLiteral.newLiteral(x); }
-  ValueLiteral newLiteral(float x) throws QueryException { return TypedLiteral.newLiteral(x); }
-  ValueLiteral newLiteral(double x) throws QueryException { return TypedLiteral.newLiteral(x); }
-  
-  // convert a literal to a basic type, explicitly
-  int getInt(Literal l) { return Integer.parseInt(l.getLexicalForm()); }
-  long getLong(Literal l) { return Long.parseLong(l.getLexicalForm()); }
-  float getFloat(Literal l) { return Float.parseFloat(l.getLexicalForm()); }
-  double getDouble(Literal l) { return Double.parseDouble(l.getLexicalForm()); }
-
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public AbstractOperationUnitTest(String name) {
-    super(name);
-  }
-
-  public static Test suite() {
-    return new TestSuite();
-  }
-
-  public void testLiteral() throws Exception {
-    NumericLiteral op1i = new NumericLiteral(op1().intValue());
-    NumericLiteral op2i = new NumericLiteral(op2().intValue());
-    NumericLiteral op1l = new NumericLiteral(op1().longValue());
-    NumericLiteral op2l = new NumericLiteral(op2().longValue());
-    NumericLiteral op1f = new NumericLiteral(op1().floatValue());
-    NumericLiteral op2f = new NumericLiteral(op2().floatValue());
-    NumericLiteral op1d = new NumericLiteral(op1().doubleValue());
-    NumericLiteral op2d = new NumericLiteral(op2().doubleValue());
-
-    basicTest(op1i, op2i, doOperation(op1i, op2i));
-    basicTest(op1i, op2l, doOperation(op1i, op2l));
-    basicTest(op1i, op2f, doOperation(op1i, op2f));
-    basicTest(op1i, op2d, doOperation(op1i, op2d));
-    basicTest(op1l, op2l, doOperation(op1l, op2l));
-    basicTest(op1l, op2f, doOperation(op1l, op2f));
-    basicTest(op1l, op2d, doOperation(op1l, op2d));
-    basicTest(op1f, op2f, doOperation(op1f, op2f));
-    basicTest(op1f, op2d, doOperation(op1f, op2d));
-    basicTest(op1d, op2d, doOperation(op1d, op2d));
-  }
-
-  private void basicTest(NumericLiteral literal1, NumericLiteral literal2, NumericLiteral literalResult) throws Exception {
-    BinaryOperation op = getOperation(literal1, literal2);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    Var y = new Var("y");
-    BinaryOperation fn = getOperation(x, y);
-    
-    URI fooBar = URI.create("foo:bar");
-    Literal iop1 = new LiteralImpl("" + op1().intValue(), xsdInt);
-    Literal iop2 = new LiteralImpl("" + op2().intValue(), xsdInt);
-    Literal lop1 = new LiteralImpl("" + op1().longValue(), xsdLong);
-    Literal lop2 = new LiteralImpl("" + op2().longValue(), xsdLong);
-    Literal fop1 = new LiteralImpl("" + op1().floatValue(), xsdFloat);
-    Literal fop2 = new LiteralImpl("" + op2().floatValue(), xsdFloat);
-    Literal dop1 = new LiteralImpl("" + op1().doubleValue(), xsdDouble);
-    Literal dop2 = new LiteralImpl("" + op2().doubleValue(), xsdDouble);
-    Node[][] rows = {
-      new Node[] {iop1, iop2},
-      new Node[] {iop1, lop2},
-      new Node[] {iop1, fop2},
-      new Node[] {iop1, dop2},
-      new Node[] {lop1, lop2},
-      new Node[] {lop1, fop2},
-      new Node[] {lop1, dop2},
-      new Node[] {fop1, fop2},
-      new Node[] {fop1, dop2},
-      new Node[] {dop1, dop2},
-      // The following are to fail
-      new Node[] {new LiteralImpl("foo", "en"), iop2},
-      new Node[] {new LiteralImpl("foo", fooBar), iop2},
-      new Node[] {new URIReferenceImpl(fooBar), iop2},
-      new Node[] {new BlankNodeImpl(), iop2},
-      new Node[] {null, iop2}
-    };
-    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    for (int r = 0; r < 10; r++) {
-      assertTrue(c.next());
-      assertTrue(getLiteralResult(rows[r][0], rows[r][1]).equals(fn));
-    }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Applied operation to a language string and an integer");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Applied operation to an unknown typed literal and an integer");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Applied operation to a uri and an integer");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Applied operation to a blank node and an integer");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Applied operation to an unbound and an integer");
-    } catch (QueryException qe) { }
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AbstractOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,225 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+import org.mulgara.query.filter.value.Var;
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the numeric operation classes.
+ * This uses a convoluted mechanism to let the compiler determine the correct return types
+ * in each of the implementing classes.
+ *
+ * @created Apr 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractOperationUnitTest extends TestCase {
+
+  URI xsdInt = URI.create(XSD_NS + "int");
+  URI xsdLong = URI.create(XSD_NS + "long");
+  URI xsdFloat = URI.create(XSD_NS + "float");
+  URI xsdDouble = URI.create(XSD_NS + "double");
+
+  /** The first operand to use for this test */
+  abstract Number op1();
+
+  /** The second operand to use for this test */
+  abstract Number op2();
+
+  /** Get an instance of the operation for this test */
+  abstract BinaryOperation getOperation(NumericExpression e1, NumericExpression e2);
+
+  /** perform the operation using native data types which are passed in two literals */
+  abstract ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException;
+
+  NumericLiteral doOperation(NumericLiteral l1, NumericLiteral l2) throws QueryException {
+    return (NumericLiteral)doOperation(new LiteralImpl(l1.getLexical(), l1.getType().getValue()), new LiteralImpl(l2.getLexical(), l2.getType().getValue()));
+  }
+
+  enum NumberType { tInt, tLong, tFloat, tDouble };
+
+  /** Gets the type of a URI as one of the defined number types */
+  NumberType getType(Literal l) {
+    URI dt = l.getDatatypeURI();
+    if (dt.equals(xsdInt)) return NumberType.tInt;
+    if (dt.equals(xsdLong)) return NumberType.tLong;
+    if (dt.equals(xsdFloat)) return NumberType.tFloat;
+    if (dt.equals(xsdDouble)) return NumberType.tDouble;
+    throw new Error("Unknown number type: " + dt);
+  }
+
+  /** request that the implementing class do the operation and creates a literal */
+  ValueLiteral getLiteralResult(Node n1, Node n2) throws QueryException {
+    Literal l1 = (Literal)n1;
+    Literal l2 = (Literal)n2;
+    return doOperation(l1, l2);
+  }
+
+  // use compiler dispatch and autoboxing to convert a value to a typed literal
+  ValueLiteral newLiteral(int x) throws QueryException { return TypedLiteral.newLiteral(x); }
+  ValueLiteral newLiteral(long x) throws QueryException { return TypedLiteral.newLiteral(x); }
+  ValueLiteral newLiteral(float x) throws QueryException { return TypedLiteral.newLiteral(x); }
+  ValueLiteral newLiteral(double x) throws QueryException { return TypedLiteral.newLiteral(x); }
+  
+  // convert a literal to a basic type, explicitly
+  int getInt(Literal l) { return Integer.parseInt(l.getLexicalForm()); }
+  long getLong(Literal l) { return Long.parseLong(l.getLexicalForm()); }
+  float getFloat(Literal l) { return Float.parseFloat(l.getLexicalForm()); }
+  double getDouble(Literal l) { return Double.parseDouble(l.getLexicalForm()); }
+
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public AbstractOperationUnitTest(String name) {
+    super(name);
+  }
+
+  public static Test suite() {
+    return new TestSuite();
+  }
+
+  public void testLiteral() throws Exception {
+    NumericLiteral op1i = new NumericLiteral(op1().intValue());
+    NumericLiteral op2i = new NumericLiteral(op2().intValue());
+    NumericLiteral op1l = new NumericLiteral(op1().longValue());
+    NumericLiteral op2l = new NumericLiteral(op2().longValue());
+    NumericLiteral op1f = new NumericLiteral(op1().floatValue());
+    NumericLiteral op2f = new NumericLiteral(op2().floatValue());
+    NumericLiteral op1d = new NumericLiteral(op1().doubleValue());
+    NumericLiteral op2d = new NumericLiteral(op2().doubleValue());
+
+    basicTest(op1i, op2i, doOperation(op1i, op2i));
+    basicTest(op1i, op2l, doOperation(op1i, op2l));
+    basicTest(op1i, op2f, doOperation(op1i, op2f));
+    basicTest(op1i, op2d, doOperation(op1i, op2d));
+    basicTest(op1l, op2l, doOperation(op1l, op2l));
+    basicTest(op1l, op2f, doOperation(op1l, op2f));
+    basicTest(op1l, op2d, doOperation(op1l, op2d));
+    basicTest(op1f, op2f, doOperation(op1f, op2f));
+    basicTest(op1f, op2d, doOperation(op1f, op2d));
+    basicTest(op1d, op2d, doOperation(op1d, op2d));
+  }
+
+  private void basicTest(NumericLiteral literal1, NumericLiteral literal2, NumericLiteral literalResult) throws Exception {
+    BinaryOperation op = getOperation(literal1, literal2);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    Var y = new Var("y");
+    BinaryOperation fn = getOperation(x, y);
+    
+    URI fooBar = URI.create("foo:bar");
+    Literal iop1 = new LiteralImpl("" + op1().intValue(), xsdInt);
+    Literal iop2 = new LiteralImpl("" + op2().intValue(), xsdInt);
+    Literal lop1 = new LiteralImpl("" + op1().longValue(), xsdLong);
+    Literal lop2 = new LiteralImpl("" + op2().longValue(), xsdLong);
+    Literal fop1 = new LiteralImpl("" + op1().floatValue(), xsdFloat);
+    Literal fop2 = new LiteralImpl("" + op2().floatValue(), xsdFloat);
+    Literal dop1 = new LiteralImpl("" + op1().doubleValue(), xsdDouble);
+    Literal dop2 = new LiteralImpl("" + op2().doubleValue(), xsdDouble);
+    Node[][] rows = {
+      new Node[] {iop1, iop2},
+      new Node[] {iop1, lop2},
+      new Node[] {iop1, fop2},
+      new Node[] {iop1, dop2},
+      new Node[] {lop1, lop2},
+      new Node[] {lop1, fop2},
+      new Node[] {lop1, dop2},
+      new Node[] {fop1, fop2},
+      new Node[] {fop1, dop2},
+      new Node[] {dop1, dop2},
+      // The following are to fail
+      new Node[] {new LiteralImpl("foo", "en"), iop2},
+      new Node[] {new LiteralImpl("foo", fooBar), iop2},
+      new Node[] {new URIReferenceImpl(fooBar), iop2},
+      new Node[] {new BlankNodeImpl(), iop2},
+      new Node[] {null, iop2}
+    };
+    TestContext c = new TestContext(new String[] {"x", "y"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    for (int r = 0; r < 10; r++) {
+      assertTrue(c.next());
+      assertTrue(getLiteralResult(rows[r][0], rows[r][1]).equals(fn));
+    }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Applied operation to a language string and an integer");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Applied operation to an unknown typed literal and an integer");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Applied operation to a uri and an integer");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Applied operation to a blank node and an integer");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Applied operation to an unbound and an integer");
+    } catch (QueryException qe) { }
+
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,73 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.List;
-
-import org.mulgara.query.filter.value.NumericExpression;
-
-
-/**
- * Represents an add operation.
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class AddOperation extends BinaryOperation {
-
-  /** */
-  private static final long serialVersionUID = -3447020240032464622L;
-
-  public AddOperation(NumericExpression lhs, NumericExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /**
-   * Use an operation set to perform an addition
-   * @param ops The operations to use for the current parameters
-   * @param left The first addend
-   * @param right The second addend
-   * @return The sum of left and right
-   */
-  @SuppressWarnings("unchecked")
-  Number doOperation(NumberOps ops, Number left, Number right) {
-    return ops.sum(left, right);
-  }
-
-  /**
-   * A constructor to handle adding lists of addends.
-   * @param operands The list of addends to sum.
-   * @return A new AddOperation which is adding all the addends.
-   */
-  public static AddOperation newAddOperation(List<NumericExpression> operands) {
-    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for addition. Got " + operands.size());
-    return (AddOperation)createNestedAdd(operands);
-  }
-
-  /**
-   * A recursive method to build a NumericExpression that represents the addition of all addends in the list.
-   * @param operands The list of addends to sum.
-   * @return A NumericExpression which represents the addition of everything in the ops list.
-   */
-  private static NumericExpression createNestedAdd(List<NumericExpression> ops) {
-    int listSize = ops.size();
-    // terminate on singleton lists
-    if (listSize == 1) return ops.get(0);
-    // short circuit for 2 element lists - optimization
-    if (listSize == 2) return new AddOperation(ops.get(0), ops.get(1));
-    // general case
-    return new AddOperation(createNestedAdd(ops.subList(0, listSize / 2)), createNestedAdd(ops.subList(listSize / 2, listSize)));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,73 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.List;
+
+import org.mulgara.query.filter.value.NumericExpression;
+
+
+/**
+ * Represents an add operation.
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class AddOperation extends BinaryOperation {
+
+  /** */
+  private static final long serialVersionUID = -3447020240032464622L;
+
+  public AddOperation(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * Use an operation set to perform an addition
+   * @param ops The operations to use for the current parameters
+   * @param left The first addend
+   * @param right The second addend
+   * @return The sum of left and right
+   */
+  @SuppressWarnings("unchecked")
+  Number doOperation(NumberOps ops, Number left, Number right) {
+    return ops.sum(left, right);
+  }
+
+  /**
+   * A constructor to handle adding lists of addends.
+   * @param operands The list of addends to sum.
+   * @return A new AddOperation which is adding all the addends.
+   */
+  public static AddOperation newAddOperation(List<NumericExpression> operands) {
+    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for addition. Got " + operands.size());
+    return (AddOperation)createNestedAdd(operands);
+  }
+
+  /**
+   * A recursive method to build a NumericExpression that represents the addition of all addends in the list.
+   * @param operands The list of addends to sum.
+   * @return A NumericExpression which represents the addition of everything in the ops list.
+   */
+  private static NumericExpression createNestedAdd(List<NumericExpression> ops) {
+    int listSize = ops.size();
+    // terminate on singleton lists
+    if (listSize == 1) return ops.get(0);
+    // short circuit for 2 element lists - optimization
+    if (listSize == 2) return new AddOperation(ops.get(0), ops.get(1));
+    // general case
+    return new AddOperation(createNestedAdd(ops.subList(0, listSize / 2)), createNestedAdd(ops.subList(listSize / 2, listSize)));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,140 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jrdf.graph.Literal;
-import org.mulgara.query.QueryException;
-
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the numeric operation classes.
- *
- * @created Apr 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class AddOperationUnitTest extends AbstractOperationUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public AddOperationUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new AddOperationUnitTest("testLiteral"));
-    suite.addTest(new AddOperationUnitTest("testVar"));
-    suite.addTest(new AddOperationUnitTest("testMultiOp"));
-    return suite;
-  }
-
-  Number op1() { return 4; }
-
-  Number op2() { return 5; }
-
-  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
-    return new AddOperation(literal1, literal2);
-  }
-
-  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
-    NumberType t1 = getType(l1);
-    NumberType t2 = getType(l2);
-    switch (t1) {
-    case tInt:
-      int int1 = getInt(l1);
-      switch (t2) {
-      case tInt: return newLiteral(int1 + getInt(l2));
-      case tLong: return newLiteral(int1 + getLong(l2));
-      case tFloat: return newLiteral(int1 + getFloat(l2));
-      case tDouble: return newLiteral(int1 + getDouble(l2));
-      }
-    case tLong:
-      long long1 = getLong(l1);
-      switch (t2) {
-      case tInt: return newLiteral(long1 + getInt(l2));
-      case tLong: return newLiteral(long1 + getLong(l2));
-      case tFloat: return newLiteral(long1 + getFloat(l2));
-      case tDouble: return newLiteral(long1 + getDouble(l2));
-      }
-    case tFloat:
-      float float1 = getFloat(l1);
-      switch (t2) {
-      case tInt: return newLiteral(float1 + getInt(l2));
-      case tLong: return newLiteral(float1 + getLong(l2));
-      case tFloat: return newLiteral(float1 + getFloat(l2));
-      case tDouble: return newLiteral(float1 + getDouble(l2));
-      }
-    case tDouble:
-      double double1 = getDouble(l1);
-      switch (t2) {
-      case tInt: return newLiteral(double1 + getInt(l2));
-      case tLong: return newLiteral(double1 + getLong(l2));
-      case tFloat: return newLiteral(double1 + getFloat(l2));
-      case tDouble: return newLiteral(double1 + getDouble(l2));
-      }
-    }
-    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
-  }
-
-  public void testMultiOp() throws Exception {
-    List<NumericExpression> ops = new ArrayList<NumericExpression>();
-    int sum = 0;
-    for (int i = 1; i <= 10; i++) {
-      sum += i;
-      ops.add(new NumericLiteral(i));
-    }
-    AddOperation op = AddOperation.newAddOperation(ops);
-    NumericLiteral literalResult = new NumericLiteral(sum);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-
-    ops.clear();
-    ops.add(new NumericLiteral(1));
-    ops.add(new NumericLiteral((float)2.0));
-    ops.add(new NumericLiteral(3L));
-    ops.add(new NumericLiteral(4.0));
-    op = AddOperation.newAddOperation(ops);
-    literalResult = new NumericLiteral(1 + ((float)2.0) + 3L + 4.0);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());    
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/AddOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,140 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jrdf.graph.Literal;
+import org.mulgara.query.QueryException;
+
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the numeric operation classes.
+ *
+ * @created Apr 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class AddOperationUnitTest extends AbstractOperationUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public AddOperationUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new AddOperationUnitTest("testLiteral"));
+    suite.addTest(new AddOperationUnitTest("testVar"));
+    suite.addTest(new AddOperationUnitTest("testMultiOp"));
+    return suite;
+  }
+
+  Number op1() { return 4; }
+
+  Number op2() { return 5; }
+
+  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
+    return new AddOperation(literal1, literal2);
+  }
+
+  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
+    NumberType t1 = getType(l1);
+    NumberType t2 = getType(l2);
+    switch (t1) {
+    case tInt:
+      int int1 = getInt(l1);
+      switch (t2) {
+      case tInt: return newLiteral(int1 + getInt(l2));
+      case tLong: return newLiteral(int1 + getLong(l2));
+      case tFloat: return newLiteral(int1 + getFloat(l2));
+      case tDouble: return newLiteral(int1 + getDouble(l2));
+      }
+    case tLong:
+      long long1 = getLong(l1);
+      switch (t2) {
+      case tInt: return newLiteral(long1 + getInt(l2));
+      case tLong: return newLiteral(long1 + getLong(l2));
+      case tFloat: return newLiteral(long1 + getFloat(l2));
+      case tDouble: return newLiteral(long1 + getDouble(l2));
+      }
+    case tFloat:
+      float float1 = getFloat(l1);
+      switch (t2) {
+      case tInt: return newLiteral(float1 + getInt(l2));
+      case tLong: return newLiteral(float1 + getLong(l2));
+      case tFloat: return newLiteral(float1 + getFloat(l2));
+      case tDouble: return newLiteral(float1 + getDouble(l2));
+      }
+    case tDouble:
+      double double1 = getDouble(l1);
+      switch (t2) {
+      case tInt: return newLiteral(double1 + getInt(l2));
+      case tLong: return newLiteral(double1 + getLong(l2));
+      case tFloat: return newLiteral(double1 + getFloat(l2));
+      case tDouble: return newLiteral(double1 + getDouble(l2));
+      }
+    }
+    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
+  }
+
+  public void testMultiOp() throws Exception {
+    List<NumericExpression> ops = new ArrayList<NumericExpression>();
+    int sum = 0;
+    for (int i = 1; i <= 10; i++) {
+      sum += i;
+      ops.add(new NumericLiteral(i));
+    }
+    AddOperation op = AddOperation.newAddOperation(ops);
+    NumericLiteral literalResult = new NumericLiteral(sum);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+
+    ops.clear();
+    ops.add(new NumericLiteral(1));
+    ops.add(new NumericLiteral((float)2.0));
+    ops.add(new NumericLiteral(3L));
+    ops.add(new NumericLiteral(4.0));
+    op = AddOperation.newAddOperation(ops);
+    literalResult = new NumericLiteral(1 + ((float)2.0) + 3L + 4.0);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());    
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,509 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.NumericExpression;
-
-
-/**
- * Represents a binary arithmetic operation.
- *
- * @created Mar 13, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class BinaryOperation extends AbstractNumericOperation implements NumericExpression {
-
-  /** The first operand */
-  protected NumericExpression lhs;
-
-  /** The second operand */
-  protected NumericExpression rhs;
-
-  /**
-   * Creates an operation between two terms
-   * @param lhs The left side of the operation
-   * @param rhs The right side of the operation
-   */
-  BinaryOperation(NumericExpression lhs, NumericExpression rhs) {
-    this.lhs = lhs;
-    this.rhs = rhs;
-    lhs.setContextOwner(this);
-    rhs.setContextOwner(this);
-  }
-
-  // Not using generics in NumberOps as we can't know the types at this stage, but they are handy
-  // for defining the classes correctly
-  /**
-   * Calculate the result of this operation, returning it as a normal number.
-   * @throws QueryException The values of one of the operands could not be resolved.
-   * @see org.mulgara.query.filter.value.NumericExpression#getNumber()
-   */
-  @SuppressWarnings("unchecked")
-  public Number getNumber() throws QueryException {
-    Number left = lhs.getNumber();
-    Number right = rhs.getNumber();
-    NumberOps op = opMap.get(new ClassPair(left, right));
-    if (op == null) throw new AssertionError("Missing entry in operation map");
-    return doOperation(op, left, right);
-  }
-
-  /**
-   * Perform the operation specific to the implementing class
-   * @param ops The operations to use for the current parameters
-   * @param left The first operand
-   * @param right The second operand
-   * @return The arithmetic result of applying the operation to the parameters
-   */
-  @SuppressWarnings("unchecked")
-  abstract Number doOperation(NumberOps ops, Number left, Number right);
-
-  /** Stores classes as an integrated pair for mapping pairs of Numbers to their appropriate functions */
-  static class ClassPair {
-    private Class<? extends Number> left;
-    private Class<? extends Number> right;
-
-    /**
-     * Create the pair using two classes
-     * @param left The left side of the pair
-     * @param right The right side of the pair
-     */
-    public ClassPair(Class<? extends Number> left, Class<? extends Number> right) {
-      this.left = left;
-      this.right = right;
-    }
- 
-    /**
-     * Create the pair using two <em>instance</em> of classes
-     * @param left The left side instance for the pair
-     * @param right The right side instance for the pair
-     */
-    public ClassPair(Number left, Number right) {
-      this.left = left.getClass();
-      this.right = right.getClass();
-    }
- 
-    /** @return The left side of the pair */
-    public Class<? extends Number> getLeft() { return left; }
-    /** @return The right side of the pair */
-    public Class<? extends Number> getRight() { return right; }
- 
-    /** @return a hashcode determined by mising the hashcodes of the contributing classes */
-    public int hashCode() { return left.hashCode() ^ ~right.hashCode(); }
-    /** @return <code>true</code> iff o is a class pair containing equal elements */
-    public boolean equals(Object o) {
-      if (o == null || (!(o instanceof ClassPair))) return false;
-      return left.equals(((ClassPair)o).left) && right.equals(((ClassPair)o).right);
-    }
-  }
-
-  /** Defines a binary function that takes two numbers and returns a new one */
-  interface NumberOps<LT extends Number,RT extends Number> {
-    /**
-     * Get a ClassPair that represents this operation
-     * @return a new ClassPair for this operation type
-     */
-    public ClassPair getClassPair();
-    /**
-     * Perform a multiplication on arguments of the specified types.
-     * @param left The first multiplicands
-     * @param right The second multiplicands
-     * @return The product as a number of the type defined in this class.
-     */
-    public Number product(LT left, RT right);
-    /**
-     * Perform a sum on arguments of the specified types.
-     * @param left The first addend
-     * @param right The second addend
-     * @return The sum as a number of the type defined in this class.
-     */
-    public Number sum(LT left, RT right);
-    /**
-     * Perform a subtraction on arguments of the specified types.
-     * @param left The minuend
-     * @param right The subtrahend
-     * @return The difference as a number of the type defined in this class.
-     */
-    public Number subtract(LT left, RT right);
-    /**
-     * Perform a multiplication on arguments of the specified types.
-     * @param left The dividend
-     * @param right The divisor
-     * @return The quotient as a number of the type defined in this class.
-     */
-    public Number divide(LT left, RT right);
-  }
-
-  /** A map of types to the functions that multiply them with correct type promotions */
-  protected static Map<ClassPair,NumberOps<? extends Number,? extends Number>> opMap = new HashMap<ClassPair,NumberOps<? extends Number,? extends Number>>();
-
-  /** A utility to add a number function to the promotion map */
-  private static void addType(NumberOps<?,?> nf) { opMap.put(nf.getClassPair(), nf); }
-
-  // The following population of the operation map was generated with this ruby script:
-  /*
-   * types = [ "Double", "Float", "Long", "Integer", "Short", "Byte" ]
-   * puts "  static {"
-   * types.each do |l|
-   *   types.each do |r|
-   *     puts "    addType(new #{l[0].chr}#{r[0].chr}());"
-   *   end
-   * end
-   * puts "  }"
-   * puts
-   * types.each do |l|
-   *   types.each do |r|
-   *     puts "  private static class #{l[0].chr}#{r[0].chr} implements NumberOps<#{l},#{r}> {"
-   *     puts "    public ClassPair getClassPair() { return new ClassPair(#{l}.class, #{r}.class); }"
-   *     puts "    public Number product(#{l} left, #{r} right) { return left * right; }"
-   *     puts "    public Number sum(#{l} left, #{r} right) { return left + right; }"
-   *     puts "    public Number subtract(#{l} left, #{r} right) { return left - right; }"
-   *     puts "    public Number divide(#{l} left, #{r} right) { return left / right; }"
-   *     puts "  }"
-   *     puts
-   *   end
-   * end
-   */  
-
-  static {
-    addType(new DD());
-    addType(new DF());
-    addType(new DL());
-    addType(new DI());
-    addType(new DS());
-    addType(new DB());
-    addType(new FD());
-    addType(new FF());
-    addType(new FL());
-    addType(new FI());
-    addType(new FS());
-    addType(new FB());
-    addType(new LD());
-    addType(new LF());
-    addType(new LL());
-    addType(new LI());
-    addType(new LS());
-    addType(new LB());
-    addType(new ID());
-    addType(new IF());
-    addType(new IL());
-    addType(new II());
-    addType(new IS());
-    addType(new IB());
-    addType(new SD());
-    addType(new SF());
-    addType(new SL());
-    addType(new SI());
-    addType(new SS());
-    addType(new SB());
-    addType(new BD());
-    addType(new BF());
-    addType(new BL());
-    addType(new BI());
-    addType(new BS());
-    addType(new BB());
-  }
-
-  private static class DD implements NumberOps<Double,Double> {
-    public ClassPair getClassPair() { return new ClassPair(Double.class, Double.class); }
-    public Number product(Double left, Double right) { return left * right; }
-    public Number sum(Double left, Double right) { return left + right; }
-    public Number subtract(Double left, Double right) { return left - right; }
-    public Number divide(Double left, Double right) { return left / right; }
-  }
-
-  private static class DF implements NumberOps<Double,Float> {
-    public ClassPair getClassPair() { return new ClassPair(Double.class, Float.class); }
-    public Number product(Double left, Float right) { return left * right; }
-    public Number sum(Double left, Float right) { return left + right; }
-    public Number subtract(Double left, Float right) { return left - right; }
-    public Number divide(Double left, Float right) { return left / right; }
-  }
-
-  private static class DL implements NumberOps<Double,Long> {
-    public ClassPair getClassPair() { return new ClassPair(Double.class, Long.class); }
-    public Number product(Double left, Long right) { return left * right; }
-    public Number sum(Double left, Long right) { return left + right; }
-    public Number subtract(Double left, Long right) { return left - right; }
-    public Number divide(Double left, Long right) { return left / right; }
-  }
-
-  private static class DI implements NumberOps<Double,Integer> {
-    public ClassPair getClassPair() { return new ClassPair(Double.class, Integer.class); }
-    public Number product(Double left, Integer right) { return left * right; }
-    public Number sum(Double left, Integer right) { return left + right; }
-    public Number subtract(Double left, Integer right) { return left - right; }
-    public Number divide(Double left, Integer right) { return left / right; }
-  }
-
-  private static class DS implements NumberOps<Double,Short> {
-    public ClassPair getClassPair() { return new ClassPair(Double.class, Short.class); }
-    public Number product(Double left, Short right) { return left * right; }
-    public Number sum(Double left, Short right) { return left + right; }
-    public Number subtract(Double left, Short right) { return left - right; }
-    public Number divide(Double left, Short right) { return left / right; }
-  }
-
-  private static class DB implements NumberOps<Double,Byte> {
-    public ClassPair getClassPair() { return new ClassPair(Double.class, Byte.class); }
-    public Number product(Double left, Byte right) { return left * right; }
-    public Number sum(Double left, Byte right) { return left + right; }
-    public Number subtract(Double left, Byte right) { return left - right; }
-    public Number divide(Double left, Byte right) { return left / right; }
-  }
-
-  private static class FD implements NumberOps<Float,Double> {
-    public ClassPair getClassPair() { return new ClassPair(Float.class, Double.class); }
-    public Number product(Float left, Double right) { return left * right; }
-    public Number sum(Float left, Double right) { return left + right; }
-    public Number subtract(Float left, Double right) { return left - right; }
-    public Number divide(Float left, Double right) { return left / right; }
-  }
-
-  private static class FF implements NumberOps<Float,Float> {
-    public ClassPair getClassPair() { return new ClassPair(Float.class, Float.class); }
-    public Number product(Float left, Float right) { return left * right; }
-    public Number sum(Float left, Float right) { return left + right; }
-    public Number subtract(Float left, Float right) { return left - right; }
-    public Number divide(Float left, Float right) { return left / right; }
-  }
-
-  private static class FL implements NumberOps<Float,Long> {
-    public ClassPair getClassPair() { return new ClassPair(Float.class, Long.class); }
-    public Number product(Float left, Long right) { return left * right; }
-    public Number sum(Float left, Long right) { return left + right; }
-    public Number subtract(Float left, Long right) { return left - right; }
-    public Number divide(Float left, Long right) { return left / right; }
-  }
-
-  private static class FI implements NumberOps<Float,Integer> {
-    public ClassPair getClassPair() { return new ClassPair(Float.class, Integer.class); }
-    public Number product(Float left, Integer right) { return left * right; }
-    public Number sum(Float left, Integer right) { return left + right; }
-    public Number subtract(Float left, Integer right) { return left - right; }
-    public Number divide(Float left, Integer right) { return left / right; }
-  }
-
-  private static class FS implements NumberOps<Float,Short> {
-    public ClassPair getClassPair() { return new ClassPair(Float.class, Short.class); }
-    public Number product(Float left, Short right) { return left * right; }
-    public Number sum(Float left, Short right) { return left + right; }
-    public Number subtract(Float left, Short right) { return left - right; }
-    public Number divide(Float left, Short right) { return left / right; }
-  }
-
-  private static class FB implements NumberOps<Float,Byte> {
-    public ClassPair getClassPair() { return new ClassPair(Float.class, Byte.class); }
-    public Number product(Float left, Byte right) { return left * right; }
-    public Number sum(Float left, Byte right) { return left + right; }
-    public Number subtract(Float left, Byte right) { return left - right; }
-    public Number divide(Float left, Byte right) { return left / right; }
-  }
-
-  private static class LD implements NumberOps<Long,Double> {
-    public ClassPair getClassPair() { return new ClassPair(Long.class, Double.class); }
-    public Number product(Long left, Double right) { return left * right; }
-    public Number sum(Long left, Double right) { return left + right; }
-    public Number subtract(Long left, Double right) { return left - right; }
-    public Number divide(Long left, Double right) { return left / right; }
-  }
-
-  private static class LF implements NumberOps<Long,Float> {
-    public ClassPair getClassPair() { return new ClassPair(Long.class, Float.class); }
-    public Number product(Long left, Float right) { return left * right; }
-    public Number sum(Long left, Float right) { return left + right; }
-    public Number subtract(Long left, Float right) { return left - right; }
-    public Number divide(Long left, Float right) { return left / right; }
-  }
-
-  private static class LL implements NumberOps<Long,Long> {
-    public ClassPair getClassPair() { return new ClassPair(Long.class, Long.class); }
-    public Number product(Long left, Long right) { return left * right; }
-    public Number sum(Long left, Long right) { return left + right; }
-    public Number subtract(Long left, Long right) { return left - right; }
-    public Number divide(Long left, Long right) { return left / right; }
-  }
-
-  private static class LI implements NumberOps<Long,Integer> {
-    public ClassPair getClassPair() { return new ClassPair(Long.class, Integer.class); }
-    public Number product(Long left, Integer right) { return left * right; }
-    public Number sum(Long left, Integer right) { return left + right; }
-    public Number subtract(Long left, Integer right) { return left - right; }
-    public Number divide(Long left, Integer right) { return left / right; }
-  }
-
-  private static class LS implements NumberOps<Long,Short> {
-    public ClassPair getClassPair() { return new ClassPair(Long.class, Short.class); }
-    public Number product(Long left, Short right) { return left * right; }
-    public Number sum(Long left, Short right) { return left + right; }
-    public Number subtract(Long left, Short right) { return left - right; }
-    public Number divide(Long left, Short right) { return left / right; }
-  }
-
-  private static class LB implements NumberOps<Long,Byte> {
-    public ClassPair getClassPair() { return new ClassPair(Long.class, Byte.class); }
-    public Number product(Long left, Byte right) { return left * right; }
-    public Number sum(Long left, Byte right) { return left + right; }
-    public Number subtract(Long left, Byte right) { return left - right; }
-    public Number divide(Long left, Byte right) { return left / right; }
-  }
-
-  private static class ID implements NumberOps<Integer,Double> {
-    public ClassPair getClassPair() { return new ClassPair(Integer.class, Double.class); }
-    public Number product(Integer left, Double right) { return left * right; }
-    public Number sum(Integer left, Double right) { return left + right; }
-    public Number subtract(Integer left, Double right) { return left - right; }
-    public Number divide(Integer left, Double right) { return left / right; }
-  }
-
-  private static class IF implements NumberOps<Integer,Float> {
-    public ClassPair getClassPair() { return new ClassPair(Integer.class, Float.class); }
-    public Number product(Integer left, Float right) { return left * right; }
-    public Number sum(Integer left, Float right) { return left + right; }
-    public Number subtract(Integer left, Float right) { return left - right; }
-    public Number divide(Integer left, Float right) { return left / right; }
-  }
-
-  private static class IL implements NumberOps<Integer,Long> {
-    public ClassPair getClassPair() { return new ClassPair(Integer.class, Long.class); }
-    public Number product(Integer left, Long right) { return left * right; }
-    public Number sum(Integer left, Long right) { return left + right; }
-    public Number subtract(Integer left, Long right) { return left - right; }
-    public Number divide(Integer left, Long right) { return left / right; }
-  }
-
-  private static class II implements NumberOps<Integer,Integer> {
-    public ClassPair getClassPair() { return new ClassPair(Integer.class, Integer.class); }
-    public Number product(Integer left, Integer right) { return left * right; }
-    public Number sum(Integer left, Integer right) { return left + right; }
-    public Number subtract(Integer left, Integer right) { return left - right; }
-    public Number divide(Integer left, Integer right) { return left / right; }
-  }
-
-  private static class IS implements NumberOps<Integer,Short> {
-    public ClassPair getClassPair() { return new ClassPair(Integer.class, Short.class); }
-    public Number product(Integer left, Short right) { return left * right; }
-    public Number sum(Integer left, Short right) { return left + right; }
-    public Number subtract(Integer left, Short right) { return left - right; }
-    public Number divide(Integer left, Short right) { return left / right; }
-  }
-
-  private static class IB implements NumberOps<Integer,Byte> {
-    public ClassPair getClassPair() { return new ClassPair(Integer.class, Byte.class); }
-    public Number product(Integer left, Byte right) { return left * right; }
-    public Number sum(Integer left, Byte right) { return left + right; }
-    public Number subtract(Integer left, Byte right) { return left - right; }
-    public Number divide(Integer left, Byte right) { return left / right; }
-  }
-
-  private static class SD implements NumberOps<Short,Double> {
-    public ClassPair getClassPair() { return new ClassPair(Short.class, Double.class); }
-    public Number product(Short left, Double right) { return left * right; }
-    public Number sum(Short left, Double right) { return left + right; }
-    public Number subtract(Short left, Double right) { return left - right; }
-    public Number divide(Short left, Double right) { return left / right; }
-  }
-
-  private static class SF implements NumberOps<Short,Float> {
-    public ClassPair getClassPair() { return new ClassPair(Short.class, Float.class); }
-    public Number product(Short left, Float right) { return left * right; }
-    public Number sum(Short left, Float right) { return left + right; }
-    public Number subtract(Short left, Float right) { return left - right; }
-    public Number divide(Short left, Float right) { return left / right; }
-  }
-
-  private static class SL implements NumberOps<Short,Long> {
-    public ClassPair getClassPair() { return new ClassPair(Short.class, Long.class); }
-    public Number product(Short left, Long right) { return left * right; }
-    public Number sum(Short left, Long right) { return left + right; }
-    public Number subtract(Short left, Long right) { return left - right; }
-    public Number divide(Short left, Long right) { return left / right; }
-  }
-
-  private static class SI implements NumberOps<Short,Integer> {
-    public ClassPair getClassPair() { return new ClassPair(Short.class, Integer.class); }
-    public Number product(Short left, Integer right) { return left * right; }
-    public Number sum(Short left, Integer right) { return left + right; }
-    public Number subtract(Short left, Integer right) { return left - right; }
-    public Number divide(Short left, Integer right) { return left / right; }
-  }
-
-  private static class SS implements NumberOps<Short,Short> {
-    public ClassPair getClassPair() { return new ClassPair(Short.class, Short.class); }
-    public Number product(Short left, Short right) { return left * right; }
-    public Number sum(Short left, Short right) { return left + right; }
-    public Number subtract(Short left, Short right) { return left - right; }
-    public Number divide(Short left, Short right) { return left / right; }
-  }
-
-  private static class SB implements NumberOps<Short,Byte> {
-    public ClassPair getClassPair() { return new ClassPair(Short.class, Byte.class); }
-    public Number product(Short left, Byte right) { return left * right; }
-    public Number sum(Short left, Byte right) { return left + right; }
-    public Number subtract(Short left, Byte right) { return left - right; }
-    public Number divide(Short left, Byte right) { return left / right; }
-  }
-
-  private static class BD implements NumberOps<Byte,Double> {
-    public ClassPair getClassPair() { return new ClassPair(Byte.class, Double.class); }
-    public Number product(Byte left, Double right) { return left * right; }
-    public Number sum(Byte left, Double right) { return left + right; }
-    public Number subtract(Byte left, Double right) { return left - right; }
-    public Number divide(Byte left, Double right) { return left / right; }
-  }
-
-  private static class BF implements NumberOps<Byte,Float> {
-    public ClassPair getClassPair() { return new ClassPair(Byte.class, Float.class); }
-    public Number product(Byte left, Float right) { return left * right; }
-    public Number sum(Byte left, Float right) { return left + right; }
-    public Number subtract(Byte left, Float right) { return left - right; }
-    public Number divide(Byte left, Float right) { return left / right; }
-  }
-
-  private static class BL implements NumberOps<Byte,Long> {
-    public ClassPair getClassPair() { return new ClassPair(Byte.class, Long.class); }
-    public Number product(Byte left, Long right) { return left * right; }
-    public Number sum(Byte left, Long right) { return left + right; }
-    public Number subtract(Byte left, Long right) { return left - right; }
-    public Number divide(Byte left, Long right) { return left / right; }
-  }
-
-  private static class BI implements NumberOps<Byte,Integer> {
-    public ClassPair getClassPair() { return new ClassPair(Byte.class, Integer.class); }
-    public Number product(Byte left, Integer right) { return left * right; }
-    public Number sum(Byte left, Integer right) { return left + right; }
-    public Number subtract(Byte left, Integer right) { return left - right; }
-    public Number divide(Byte left, Integer right) { return left / right; }
-  }
-
-  private static class BS implements NumberOps<Byte,Short> {
-    public ClassPair getClassPair() { return new ClassPair(Byte.class, Short.class); }
-    public Number product(Byte left, Short right) { return left * right; }
-    public Number sum(Byte left, Short right) { return left + right; }
-    public Number subtract(Byte left, Short right) { return left - right; }
-    public Number divide(Byte left, Short right) { return left / right; }
-  }
-
-  private static class BB implements NumberOps<Byte,Byte> {
-    public ClassPair getClassPair() { return new ClassPair(Byte.class, Byte.class); }
-    public Number product(Byte left, Byte right) { return left * right; }
-    public Number sum(Byte left, Byte right) { return left + right; }
-    public Number subtract(Byte left, Byte right) { return left - right; }
-    public Number divide(Byte left, Byte right) { return left / right; }
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/BinaryOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,509 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.NumericExpression;
+
+
+/**
+ * Represents a binary arithmetic operation.
+ *
+ * @created Mar 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class BinaryOperation extends AbstractNumericOperation implements NumericExpression {
+
+  /** The first operand */
+  protected NumericExpression lhs;
+
+  /** The second operand */
+  protected NumericExpression rhs;
+
+  /**
+   * Creates an operation between two terms
+   * @param lhs The left side of the operation
+   * @param rhs The right side of the operation
+   */
+  BinaryOperation(NumericExpression lhs, NumericExpression rhs) {
+    this.lhs = lhs;
+    this.rhs = rhs;
+    lhs.setContextOwner(this);
+    rhs.setContextOwner(this);
+  }
+
+  // Not using generics in NumberOps as we can't know the types at this stage, but they are handy
+  // for defining the classes correctly
+  /**
+   * Calculate the result of this operation, returning it as a normal number.
+   * @throws QueryException The values of one of the operands could not be resolved.
+   * @see org.mulgara.query.filter.value.NumericExpression#getNumber()
+   */
+  @SuppressWarnings("unchecked")
+  public Number getNumber() throws QueryException {
+    Number left = lhs.getNumber();
+    Number right = rhs.getNumber();
+    NumberOps op = opMap.get(new ClassPair(left, right));
+    if (op == null) throw new AssertionError("Missing entry in operation map");
+    return doOperation(op, left, right);
+  }
+
+  /**
+   * Perform the operation specific to the implementing class
+   * @param ops The operations to use for the current parameters
+   * @param left The first operand
+   * @param right The second operand
+   * @return The arithmetic result of applying the operation to the parameters
+   */
+  @SuppressWarnings("unchecked")
+  abstract Number doOperation(NumberOps ops, Number left, Number right);
+
+  /** Stores classes as an integrated pair for mapping pairs of Numbers to their appropriate functions */
+  static class ClassPair {
+    private Class<? extends Number> left;
+    private Class<? extends Number> right;
+
+    /**
+     * Create the pair using two classes
+     * @param left The left side of the pair
+     * @param right The right side of the pair
+     */
+    public ClassPair(Class<? extends Number> left, Class<? extends Number> right) {
+      this.left = left;
+      this.right = right;
+    }
+ 
+    /**
+     * Create the pair using two <em>instance</em> of classes
+     * @param left The left side instance for the pair
+     * @param right The right side instance for the pair
+     */
+    public ClassPair(Number left, Number right) {
+      this.left = left.getClass();
+      this.right = right.getClass();
+    }
+ 
+    /** @return The left side of the pair */
+    public Class<? extends Number> getLeft() { return left; }
+    /** @return The right side of the pair */
+    public Class<? extends Number> getRight() { return right; }
+ 
+    /** @return a hashcode determined by mising the hashcodes of the contributing classes */
+    public int hashCode() { return left.hashCode() ^ ~right.hashCode(); }
+    /** @return <code>true</code> iff o is a class pair containing equal elements */
+    public boolean equals(Object o) {
+      if (o == null || (!(o instanceof ClassPair))) return false;
+      return left.equals(((ClassPair)o).left) && right.equals(((ClassPair)o).right);
+    }
+  }
+
+  /** Defines a binary function that takes two numbers and returns a new one */
+  interface NumberOps<LT extends Number,RT extends Number> {
+    /**
+     * Get a ClassPair that represents this operation
+     * @return a new ClassPair for this operation type
+     */
+    public ClassPair getClassPair();
+    /**
+     * Perform a multiplication on arguments of the specified types.
+     * @param left The first multiplicands
+     * @param right The second multiplicands
+     * @return The product as a number of the type defined in this class.
+     */
+    public Number product(LT left, RT right);
+    /**
+     * Perform a sum on arguments of the specified types.
+     * @param left The first addend
+     * @param right The second addend
+     * @return The sum as a number of the type defined in this class.
+     */
+    public Number sum(LT left, RT right);
+    /**
+     * Perform a subtraction on arguments of the specified types.
+     * @param left The minuend
+     * @param right The subtrahend
+     * @return The difference as a number of the type defined in this class.
+     */
+    public Number subtract(LT left, RT right);
+    /**
+     * Perform a multiplication on arguments of the specified types.
+     * @param left The dividend
+     * @param right The divisor
+     * @return The quotient as a number of the type defined in this class.
+     */
+    public Number divide(LT left, RT right);
+  }
+
+  /** A map of types to the functions that multiply them with correct type promotions */
+  protected static Map<ClassPair,NumberOps<? extends Number,? extends Number>> opMap = new HashMap<ClassPair,NumberOps<? extends Number,? extends Number>>();
+
+  /** A utility to add a number function to the promotion map */
+  private static void addType(NumberOps<?,?> nf) { opMap.put(nf.getClassPair(), nf); }
+
+  // The following population of the operation map was generated with this ruby script:
+  /*
+   * types = [ "Double", "Float", "Long", "Integer", "Short", "Byte" ]
+   * puts "  static {"
+   * types.each do |l|
+   *   types.each do |r|
+   *     puts "    addType(new #{l[0].chr}#{r[0].chr}());"
+   *   end
+   * end
+   * puts "  }"
+   * puts
+   * types.each do |l|
+   *   types.each do |r|
+   *     puts "  private static class #{l[0].chr}#{r[0].chr} implements NumberOps<#{l},#{r}> {"
+   *     puts "    public ClassPair getClassPair() { return new ClassPair(#{l}.class, #{r}.class); }"
+   *     puts "    public Number product(#{l} left, #{r} right) { return left * right; }"
+   *     puts "    public Number sum(#{l} left, #{r} right) { return left + right; }"
+   *     puts "    public Number subtract(#{l} left, #{r} right) { return left - right; }"
+   *     puts "    public Number divide(#{l} left, #{r} right) { return left / right; }"
+   *     puts "  }"
+   *     puts
+   *   end
+   * end
+   */  
+
+  static {
+    addType(new DD());
+    addType(new DF());
+    addType(new DL());
+    addType(new DI());
+    addType(new DS());
+    addType(new DB());
+    addType(new FD());
+    addType(new FF());
+    addType(new FL());
+    addType(new FI());
+    addType(new FS());
+    addType(new FB());
+    addType(new LD());
+    addType(new LF());
+    addType(new LL());
+    addType(new LI());
+    addType(new LS());
+    addType(new LB());
+    addType(new ID());
+    addType(new IF());
+    addType(new IL());
+    addType(new II());
+    addType(new IS());
+    addType(new IB());
+    addType(new SD());
+    addType(new SF());
+    addType(new SL());
+    addType(new SI());
+    addType(new SS());
+    addType(new SB());
+    addType(new BD());
+    addType(new BF());
+    addType(new BL());
+    addType(new BI());
+    addType(new BS());
+    addType(new BB());
+  }
+
+  private static class DD implements NumberOps<Double,Double> {
+    public ClassPair getClassPair() { return new ClassPair(Double.class, Double.class); }
+    public Number product(Double left, Double right) { return left * right; }
+    public Number sum(Double left, Double right) { return left + right; }
+    public Number subtract(Double left, Double right) { return left - right; }
+    public Number divide(Double left, Double right) { return left / right; }
+  }
+
+  private static class DF implements NumberOps<Double,Float> {
+    public ClassPair getClassPair() { return new ClassPair(Double.class, Float.class); }
+    public Number product(Double left, Float right) { return left * right; }
+    public Number sum(Double left, Float right) { return left + right; }
+    public Number subtract(Double left, Float right) { return left - right; }
+    public Number divide(Double left, Float right) { return left / right; }
+  }
+
+  private static class DL implements NumberOps<Double,Long> {
+    public ClassPair getClassPair() { return new ClassPair(Double.class, Long.class); }
+    public Number product(Double left, Long right) { return left * right; }
+    public Number sum(Double left, Long right) { return left + right; }
+    public Number subtract(Double left, Long right) { return left - right; }
+    public Number divide(Double left, Long right) { return left / right; }
+  }
+
+  private static class DI implements NumberOps<Double,Integer> {
+    public ClassPair getClassPair() { return new ClassPair(Double.class, Integer.class); }
+    public Number product(Double left, Integer right) { return left * right; }
+    public Number sum(Double left, Integer right) { return left + right; }
+    public Number subtract(Double left, Integer right) { return left - right; }
+    public Number divide(Double left, Integer right) { return left / right; }
+  }
+
+  private static class DS implements NumberOps<Double,Short> {
+    public ClassPair getClassPair() { return new ClassPair(Double.class, Short.class); }
+    public Number product(Double left, Short right) { return left * right; }
+    public Number sum(Double left, Short right) { return left + right; }
+    public Number subtract(Double left, Short right) { return left - right; }
+    public Number divide(Double left, Short right) { return left / right; }
+  }
+
+  private static class DB implements NumberOps<Double,Byte> {
+    public ClassPair getClassPair() { return new ClassPair(Double.class, Byte.class); }
+    public Number product(Double left, Byte right) { return left * right; }
+    public Number sum(Double left, Byte right) { return left + right; }
+    public Number subtract(Double left, Byte right) { return left - right; }
+    public Number divide(Double left, Byte right) { return left / right; }
+  }
+
+  private static class FD implements NumberOps<Float,Double> {
+    public ClassPair getClassPair() { return new ClassPair(Float.class, Double.class); }
+    public Number product(Float left, Double right) { return left * right; }
+    public Number sum(Float left, Double right) { return left + right; }
+    public Number subtract(Float left, Double right) { return left - right; }
+    public Number divide(Float left, Double right) { return left / right; }
+  }
+
+  private static class FF implements NumberOps<Float,Float> {
+    public ClassPair getClassPair() { return new ClassPair(Float.class, Float.class); }
+    public Number product(Float left, Float right) { return left * right; }
+    public Number sum(Float left, Float right) { return left + right; }
+    public Number subtract(Float left, Float right) { return left - right; }
+    public Number divide(Float left, Float right) { return left / right; }
+  }
+
+  private static class FL implements NumberOps<Float,Long> {
+    public ClassPair getClassPair() { return new ClassPair(Float.class, Long.class); }
+    public Number product(Float left, Long right) { return left * right; }
+    public Number sum(Float left, Long right) { return left + right; }
+    public Number subtract(Float left, Long right) { return left - right; }
+    public Number divide(Float left, Long right) { return left / right; }
+  }
+
+  private static class FI implements NumberOps<Float,Integer> {
+    public ClassPair getClassPair() { return new ClassPair(Float.class, Integer.class); }
+    public Number product(Float left, Integer right) { return left * right; }
+    public Number sum(Float left, Integer right) { return left + right; }
+    public Number subtract(Float left, Integer right) { return left - right; }
+    public Number divide(Float left, Integer right) { return left / right; }
+  }
+
+  private static class FS implements NumberOps<Float,Short> {
+    public ClassPair getClassPair() { return new ClassPair(Float.class, Short.class); }
+    public Number product(Float left, Short right) { return left * right; }
+    public Number sum(Float left, Short right) { return left + right; }
+    public Number subtract(Float left, Short right) { return left - right; }
+    public Number divide(Float left, Short right) { return left / right; }
+  }
+
+  private static class FB implements NumberOps<Float,Byte> {
+    public ClassPair getClassPair() { return new ClassPair(Float.class, Byte.class); }
+    public Number product(Float left, Byte right) { return left * right; }
+    public Number sum(Float left, Byte right) { return left + right; }
+    public Number subtract(Float left, Byte right) { return left - right; }
+    public Number divide(Float left, Byte right) { return left / right; }
+  }
+
+  private static class LD implements NumberOps<Long,Double> {
+    public ClassPair getClassPair() { return new ClassPair(Long.class, Double.class); }
+    public Number product(Long left, Double right) { return left * right; }
+    public Number sum(Long left, Double right) { return left + right; }
+    public Number subtract(Long left, Double right) { return left - right; }
+    public Number divide(Long left, Double right) { return left / right; }
+  }
+
+  private static class LF implements NumberOps<Long,Float> {
+    public ClassPair getClassPair() { return new ClassPair(Long.class, Float.class); }
+    public Number product(Long left, Float right) { return left * right; }
+    public Number sum(Long left, Float right) { return left + right; }
+    public Number subtract(Long left, Float right) { return left - right; }
+    public Number divide(Long left, Float right) { return left / right; }
+  }
+
+  private static class LL implements NumberOps<Long,Long> {
+    public ClassPair getClassPair() { return new ClassPair(Long.class, Long.class); }
+    public Number product(Long left, Long right) { return left * right; }
+    public Number sum(Long left, Long right) { return left + right; }
+    public Number subtract(Long left, Long right) { return left - right; }
+    public Number divide(Long left, Long right) { return left / right; }
+  }
+
+  private static class LI implements NumberOps<Long,Integer> {
+    public ClassPair getClassPair() { return new ClassPair(Long.class, Integer.class); }
+    public Number product(Long left, Integer right) { return left * right; }
+    public Number sum(Long left, Integer right) { return left + right; }
+    public Number subtract(Long left, Integer right) { return left - right; }
+    public Number divide(Long left, Integer right) { return left / right; }
+  }
+
+  private static class LS implements NumberOps<Long,Short> {
+    public ClassPair getClassPair() { return new ClassPair(Long.class, Short.class); }
+    public Number product(Long left, Short right) { return left * right; }
+    public Number sum(Long left, Short right) { return left + right; }
+    public Number subtract(Long left, Short right) { return left - right; }
+    public Number divide(Long left, Short right) { return left / right; }
+  }
+
+  private static class LB implements NumberOps<Long,Byte> {
+    public ClassPair getClassPair() { return new ClassPair(Long.class, Byte.class); }
+    public Number product(Long left, Byte right) { return left * right; }
+    public Number sum(Long left, Byte right) { return left + right; }
+    public Number subtract(Long left, Byte right) { return left - right; }
+    public Number divide(Long left, Byte right) { return left / right; }
+  }
+
+  private static class ID implements NumberOps<Integer,Double> {
+    public ClassPair getClassPair() { return new ClassPair(Integer.class, Double.class); }
+    public Number product(Integer left, Double right) { return left * right; }
+    public Number sum(Integer left, Double right) { return left + right; }
+    public Number subtract(Integer left, Double right) { return left - right; }
+    public Number divide(Integer left, Double right) { return left / right; }
+  }
+
+  private static class IF implements NumberOps<Integer,Float> {
+    public ClassPair getClassPair() { return new ClassPair(Integer.class, Float.class); }
+    public Number product(Integer left, Float right) { return left * right; }
+    public Number sum(Integer left, Float right) { return left + right; }
+    public Number subtract(Integer left, Float right) { return left - right; }
+    public Number divide(Integer left, Float right) { return left / right; }
+  }
+
+  private static class IL implements NumberOps<Integer,Long> {
+    public ClassPair getClassPair() { return new ClassPair(Integer.class, Long.class); }
+    public Number product(Integer left, Long right) { return left * right; }
+    public Number sum(Integer left, Long right) { return left + right; }
+    public Number subtract(Integer left, Long right) { return left - right; }
+    public Number divide(Integer left, Long right) { return left / right; }
+  }
+
+  private static class II implements NumberOps<Integer,Integer> {
+    public ClassPair getClassPair() { return new ClassPair(Integer.class, Integer.class); }
+    public Number product(Integer left, Integer right) { return left * right; }
+    public Number sum(Integer left, Integer right) { return left + right; }
+    public Number subtract(Integer left, Integer right) { return left - right; }
+    public Number divide(Integer left, Integer right) { return left / right; }
+  }
+
+  private static class IS implements NumberOps<Integer,Short> {
+    public ClassPair getClassPair() { return new ClassPair(Integer.class, Short.class); }
+    public Number product(Integer left, Short right) { return left * right; }
+    public Number sum(Integer left, Short right) { return left + right; }
+    public Number subtract(Integer left, Short right) { return left - right; }
+    public Number divide(Integer left, Short right) { return left / right; }
+  }
+
+  private static class IB implements NumberOps<Integer,Byte> {
+    public ClassPair getClassPair() { return new ClassPair(Integer.class, Byte.class); }
+    public Number product(Integer left, Byte right) { return left * right; }
+    public Number sum(Integer left, Byte right) { return left + right; }
+    public Number subtract(Integer left, Byte right) { return left - right; }
+    public Number divide(Integer left, Byte right) { return left / right; }
+  }
+
+  private static class SD implements NumberOps<Short,Double> {
+    public ClassPair getClassPair() { return new ClassPair(Short.class, Double.class); }
+    public Number product(Short left, Double right) { return left * right; }
+    public Number sum(Short left, Double right) { return left + right; }
+    public Number subtract(Short left, Double right) { return left - right; }
+    public Number divide(Short left, Double right) { return left / right; }
+  }
+
+  private static class SF implements NumberOps<Short,Float> {
+    public ClassPair getClassPair() { return new ClassPair(Short.class, Float.class); }
+    public Number product(Short left, Float right) { return left * right; }
+    public Number sum(Short left, Float right) { return left + right; }
+    public Number subtract(Short left, Float right) { return left - right; }
+    public Number divide(Short left, Float right) { return left / right; }
+  }
+
+  private static class SL implements NumberOps<Short,Long> {
+    public ClassPair getClassPair() { return new ClassPair(Short.class, Long.class); }
+    public Number product(Short left, Long right) { return left * right; }
+    public Number sum(Short left, Long right) { return left + right; }
+    public Number subtract(Short left, Long right) { return left - right; }
+    public Number divide(Short left, Long right) { return left / right; }
+  }
+
+  private static class SI implements NumberOps<Short,Integer> {
+    public ClassPair getClassPair() { return new ClassPair(Short.class, Integer.class); }
+    public Number product(Short left, Integer right) { return left * right; }
+    public Number sum(Short left, Integer right) { return left + right; }
+    public Number subtract(Short left, Integer right) { return left - right; }
+    public Number divide(Short left, Integer right) { return left / right; }
+  }
+
+  private static class SS implements NumberOps<Short,Short> {
+    public ClassPair getClassPair() { return new ClassPair(Short.class, Short.class); }
+    public Number product(Short left, Short right) { return left * right; }
+    public Number sum(Short left, Short right) { return left + right; }
+    public Number subtract(Short left, Short right) { return left - right; }
+    public Number divide(Short left, Short right) { return left / right; }
+  }
+
+  private static class SB implements NumberOps<Short,Byte> {
+    public ClassPair getClassPair() { return new ClassPair(Short.class, Byte.class); }
+    public Number product(Short left, Byte right) { return left * right; }
+    public Number sum(Short left, Byte right) { return left + right; }
+    public Number subtract(Short left, Byte right) { return left - right; }
+    public Number divide(Short left, Byte right) { return left / right; }
+  }
+
+  private static class BD implements NumberOps<Byte,Double> {
+    public ClassPair getClassPair() { return new ClassPair(Byte.class, Double.class); }
+    public Number product(Byte left, Double right) { return left * right; }
+    public Number sum(Byte left, Double right) { return left + right; }
+    public Number subtract(Byte left, Double right) { return left - right; }
+    public Number divide(Byte left, Double right) { return left / right; }
+  }
+
+  private static class BF implements NumberOps<Byte,Float> {
+    public ClassPair getClassPair() { return new ClassPair(Byte.class, Float.class); }
+    public Number product(Byte left, Float right) { return left * right; }
+    public Number sum(Byte left, Float right) { return left + right; }
+    public Number subtract(Byte left, Float right) { return left - right; }
+    public Number divide(Byte left, Float right) { return left / right; }
+  }
+
+  private static class BL implements NumberOps<Byte,Long> {
+    public ClassPair getClassPair() { return new ClassPair(Byte.class, Long.class); }
+    public Number product(Byte left, Long right) { return left * right; }
+    public Number sum(Byte left, Long right) { return left + right; }
+    public Number subtract(Byte left, Long right) { return left - right; }
+    public Number divide(Byte left, Long right) { return left / right; }
+  }
+
+  private static class BI implements NumberOps<Byte,Integer> {
+    public ClassPair getClassPair() { return new ClassPair(Byte.class, Integer.class); }
+    public Number product(Byte left, Integer right) { return left * right; }
+    public Number sum(Byte left, Integer right) { return left + right; }
+    public Number subtract(Byte left, Integer right) { return left - right; }
+    public Number divide(Byte left, Integer right) { return left / right; }
+  }
+
+  private static class BS implements NumberOps<Byte,Short> {
+    public ClassPair getClassPair() { return new ClassPair(Byte.class, Short.class); }
+    public Number product(Byte left, Short right) { return left * right; }
+    public Number sum(Byte left, Short right) { return left + right; }
+    public Number subtract(Byte left, Short right) { return left - right; }
+    public Number divide(Byte left, Short right) { return left / right; }
+  }
+
+  private static class BB implements NumberOps<Byte,Byte> {
+    public ClassPair getClassPair() { return new ClassPair(Byte.class, Byte.class); }
+    public Number product(Byte left, Byte right) { return left * right; }
+    public Number sum(Byte left, Byte right) { return left + right; }
+    public Number subtract(Byte left, Byte right) { return left - right; }
+    public Number divide(Byte left, Byte right) { return left / right; }
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,74 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.List;
-
-import org.mulgara.query.filter.value.NumericExpression;
-
-
-/**
- * Represents a division operation.
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class DivideOperation extends BinaryOperation {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 5863800753778864432L;
-
-  public DivideOperation(NumericExpression lhs, NumericExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /**
-   * Use an operation set to perform a division
-   * @param ops The operations to use for the current parameters
-   * @param left The dividend
-   * @param right The divisor
-   * @return The quotient of dividing right into left
-   */
-  @SuppressWarnings("unchecked")
-  Number doOperation(NumberOps ops, Number left, Number right) {
-    return ops.divide(left, right);
-  }
-
-  /**
-   * A constructor to handle dividnd lists of values.
-   * @param operands The list of numbers to divide.
-   * @return A new DivideOperation which is dividing numbers in order.
-   */
-  public static DivideOperation newDivideOperation(List<NumericExpression> operands) {
-    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for subtraction. Got " + operands.size());
-    return (DivideOperation)createNestedDivision(operands);
-  }
-
-  /**
-   * A recursive method to build a NumericExpression that represents the division of all values in the list.
-   * This constructs a linked list of divisions.
-   * @param operands The list of values to divide.
-   * @return A NumericExpression which represents the ordered division of everything in the ops list.
-   */
-  private static NumericExpression createNestedDivision(List<NumericExpression> ops) {
-    int listSize = ops.size();
-    // error on singleton lists
-    if (listSize == 1) throw new IllegalStateException("Should not be creating divisions with single elements");
-    // terminate on 2 element lists
-    if (listSize == 2) return new DivideOperation(ops.get(0), ops.get(1));
-    // general case
-    return new DivideOperation(createNestedDivision(ops.subList(0, listSize - 1)), ops.get(listSize - 1));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,74 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.List;
+
+import org.mulgara.query.filter.value.NumericExpression;
+
+
+/**
+ * Represents a division operation.
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DivideOperation extends BinaryOperation {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 5863800753778864432L;
+
+  public DivideOperation(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * Use an operation set to perform a division
+   * @param ops The operations to use for the current parameters
+   * @param left The dividend
+   * @param right The divisor
+   * @return The quotient of dividing right into left
+   */
+  @SuppressWarnings("unchecked")
+  Number doOperation(NumberOps ops, Number left, Number right) {
+    return ops.divide(left, right);
+  }
+
+  /**
+   * A constructor to handle dividnd lists of values.
+   * @param operands The list of numbers to divide.
+   * @return A new DivideOperation which is dividing numbers in order.
+   */
+  public static DivideOperation newDivideOperation(List<NumericExpression> operands) {
+    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for subtraction. Got " + operands.size());
+    return (DivideOperation)createNestedDivision(operands);
+  }
+
+  /**
+   * A recursive method to build a NumericExpression that represents the division of all values in the list.
+   * This constructs a linked list of divisions.
+   * @param operands The list of values to divide.
+   * @return A NumericExpression which represents the ordered division of everything in the ops list.
+   */
+  private static NumericExpression createNestedDivision(List<NumericExpression> ops) {
+    int listSize = ops.size();
+    // error on singleton lists
+    if (listSize == 1) throw new IllegalStateException("Should not be creating divisions with single elements");
+    // terminate on 2 element lists
+    if (listSize == 2) return new DivideOperation(ops.get(0), ops.get(1));
+    // general case
+    return new DivideOperation(createNestedDivision(ops.subList(0, listSize - 1)), ops.get(listSize - 1));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,138 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jrdf.graph.Literal;
-import org.mulgara.query.QueryException;
-
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the dividing operation classes.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class DivideOperationUnitTest extends AbstractOperationUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public DivideOperationUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new DivideOperationUnitTest("testLiteral"));
-    suite.addTest(new DivideOperationUnitTest("testVar"));
-    suite.addTest(new DivideOperationUnitTest("testMultiOp"));
-    return suite;
-  }
-
-  Number op1() { return 12; }
-
-  Number op2() { return 5; }
-
-  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
-    return new DivideOperation(literal1, literal2);
-  }
-
-  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
-    NumberType t1 = getType(l1);
-    NumberType t2 = getType(l2);
-    switch (t1) {
-    case tInt:
-      int int1 = getInt(l1);
-      switch (t2) {
-      case tInt: return newLiteral(int1 / getInt(l2));
-      case tLong: return newLiteral(int1 / getLong(l2));
-      case tFloat: return newLiteral(int1 / getFloat(l2));
-      case tDouble: return newLiteral(int1 / getDouble(l2));
-      }
-    case tLong:
-      long long1 = getLong(l1);
-      switch (t2) {
-      case tInt: return newLiteral(long1 / getInt(l2));
-      case tLong: return newLiteral(long1 / getLong(l2));
-      case tFloat: return newLiteral(long1 / getFloat(l2));
-      case tDouble: return newLiteral(long1 / getDouble(l2));
-      }
-    case tFloat:
-      float float1 = getFloat(l1);
-      switch (t2) {
-      case tInt: return newLiteral(float1 / getInt(l2));
-      case tLong: return newLiteral(float1 / getLong(l2));
-      case tFloat: return newLiteral(float1 / getFloat(l2));
-      case tDouble: return newLiteral(float1 / getDouble(l2));
-      }
-    case tDouble:
-      double double1 = getDouble(l1);
-      switch (t2) {
-      case tInt: return newLiteral(double1 / getInt(l2));
-      case tLong: return newLiteral(double1 / getLong(l2));
-      case tFloat: return newLiteral(double1 / getFloat(l2));
-      case tDouble: return newLiteral(double1 / getDouble(l2));
-      }
-    }
-    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
-  }
-
-  public void testMultiOp() throws Exception {
-    List<NumericExpression> ops = new ArrayList<NumericExpression>();
-    ops.add(new NumericLiteral(100));
-    ops.add(new NumericLiteral(4));
-    ops.add(new NumericLiteral(5));
-    DivideOperation op = DivideOperation.newDivideOperation(ops);
-    NumericLiteral literalResult = new NumericLiteral(5);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-
-    ops.clear();
-    ops.add(new NumericLiteral(100));
-    ops.add(new NumericLiteral((float)2.0));
-    ops.add(new NumericLiteral(5L));
-    ops.add(new NumericLiteral(4.0));
-    op = DivideOperation.newDivideOperation(ops);
-    literalResult = new NumericLiteral(100 / ((float)2.0) / 5L / 4.0);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/DivideOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,138 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jrdf.graph.Literal;
+import org.mulgara.query.QueryException;
+
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the dividing operation classes.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DivideOperationUnitTest extends AbstractOperationUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public DivideOperationUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new DivideOperationUnitTest("testLiteral"));
+    suite.addTest(new DivideOperationUnitTest("testVar"));
+    suite.addTest(new DivideOperationUnitTest("testMultiOp"));
+    return suite;
+  }
+
+  Number op1() { return 12; }
+
+  Number op2() { return 5; }
+
+  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
+    return new DivideOperation(literal1, literal2);
+  }
+
+  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
+    NumberType t1 = getType(l1);
+    NumberType t2 = getType(l2);
+    switch (t1) {
+    case tInt:
+      int int1 = getInt(l1);
+      switch (t2) {
+      case tInt: return newLiteral(int1 / getInt(l2));
+      case tLong: return newLiteral(int1 / getLong(l2));
+      case tFloat: return newLiteral(int1 / getFloat(l2));
+      case tDouble: return newLiteral(int1 / getDouble(l2));
+      }
+    case tLong:
+      long long1 = getLong(l1);
+      switch (t2) {
+      case tInt: return newLiteral(long1 / getInt(l2));
+      case tLong: return newLiteral(long1 / getLong(l2));
+      case tFloat: return newLiteral(long1 / getFloat(l2));
+      case tDouble: return newLiteral(long1 / getDouble(l2));
+      }
+    case tFloat:
+      float float1 = getFloat(l1);
+      switch (t2) {
+      case tInt: return newLiteral(float1 / getInt(l2));
+      case tLong: return newLiteral(float1 / getLong(l2));
+      case tFloat: return newLiteral(float1 / getFloat(l2));
+      case tDouble: return newLiteral(float1 / getDouble(l2));
+      }
+    case tDouble:
+      double double1 = getDouble(l1);
+      switch (t2) {
+      case tInt: return newLiteral(double1 / getInt(l2));
+      case tLong: return newLiteral(double1 / getLong(l2));
+      case tFloat: return newLiteral(double1 / getFloat(l2));
+      case tDouble: return newLiteral(double1 / getDouble(l2));
+      }
+    }
+    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
+  }
+
+  public void testMultiOp() throws Exception {
+    List<NumericExpression> ops = new ArrayList<NumericExpression>();
+    ops.add(new NumericLiteral(100));
+    ops.add(new NumericLiteral(4));
+    ops.add(new NumericLiteral(5));
+    DivideOperation op = DivideOperation.newDivideOperation(ops);
+    NumericLiteral literalResult = new NumericLiteral(5);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+
+    ops.clear();
+    ops.add(new NumericLiteral(100));
+    ops.add(new NumericLiteral((float)2.0));
+    ops.add(new NumericLiteral(5L));
+    ops.add(new NumericLiteral(4.0));
+    op = DivideOperation.newDivideOperation(ops);
+    literalResult = new NumericLiteral(100 / ((float)2.0) / 5L / 4.0);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,73 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.List;
-
-import org.mulgara.query.filter.value.NumericExpression;
-
-
-/**
- * Represents a subtraction operation.
- *
- * @created Mar 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class MinusOperation extends BinaryOperation {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 3356396260843373856L;
-
-  public MinusOperation(NumericExpression lhs, NumericExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /**
-   * Use an operation set to perform a subtraction
-   * @param ops The operations to use for the current parameters
-   * @param left The minuend
-   * @param right The subtrahend
-   * @return The difference between left and right
-   */
-  @SuppressWarnings("unchecked")
-  Number doOperation(NumberOps ops, Number left, Number right) {
-    return ops.subtract(left, right);
-  }
-
-  /**
-   * A constructor to handle subtracting lists of values.
-   * @param operands The list of numbers to subtract.
-   * @return A new MinusOperation which is subtracting numbers in order.
-   */
-  public static MinusOperation newMinusOperation(List<NumericExpression> operands) {
-    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for subtraction. Got " + operands.size());
-    return (MinusOperation)createNestedSubtraction(operands);
-  }
-
-  /**
-   * A recursive method to build a NumericExpression that represents the subtraction of all values in the list.
-   * @param operands The list of values to subtract.
-   * @return A NumericExpression which represents the ordered subtraction of everything in the ops list.
-   */
-  private static NumericExpression createNestedSubtraction(List<NumericExpression> ops) {
-    int listSize = ops.size();
-    // error on singleton lists
-    if (listSize == 1) throw new IllegalStateException("Should not be creating subtractions with single elements");
-    // terminate on 2 element lists
-    if (listSize == 2) return new MinusOperation(ops.get(0), ops.get(1));
-    // general case
-    return new MinusOperation(createNestedSubtraction(ops.subList(0, listSize - 1)), ops.get(listSize - 1));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,73 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.List;
+
+import org.mulgara.query.filter.value.NumericExpression;
+
+
+/**
+ * Represents a subtraction operation.
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class MinusOperation extends BinaryOperation {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 3356396260843373856L;
+
+  public MinusOperation(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * Use an operation set to perform a subtraction
+   * @param ops The operations to use for the current parameters
+   * @param left The minuend
+   * @param right The subtrahend
+   * @return The difference between left and right
+   */
+  @SuppressWarnings("unchecked")
+  Number doOperation(NumberOps ops, Number left, Number right) {
+    return ops.subtract(left, right);
+  }
+
+  /**
+   * A constructor to handle subtracting lists of values.
+   * @param operands The list of numbers to subtract.
+   * @return A new MinusOperation which is subtracting numbers in order.
+   */
+  public static MinusOperation newMinusOperation(List<NumericExpression> operands) {
+    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for subtraction. Got " + operands.size());
+    return (MinusOperation)createNestedSubtraction(operands);
+  }
+
+  /**
+   * A recursive method to build a NumericExpression that represents the subtraction of all values in the list.
+   * @param operands The list of values to subtract.
+   * @return A NumericExpression which represents the ordered subtraction of everything in the ops list.
+   */
+  private static NumericExpression createNestedSubtraction(List<NumericExpression> ops) {
+    int listSize = ops.size();
+    // error on singleton lists
+    if (listSize == 1) throw new IllegalStateException("Should not be creating subtractions with single elements");
+    // terminate on 2 element lists
+    if (listSize == 2) return new MinusOperation(ops.get(0), ops.get(1));
+    // general case
+    return new MinusOperation(createNestedSubtraction(ops.subList(0, listSize - 1)), ops.get(listSize - 1));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,139 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jrdf.graph.Literal;
-import org.mulgara.query.QueryException;
-
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the subtraction operation classes.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class MinusOperationUnitTest extends AbstractOperationUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public MinusOperationUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new MinusOperationUnitTest("testLiteral"));
-    suite.addTest(new MinusOperationUnitTest("testVar"));
-    suite.addTest(new MinusOperationUnitTest("testMultiOp"));
-    return suite;
-  }
-
-  Number op1() { return 9; }
-
-  Number op2() { return 5; }
-
-  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
-    return new MinusOperation(literal1, literal2);
-  }
-
-  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
-    NumberType t1 = getType(l1);
-    NumberType t2 = getType(l2);
-    switch (t1) {
-    case tInt:
-      int int1 = getInt(l1);
-      switch (t2) {
-      case tInt: return newLiteral(int1 - getInt(l2));
-      case tLong: return newLiteral(int1 - getLong(l2));
-      case tFloat: return newLiteral(int1 - getFloat(l2));
-      case tDouble: return newLiteral(int1 - getDouble(l2));
-      }
-    case tLong:
-      long long1 = getLong(l1);
-      switch (t2) {
-      case tInt: return newLiteral(long1 - getInt(l2));
-      case tLong: return newLiteral(long1 - getLong(l2));
-      case tFloat: return newLiteral(long1 - getFloat(l2));
-      case tDouble: return newLiteral(long1 - getDouble(l2));
-      }
-    case tFloat:
-      float float1 = getFloat(l1);
-      switch (t2) {
-      case tInt: return newLiteral(float1 - getInt(l2));
-      case tLong: return newLiteral(float1 - getLong(l2));
-      case tFloat: return newLiteral(float1 - getFloat(l2));
-      case tDouble: return newLiteral(float1 - getDouble(l2));
-      }
-    case tDouble:
-      double double1 = getDouble(l1);
-      switch (t2) {
-      case tInt: return newLiteral(double1 - getInt(l2));
-      case tLong: return newLiteral(double1 - getLong(l2));
-      case tFloat: return newLiteral(double1 - getFloat(l2));
-      case tDouble: return newLiteral(double1 - getDouble(l2));
-      }
-    }
-    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
-  }
-
-  public void testMultiOp() throws Exception {
-    List<NumericExpression> ops = new ArrayList<NumericExpression>();
-    ops.add(new NumericLiteral(100));
-    ops.add(new NumericLiteral(60));
-    ops.add(new NumericLiteral(5));
-    MinusOperation op = MinusOperation.newMinusOperation(ops);
-    NumericLiteral literalResult = new NumericLiteral(35);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-
-    ops.clear();
-    ops.add(new NumericLiteral(100));
-    ops.add(new NumericLiteral((float)2.0));
-    ops.add(new NumericLiteral(5L));
-    ops.add(new NumericLiteral(4.0));
-    op = MinusOperation.newMinusOperation(ops);
-    literalResult = new NumericLiteral(100 - ((float)2.0) - 5L - 4.0);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-  }
-
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MinusOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,139 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jrdf.graph.Literal;
+import org.mulgara.query.QueryException;
+
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the subtraction operation classes.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class MinusOperationUnitTest extends AbstractOperationUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public MinusOperationUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new MinusOperationUnitTest("testLiteral"));
+    suite.addTest(new MinusOperationUnitTest("testVar"));
+    suite.addTest(new MinusOperationUnitTest("testMultiOp"));
+    return suite;
+  }
+
+  Number op1() { return 9; }
+
+  Number op2() { return 5; }
+
+  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
+    return new MinusOperation(literal1, literal2);
+  }
+
+  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
+    NumberType t1 = getType(l1);
+    NumberType t2 = getType(l2);
+    switch (t1) {
+    case tInt:
+      int int1 = getInt(l1);
+      switch (t2) {
+      case tInt: return newLiteral(int1 - getInt(l2));
+      case tLong: return newLiteral(int1 - getLong(l2));
+      case tFloat: return newLiteral(int1 - getFloat(l2));
+      case tDouble: return newLiteral(int1 - getDouble(l2));
+      }
+    case tLong:
+      long long1 = getLong(l1);
+      switch (t2) {
+      case tInt: return newLiteral(long1 - getInt(l2));
+      case tLong: return newLiteral(long1 - getLong(l2));
+      case tFloat: return newLiteral(long1 - getFloat(l2));
+      case tDouble: return newLiteral(long1 - getDouble(l2));
+      }
+    case tFloat:
+      float float1 = getFloat(l1);
+      switch (t2) {
+      case tInt: return newLiteral(float1 - getInt(l2));
+      case tLong: return newLiteral(float1 - getLong(l2));
+      case tFloat: return newLiteral(float1 - getFloat(l2));
+      case tDouble: return newLiteral(float1 - getDouble(l2));
+      }
+    case tDouble:
+      double double1 = getDouble(l1);
+      switch (t2) {
+      case tInt: return newLiteral(double1 - getInt(l2));
+      case tLong: return newLiteral(double1 - getLong(l2));
+      case tFloat: return newLiteral(double1 - getFloat(l2));
+      case tDouble: return newLiteral(double1 - getDouble(l2));
+      }
+    }
+    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
+  }
+
+  public void testMultiOp() throws Exception {
+    List<NumericExpression> ops = new ArrayList<NumericExpression>();
+    ops.add(new NumericLiteral(100));
+    ops.add(new NumericLiteral(60));
+    ops.add(new NumericLiteral(5));
+    MinusOperation op = MinusOperation.newMinusOperation(ops);
+    NumericLiteral literalResult = new NumericLiteral(35);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+
+    ops.clear();
+    ops.add(new NumericLiteral(100));
+    ops.add(new NumericLiteral((float)2.0));
+    ops.add(new NumericLiteral(5L));
+    ops.add(new NumericLiteral(4.0));
+    op = MinusOperation.newMinusOperation(ops);
+    literalResult = new NumericLiteral(100 - ((float)2.0) - 5L - 4.0);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+  }
+
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,73 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.List;
-
-import org.mulgara.query.filter.value.NumericExpression;
-
-
-/**
- * Represents a multiplication operation.
- *
- * @created Mar 13, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class MultiplyOperation extends BinaryOperation {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -2996017159385273832L;
-
-  public MultiplyOperation(NumericExpression lhs, NumericExpression rhs) {
-    super(lhs, rhs);
-  }
-
-  /**
-   * Use an operation set to perform a multiplication
-   * @param ops The operations to use for the current parameters
-   * @param left The first operand
-   * @param right The second operand
-   * @return The product of left and right
-   */
-  @SuppressWarnings("unchecked")
-  Number doOperation(NumberOps ops, Number left, Number right) {
-    return ops.product(left, right);
-  }
-
-  /**
-   * A constructor to handle adding lists of multipliers.
-   * @param operands The list of multipliers to multiply.
-   * @return A new MultiplyOperation which is multiplying all the elements.
-   */
-  public static MultiplyOperation newMultiplyOperation(List<NumericExpression> operands) {
-    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for multiplication. Got " + operands.size());
-    return (MultiplyOperation)createNestedMultiply(operands);
-  }
-
-  /**
-   * A recursive method to build a NumericExpression that represents the product of all multipliers in the list.
-   * @param operands The list of multipliers to multiply.
-   * @return A NumericExpression which represents the product of everything in the ops list.
-   */
-  private static NumericExpression createNestedMultiply(List<NumericExpression> ops) {
-    int listSize = ops.size();
-    // terminate on singleton lists
-    if (listSize == 1) return ops.get(0);
-    // short circuit for 2 element lists - optimization
-    if (listSize == 2) return new MultiplyOperation(ops.get(0), ops.get(1));
-    // general case
-    return new MultiplyOperation(createNestedMultiply(ops.subList(0, listSize / 2)), createNestedMultiply(ops.subList(listSize / 2, listSize)));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperation.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,73 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.List;
+
+import org.mulgara.query.filter.value.NumericExpression;
+
+
+/**
+ * Represents a multiplication operation.
+ *
+ * @created Mar 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class MultiplyOperation extends BinaryOperation {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -2996017159385273832L;
+
+  public MultiplyOperation(NumericExpression lhs, NumericExpression rhs) {
+    super(lhs, rhs);
+  }
+
+  /**
+   * Use an operation set to perform a multiplication
+   * @param ops The operations to use for the current parameters
+   * @param left The first operand
+   * @param right The second operand
+   * @return The product of left and right
+   */
+  @SuppressWarnings("unchecked")
+  Number doOperation(NumberOps ops, Number left, Number right) {
+    return ops.product(left, right);
+  }
+
+  /**
+   * A constructor to handle adding lists of multipliers.
+   * @param operands The list of multipliers to multiply.
+   * @return A new MultiplyOperation which is multiplying all the elements.
+   */
+  public static MultiplyOperation newMultiplyOperation(List<NumericExpression> operands) {
+    if (operands.size() < 2) throw new IllegalArgumentException("Require at least 2 addends for multiplication. Got " + operands.size());
+    return (MultiplyOperation)createNestedMultiply(operands);
+  }
+
+  /**
+   * A recursive method to build a NumericExpression that represents the product of all multipliers in the list.
+   * @param operands The list of multipliers to multiply.
+   * @return A NumericExpression which represents the product of everything in the ops list.
+   */
+  private static NumericExpression createNestedMultiply(List<NumericExpression> ops) {
+    int listSize = ops.size();
+    // terminate on singleton lists
+    if (listSize == 1) return ops.get(0);
+    // short circuit for 2 element lists - optimization
+    if (listSize == 2) return new MultiplyOperation(ops.get(0), ops.get(1));
+    // general case
+    return new MultiplyOperation(createNestedMultiply(ops.subList(0, listSize / 2)), createNestedMultiply(ops.subList(listSize / 2, listSize)));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,140 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.jrdf.graph.Literal;
-import org.mulgara.query.QueryException;
-
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-
-import junit.framework.Test;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the multiplication operation classes.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class MultiplyOperationUnitTest extends AbstractOperationUnitTest {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public MultiplyOperationUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new MultiplyOperationUnitTest("testLiteral"));
-    suite.addTest(new MultiplyOperationUnitTest("testVar"));
-    suite.addTest(new MultiplyOperationUnitTest("testMultiOp"));
-    return suite;
-  }
-
-  Number op1() { return 4; }
-
-  Number op2() { return 5; }
-
-  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
-    return new MultiplyOperation(literal1, literal2);
-  }
-
-  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
-    NumberType t1 = getType(l1);
-    NumberType t2 = getType(l2);
-    switch (t1) {
-    case tInt:
-      int int1 = getInt(l1);
-      switch (t2) {
-      case tInt: return newLiteral(int1 * getInt(l2));
-      case tLong: return newLiteral(int1 * getLong(l2));
-      case tFloat: return newLiteral(int1 * getFloat(l2));
-      case tDouble: return newLiteral(int1 * getDouble(l2));
-      }
-    case tLong:
-      long long1 = getLong(l1);
-      switch (t2) {
-      case tInt: return newLiteral(long1 * getInt(l2));
-      case tLong: return newLiteral(long1 * getLong(l2));
-      case tFloat: return newLiteral(long1 * getFloat(l2));
-      case tDouble: return newLiteral(long1 * getDouble(l2));
-      }
-    case tFloat:
-      float float1 = getFloat(l1);
-      switch (t2) {
-      case tInt: return newLiteral(float1 * getInt(l2));
-      case tLong: return newLiteral(float1 * getLong(l2));
-      case tFloat: return newLiteral(float1 * getFloat(l2));
-      case tDouble: return newLiteral(float1 * getDouble(l2));
-      }
-    case tDouble:
-      double double1 = getDouble(l1);
-      switch (t2) {
-      case tInt: return newLiteral(double1 * getInt(l2));
-      case tLong: return newLiteral(double1 * getLong(l2));
-      case tFloat: return newLiteral(double1 * getFloat(l2));
-      case tDouble: return newLiteral(double1 * getDouble(l2));
-      }
-    }
-    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
-  }
-
-  public void testMultiOp() throws Exception {
-    List<NumericExpression> ops = new ArrayList<NumericExpression>();
-    int product = 1;
-    for (int i = 2; i <= 5; i++) {
-      product *= i;
-      ops.add(new NumericLiteral(i));
-    }
-    MultiplyOperation op = MultiplyOperation.newMultiplyOperation(ops);
-    NumericLiteral literalResult = new NumericLiteral(product);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-
-    ops.clear();
-    ops.add(new NumericLiteral(1));
-    ops.add(new NumericLiteral((float)2.0));
-    ops.add(new NumericLiteral(3L));
-    ops.add(new NumericLiteral(4.0));
-    op = MultiplyOperation.newMultiplyOperation(ops);
-    literalResult = new NumericLiteral(1 * ((float)2.0) * 3L * 4.0);
-    assertTrue(op.equals(literalResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(literalResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());    
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/MultiplyOperationUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,140 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jrdf.graph.Literal;
+import org.mulgara.query.QueryException;
+
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the multiplication operation classes.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class MultiplyOperationUnitTest extends AbstractOperationUnitTest {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public MultiplyOperationUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new MultiplyOperationUnitTest("testLiteral"));
+    suite.addTest(new MultiplyOperationUnitTest("testVar"));
+    suite.addTest(new MultiplyOperationUnitTest("testMultiOp"));
+    return suite;
+  }
+
+  Number op1() { return 4; }
+
+  Number op2() { return 5; }
+
+  BinaryOperation getOperation(NumericExpression literal1, NumericExpression literal2) {
+    return new MultiplyOperation(literal1, literal2);
+  }
+
+  ValueLiteral doOperation(Literal l1, Literal l2) throws QueryException {
+    NumberType t1 = getType(l1);
+    NumberType t2 = getType(l2);
+    switch (t1) {
+    case tInt:
+      int int1 = getInt(l1);
+      switch (t2) {
+      case tInt: return newLiteral(int1 * getInt(l2));
+      case tLong: return newLiteral(int1 * getLong(l2));
+      case tFloat: return newLiteral(int1 * getFloat(l2));
+      case tDouble: return newLiteral(int1 * getDouble(l2));
+      }
+    case tLong:
+      long long1 = getLong(l1);
+      switch (t2) {
+      case tInt: return newLiteral(long1 * getInt(l2));
+      case tLong: return newLiteral(long1 * getLong(l2));
+      case tFloat: return newLiteral(long1 * getFloat(l2));
+      case tDouble: return newLiteral(long1 * getDouble(l2));
+      }
+    case tFloat:
+      float float1 = getFloat(l1);
+      switch (t2) {
+      case tInt: return newLiteral(float1 * getInt(l2));
+      case tLong: return newLiteral(float1 * getLong(l2));
+      case tFloat: return newLiteral(float1 * getFloat(l2));
+      case tDouble: return newLiteral(float1 * getDouble(l2));
+      }
+    case tDouble:
+      double double1 = getDouble(l1);
+      switch (t2) {
+      case tInt: return newLiteral(double1 * getInt(l2));
+      case tLong: return newLiteral(double1 * getLong(l2));
+      case tFloat: return newLiteral(double1 * getFloat(l2));
+      case tDouble: return newLiteral(double1 * getDouble(l2));
+      }
+    }
+    throw new IllegalArgumentException("Unable to process argument of types: " + t1 + ", " + t2);
+  }
+
+  public void testMultiOp() throws Exception {
+    List<NumericExpression> ops = new ArrayList<NumericExpression>();
+    int product = 1;
+    for (int i = 2; i <= 5; i++) {
+      product *= i;
+      ops.add(new NumericLiteral(i));
+    }
+    MultiplyOperation op = MultiplyOperation.newMultiplyOperation(ops);
+    NumericLiteral literalResult = new NumericLiteral(product);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+
+    ops.clear();
+    ops.add(new NumericLiteral(1));
+    ops.add(new NumericLiteral((float)2.0));
+    ops.add(new NumericLiteral(3L));
+    ops.add(new NumericLiteral(4.0));
+    op = MultiplyOperation.newMultiplyOperation(ops);
+    literalResult = new NumericLiteral(1 * ((float)2.0) * 3L * 4.0);
+    assertTrue(op.equals(literalResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(literalResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());    
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,112 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.NumericExpression;
-
-
-/**
- * Represents a numeric negation.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class UnaryMinus extends AbstractNumericOperation implements NumericExpression {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 33264336439539952L;
-
-  /** The operand */
-  protected NumericExpression operand;
-
-  /**
-   * Creates a negation of the given term.
-   * @param operand The numeric term to negate.
-   */
-  public UnaryMinus(NumericExpression operand) {
-    this.operand = operand;
-    operand.setContextOwner(this);
-  }
-
-  // Not using generics in NumberOps as we can't know the types at this stage, but they are handy
-  // for defining the classes correctly
-  /**
-   * Calculate the result of this operation, returning it as a normal number.
-   * @throws QueryException The values of one of the operands could not be resolved.
-   * @see org.mulgara.query.filter.value.NumericExpression#getNumber()
-   */
-  @SuppressWarnings("unchecked")
-  public Number getNumber() throws QueryException {
-    Number n = operand.getNumber();
-    InversionOp op = opMap.get(n.getClass());
-    if (op == null) throw new AssertionError("Missing entry in negation operation map");
-    return op.invert(n);
-  }
-
-  /** Defines a unary negation function that returns a number of the same type as it receives */
-  interface InversionOp<T extends Number> {
-    public Class<T> getType();
-    public Number invert(T v);
-  }
-
-  /** A map of types to the functions that multiply them with correct type promotions */
-  protected static Map<Class<? extends Number>,InversionOp<? extends Number>> opMap = new HashMap<Class<? extends Number>,InversionOp<? extends Number>>();
-
-  /** A utility to add a number function to the promotion map */
-  private static void addType(InversionOp<? extends Number> op) { opMap.put(op.getType(), op); }
-
-  static {
-    addType(new InvertD());
-    addType(new InvertF());
-    addType(new InvertL());
-    addType(new InvertI());
-    addType(new InvertS());
-    addType(new InvertB());
-  }
-
-  private static class InvertD implements InversionOp<Double> {
-    public Class<Double> getType() { return Double.class; }
-    public Number invert(Double v) { return -v; }
-  }
-
-  private static class InvertF implements InversionOp<Float> {
-    public Class<Float> getType() { return Float.class; }
-    public Number invert(Float v) { return -v; }
-  }
-
-  private static class InvertL implements InversionOp<Long> {
-    public Class<Long> getType() { return Long.class; }
-    public Number invert(Long v) { return -v; }
-  }
-
-  private static class InvertI implements InversionOp<Integer> {
-    public Class<Integer> getType() { return Integer.class; }
-    public Number invert(Integer v) { return -v; }
-  }
-
-  private static class InvertS implements InversionOp<Short> {
-    public Class<Short> getType() { return Short.class; }
-    public Number invert(Short v) { return -v; }
-  }
-
-  private static class InvertB implements InversionOp<Byte> {
-    public Class<Byte> getType() { return Byte.class; }
-    public Number invert(Byte v) { return -v; }
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinus.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,112 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.NumericExpression;
+
+
+/**
+ * Represents a numeric negation.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class UnaryMinus extends AbstractNumericOperation implements NumericExpression {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 33264336439539952L;
+
+  /** The operand */
+  protected NumericExpression operand;
+
+  /**
+   * Creates a negation of the given term.
+   * @param operand The numeric term to negate.
+   */
+  public UnaryMinus(NumericExpression operand) {
+    this.operand = operand;
+    operand.setContextOwner(this);
+  }
+
+  // Not using generics in NumberOps as we can't know the types at this stage, but they are handy
+  // for defining the classes correctly
+  /**
+   * Calculate the result of this operation, returning it as a normal number.
+   * @throws QueryException The values of one of the operands could not be resolved.
+   * @see org.mulgara.query.filter.value.NumericExpression#getNumber()
+   */
+  @SuppressWarnings("unchecked")
+  public Number getNumber() throws QueryException {
+    Number n = operand.getNumber();
+    InversionOp op = opMap.get(n.getClass());
+    if (op == null) throw new AssertionError("Missing entry in negation operation map");
+    return op.invert(n);
+  }
+
+  /** Defines a unary negation function that returns a number of the same type as it receives */
+  interface InversionOp<T extends Number> {
+    public Class<T> getType();
+    public Number invert(T v);
+  }
+
+  /** A map of types to the functions that multiply them with correct type promotions */
+  protected static Map<Class<? extends Number>,InversionOp<? extends Number>> opMap = new HashMap<Class<? extends Number>,InversionOp<? extends Number>>();
+
+  /** A utility to add a number function to the promotion map */
+  private static void addType(InversionOp<? extends Number> op) { opMap.put(op.getType(), op); }
+
+  static {
+    addType(new InvertD());
+    addType(new InvertF());
+    addType(new InvertL());
+    addType(new InvertI());
+    addType(new InvertS());
+    addType(new InvertB());
+  }
+
+  private static class InvertD implements InversionOp<Double> {
+    public Class<Double> getType() { return Double.class; }
+    public Number invert(Double v) { return -v; }
+  }
+
+  private static class InvertF implements InversionOp<Float> {
+    public Class<Float> getType() { return Float.class; }
+    public Number invert(Float v) { return -v; }
+  }
+
+  private static class InvertL implements InversionOp<Long> {
+    public Class<Long> getType() { return Long.class; }
+    public Number invert(Long v) { return -v; }
+  }
+
+  private static class InvertI implements InversionOp<Integer> {
+    public Class<Integer> getType() { return Integer.class; }
+    public Number invert(Integer v) { return -v; }
+  }
+
+  private static class InvertS implements InversionOp<Short> {
+    public Class<Short> getType() { return Short.class; }
+    public Number invert(Short v) { return -v; }
+  }
+
+  private static class InvertB implements InversionOp<Byte> {
+    public Class<Byte> getType() { return Byte.class; }
+    public Number invert(Byte v) { return -v; }
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,177 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.arithmetic;
-
-import java.net.URI;
-
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.Var;
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the unary minus operation.
- *
- * @created Apr 14, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class UnaryMinusUnitTest extends TestCase {
-
-  URI xsdInt = URI.create(XSD_NS + "int");
-  URI xsdLong = URI.create(XSD_NS + "long");
-  URI xsdFloat = URI.create(XSD_NS + "float");
-  URI xsdDouble = URI.create(XSD_NS + "double");
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public UnaryMinusUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new UnaryMinusUnitTest("testLiteral"));
-    suite.addTest(new UnaryMinusUnitTest("testVar"));
-    return suite;
-  }
-
-  public void testLiteral() throws Exception {
-    Number op = 7.3;
-    basicTest(new NumericLiteral(op.intValue()));
-    basicTest(new NumericLiteral(op.longValue()));
-    basicTest(new NumericLiteral(op.floatValue()));
-    basicTest(new NumericLiteral(op.doubleValue()));
-    op = -42;
-    basicTest(new NumericLiteral(op.intValue()));
-    basicTest(new NumericLiteral(op.longValue()));
-    basicTest(new NumericLiteral(op.floatValue()));
-    basicTest(new NumericLiteral(op.doubleValue()));
-  }
-
-  private void basicTest(NumericExpression value) throws Exception {
-    UnaryMinus op = new UnaryMinus(value);
-    NumericExpression expectedResult = new NumericLiteral(negate(value.getNumber()));
-    assertTrue(op.equals(expectedResult));
-    assertFalse(op.isBlank());
-    assertFalse(op.isIRI());
-    assertTrue(op.isLiteral());
-    assertFalse(op.isURI());
-    assertTrue(expectedResult.getType().equals(op.getType()));
-    assertEquals(SimpleLiteral.EMPTY, op.getLang());
-  }
-
-  private Number negate(Number n) {
-    if (n instanceof Integer) return -n.intValue();
-    if (n instanceof Long) return -n.longValue();
-    if (n instanceof Float) return -n.floatValue();
-    if (n instanceof Double) return -n.doubleValue();
-    throw new IllegalArgumentException("Unexpected numeric type: " + n.getClass().getSimpleName());
-  }
-
-  public void testVar() throws Exception {
-    Var x = new Var("x");
-    UnaryMinus fn = new UnaryMinus(x);
-    
-    URI fooBar = URI.create("foo:bar");
-    Number op = 7.3;
-    Literal iop = new LiteralImpl("" + op.intValue(), xsdInt);
-    Literal lop = new LiteralImpl("" + op.longValue(), xsdLong);
-    Literal fop = new LiteralImpl("" + op.floatValue(), xsdFloat);
-    Literal dop = new LiteralImpl("" + op.doubleValue(), xsdDouble);
-    Node[][] rows = {
-      new Node[] {iop},
-      new Node[] {lop},
-      new Node[] {fop},
-      new Node[] {dop},
-      // The following are to fail
-      new Node[] {new LiteralImpl("foo", "en")},
-      new Node[] {new LiteralImpl("foo", fooBar)},
-      new Node[] {new URIReferenceImpl(fooBar)},
-      new Node[] {new BlankNodeImpl()},
-      new Node[] {null}
-    };
-    TestContext c = new TestContext(new String[] {"x"}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertTrue(new NumericLiteral(-op.intValue()).equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(new NumericLiteral(-op.longValue()).equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(new NumericLiteral(-op.floatValue()).equals(fn));
-
-    assertTrue(c.next());
-    assertTrue(new NumericLiteral(-op.doubleValue()).equals(fn));
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Negated a language string");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Negated ab unknown typed literal");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Negated a uri");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Negated a blank node");
-    } catch (QueryException qe) { }
-
-    assertTrue(c.next());
-    try {
-      fn.getValue();
-      fail("Negated an unbound");
-    } catch (QueryException qe) { }
-
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/arithmetic/UnaryMinusUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,177 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.arithmetic;
+
+import java.net.URI;
+
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.Var;
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the unary minus operation.
+ *
+ * @created Apr 14, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class UnaryMinusUnitTest extends TestCase {
+
+  URI xsdInt = URI.create(XSD_NS + "int");
+  URI xsdLong = URI.create(XSD_NS + "long");
+  URI xsdFloat = URI.create(XSD_NS + "float");
+  URI xsdDouble = URI.create(XSD_NS + "double");
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public UnaryMinusUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new UnaryMinusUnitTest("testLiteral"));
+    suite.addTest(new UnaryMinusUnitTest("testVar"));
+    return suite;
+  }
+
+  public void testLiteral() throws Exception {
+    Number op = 7.3;
+    basicTest(new NumericLiteral(op.intValue()));
+    basicTest(new NumericLiteral(op.longValue()));
+    basicTest(new NumericLiteral(op.floatValue()));
+    basicTest(new NumericLiteral(op.doubleValue()));
+    op = -42;
+    basicTest(new NumericLiteral(op.intValue()));
+    basicTest(new NumericLiteral(op.longValue()));
+    basicTest(new NumericLiteral(op.floatValue()));
+    basicTest(new NumericLiteral(op.doubleValue()));
+  }
+
+  private void basicTest(NumericExpression value) throws Exception {
+    UnaryMinus op = new UnaryMinus(value);
+    NumericExpression expectedResult = new NumericLiteral(negate(value.getNumber()));
+    assertTrue(op.equals(expectedResult));
+    assertFalse(op.isBlank());
+    assertFalse(op.isIRI());
+    assertTrue(op.isLiteral());
+    assertFalse(op.isURI());
+    assertTrue(expectedResult.getType().equals(op.getType()));
+    assertEquals(SimpleLiteral.EMPTY, op.getLang());
+  }
+
+  private Number negate(Number n) {
+    if (n instanceof Integer) return -n.intValue();
+    if (n instanceof Long) return -n.longValue();
+    if (n instanceof Float) return -n.floatValue();
+    if (n instanceof Double) return -n.doubleValue();
+    throw new IllegalArgumentException("Unexpected numeric type: " + n.getClass().getSimpleName());
+  }
+
+  public void testVar() throws Exception {
+    Var x = new Var("x");
+    UnaryMinus fn = new UnaryMinus(x);
+    
+    URI fooBar = URI.create("foo:bar");
+    Number op = 7.3;
+    Literal iop = new LiteralImpl("" + op.intValue(), xsdInt);
+    Literal lop = new LiteralImpl("" + op.longValue(), xsdLong);
+    Literal fop = new LiteralImpl("" + op.floatValue(), xsdFloat);
+    Literal dop = new LiteralImpl("" + op.doubleValue(), xsdDouble);
+    Node[][] rows = {
+      new Node[] {iop},
+      new Node[] {lop},
+      new Node[] {fop},
+      new Node[] {dop},
+      // The following are to fail
+      new Node[] {new LiteralImpl("foo", "en")},
+      new Node[] {new LiteralImpl("foo", fooBar)},
+      new Node[] {new URIReferenceImpl(fooBar)},
+      new Node[] {new BlankNodeImpl()},
+      new Node[] {null}
+    };
+    TestContext c = new TestContext(new String[] {"x"}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertTrue(new NumericLiteral(-op.intValue()).equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(new NumericLiteral(-op.longValue()).equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(new NumericLiteral(-op.floatValue()).equals(fn));
+
+    assertTrue(c.next());
+    assertTrue(new NumericLiteral(-op.doubleValue()).equals(fn));
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Negated a language string");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Negated ab unknown typed literal");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Negated a uri");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Negated a blank node");
+    } catch (QueryException qe) { }
+
+    assertTrue(c.next());
+    try {
+      fn.getValue();
+      fail("Negated an unbound");
+    } catch (QueryException qe) { }
+
+    assertFalse(c.next());
+  }
+  
+}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value)

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,96 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.AbstractFilterValue;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * Represents a function that accesses an RDF value.
- * This node acts as an RDFTerm and as a ValueLiteral, so that it can act as
- * either a Literal (Simple or Typed) or an IRI.
- * By default, this object will act as a literal.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractAccessorFn extends AbstractFilterValue implements ValueLiteral {
-
-  /** The operand for the function */
-  RDFTerm operand;
-
-  /**
-   * Single argument constructor.
-   * @param operand The single argument for this function.
-   */
-  public AbstractAccessorFn(RDFTerm operand) {
-    super(operand);
-    this.operand = operand;
-  }
-
-  /**
-   * Multiple argument constructor.
-   * @param operands All the arguments for this function, in order.
-   */
-  public AbstractAccessorFn(RDFTerm... operands) {
-    super(operands);
-    this.operand = operands[0];
-  }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
-  public IRI getType() throws QueryException {
-    return SimpleLiteral.STRING_TYPE;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.ContextOwner#setCurrentContext(org.mulgara.query.filter.Context)
-   * Overridden from AbstractFilterValue to provide a different error message.
-   */
-  public void setCurrentContext(Context context) {
-    if (!(context.equals(getContextOwner().getCurrentContext()))) throw new AssertionError("Function context being set differently to initial calling context.");
-  }
-
-  public boolean greaterThan(ComparableExpression v) throws QueryException {
-    return resolveComparable().greaterThan(v);
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
-    return resolveComparable().greaterThanEqualTo(v);
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThan(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean lessThan(ComparableExpression v) throws QueryException {
-    return resolveComparable().lessThan(v);
-  }
-
-  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
-  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
-    return resolveComparable().lessThanEqualTo(v);
-  }
-
-  /**
-   * Resolves this function to a value that can be compared, or throws an exception if it cannot be compared.
-   * @return A value that can be compared for inequality.
-   * @throws QueryException If there was a problem resolving the function, or if the value is not comparable.
-   */
-  protected ComparableExpression resolveComparable() throws QueryException {
-    RDFTerm result = resolve();
-    if (!(result instanceof ComparableExpression)) throw new QueryException("Type error: cannot compare with a: " + result.getClass().getSimpleName());
-    return (ComparableExpression)result;
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractAccessorFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,96 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.AbstractFilterValue;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * Represents a function that accesses an RDF value.
+ * This node acts as an RDFTerm and as a ValueLiteral, so that it can act as
+ * either a Literal (Simple or Typed) or an IRI.
+ * By default, this object will act as a literal.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractAccessorFn extends AbstractFilterValue implements ValueLiteral {
+
+  /** The operand for the function */
+  RDFTerm operand;
+
+  /**
+   * Single argument constructor.
+   * @param operand The single argument for this function.
+   */
+  public AbstractAccessorFn(RDFTerm operand) {
+    super(operand);
+    this.operand = operand;
+  }
+
+  /**
+   * Multiple argument constructor.
+   * @param operands All the arguments for this function, in order.
+   */
+  public AbstractAccessorFn(RDFTerm... operands) {
+    super(operands);
+    this.operand = operands[0];
+  }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#getType() */
+  public IRI getType() throws QueryException {
+    return SimpleLiteral.STRING_TYPE;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.ContextOwner#setCurrentContext(org.mulgara.query.filter.Context)
+   * Overridden from AbstractFilterValue to provide a different error message.
+   */
+  public void setCurrentContext(Context context) {
+    if (!(context.equals(getContextOwner().getCurrentContext()))) throw new AssertionError("Function context being set differently to initial calling context.");
+  }
+
+  public boolean greaterThan(ComparableExpression v) throws QueryException {
+    return resolveComparable().greaterThan(v);
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#greaterThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
+    return resolveComparable().greaterThanEqualTo(v);
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThan(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean lessThan(ComparableExpression v) throws QueryException {
+    return resolveComparable().lessThan(v);
+  }
+
+  /** @see org.mulgara.query.filter.value.ComparableExpression#lessThanEqualTo(org.mulgara.query.filter.value.ComparableExpression) */
+  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
+    return resolveComparable().lessThanEqualTo(v);
+  }
+
+  /**
+   * Resolves this function to a value that can be compared, or throws an exception if it cannot be compared.
+   * @return A value that can be compared for inequality.
+   * @throws QueryException If there was a problem resolving the function, or if the value is not comparable.
+   */
+  protected ComparableExpression resolveComparable() throws QueryException {
+    RDFTerm result = resolve();
+    if (!(result instanceof ComparableExpression)) throw new QueryException("Type error: cannot compare with a: " + result.getClass().getSimpleName());
+    return (ComparableExpression)result;
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,79 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.AbstractContextOwner;
-
-/**
- * Represents literal values that can be compared.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractComparable extends AbstractContextOwner implements ComparableExpression {
-
-  /** {@inheritDoc} */
-  public boolean lessThan(ComparableExpression v) throws QueryException {
-    compatibilityTest(v);
-    return compare(getValue(), v.getValue()) < 0;
-  }
-
-  /** {@inheritDoc} */
-  public boolean greaterThan(ComparableExpression v) throws QueryException {
-    compatibilityTest(v);
-    return compare(getValue(), v.getValue()) > 0;
-  }
-
-  /** {@inheritDoc} */
-  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
-    return !greaterThan(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
-    return !lessThan(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean equals(ComparableExpression v) throws QueryException {
-    return compare(getValue(), v.getValue()) == 0;
-  }
-
-  /** {@inheritDoc} */
-  public boolean notEquals(ComparableExpression v) throws QueryException {
-    return !equals(v);
-  }
-
-  /**
-   * Tests a value to see if it is a simple literal, and throws an exception if it is.
-   * Simple literals do a similar test when compared with a ComparableExpression.
-   * @param v The comparable expression to test.
-   * @throws QueryException If the comparable expression resolves to a {@link SimpleLiteral}.
-   */
-  private void compatibilityTest(ComparableExpression v) throws QueryException {
-    if (v.isLiteral() && ((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal with a: " + getClass().getSimpleName());
-  }
-
-  /**
-   * Compares elements of the type handled by the implementing class.
-   * @param left The LHS of the comparison
-   * @param right The RHS of the comparison
-   * @return -1 if left<right, +1 if left>right, 0 if left==right
-   * @throws QueryException If getting the values for the comparison is invalid.
-   */
-  protected abstract int compare(Object left, Object right) throws QueryException;
-
-}
\ No newline at end of file

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparable.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,79 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.AbstractContextOwner;
+
+/**
+ * Represents literal values that can be compared.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractComparable extends AbstractContextOwner implements ComparableExpression {
+
+  /** {@inheritDoc} */
+  public boolean lessThan(ComparableExpression v) throws QueryException {
+    compatibilityTest(v);
+    return compare(getValue(), v.getValue()) < 0;
+  }
+
+  /** {@inheritDoc} */
+  public boolean greaterThan(ComparableExpression v) throws QueryException {
+    compatibilityTest(v);
+    return compare(getValue(), v.getValue()) > 0;
+  }
+
+  /** {@inheritDoc} */
+  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
+    return !greaterThan(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
+    return !lessThan(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(ComparableExpression v) throws QueryException {
+    return compare(getValue(), v.getValue()) == 0;
+  }
+
+  /** {@inheritDoc} */
+  public boolean notEquals(ComparableExpression v) throws QueryException {
+    return !equals(v);
+  }
+
+  /**
+   * Tests a value to see if it is a simple literal, and throws an exception if it is.
+   * Simple literals do a similar test when compared with a ComparableExpression.
+   * @param v The comparable expression to test.
+   * @throws QueryException If the comparable expression resolves to a {@link SimpleLiteral}.
+   */
+  private void compatibilityTest(ComparableExpression v) throws QueryException {
+    if (v.isLiteral() && ((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal with a: " + getClass().getSimpleName());
+  }
+
+  /**
+   * Compares elements of the type handled by the implementing class.
+   * @param left The LHS of the comparison
+   * @param right The RHS of the comparison
+   * @return -1 if left<right, +1 if left>right, 0 if left==right
+   * @throws QueryException If getting the values for the comparison is invalid.
+   */
+  protected abstract int compare(Object left, Object right) throws QueryException;
+
+}
\ No newline at end of file

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,240 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * Basic common representation of literals.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public abstract class AbstractComparableLiteral extends AbstractComparable implements ValueLiteral {
-
-  /** The wrapped value */
-  Object value;
-
-  /**
-   * Creates a value
-   * @param value The value to use
-   */
-  public AbstractComparableLiteral(Object value) {
-    this.value = value;
-  }
-
-  /**
-   * Returns the wrapped data for this value.
-   * @return The wrapped data.
-   */
-  public Object getValue() {
-    return value;
-  }
-
-  /**
-   * {@inheritDoc}
-   * Override this if a tagged string.
-   */
-  public SimpleLiteral getLang() throws QueryException {
-    return SimpleLiteral.EMPTY;
-  }
-
-  /** {@inheritDoc} */
-  public boolean isBlank() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean isIRI() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean isURI() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean isLiteral() { return true; }
-
-  /** {@inheritDoc} */
-  public boolean sameTerm(RDFTerm v) throws QueryException {
-    if (!v.isLiteral()) return false;
-    return equalLiteralTypes((ValueLiteral)v) && getValue().equals(v.getValue());
-  }
-
-  /**
-   * {@inheritDoc}
-   * This method will only return <code>true</code> when the elements are identical.
-   * Since this object is a literal, then an incorrect comparison will throw an exception.
-   * {@link http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal}
-   * <em>produces a type error if the arguments are both literal but are not the same RDF term</em>
-   */
-  public boolean equals(RDFTerm v) throws QueryException {
-    if (!v.isLiteral()) return false;
-    // compare types, and then check values
-    if (equalLiteralTypes((ValueLiteral)v) && getValue().equals(v.getValue())) return true;
-    throw new QueryException("Type Error: Terms are not equal");
-  }
-  
-  /**
-   * {@inheritDoc}
-   * Not the inverse of #equals().  This method returns true when the elements connot be determined
-   * to be equal.
-   */
-  public boolean notEquals(RDFTerm v) throws QueryException {
-    try {
-      return !equals(v);
-    } catch (QueryException qe) {
-      return true;
-    }
-  }
-
-  /**
-   * Compares the type of this object to the type of another object. This takes into account
-   * that Simple Literals claim to have a string type, when they have no type at all.
-   * @param vl The object to test.
-   * @return <code>true</code> if the types are exactly the same. If both types are strings,
-   *   then both objects have to be typed literals, or untyped literals.
-   * @throws QueryException If there is an error accessing the type data.
-   */
-  private boolean equalLiteralTypes(ValueLiteral vl) throws QueryException {
-    IRI opType = vl.getType();
-    IRI thisType = getType();
-    assert opType != null && thisType != null;
-    // if the types differ, then not equal
-    if (!opType.equals(thisType)) return false;
-    // types are the same. If they are not strings, then definitely equal
-    if (!opType.equals(SimpleLiteral.STRING_TYPE)) return true;
-    // both types are strings. Only true if the other object is not a simple literal
-    return !vl.isSimple();
-  }
-
-  /**
-   * Extended numerical comparison function. Currently unused.
-   * @param v The term to compare against.
-   * @return <code>true</code> if this compares against v with semantic equivalence, regardless of lexical equivalence
-   * @throws QueryException Thrown when a value cannot be resolved, or if the types are no numbers.
-   */
-  @SuppressWarnings("unused")
-  private boolean numberCompare(RDFTerm v) throws QueryException {
-    if (!(value instanceof Number) || !(v.getValue() instanceof Number)) throw new QueryException("Terms are not equal");
-    return compare(value, v) == 0;
-  }
-
-  /**
-   * Type-based switching to handle comparison of things that may not be directly comparable.
-   * @param left The first thing to compare
-   * @param right The second thing to compare
-   * @return -1 if left<right, +1 if left>right, and 0 if left=right
-   * @throws QueryException The data could not be compared.
-   */
-  protected int compare(Object left, Object right) throws QueryException {
-    DataCompare cmpFn = typeMap.get(left.getClass());
-    if (cmpFn == null) throw new QueryException("Type Error: Cannot compare a " + left.getClass() + " to a " + right.getClass());
-    return cmpFn.compare(left, right);
-  }
-
-  /** Map of types to the functions used to compare those types */
-  protected static Map<Class<? extends Comparable<?>>,DataCompare> typeMap = new HashMap<Class<? extends Comparable<?>>,DataCompare>();
-
-  static {
-    typeMap.put(String.class, new StringCompare());
-    typeMap.put(Date.class, new DateCompare());
-    typeMap.put(Boolean.class, new BooleanCompare());
-    typeMap.put(Float.class, new FloatCompare());
-    typeMap.put(Double.class, new DoubleCompare());
-    typeMap.put(Long.class, new DecimalCompare());
-    typeMap.put(Integer.class, new DecimalCompare());
-    typeMap.put(Short.class, new DecimalCompare());
-    typeMap.put(Byte.class, new DecimalCompare());
-  }
-
-  /** Defines a function for comparing objects of arbitrary type */
-  protected interface DataCompare {
-    /**
-     * Comparison method used for any kind of type that might be compared.
-     * @param left The left hand side of the comparison. This must be of the correct type for the class.
-     * @param right The right hand side of the comparison. This should be tested for type compatibility with the left parameter
-     * @return -1 if left<right, 1 if left>right, and 0 if left==right
-     * @throws QueryException Due to an error in resolution of the values to be compared
-     */
-    int compare(Object left, Object right) throws QueryException;
-    /**
-     * Creates a new ValueLiteral compatible with this comparison type, from given data
-     * @param data The data in the correct native {@link java.lang.Class} to be converted.
-     * @return A new literal containing the data.
-     */
-    ValueLiteral newLiteral(Object data);
-  }
-
-  /** Implements string comparisons */
-  private static class StringCompare implements DataCompare {
-    public int compare(Object left, Object right) throws QueryException {
-      if (!(right instanceof String)) throw new QueryException("Type Error: Cannot compare a String to a: " + right.getClass());
-      return ((String)left).compareTo((String)right);
-    }
-    public ValueLiteral newLiteral(Object data) { return new TypedLiteral((String)data, SimpleLiteral.STRING_TYPE.getValue()); }
-  }
-
-  /** Implements string comparisons */
-  private static class DateCompare implements DataCompare {
-    public int compare(Object left, Object right) throws QueryException {
-      if (!(right instanceof Date)) throw new QueryException("Type Error: Cannot compare a Date to a: " + right.getClass());
-      return ((Date)left).compareTo((Date)right);
-    }
-    public ValueLiteral newLiteral(Object data) { return new DateTime((Date)data); }
-  }
-
-  /** Implements boolean comparisons */
-  private static class BooleanCompare implements DataCompare {
-    public int compare(Object left, Object right) throws QueryException {
-      if (!(right instanceof Boolean)) throw new QueryException("Type Error: Cannot compare a boolean to a: " + right.getClass());
-      return ((Boolean)left).compareTo((Boolean)right);
-    }
-    public ValueLiteral newLiteral(Object data) { return new Bool((Boolean)data); }
-  }
-
-  /** Implements floating point comparisons, or double comparisons if the rhs parameter is a double */
-  private static class FloatCompare implements DataCompare {
-    public int compare(Object left, Object right) throws QueryException {
-      Float fleft = (Float)left;
-      if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a float to a: " + right.getClass());
-      // if right has more precision, then promote lfloat, and compare the other way around
-      if (right instanceof Double) return -((Double)right).compareTo(fleft.doubleValue());
-      return fleft.compareTo(((Number)right).floatValue());
-    }
-    public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Float)data); }
-  }
-
-  /** Implements double precision floating point comparisons */
-  private static class DoubleCompare implements DataCompare {
-    public int compare(Object left, Object right) throws QueryException {
-      if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a double to a: " + right.getClass());
-      return ((Double)left).compareTo(((Number)right).doubleValue());
-    }
-    public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Double)data); }
-  }
-
-  /** Implements integer comparisons */
-  private static class DecimalCompare implements DataCompare {
-    public int compare(Object left, Object right) throws QueryException {
-      if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a decimal number to a: " + right.getClass());
-      Long lleft = ((Number)left).longValue();
-      return lleft.compareTo(((Number)right).longValue());
-    }
-    public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Number)data); }
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/AbstractComparableLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,240 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * Basic common representation of literals.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public abstract class AbstractComparableLiteral extends AbstractComparable implements ValueLiteral {
+
+  /** The wrapped value */
+  Object value;
+
+  /**
+   * Creates a value
+   * @param value The value to use
+   */
+  public AbstractComparableLiteral(Object value) {
+    this.value = value;
+  }
+
+  /**
+   * Returns the wrapped data for this value.
+   * @return The wrapped data.
+   */
+  public Object getValue() {
+    return value;
+  }
+
+  /**
+   * {@inheritDoc}
+   * Override this if a tagged string.
+   */
+  public SimpleLiteral getLang() throws QueryException {
+    return SimpleLiteral.EMPTY;
+  }
+
+  /** {@inheritDoc} */
+  public boolean isBlank() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean isIRI() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean isURI() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean isLiteral() { return true; }
+
+  /** {@inheritDoc} */
+  public boolean sameTerm(RDFTerm v) throws QueryException {
+    if (!v.isLiteral()) return false;
+    return equalLiteralTypes((ValueLiteral)v) && getValue().equals(v.getValue());
+  }
+
+  /**
+   * {@inheritDoc}
+   * This method will only return <code>true</code> when the elements are identical.
+   * Since this object is a literal, then an incorrect comparison will throw an exception.
+   * {@link http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal}
+   * <em>produces a type error if the arguments are both literal but are not the same RDF term</em>
+   */
+  public boolean equals(RDFTerm v) throws QueryException {
+    if (!v.isLiteral()) return false;
+    // compare types, and then check values
+    if (equalLiteralTypes((ValueLiteral)v) && getValue().equals(v.getValue())) return true;
+    throw new QueryException("Type Error: Terms are not equal");
+  }
+  
+  /**
+   * {@inheritDoc}
+   * Not the inverse of #equals().  This method returns true when the elements connot be determined
+   * to be equal.
+   */
+  public boolean notEquals(RDFTerm v) throws QueryException {
+    try {
+      return !equals(v);
+    } catch (QueryException qe) {
+      return true;
+    }
+  }
+
+  /**
+   * Compares the type of this object to the type of another object. This takes into account
+   * that Simple Literals claim to have a string type, when they have no type at all.
+   * @param vl The object to test.
+   * @return <code>true</code> if the types are exactly the same. If both types are strings,
+   *   then both objects have to be typed literals, or untyped literals.
+   * @throws QueryException If there is an error accessing the type data.
+   */
+  private boolean equalLiteralTypes(ValueLiteral vl) throws QueryException {
+    IRI opType = vl.getType();
+    IRI thisType = getType();
+    assert opType != null && thisType != null;
+    // if the types differ, then not equal
+    if (!opType.equals(thisType)) return false;
+    // types are the same. If they are not strings, then definitely equal
+    if (!opType.equals(SimpleLiteral.STRING_TYPE)) return true;
+    // both types are strings. Only true if the other object is not a simple literal
+    return !vl.isSimple();
+  }
+
+  /**
+   * Extended numerical comparison function. Currently unused.
+   * @param v The term to compare against.
+   * @return <code>true</code> if this compares against v with semantic equivalence, regardless of lexical equivalence
+   * @throws QueryException Thrown when a value cannot be resolved, or if the types are no numbers.
+   */
+  @SuppressWarnings("unused")
+  private boolean numberCompare(RDFTerm v) throws QueryException {
+    if (!(value instanceof Number) || !(v.getValue() instanceof Number)) throw new QueryException("Terms are not equal");
+    return compare(value, v) == 0;
+  }
+
+  /**
+   * Type-based switching to handle comparison of things that may not be directly comparable.
+   * @param left The first thing to compare
+   * @param right The second thing to compare
+   * @return -1 if left<right, +1 if left>right, and 0 if left=right
+   * @throws QueryException The data could not be compared.
+   */
+  protected int compare(Object left, Object right) throws QueryException {
+    DataCompare cmpFn = typeMap.get(left.getClass());
+    if (cmpFn == null) throw new QueryException("Type Error: Cannot compare a " + left.getClass() + " to a " + right.getClass());
+    return cmpFn.compare(left, right);
+  }
+
+  /** Map of types to the functions used to compare those types */
+  protected static Map<Class<? extends Comparable<?>>,DataCompare> typeMap = new HashMap<Class<? extends Comparable<?>>,DataCompare>();
+
+  static {
+    typeMap.put(String.class, new StringCompare());
+    typeMap.put(Date.class, new DateCompare());
+    typeMap.put(Boolean.class, new BooleanCompare());
+    typeMap.put(Float.class, new FloatCompare());
+    typeMap.put(Double.class, new DoubleCompare());
+    typeMap.put(Long.class, new DecimalCompare());
+    typeMap.put(Integer.class, new DecimalCompare());
+    typeMap.put(Short.class, new DecimalCompare());
+    typeMap.put(Byte.class, new DecimalCompare());
+  }
+
+  /** Defines a function for comparing objects of arbitrary type */
+  protected interface DataCompare {
+    /**
+     * Comparison method used for any kind of type that might be compared.
+     * @param left The left hand side of the comparison. This must be of the correct type for the class.
+     * @param right The right hand side of the comparison. This should be tested for type compatibility with the left parameter
+     * @return -1 if left<right, 1 if left>right, and 0 if left==right
+     * @throws QueryException Due to an error in resolution of the values to be compared
+     */
+    int compare(Object left, Object right) throws QueryException;
+    /**
+     * Creates a new ValueLiteral compatible with this comparison type, from given data
+     * @param data The data in the correct native {@link java.lang.Class} to be converted.
+     * @return A new literal containing the data.
+     */
+    ValueLiteral newLiteral(Object data);
+  }
+
+  /** Implements string comparisons */
+  private static class StringCompare implements DataCompare {
+    public int compare(Object left, Object right) throws QueryException {
+      if (!(right instanceof String)) throw new QueryException("Type Error: Cannot compare a String to a: " + right.getClass());
+      return ((String)left).compareTo((String)right);
+    }
+    public ValueLiteral newLiteral(Object data) { return new TypedLiteral((String)data, SimpleLiteral.STRING_TYPE.getValue()); }
+  }
+
+  /** Implements string comparisons */
+  private static class DateCompare implements DataCompare {
+    public int compare(Object left, Object right) throws QueryException {
+      if (!(right instanceof Date)) throw new QueryException("Type Error: Cannot compare a Date to a: " + right.getClass());
+      return ((Date)left).compareTo((Date)right);
+    }
+    public ValueLiteral newLiteral(Object data) { return new DateTime((Date)data); }
+  }
+
+  /** Implements boolean comparisons */
+  private static class BooleanCompare implements DataCompare {
+    public int compare(Object left, Object right) throws QueryException {
+      if (!(right instanceof Boolean)) throw new QueryException("Type Error: Cannot compare a boolean to a: " + right.getClass());
+      return ((Boolean)left).compareTo((Boolean)right);
+    }
+    public ValueLiteral newLiteral(Object data) { return new Bool((Boolean)data); }
+  }
+
+  /** Implements floating point comparisons, or double comparisons if the rhs parameter is a double */
+  private static class FloatCompare implements DataCompare {
+    public int compare(Object left, Object right) throws QueryException {
+      Float fleft = (Float)left;
+      if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a float to a: " + right.getClass());
+      // if right has more precision, then promote lfloat, and compare the other way around
+      if (right instanceof Double) return -((Double)right).compareTo(fleft.doubleValue());
+      return fleft.compareTo(((Number)right).floatValue());
+    }
+    public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Float)data); }
+  }
+
+  /** Implements double precision floating point comparisons */
+  private static class DoubleCompare implements DataCompare {
+    public int compare(Object left, Object right) throws QueryException {
+      if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a double to a: " + right.getClass());
+      return ((Double)left).compareTo(((Number)right).doubleValue());
+    }
+    public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Double)data); }
+  }
+
+  /** Implements integer comparisons */
+  private static class DecimalCompare implements DataCompare {
+    public int compare(Object left, Object right) throws QueryException {
+      if (!(right instanceof Number)) throw new QueryException("Type Error: Cannot compare a decimal number to a: " + right.getClass());
+      Long lleft = ((Number)left).longValue();
+      return lleft.compareTo(((Number)right).longValue());
+    }
+    public ValueLiteral newLiteral(Object data) { return new NumericLiteral((Number)data); }
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,81 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.jrdf.graph.BlankNode;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.ContextOwner;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * A blank node.
- *
- * @created Mar 12, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class BlankNodeValue implements RDFTerm {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -3419477428127742326L;
-
-  /** The wrapped blank node */
-  private final BlankNode node;
-
-  /**
-   * Creates the value to wrap the string
-   * @param s The string to wrap
-   */
-  public BlankNodeValue(BlankNode node) {
-    this.node = node;
-  }
-
-  /** {@inheritDoc} */
-  public BlankNode getValue() {
-    return node;
-  }
-
-  /** {@inheritDoc} */
-  public boolean equals(RDFTerm v) throws QueryException {
-    return v.isBlank() && node.equals(v.getValue());
-  }
-
-  /** {@inheritDoc} */
-  public boolean notEquals(RDFTerm v) throws QueryException {
-    return !equals(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean sameTerm(RDFTerm v) throws QueryException {
-    return equals(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean isBlank() { return true; }
-
-  /** {@inheritDoc} */
-  public boolean isIRI() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean isLiteral() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean isURI() { return false; }
-
-  /** This value does not need a context */
-  public ContextOwner getContextOwner() {  return null; }
-
-  /** This value does not need a context */
-  public void setContextOwner(ContextOwner owner) { }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValue.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,81 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.jrdf.graph.BlankNode;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * A blank node.
+ *
+ * @created Mar 12, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class BlankNodeValue implements RDFTerm {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -3419477428127742326L;
+
+  /** The wrapped blank node */
+  private final BlankNode node;
+
+  /**
+   * Creates the value to wrap the string
+   * @param s The string to wrap
+   */
+  public BlankNodeValue(BlankNode node) {
+    this.node = node;
+  }
+
+  /** {@inheritDoc} */
+  public BlankNode getValue() {
+    return node;
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(RDFTerm v) throws QueryException {
+    return v.isBlank() && node.equals(v.getValue());
+  }
+
+  /** {@inheritDoc} */
+  public boolean notEquals(RDFTerm v) throws QueryException {
+    return !equals(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean sameTerm(RDFTerm v) throws QueryException {
+    return equals(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean isBlank() { return true; }
+
+  /** {@inheritDoc} */
+  public boolean isIRI() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean isLiteral() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean isURI() { return false; }
+
+  /** This value does not need a context */
+  public ContextOwner getContextOwner() {  return null; }
+
+  /** This value does not need a context */
+  public void setContextOwner(ContextOwner owner) { }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,74 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.jrdf.graph.BlankNode;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the BlankNode value class.
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class BlankNodeValueUnitTest extends TestCase {
-
-  private BlankNode b = new BlankNodeImpl();
-  
-  private BlankNode b2 = new BlankNodeImpl();
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public BlankNodeValueUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new BlankNodeValueUnitTest("testValues"));
-    suite.addTest(new BlankNodeValueUnitTest("testProperties"));
-    return suite;
-  }
-
-
-  public void testValues() throws Exception {
-    BlankNodeValue bv = new BlankNodeValue(b);
-    assertEquals(b, bv.getValue());
-    assertFalse(b2.equals(bv.getValue()));
-    BlankNodeValue bv2 = new BlankNodeValue(b2);
-    assertTrue(bv.equals(bv));
-    assertTrue(bv.notEquals(bv2));
-    assertFalse(bv.notEquals(bv));
-    assertFalse(bv.equals(bv2));
-  }
-
-  public void testProperties() throws Exception {
-    BlankNodeValue bv = new BlankNodeValue(b);
-    assertTrue(bv.isBlank());
-    assertFalse(bv.isIRI());
-    assertFalse(bv.isLiteral());
-    assertFalse(bv.isURI());
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/BlankNodeValueUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,74 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.jrdf.graph.BlankNode;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the BlankNode value class.
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class BlankNodeValueUnitTest extends TestCase {
+
+  private BlankNode b = new BlankNodeImpl();
+  
+  private BlankNode b2 = new BlankNodeImpl();
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public BlankNodeValueUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new BlankNodeValueUnitTest("testValues"));
+    suite.addTest(new BlankNodeValueUnitTest("testProperties"));
+    return suite;
+  }
+
+
+  public void testValues() throws Exception {
+    BlankNodeValue bv = new BlankNodeValue(b);
+    assertEquals(b, bv.getValue());
+    assertFalse(b2.equals(bv.getValue()));
+    BlankNodeValue bv2 = new BlankNodeValue(b2);
+    assertTrue(bv.equals(bv));
+    assertTrue(bv.notEquals(bv2));
+    assertFalse(bv.notEquals(bv));
+    assertFalse(bv.equals(bv2));
+  }
+
+  public void testProperties() throws Exception {
+    BlankNodeValue bv = new BlankNodeValue(b);
+    assertTrue(bv.isBlank());
+    assertFalse(bv.isIRI());
+    assertFalse(bv.isLiteral());
+    assertFalse(bv.isURI());
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Bool.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,56 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-
-/**
- * A boolean value.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class Bool extends TypedLiteral {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -1139308134744630943L;
-
-  /** xsd:boolean */
-  public static final URI TYPE = URI.create(XSD_NS + "boolean");
-
-  /** xsd:boolean as an IRI */
-  public static final IRI IRI_TYPE = new IRI(URI.create(XSD_NS + "boolean"));
-
-  /** A single boolean value for true */
-  public static final Bool TRUE = new Bool(Boolean.TRUE);
-
-  /** A single boolean value for false */
-  public static final Bool FALSE = new Bool(Boolean.FALSE);
-
-  /**
-   * Creates the value to wrap the boolean
-   * @param n The boolean to wrap
-   */
-  public Bool(Boolean b) {
-    super(b, TYPE);
-  }
-
-  /** {@inheritDoc} */
-  public boolean test(Context context) throws QueryException {
-    return (Boolean)value;
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Bool.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/Bool.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,56 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+
+/**
+ * A boolean value.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Bool extends TypedLiteral {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -1139308134744630943L;
+
+  /** xsd:boolean */
+  public static final URI TYPE = URI.create(XSD_NS + "boolean");
+
+  /** xsd:boolean as an IRI */
+  public static final IRI IRI_TYPE = new IRI(URI.create(XSD_NS + "boolean"));
+
+  /** A single boolean value for true */
+  public static final Bool TRUE = new Bool(Boolean.TRUE);
+
+  /** A single boolean value for false */
+  public static final Bool FALSE = new Bool(Boolean.FALSE);
+
+  /**
+   * Creates the value to wrap the boolean
+   * @param n The boolean to wrap
+   */
+  public Bool(Boolean b) {
+    super(b, TYPE);
+  }
+
+  /** {@inheritDoc} */
+  public boolean test(Context context) throws QueryException {
+    return (Boolean)value;
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,82 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.TestContext;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the Bool literal class.
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class BoolUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public BoolUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new BoolUnitTest("testValues"));
-    suite.addTest(new BoolUnitTest("testFilter"));
-    suite.addTest(new BoolUnitTest("testType"));
-    suite.addTest(new BoolUnitTest("testProperties"));
-    return suite;
-  }
-
-
-  public void testValues() throws Exception {
-    Bool b = new Bool(true);
-    assertTrue((Boolean)b.getValue());
-    b = new Bool(false);
-    assertFalse((Boolean)b.getValue());
-  }
-
-  public void testFilter() throws Exception {
-    Context c = new TestContext();
-    Bool b = new Bool(true);
-    assertTrue(b.test(c));
-    b = new Bool(false);
-    assertFalse(b.test(c));
-  }
-
-  public void testType() throws Exception {
-    Bool b = new Bool(true);
-    assertTrue(b.getType().isIRI());
-    assertEquals(b.getType().getValue(), Bool.TYPE);
-  }
-
-  public void testProperties() throws Exception {
-    Bool b = new Bool(true);
-    assertFalse(b.isBlank());
-    assertFalse(b.isIRI());
-    assertTrue(b.isLiteral());
-    assertFalse(b.isURI());
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/BoolUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,82 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.TestContext;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the Bool literal class.
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class BoolUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public BoolUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new BoolUnitTest("testValues"));
+    suite.addTest(new BoolUnitTest("testFilter"));
+    suite.addTest(new BoolUnitTest("testType"));
+    suite.addTest(new BoolUnitTest("testProperties"));
+    return suite;
+  }
+
+
+  public void testValues() throws Exception {
+    Bool b = new Bool(true);
+    assertTrue((Boolean)b.getValue());
+    b = new Bool(false);
+    assertFalse((Boolean)b.getValue());
+  }
+
+  public void testFilter() throws Exception {
+    Context c = new TestContext();
+    Bool b = new Bool(true);
+    assertTrue(b.test(c));
+    b = new Bool(false);
+    assertFalse(b.test(c));
+  }
+
+  public void testType() throws Exception {
+    Bool b = new Bool(true);
+    assertTrue(b.getType().isIRI());
+    assertEquals(b.getType().getValue(), Bool.TYPE);
+  }
+
+  public void testProperties() throws Exception {
+    Bool b = new Bool(true);
+    assertFalse(b.isBlank());
+    assertFalse(b.isIRI());
+    assertTrue(b.isLiteral());
+    assertFalse(b.isURI());
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,71 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Filter;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * Represents expressions that can appear in a comparison expression, used by filters
- *
- * @created Mar 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface ComparableExpression extends RDFTerm, Filter {
-
-  /**
-   * Returns the data represented by this expression.
-   * @return The represented data.
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public Object getValue() throws QueryException;
-
-  /**
-   * A value based magnitude test.
-   * @param v The object to compare to
-   * @return <code>true</code> iff v has a greater value than the current object.
-   * @throws QueryException Resolving the data for this value leads to an error,
-   *                        or the types are incompatible.
-   */
-  public boolean lessThan(ComparableExpression v) throws QueryException;
-
-  /**
-   * A value based magnitude test.
-   * @param v The object to compare to
-   * @return <code>true</code> iff v has a lesser value than the current object.
-   * @throws QueryException Resolving the data for this value leads to an error,
-   *                        or the types are incompatible.
-   */
-  public boolean greaterThan(ComparableExpression v) throws QueryException;
-  
-  /**
-   * A value based magnitude test.
-   * @param v The object to compare to
-   * @return <code>false</code> iff v has a lesser value than the current object.
-   * @throws QueryException Resolving the data for this value leads to an error,
-   *                        or the types are incompatible.
-   */
-  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException;
-  
-  /**
-   * A value based magnitude test.
-   * @param v The object to compare to
-   * @return <code>false</code> iff v has a greater value than the current object.
-   * @throws QueryException Resolving the data for this value leads to an error,
-   *                        or the types are incompatible.
-   */
-  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException;
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ComparableExpression.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,71 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * Represents expressions that can appear in a comparison expression, used by filters
+ *
+ * @created Mar 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface ComparableExpression extends RDFTerm, Filter {
+
+  /**
+   * Returns the data represented by this expression.
+   * @return The represented data.
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public Object getValue() throws QueryException;
+
+  /**
+   * A value based magnitude test.
+   * @param v The object to compare to
+   * @return <code>true</code> iff v has a greater value than the current object.
+   * @throws QueryException Resolving the data for this value leads to an error,
+   *                        or the types are incompatible.
+   */
+  public boolean lessThan(ComparableExpression v) throws QueryException;
+
+  /**
+   * A value based magnitude test.
+   * @param v The object to compare to
+   * @return <code>true</code> iff v has a lesser value than the current object.
+   * @throws QueryException Resolving the data for this value leads to an error,
+   *                        or the types are incompatible.
+   */
+  public boolean greaterThan(ComparableExpression v) throws QueryException;
+  
+  /**
+   * A value based magnitude test.
+   * @param v The object to compare to
+   * @return <code>false</code> iff v has a lesser value than the current object.
+   * @throws QueryException Resolving the data for this value leads to an error,
+   *                        or the types are incompatible.
+   */
+  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException;
+  
+  /**
+   * A value based magnitude test.
+   * @param v The object to compare to
+   * @return <code>false</code> iff v has a greater value than the current object.
+   * @throws QueryException Resolving the data for this value leads to an error,
+   *                        or the types are incompatible.
+   */
+  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException;
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,89 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.RDFTerm;
-
-/**
- * Represents a datatype() function that accesses the datatype on a literal.
- * This operation is made to look like an IRI.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class DataTypeFn extends AbstractAccessorFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 5326464040907090543L;
-
-  /**
-   * Create a new language extractor function.
-   * @param operand The operand for the function.
-   */
-  public DataTypeFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isLiteral() */
-  public boolean isLiteral() throws QueryException {
-    return false;
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isIri() */
-  public boolean isIRI() throws QueryException {
-    return true;
-  }
-
-  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#getLexical() */
-  public String getLexical() throws QueryException {
-    throw new QueryException("Invalid to get lexical information on an IRI.");
-  }
-
-  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#getLang() */
-  public SimpleLiteral getLang() throws QueryException {
-    throw new QueryException("Invalid to get a language on an IRI.");
-  }
-
-  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#getType() */
-  public IRI getType() throws QueryException {
-    throw new QueryException("Invalid to get a type IRI on an IRI.");
-  }
-
-  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#test(org.mulgara.query.filter.Context) */
-  public boolean test(Context context) throws QueryException {
-    throw new QueryException("Invalid to get an effective boolean value on an IRI.");
-  }
-
-  /**
-   * Get the type from the underlying operand
-   * @return The operands type IRI
-   * @throws QueryException If there was an error resolving the operand 
-   */
-  protected RDFTerm resolve() throws QueryException {
-    if (!operand.isLiteral()) throw new QueryException("Disallowed type in DATATYPE function. Expected a Literal. Got a : " + operand.getClass().getSimpleName());
-    return ((ValueLiteral)operand).getType();
-  }
-
-  /**
-   * The return value of this class is not comparable, so always throw an exception.
-   * @return never returns a value.
-   * @throws QueryException To indicate that this class cannot be compared.
-   */
-  protected ComparableExpression resolveComparable() throws QueryException {
-    throw new QueryException("Type error: datatypes are IRIs which cannot be compared for anything but equality");
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,89 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.RDFTerm;
+
+/**
+ * Represents a datatype() function that accesses the datatype on a literal.
+ * This operation is made to look like an IRI.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DataTypeFn extends AbstractAccessorFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 5326464040907090543L;
+
+  /**
+   * Create a new language extractor function.
+   * @param operand The operand for the function.
+   */
+  public DataTypeFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isLiteral() */
+  public boolean isLiteral() throws QueryException {
+    return false;
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isIri() */
+  public boolean isIRI() throws QueryException {
+    return true;
+  }
+
+  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#getLexical() */
+  public String getLexical() throws QueryException {
+    throw new QueryException("Invalid to get lexical information on an IRI.");
+  }
+
+  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#getLang() */
+  public SimpleLiteral getLang() throws QueryException {
+    throw new QueryException("Invalid to get a language on an IRI.");
+  }
+
+  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#getType() */
+  public IRI getType() throws QueryException {
+    throw new QueryException("Invalid to get a type IRI on an IRI.");
+  }
+
+  /** @see org.mulgara.query.filter.value.AbstractAccessorFn#test(org.mulgara.query.filter.Context) */
+  public boolean test(Context context) throws QueryException {
+    throw new QueryException("Invalid to get an effective boolean value on an IRI.");
+  }
+
+  /**
+   * Get the type from the underlying operand
+   * @return The operands type IRI
+   * @throws QueryException If there was an error resolving the operand 
+   */
+  protected RDFTerm resolve() throws QueryException {
+    if (!operand.isLiteral()) throw new QueryException("Disallowed type in DATATYPE function. Expected a Literal. Got a : " + operand.getClass().getSimpleName());
+    return ((ValueLiteral)operand).getType();
+  }
+
+  /**
+   * The return value of this class is not comparable, so always throw an exception.
+   * @return never returns a value.
+   * @throws QueryException To indicate that this class cannot be compared.
+   */
+  protected ComparableExpression resolveComparable() throws QueryException {
+    throw new QueryException("Type error: datatypes are IRIs which cannot be compared for anything but equality");
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,155 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import java.net.URI;
-
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the data type function class.
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class DataTypeFnUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public DataTypeFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new DataTypeFnUnitTest("testValues"));
-    suite.addTest(new DataTypeFnUnitTest("testVar"));
-    return suite;
-  }
-
-
-  public void testValues() throws Exception {
-    String str = "test";
-    URI t = URI.create(XSD_NS + "string");
-    TypedLiteral l = (TypedLiteral) TypedLiteral.newLiteral(str, t, null);
-    DataTypeFn fn = new DataTypeFn(l);
-    IRI i = new IRI(t);
-    assertTrue(fn.equals(i));
-    assertFalse(fn.isBlank());
-    assertTrue(fn.isIRI());
-    assertFalse(fn.isLiteral());
-    assertTrue(fn.isURI());
-    try {
-      fn.getType();
-      fail("Should not be able to get a type for an IRI");
-    } catch (QueryException qe) { }
-    try {
-      fn.getLang();
-      fail("Should not be able to get a lang for an IRI");
-    } catch (QueryException qe) { }
-
-    l = (TypedLiteral)TypedLiteral.newLiteral(str);
-    fn = new DataTypeFn(l);
-    i = new IRI(t);
-    assertTrue(fn.equals(i));
-    assertFalse(fn.isBlank());
-    assertTrue(fn.isIRI());
-    assertFalse(fn.isLiteral());
-    assertTrue(fn.isURI());
-
-    String s2 = "foobar";
-    URI t2 = URI.create(XSD_NS + "foo:bar");
-    l = (TypedLiteral)TypedLiteral.newLiteral(s2, t2, null);
-    fn = new DataTypeFn(l);
-    i = new IRI(t2);
-    assertTrue(fn.equals(i));
-    assertFalse(fn.isBlank());
-    assertTrue(fn.isIRI());
-    assertFalse(fn.isLiteral());
-    assertTrue(fn.isURI());
-
-    Long v = Long.valueOf(5);
-    l = (TypedLiteral)TypedLiteral.newLiteral(v);
-    fn = new DataTypeFn(l);
-    i = new IRI(URI.create(XSD_NS + "long"));
-    assertTrue(fn.equals(i));
-  }
-
-  public void testVar() throws Exception {
-    String vName = "foo";
-    Var v = new Var(vName);
-    DataTypeFn fn = new DataTypeFn(v);
-    
-    URI xsdString = URI.create(XSD_NS + "string");
-    URI xsdDouble = URI.create(XSD_NS + "double");
-    URI fooBar = URI.create("foo:bar");
-    Node[][] rows = {
-      new Node[] {new LiteralImpl("foo")},
-      new Node[] {new LiteralImpl("foo", xsdString)},
-      new Node[] {new LiteralImpl("5.0", xsdDouble)},
-      new Node[] {new LiteralImpl("foo", "en")},
-      new Node[] {new LiteralImpl("foo", fooBar)},
-      new Node[] {new URIReferenceImpl(fooBar)},
-      new Node[] {new BlankNodeImpl()},
-    };
-    TestContext c = new TestContext(new String[] {vName}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertEquals(xsdString, fn.getValue());
-    assertTrue(c.next());
-    assertEquals(xsdString, fn.getValue());
-    assertTrue(c.next());
-    assertEquals(xsdDouble, fn.getValue());
-    assertTrue(c.next());
-    assertEquals(SimpleLiteral.STRING_TYPE.getValue(), fn.getValue());
-    assertTrue(c.next());
-    assertEquals(fooBar, fn.getValue());
-    assertTrue(c.next());
-    try {
-      Object o = fn.getValue();
-      fail("Got the type of a URI reference: " + o);
-    } catch (QueryException qe) { }
-    assertTrue(c.next());
-    try {
-      Object o = fn.getValue();
-      fail("Got the type of a Blank Node: " + o);
-    } catch (QueryException qe) { }
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DataTypeFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,155 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import java.net.URI;
+
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the data type function class.
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DataTypeFnUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public DataTypeFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new DataTypeFnUnitTest("testValues"));
+    suite.addTest(new DataTypeFnUnitTest("testVar"));
+    return suite;
+  }
+
+
+  public void testValues() throws Exception {
+    String str = "test";
+    URI t = URI.create(XSD_NS + "string");
+    TypedLiteral l = (TypedLiteral) TypedLiteral.newLiteral(str, t, null);
+    DataTypeFn fn = new DataTypeFn(l);
+    IRI i = new IRI(t);
+    assertTrue(fn.equals(i));
+    assertFalse(fn.isBlank());
+    assertTrue(fn.isIRI());
+    assertFalse(fn.isLiteral());
+    assertTrue(fn.isURI());
+    try {
+      fn.getType();
+      fail("Should not be able to get a type for an IRI");
+    } catch (QueryException qe) { }
+    try {
+      fn.getLang();
+      fail("Should not be able to get a lang for an IRI");
+    } catch (QueryException qe) { }
+
+    l = (TypedLiteral)TypedLiteral.newLiteral(str);
+    fn = new DataTypeFn(l);
+    i = new IRI(t);
+    assertTrue(fn.equals(i));
+    assertFalse(fn.isBlank());
+    assertTrue(fn.isIRI());
+    assertFalse(fn.isLiteral());
+    assertTrue(fn.isURI());
+
+    String s2 = "foobar";
+    URI t2 = URI.create(XSD_NS + "foo:bar");
+    l = (TypedLiteral)TypedLiteral.newLiteral(s2, t2, null);
+    fn = new DataTypeFn(l);
+    i = new IRI(t2);
+    assertTrue(fn.equals(i));
+    assertFalse(fn.isBlank());
+    assertTrue(fn.isIRI());
+    assertFalse(fn.isLiteral());
+    assertTrue(fn.isURI());
+
+    Long v = Long.valueOf(5);
+    l = (TypedLiteral)TypedLiteral.newLiteral(v);
+    fn = new DataTypeFn(l);
+    i = new IRI(URI.create(XSD_NS + "long"));
+    assertTrue(fn.equals(i));
+  }
+
+  public void testVar() throws Exception {
+    String vName = "foo";
+    Var v = new Var(vName);
+    DataTypeFn fn = new DataTypeFn(v);
+    
+    URI xsdString = URI.create(XSD_NS + "string");
+    URI xsdDouble = URI.create(XSD_NS + "double");
+    URI fooBar = URI.create("foo:bar");
+    Node[][] rows = {
+      new Node[] {new LiteralImpl("foo")},
+      new Node[] {new LiteralImpl("foo", xsdString)},
+      new Node[] {new LiteralImpl("5.0", xsdDouble)},
+      new Node[] {new LiteralImpl("foo", "en")},
+      new Node[] {new LiteralImpl("foo", fooBar)},
+      new Node[] {new URIReferenceImpl(fooBar)},
+      new Node[] {new BlankNodeImpl()},
+    };
+    TestContext c = new TestContext(new String[] {vName}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertEquals(xsdString, fn.getValue());
+    assertTrue(c.next());
+    assertEquals(xsdString, fn.getValue());
+    assertTrue(c.next());
+    assertEquals(xsdDouble, fn.getValue());
+    assertTrue(c.next());
+    assertEquals(SimpleLiteral.STRING_TYPE.getValue(), fn.getValue());
+    assertTrue(c.next());
+    assertEquals(fooBar, fn.getValue());
+    assertTrue(c.next());
+    try {
+      Object o = fn.getValue();
+      fail("Got the type of a URI reference: " + o);
+    } catch (QueryException qe) { }
+    assertTrue(c.next());
+    try {
+      Object o = fn.getValue();
+      fail("Got the type of a Blank Node: " + o);
+    } catch (QueryException qe) { }
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,66 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-import java.util.Date;
-
-import javax.xml.datatype.DatatypeConfigurationException;
-import javax.xml.datatype.DatatypeFactory;
-import javax.xml.datatype.XMLGregorianCalendar;
-
-/**
- * A date value.
- *
- * @created Mar 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class DateTime extends TypedLiteral {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 7517437419033492738L;
-
-  /** xsd:dateTime */
-  public static final URI TYPE = URI.create(XSD_NS + "dateTime");
-
-  /** Singleton reference to the datatype factory for date parsers */
-  private static DatatypeFactory factory;
-  static {
-    try {
-      factory = DatatypeFactory.newInstance();
-    } catch (DatatypeConfigurationException e) {
-      throw new RuntimeException("Unable to initialize XML date parser");
-    }
-  }
-
-  /**
-   * Creates the date value
-   * @param value The date to wrap
-   */
-  public DateTime(java.util.Date value) {
-    super(value, TYPE);
-  }
-
-  /**
-   * Converts a lexical representation of an XSD date into a Date object.
-   * Note necessarily the most efficient way to handle this, but it has the
-   * advantage of simplicity and of using standard Java libraries.
-   * @param lexical The lexical form of the date.
-   * @return A {@link java.util.Date} for the represented date.
-   */
-  public static Date parseDate(String lexical) {
-    XMLGregorianCalendar cal = factory.newXMLGregorianCalendar(lexical);
-    return cal.toGregorianCalendar().getTime();
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTime.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,66 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+import java.util.Date;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+import javax.xml.datatype.XMLGregorianCalendar;
+
+/**
+ * A date value.
+ *
+ * @created Mar 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DateTime extends TypedLiteral {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 7517437419033492738L;
+
+  /** xsd:dateTime */
+  public static final URI TYPE = URI.create(XSD_NS + "dateTime");
+
+  /** Singleton reference to the datatype factory for date parsers */
+  private static DatatypeFactory factory;
+  static {
+    try {
+      factory = DatatypeFactory.newInstance();
+    } catch (DatatypeConfigurationException e) {
+      throw new RuntimeException("Unable to initialize XML date parser");
+    }
+  }
+
+  /**
+   * Creates the date value
+   * @param value The date to wrap
+   */
+  public DateTime(java.util.Date value) {
+    super(value, TYPE);
+  }
+
+  /**
+   * Converts a lexical representation of an XSD date into a Date object.
+   * Note necessarily the most efficient way to handle this, but it has the
+   * advantage of simplicity and of using standard Java libraries.
+   * @param lexical The lexical form of the date.
+   * @return A {@link java.util.Date} for the represented date.
+   */
+  public static Date parseDate(String lexical) {
+    XMLGregorianCalendar cal = factory.newXMLGregorianCalendar(lexical);
+    return cal.toGregorianCalendar().getTime();
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,87 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.util.Date;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.TestContext;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the DataTime literal class
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class DateTimeUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public DateTimeUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new DateTimeUnitTest("testValues"));
-    suite.addTest(new DateTimeUnitTest("testFilter"));
-    suite.addTest(new DateTimeUnitTest("testType"));
-    suite.addTest(new DateTimeUnitTest("testProperties"));
-    return suite;
-  }
-
-  public void testValues() throws Exception {
-    Date date = new Date();
-    DateTime dt = new DateTime(date);
-    assertEquals(dt.getValue(), date);
-    Date d2 = new Date(date.getTime() + 1);
-    assertFalse(d2.equals(dt.getValue()));
-  }
-
-  public void testFilter() throws Exception {
-    Context c = new TestContext();
-    DateTime dt = new DateTime(new Date());
-    try {
-      dt.test(c);
-      fail("DateTime effective boolean value should not return a value");
-    } catch (QueryException qe) { }
-  }
-
-  public void testType() throws Exception {
-    DateTime dt = new DateTime(new Date());
-    assertTrue(dt.getType().isIRI());
-    assertEquals(dt.getType().getValue(), DateTime.TYPE);
-  }
-
-
-  public void testProperties() throws Exception {
-    DateTime dt = new DateTime(new Date());
-    assertFalse(dt.isBlank());
-    assertFalse(dt.isIRI());
-    assertTrue(dt.isLiteral());
-    assertFalse(dt.isURI());
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/DateTimeUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,87 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.util.Date;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.TestContext;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the DataTime literal class
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class DateTimeUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public DateTimeUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new DateTimeUnitTest("testValues"));
+    suite.addTest(new DateTimeUnitTest("testFilter"));
+    suite.addTest(new DateTimeUnitTest("testType"));
+    suite.addTest(new DateTimeUnitTest("testProperties"));
+    return suite;
+  }
+
+  public void testValues() throws Exception {
+    Date date = new Date();
+    DateTime dt = new DateTime(date);
+    assertEquals(dt.getValue(), date);
+    Date d2 = new Date(date.getTime() + 1);
+    assertFalse(d2.equals(dt.getValue()));
+  }
+
+  public void testFilter() throws Exception {
+    Context c = new TestContext();
+    DateTime dt = new DateTime(new Date());
+    try {
+      dt.test(c);
+      fail("DateTime effective boolean value should not return a value");
+    } catch (QueryException qe) { }
+  }
+
+  public void testType() throws Exception {
+    DateTime dt = new DateTime(new Date());
+    assertTrue(dt.getType().isIRI());
+    assertEquals(dt.getType().getValue(), DateTime.TYPE);
+  }
+
+
+  public void testProperties() throws Exception {
+    DateTime dt = new DateTime(new Date());
+    assertFalse(dt.isBlank());
+    assertFalse(dt.isIRI());
+    assertTrue(dt.isLiteral());
+    assertFalse(dt.isURI());
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,132 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.RDFTerm;
-
-/**
- * Executes a function that isn't defined in these packages.
- *
- * @created Apr 22, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class ExternalFn extends AbstractAccessorFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 5748124115023875223L;
-
-  /** The logger */
-  private final static Logger logger = Logger.getLogger(ExternalFn.class.getName());
-
-  /** The function to be run. This will be mapped to a functor or reflection code. */
-  private IRI fn;
-
-  /** The arguments of the function. */
-  private RDFTerm[] operands; 
-
-  /**
-   * Create a new function instance.
-   * @param fn The function to run.
-   * @param operands The arguments of the function.
-   */
-  public ExternalFn(IRI fn, RDFTerm... operands) {
-    super(operands);
-  }
-
-  // The ValueLiteral interface
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
-   * @throws QueryException if this function does not resolve to a literal.
-   */
-  public String getLexical() throws QueryException {
-    RDFTerm result = resolve();
-    if (result.isLiteral()) return ((ValueLiteral)result).getLexical();
-    throw new QueryException("Not valid to ask the lexical form of a: " + result.getClass().getSimpleName());
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
-   * @throws QueryException if this function does not resolve to a literal.
-   */
-  public SimpleLiteral getLang() throws QueryException {
-    RDFTerm result = resolve();
-    if (result.isLiteral()) return ((ValueLiteral)result).getLang();
-    throw new QueryException("Not valid to ask the language of a: " + result.getClass().getSimpleName());
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getType()
-   * @throws QueryException if this function does not resolve to a literal.
-   */
-  public IRI getType() throws QueryException {
-    RDFTerm result = resolve();
-    if (result.isLiteral()) return ((ValueLiteral)result).getType();
-    throw new QueryException("Not valid to ask the type of a: " + result.getClass().getSimpleName());
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
-  public boolean isSimple() throws QueryException {
-    RDFTerm result = resolve();
-    if (result.isLiteral()) return ((ValueLiteral)result).isSimple();
-    throw new QueryException("Not valid to check if a non-literal is a simple literal: " + result.getClass().getSimpleName());
-  }
-
-  // The RDFTerm interface
-
-  /** @see org.mulgara.query.filter.RDFTerm#isBlank() */
-  public boolean isBlank() throws QueryException { return resolve().isBlank(); }
-
-  /** @see org.mulgara.query.filter.RDFTerm#isIRI() */
-  public boolean isIRI() throws QueryException { return resolve().isIRI(); }
-
-  /**
-   * {@inheritDoc}
-   * The operation of this method is depended on the context in which it was called.
-   * If it is called without a context owner, then this means it was called during
-   * Filter construction, and we want to indicate that it is valid to treat this as a literal.
-   * @return <code>true</code> if there is no context, or else it calls isLiteral on the resolved value.
-   */
-  public boolean isLiteral() throws QueryException {
-    return getContextOwner() == null ? true : resolve().isLiteral();
-  }
-
-
-  /**
-   * Resolve the value of the function.
-   * @return The resolution of the function
-   * @throws QueryException if the function does not resolve
-   * TODO: call the appropriate function. This just returns the boolean TRUE for the moment.
-   */
-  protected RDFTerm resolve() throws QueryException {
-    logger.warn("Attempting to execute an unsupported function: " + fn + "(" + resolveArgs() + ")");
-    return Bool.TRUE;
-  }
-
-  /**
-   * A utility function to create a list of arguments to be passed to the external function.
-   * @return A {@link List} of arbitrary objects to be passed as arguments to the external function.
-   * @throws QueryException If any of the arguments could not be resolved.
-   */
-  private List<Object> resolveArgs() throws QueryException {
-    List<Object> result = new ArrayList<Object>(operands.length);
-    for (int i = 0; i < operands.length; i++) result.add(operands[i].getValue());
-    return result;
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,132 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.RDFTerm;
+
+/**
+ * Executes a function that isn't defined in these packages.
+ *
+ * @created Apr 22, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class ExternalFn extends AbstractAccessorFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 5748124115023875223L;
+
+  /** The logger */
+  private final static Logger logger = Logger.getLogger(ExternalFn.class.getName());
+
+  /** The function to be run. This will be mapped to a functor or reflection code. */
+  private IRI fn;
+
+  /** The arguments of the function. */
+  private RDFTerm[] operands; 
+
+  /**
+   * Create a new function instance.
+   * @param fn The function to run.
+   * @param operands The arguments of the function.
+   */
+  public ExternalFn(IRI fn, RDFTerm... operands) {
+    super(operands);
+  }
+
+  // The ValueLiteral interface
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
+   * @throws QueryException if this function does not resolve to a literal.
+   */
+  public String getLexical() throws QueryException {
+    RDFTerm result = resolve();
+    if (result.isLiteral()) return ((ValueLiteral)result).getLexical();
+    throw new QueryException("Not valid to ask the lexical form of a: " + result.getClass().getSimpleName());
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
+   * @throws QueryException if this function does not resolve to a literal.
+   */
+  public SimpleLiteral getLang() throws QueryException {
+    RDFTerm result = resolve();
+    if (result.isLiteral()) return ((ValueLiteral)result).getLang();
+    throw new QueryException("Not valid to ask the language of a: " + result.getClass().getSimpleName());
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getType()
+   * @throws QueryException if this function does not resolve to a literal.
+   */
+  public IRI getType() throws QueryException {
+    RDFTerm result = resolve();
+    if (result.isLiteral()) return ((ValueLiteral)result).getType();
+    throw new QueryException("Not valid to ask the type of a: " + result.getClass().getSimpleName());
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
+  public boolean isSimple() throws QueryException {
+    RDFTerm result = resolve();
+    if (result.isLiteral()) return ((ValueLiteral)result).isSimple();
+    throw new QueryException("Not valid to check if a non-literal is a simple literal: " + result.getClass().getSimpleName());
+  }
+
+  // The RDFTerm interface
+
+  /** @see org.mulgara.query.filter.RDFTerm#isBlank() */
+  public boolean isBlank() throws QueryException { return resolve().isBlank(); }
+
+  /** @see org.mulgara.query.filter.RDFTerm#isIRI() */
+  public boolean isIRI() throws QueryException { return resolve().isIRI(); }
+
+  /**
+   * {@inheritDoc}
+   * The operation of this method is depended on the context in which it was called.
+   * If it is called without a context owner, then this means it was called during
+   * Filter construction, and we want to indicate that it is valid to treat this as a literal.
+   * @return <code>true</code> if there is no context, or else it calls isLiteral on the resolved value.
+   */
+  public boolean isLiteral() throws QueryException {
+    return getContextOwner() == null ? true : resolve().isLiteral();
+  }
+
+
+  /**
+   * Resolve the value of the function.
+   * @return The resolution of the function
+   * @throws QueryException if the function does not resolve
+   * TODO: call the appropriate function. This just returns the boolean TRUE for the moment.
+   */
+  protected RDFTerm resolve() throws QueryException {
+    logger.warn("Attempting to execute an unsupported function: " + fn + "(" + resolveArgs() + ")");
+    return Bool.TRUE;
+  }
+
+  /**
+   * A utility function to create a list of arguments to be passed to the external function.
+   * @return A {@link List} of arbitrary objects to be passed as arguments to the external function.
+   * @throws QueryException If any of the arguments could not be resolved.
+   */
+  private List<Object> resolveArgs() throws QueryException {
+    List<Object> result = new ArrayList<Object>(operands.length);
+    for (int i = 0; i < operands.length; i++) result.add(operands[i].getValue());
+    return result;
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/IRI.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,84 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.ContextOwner;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * <p>An IRI value.</p>
- * <p>OK, so we're cheating.  This is a URI.</p>
- *
- * @created Mar 12, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class IRI implements RDFTerm {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 4875602788740429777L;
-
-  /** The URI held by this object */
-  private final URI value;
-
-  /**
-   * Creates the value to wrap the string
-   * @param s The string to wrap
-   */
-  public IRI(URI u) {
-    value = u;
-  }
-
-  /** {@inheritDoc} */
-  public URI getValue() {
-    return value;
-  }
-
-  /** {@inheritDoc} */
-  public boolean equals(RDFTerm v) throws QueryException {
-    return v.isIRI() && value.equals(v.getValue());
-  }
-
-  /** {@inheritDoc} */
-  public boolean notEquals(RDFTerm v) throws QueryException {
-    return !equals(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean isBlank() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean isIRI() { return true; }
-
-  /** {@inheritDoc} */
-  public boolean isURI() { return true; }
-
-  /** {@inheritDoc} */
-  public boolean isLiteral() { return false; }
-
-  /** {@inheritDoc} */
-  public boolean sameTerm(RDFTerm v) throws QueryException {
-    return equals(v);
-  }
-
-  /** This value does not need a context */
-  public ContextOwner getContextOwner() {  return null; }
-
-  /** This value does not need a context */
-  public void setContextOwner(ContextOwner owner) { }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/IRI.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,84 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * <p>An IRI value.</p>
+ * <p>OK, so we're cheating.  This is a URI.</p>
+ *
+ * @created Mar 12, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class IRI implements RDFTerm {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 4875602788740429777L;
+
+  /** The URI held by this object */
+  private final URI value;
+
+  /**
+   * Creates the value to wrap the string
+   * @param s The string to wrap
+   */
+  public IRI(URI u) {
+    value = u;
+  }
+
+  /** {@inheritDoc} */
+  public URI getValue() {
+    return value;
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(RDFTerm v) throws QueryException {
+    return v.isIRI() && value.equals(v.getValue());
+  }
+
+  /** {@inheritDoc} */
+  public boolean notEquals(RDFTerm v) throws QueryException {
+    return !equals(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean isBlank() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean isIRI() { return true; }
+
+  /** {@inheritDoc} */
+  public boolean isURI() { return true; }
+
+  /** {@inheritDoc} */
+  public boolean isLiteral() { return false; }
+
+  /** {@inheritDoc} */
+  public boolean sameTerm(RDFTerm v) throws QueryException {
+    return equals(v);
+  }
+
+  /** This value does not need a context */
+  public ContextOwner getContextOwner() {  return null; }
+
+  /** This value does not need a context */
+  public void setContextOwner(ContextOwner owner) { }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,69 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.RDFTerm;
-
-/**
- * Represents a Lang() function that accesses the language on a literal.
- * This operation is made to look like a SimpleLiteral.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class LangFn extends AbstractAccessorFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -6744958736249165056L;
-
-  /**
-   * Create a new language extractor function.
-   * @param operand The operand for the function.
-   */
-  public LangFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
-   * @return Always empty, as the result of this operation is a simple literal, which has no type.
-   */
-  public SimpleLiteral getLang() throws QueryException {
-    return SimpleLiteral.EMPTY;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.RDFTerm#isLiteral()
-   * May be overridden.
-   */
-  public boolean isLiteral() throws QueryException {
-    return true;
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
-  public boolean isSimple() throws QueryException {
-    return ((ValueLiteral)resolve()).isSimple();
-  }
-
-  /**
-   * Applies this function to its operands to get back a result.
-   * @return A language code for the operand.
-   * @throws QueryException If the operand was not a literal.
-   */
-  protected RDFTerm resolve() throws QueryException {
-    if (!operand.isLiteral()) throw new QueryException("Disallowed type in LANG function. Expected a Literal. Got a : " + operand.getClass().getSimpleName());
-    return ((ValueLiteral)operand).getLang();
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,69 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.RDFTerm;
+
+/**
+ * Represents a Lang() function that accesses the language on a literal.
+ * This operation is made to look like a SimpleLiteral.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class LangFn extends AbstractAccessorFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -6744958736249165056L;
+
+  /**
+   * Create a new language extractor function.
+   * @param operand The operand for the function.
+   */
+  public LangFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
+   * @return Always empty, as the result of this operation is a simple literal, which has no type.
+   */
+  public SimpleLiteral getLang() throws QueryException {
+    return SimpleLiteral.EMPTY;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.RDFTerm#isLiteral()
+   * May be overridden.
+   */
+  public boolean isLiteral() throws QueryException {
+    return true;
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
+  public boolean isSimple() throws QueryException {
+    return ((ValueLiteral)resolve()).isSimple();
+  }
+
+  /**
+   * Applies this function to its operands to get back a result.
+   * @return A language code for the operand.
+   * @throws QueryException If the operand was not a literal.
+   */
+  protected RDFTerm resolve() throws QueryException {
+    if (!operand.isLiteral()) throw new QueryException("Disallowed type in LANG function. Expected a Literal. Got a : " + operand.getClass().getSimpleName());
+    return ((ValueLiteral)operand).getLang();
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,148 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import java.net.URI;
-
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the language function class.
- *
- * @created Apr 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class LangFnUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public LangFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new LangFnUnitTest("testValues"));
-    suite.addTest(new LangFnUnitTest("testVar"));
-    return suite;
-  }
-
-
-  public void testValues() throws Exception {
-    String str = "test";
-    URI t = URI.create(XSD_NS + "string");
-    ValueLiteral l = TypedLiteral.newLiteral(str, t, null);
-    
-    LangFn fn = new LangFn(l);
-
-    assertTrue(fn.equals(SimpleLiteral.EMPTY));
-    assertFalse(fn.isBlank());
-    assertFalse(fn.isIRI());
-    assertTrue(fn.isLiteral());
-    assertFalse(fn.isURI());
-    assertEquals(SimpleLiteral.STRING_TYPE, fn.getType());
-    assertEquals(SimpleLiteral.EMPTY, fn.getLang());
-
-    l = TypedLiteral.newLiteral(str, null, "en");
-    fn = new LangFn(l);
-    SimpleLiteral lang = new SimpleLiteral("en");
-    assertTrue(fn.equals(lang));
-    assertFalse(fn.isBlank());
-    assertFalse(fn.isIRI());
-    assertTrue(fn.isLiteral());
-    assertFalse(fn.isURI());
-
-    l = TypedLiteral.newLiteral(new Integer(42));
-    fn = new LangFn(l);
-    assertTrue(fn.equals(SimpleLiteral.EMPTY));
-    assertFalse(fn.isBlank());
-    assertFalse(fn.isIRI());
-    assertTrue(fn.isLiteral());
-    assertFalse(fn.isURI());
-
-    IRI i = new IRI(URI.create("foo:bar"));
-    fn = new LangFn(i);
-    try {
-      fn.equals(SimpleLiteral.EMPTY);
-      fail("Got a language from a URI");
-    } catch (QueryException qe) { }
-  }
-
-  public void testVar() throws Exception {
-    String vName = "foo";
-    Var v = new Var(vName);
-    LangFn fn = new LangFn(v);
-    
-    URI xsdString = URI.create(XSD_NS + "string");
-    URI xsdDouble = URI.create(XSD_NS + "double");
-    URI fooBar = URI.create("foo:bar");
-    Node[][] rows = {
-      new Node[] {new LiteralImpl("foo")},
-      new Node[] {new LiteralImpl("foo", xsdString)},
-      new Node[] {new LiteralImpl("5.0", xsdDouble)},
-      new Node[] {new LiteralImpl("foo", "en")},
-      new Node[] {new LiteralImpl("foo", fooBar)},
-      new Node[] {new URIReferenceImpl(fooBar)},
-      new Node[] {new BlankNodeImpl()},
-    };
-    TestContext c = new TestContext(new String[] {vName}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertEquals("", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("en", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("", fn.getValue());
-    assertTrue(c.next());
-    try {
-      Object o = fn.getValue();
-      fail("Got the language of a URI reference: " + o);
-    } catch (QueryException qe) { }
-    assertTrue(c.next());
-    try {
-      Object o = fn.getValue();
-      fail("Got the language of a Blank Node: " + o);
-    } catch (QueryException qe) { }
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/LangFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,148 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import java.net.URI;
+
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the language function class.
+ *
+ * @created Apr 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class LangFnUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public LangFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new LangFnUnitTest("testValues"));
+    suite.addTest(new LangFnUnitTest("testVar"));
+    return suite;
+  }
+
+
+  public void testValues() throws Exception {
+    String str = "test";
+    URI t = URI.create(XSD_NS + "string");
+    ValueLiteral l = TypedLiteral.newLiteral(str, t, null);
+    
+    LangFn fn = new LangFn(l);
+
+    assertTrue(fn.equals(SimpleLiteral.EMPTY));
+    assertFalse(fn.isBlank());
+    assertFalse(fn.isIRI());
+    assertTrue(fn.isLiteral());
+    assertFalse(fn.isURI());
+    assertEquals(SimpleLiteral.STRING_TYPE, fn.getType());
+    assertEquals(SimpleLiteral.EMPTY, fn.getLang());
+
+    l = TypedLiteral.newLiteral(str, null, "en");
+    fn = new LangFn(l);
+    SimpleLiteral lang = new SimpleLiteral("en");
+    assertTrue(fn.equals(lang));
+    assertFalse(fn.isBlank());
+    assertFalse(fn.isIRI());
+    assertTrue(fn.isLiteral());
+    assertFalse(fn.isURI());
+
+    l = TypedLiteral.newLiteral(new Integer(42));
+    fn = new LangFn(l);
+    assertTrue(fn.equals(SimpleLiteral.EMPTY));
+    assertFalse(fn.isBlank());
+    assertFalse(fn.isIRI());
+    assertTrue(fn.isLiteral());
+    assertFalse(fn.isURI());
+
+    IRI i = new IRI(URI.create("foo:bar"));
+    fn = new LangFn(i);
+    try {
+      fn.equals(SimpleLiteral.EMPTY);
+      fail("Got a language from a URI");
+    } catch (QueryException qe) { }
+  }
+
+  public void testVar() throws Exception {
+    String vName = "foo";
+    Var v = new Var(vName);
+    LangFn fn = new LangFn(v);
+    
+    URI xsdString = URI.create(XSD_NS + "string");
+    URI xsdDouble = URI.create(XSD_NS + "double");
+    URI fooBar = URI.create("foo:bar");
+    Node[][] rows = {
+      new Node[] {new LiteralImpl("foo")},
+      new Node[] {new LiteralImpl("foo", xsdString)},
+      new Node[] {new LiteralImpl("5.0", xsdDouble)},
+      new Node[] {new LiteralImpl("foo", "en")},
+      new Node[] {new LiteralImpl("foo", fooBar)},
+      new Node[] {new URIReferenceImpl(fooBar)},
+      new Node[] {new BlankNodeImpl()},
+    };
+    TestContext c = new TestContext(new String[] {vName}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertEquals("", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("en", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("", fn.getValue());
+    assertTrue(c.next());
+    try {
+      Object o = fn.getValue();
+      fail("Got the language of a URI reference: " + o);
+    } catch (QueryException qe) { }
+    assertTrue(c.next());
+    try {
+      Object o = fn.getValue();
+      fail("Got the language of a Blank Node: " + o);
+    } catch (QueryException qe) { }
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,31 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-
-/**
- * A numeric expression.
- *
- * @created Mar 13, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface NumericExpression extends ComparableExpression, ValueLiteral {
-
-  /**
-   * Retrieves a numeric value for this expression.
-   * @return A value in one of the subtypes of {@link java.lang.Number}
-   */
-  Number getNumber() throws QueryException;
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericExpression.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,31 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+
+/**
+ * A numeric expression.
+ *
+ * @created Mar 13, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface NumericExpression extends ComparableExpression, ValueLiteral {
+
+  /**
+   * Retrieves a numeric value for this expression.
+   * @return A value in one of the subtypes of {@link java.lang.Number}
+   */
+  Number getNumber() throws QueryException;
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,64 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A numeric value.  Expect that this will be extended into Double, Integer, Long, etc.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class NumericLiteral extends TypedLiteral implements NumericExpression {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -2601769069462524423L;
-
-  /**
-   * Creates the value to wrap the number
-   * @param n The number to wrap
-   */
-  public NumericLiteral(Number n) {
-    super(n, typeMap.get(n.getClass()));
-  }
-
-  /** @see org.mulgara.query.filter.value.NumericExpression#getNumber() */
-  public Number getNumber() {
-    return (Number)value;
-  }
-
-  /**
-   * Gets the IRI that is used to represent the given numeric type.
-   * @param n The number to get the type for.
-   * @return An IRI containing the XSD datatype of n.
-   */
-  public static IRI getTypeFor(Number n) {
-    return new IRI(typeMap.get(n.getClass()));
-  }
-
-  /** A mapping of numeric types to their URIs */
-  private static final Map<Class<? extends Number>,URI> typeMap = new HashMap<Class<? extends Number>,URI>();
-  
-  static {
-    typeMap.put(Float.class, URI.create(XSD_NS + "float"));
-    typeMap.put(Double.class, URI.create(XSD_NS + "double"));
-    typeMap.put(Long.class, URI.create(XSD_NS + "long"));
-    typeMap.put(Integer.class, URI.create(XSD_NS + "int"));
-    typeMap.put(Short.class, URI.create(XSD_NS + "short"));
-    typeMap.put(Byte.class, URI.create(XSD_NS + "byte"));
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,64 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * A numeric value.  Expect that this will be extended into Double, Integer, Long, etc.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class NumericLiteral extends TypedLiteral implements NumericExpression {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -2601769069462524423L;
+
+  /**
+   * Creates the value to wrap the number
+   * @param n The number to wrap
+   */
+  public NumericLiteral(Number n) {
+    super(n, typeMap.get(n.getClass()));
+  }
+
+  /** @see org.mulgara.query.filter.value.NumericExpression#getNumber() */
+  public Number getNumber() {
+    return (Number)value;
+  }
+
+  /**
+   * Gets the IRI that is used to represent the given numeric type.
+   * @param n The number to get the type for.
+   * @return An IRI containing the XSD datatype of n.
+   */
+  public static IRI getTypeFor(Number n) {
+    return new IRI(typeMap.get(n.getClass()));
+  }
+
+  /** A mapping of numeric types to their URIs */
+  private static final Map<Class<? extends Number>,URI> typeMap = new HashMap<Class<? extends Number>,URI>();
+  
+  static {
+    typeMap.put(Float.class, URI.create(XSD_NS + "float"));
+    typeMap.put(Double.class, URI.create(XSD_NS + "double"));
+    typeMap.put(Long.class, URI.create(XSD_NS + "long"));
+    typeMap.put(Integer.class, URI.create(XSD_NS + "int"));
+    typeMap.put(Short.class, URI.create(XSD_NS + "short"));
+    typeMap.put(Byte.class, URI.create(XSD_NS + "byte"));
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,123 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.TestContext;
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the NumericLiteral class
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class NumericLiteralUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public NumericLiteralUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new NumericLiteralUnitTest("testValues"));
-    suite.addTest(new NumericLiteralUnitTest("testFilter"));
-    suite.addTest(new NumericLiteralUnitTest("testType"));
-    suite.addTest(new NumericLiteralUnitTest("testProperties"));
-    suite.addTest(new NumericLiteralUnitTest("testFactory"));
-    return suite;
-  }
-
-  public void testValues() throws Exception {
-    Integer five = Integer.valueOf(5);
-    NumericLiteral n = new NumericLiteral(five);
-    assertEquals(n.getValue(), five);
-    assertFalse(Integer.valueOf(4).equals(n.getValue()));
-
-    Double six = Double.valueOf(6.0);
-    n = new NumericLiteral(six);
-    assertEquals(n.getValue(), six);
-    assertFalse(Double.valueOf(4).equals(n.getValue()));
-  }
-
-  public void testFilter() throws Exception {
-    Context c = new TestContext();
-    NumericLiteral n = new NumericLiteral(Integer.valueOf(5));
-    assertTrue(n.test(c));
-    n = new NumericLiteral(Integer.valueOf(0));
-    assertFalse(n.test(c));
-
-    n = new NumericLiteral(Double.valueOf(5.0));
-    assertTrue(n.test(c));
-    n = new NumericLiteral(Double.valueOf(0));
-    assertFalse(n.test(c));
-  }
-
-  public void testType() throws Exception {
-    NumericLiteral n = new NumericLiteral(Integer.valueOf(5));
-    assertTrue(n.getType().isIRI());
-    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "int"));
-
-    n = new NumericLiteral(Long.valueOf(5));
-    assertTrue(n.getType().isIRI());
-    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "long"));
-
-    n = new NumericLiteral(Double.valueOf(5));
-    assertTrue(n.getType().isIRI());
-    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "double"));
-
-    n = new NumericLiteral(Float.valueOf(5));
-    assertTrue(n.getType().isIRI());
-    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "float"));
-  }
-
-
-  public void testProperties() throws Exception {
-    NumericLiteral n = new NumericLiteral(Integer.valueOf(5));
-    assertFalse(n.isBlank());
-    assertFalse(n.isIRI());
-    assertTrue(n.isLiteral());
-    assertFalse(n.isURI());
-  }
-
-  public void testFactory() throws Exception {
-    Integer five = Integer.valueOf(5);
-    NumericLiteral n = new NumericLiteral(five);
-    ValueLiteral n2 = TypedLiteral.newLiteral(five);
-    assertTrue(n.equals(n2));
-    assertTrue(n.getType().equals(n2.getType()));
-
-    Double six = Double.valueOf(6.0);
-    n = new NumericLiteral(six);
-    n2 = TypedLiteral.newLiteral(six);
-    assertTrue(n.equals(n2));
-    assertTrue(n.getType().equals(n2.getType()));
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/NumericLiteralUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,123 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.TestContext;
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the NumericLiteral class
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class NumericLiteralUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public NumericLiteralUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new NumericLiteralUnitTest("testValues"));
+    suite.addTest(new NumericLiteralUnitTest("testFilter"));
+    suite.addTest(new NumericLiteralUnitTest("testType"));
+    suite.addTest(new NumericLiteralUnitTest("testProperties"));
+    suite.addTest(new NumericLiteralUnitTest("testFactory"));
+    return suite;
+  }
+
+  public void testValues() throws Exception {
+    Integer five = Integer.valueOf(5);
+    NumericLiteral n = new NumericLiteral(five);
+    assertEquals(n.getValue(), five);
+    assertFalse(Integer.valueOf(4).equals(n.getValue()));
+
+    Double six = Double.valueOf(6.0);
+    n = new NumericLiteral(six);
+    assertEquals(n.getValue(), six);
+    assertFalse(Double.valueOf(4).equals(n.getValue()));
+  }
+
+  public void testFilter() throws Exception {
+    Context c = new TestContext();
+    NumericLiteral n = new NumericLiteral(Integer.valueOf(5));
+    assertTrue(n.test(c));
+    n = new NumericLiteral(Integer.valueOf(0));
+    assertFalse(n.test(c));
+
+    n = new NumericLiteral(Double.valueOf(5.0));
+    assertTrue(n.test(c));
+    n = new NumericLiteral(Double.valueOf(0));
+    assertFalse(n.test(c));
+  }
+
+  public void testType() throws Exception {
+    NumericLiteral n = new NumericLiteral(Integer.valueOf(5));
+    assertTrue(n.getType().isIRI());
+    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "int"));
+
+    n = new NumericLiteral(Long.valueOf(5));
+    assertTrue(n.getType().isIRI());
+    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "long"));
+
+    n = new NumericLiteral(Double.valueOf(5));
+    assertTrue(n.getType().isIRI());
+    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "double"));
+
+    n = new NumericLiteral(Float.valueOf(5));
+    assertTrue(n.getType().isIRI());
+    assertEquals(n.getType().getValue(), URI.create(XSD_NS + "float"));
+  }
+
+
+  public void testProperties() throws Exception {
+    NumericLiteral n = new NumericLiteral(Integer.valueOf(5));
+    assertFalse(n.isBlank());
+    assertFalse(n.isIRI());
+    assertTrue(n.isLiteral());
+    assertFalse(n.isURI());
+  }
+
+  public void testFactory() throws Exception {
+    Integer five = Integer.valueOf(5);
+    NumericLiteral n = new NumericLiteral(five);
+    ValueLiteral n2 = TypedLiteral.newLiteral(five);
+    assertTrue(n.equals(n2));
+    assertTrue(n.getType().equals(n2.getType()));
+
+    Double six = Double.valueOf(6.0);
+    n = new NumericLiteral(six);
+    n2 = TypedLiteral.newLiteral(six);
+    assertTrue(n.equals(n2));
+    assertTrue(n.getType().equals(n2.getType()));
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,165 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.ContextOwner;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * A string value.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class SimpleLiteral extends AbstractComparableLiteral {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -776959229628368456L;
-
-  /** An empty simple literal */
-  public static final SimpleLiteral EMPTY = new SimpleLiteral("", "");
-
-  /** The language tag for a simple literal */
-  private SimpleLiteral lang = EMPTY;
-
-  /** The type used for strings */
-  public static final IRI STRING_TYPE = new IRI(new TypedLiteral.XSDString().getTypeURI());
-
-  /**
-   * Creates the value to wrap the string
-   * @param s The string to wrap
-   */
-  public SimpleLiteral(String s) {
-    super(s);
-  }
-
-  /**
-   * Creates the value to wrap the string
-   * @param s The string to wrap
-   */
-  public SimpleLiteral(String s, String l) {
-    super(s);
-    lang = new SimpleLiteral(l);
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.AbstractComparableLiteral#getLang()
-   */
-  public SimpleLiteral getLang() {
-    return lang;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.AbstractComparableLiteral#getLang()
-   */
-  public String getLexical() {
-    return value == null ? (String)EMPTY.value : (String)value;
-  }
-
-  /**
-   * Gets the type of this literal
-   * @return Always the string type.
-   */
-  public IRI getType() {
-    return STRING_TYPE;
-  }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
-  public boolean isSimple() throws QueryException {
-    return true;
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ComparableExpression#test()
-   */
-  public boolean test(Context context) throws QueryException {
-    return value != null && ((String)value).length() != 0;
-  }
-
-  /** This value does not need a context */
-  public ContextOwner getContextOwner() {  return null; }
-
-  /** This value does not need a context */
-  public void setContextOwner(ContextOwner owner) { }
-
-  /** {@inheritDoc} */
-  public boolean sameTerm(RDFTerm v) throws QueryException {
-    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) return false;
-    return getValue().equals(v.getValue()) && compareLangEquals((ValueLiteral)v);
-  }
-
-  /**
-   * {@inheritDoc}
-   * This method will only return <code>true</code> when the elements are identical.
-   * Since this object is a literal, then an incorrect comparison will throw an exception.
-   * {@link http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal}
-   * <em>produces a type error if the arguments are both literal but are not the same RDF term</em>
-   */
-  public boolean equals(RDFTerm v) throws QueryException {
-    if (!v.isLiteral()) return false;
-    if (((ValueLiteral)v).isSimple()) {
-      // check values and language codes
-      if (getValue().equals(v.getValue()) && compareLangEquals((ValueLiteral)v)) return true;
-    }
-    throw new QueryException("Type Error: Terms are not equal");
-  }
-
-  /** {@inheritDoc} */
-  public boolean lessThan(ComparableExpression v) throws QueryException {
-    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
-    int result = compareLang(convertToLiteral(v));
-    if (result == 0) return compare(getValue(), v.getValue()) < 0;
-    else return result < 0;
-  }
-
-  /** {@inheritDoc} */
-  public boolean greaterThan(ComparableExpression v) throws QueryException {
-    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
-    int result = compareLang(convertToLiteral(v));
-    if (result == 0) return compare(getValue(), v.getValue()) > 0;
-    else return result > 0;
-  }
-
-  /**
-   * Convert a comparable expression to a Literal, or throw an exception if it cannot be resolved this way.
-   * @param v The object to convert after testing
-   * @return The object as a ValueLiteral
-   * @throws QueryException Indicating that v is not a SimpleLiteral.
-   */
-  private ValueLiteral convertToLiteral(ComparableExpression v) throws QueryException {
-    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
-    return (ValueLiteral)v;
-  }
-
-  /**
-   * Tests equality for the language code to the language code of the given SimpleLiteral.
-   * @param sl The simple literal to compare against.
-   * @return <code>true</code> if the codes are equal, <code>false</code> otherwise.
-   */
-  private boolean compareLangEquals(ValueLiteral sl) throws QueryException {
-    return lang.equals(sl.getLang());
-  }
-
-  /**
-   * Compares the language code to the language code of the given SimpleLiteral.
-   * @param sl The simple literal to compare against.
-   * @return -1 if this code is less than the code of s1, +1 if greater, and 0 if they are equal
-   */
-  private int compareLang(ValueLiteral sl) throws QueryException {
-    return ((String)lang.getValue()).compareTo((String)sl.getLang().getValue());
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/SimpleLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,165 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * A string value.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SimpleLiteral extends AbstractComparableLiteral {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -776959229628368456L;
+
+  /** An empty simple literal */
+  public static final SimpleLiteral EMPTY = new SimpleLiteral("", "");
+
+  /** The language tag for a simple literal */
+  private SimpleLiteral lang = EMPTY;
+
+  /** The type used for strings */
+  public static final IRI STRING_TYPE = new IRI(new TypedLiteral.XSDString().getTypeURI());
+
+  /**
+   * Creates the value to wrap the string
+   * @param s The string to wrap
+   */
+  public SimpleLiteral(String s) {
+    super(s);
+  }
+
+  /**
+   * Creates the value to wrap the string
+   * @param s The string to wrap
+   */
+  public SimpleLiteral(String s, String l) {
+    super(s);
+    lang = new SimpleLiteral(l);
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.AbstractComparableLiteral#getLang()
+   */
+  public SimpleLiteral getLang() {
+    return lang;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.AbstractComparableLiteral#getLang()
+   */
+  public String getLexical() {
+    return value == null ? (String)EMPTY.value : (String)value;
+  }
+
+  /**
+   * Gets the type of this literal
+   * @return Always the string type.
+   */
+  public IRI getType() {
+    return STRING_TYPE;
+  }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+  public boolean isSimple() throws QueryException {
+    return true;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ComparableExpression#test()
+   */
+  public boolean test(Context context) throws QueryException {
+    return value != null && ((String)value).length() != 0;
+  }
+
+  /** This value does not need a context */
+  public ContextOwner getContextOwner() {  return null; }
+
+  /** This value does not need a context */
+  public void setContextOwner(ContextOwner owner) { }
+
+  /** {@inheritDoc} */
+  public boolean sameTerm(RDFTerm v) throws QueryException {
+    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) return false;
+    return getValue().equals(v.getValue()) && compareLangEquals((ValueLiteral)v);
+  }
+
+  /**
+   * {@inheritDoc}
+   * This method will only return <code>true</code> when the elements are identical.
+   * Since this object is a literal, then an incorrect comparison will throw an exception.
+   * {@link http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal}
+   * <em>produces a type error if the arguments are both literal but are not the same RDF term</em>
+   */
+  public boolean equals(RDFTerm v) throws QueryException {
+    if (!v.isLiteral()) return false;
+    if (((ValueLiteral)v).isSimple()) {
+      // check values and language codes
+      if (getValue().equals(v.getValue()) && compareLangEquals((ValueLiteral)v)) return true;
+    }
+    throw new QueryException("Type Error: Terms are not equal");
+  }
+
+  /** {@inheritDoc} */
+  public boolean lessThan(ComparableExpression v) throws QueryException {
+    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
+    int result = compareLang(convertToLiteral(v));
+    if (result == 0) return compare(getValue(), v.getValue()) < 0;
+    else return result < 0;
+  }
+
+  /** {@inheritDoc} */
+  public boolean greaterThan(ComparableExpression v) throws QueryException {
+    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
+    int result = compareLang(convertToLiteral(v));
+    if (result == 0) return compare(getValue(), v.getValue()) > 0;
+    else return result > 0;
+  }
+
+  /**
+   * Convert a comparable expression to a Literal, or throw an exception if it cannot be resolved this way.
+   * @param v The object to convert after testing
+   * @return The object as a ValueLiteral
+   * @throws QueryException Indicating that v is not a SimpleLiteral.
+   */
+  private ValueLiteral convertToLiteral(ComparableExpression v) throws QueryException {
+    if (!v.isLiteral() || !((ValueLiteral)v).isSimple()) throw new QueryException("Type Error: cannot compare a simple literal to a: " + v.getClass().getSimpleName());
+    return (ValueLiteral)v;
+  }
+
+  /**
+   * Tests equality for the language code to the language code of the given SimpleLiteral.
+   * @param sl The simple literal to compare against.
+   * @return <code>true</code> if the codes are equal, <code>false</code> otherwise.
+   */
+  private boolean compareLangEquals(ValueLiteral sl) throws QueryException {
+    return lang.equals(sl.getLang());
+  }
+
+  /**
+   * Compares the language code to the language code of the given SimpleLiteral.
+   * @param sl The simple literal to compare against.
+   * @return -1 if this code is less than the code of s1, +1 if greater, and 0 if they are equal
+   */
+  private int compareLang(ValueLiteral sl) throws QueryException {
+    return ((String)lang.getValue()).compareTo((String)sl.getLang().getValue());
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,72 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.jrdf.graph.BlankNode;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.RDFTerm;
-
-/**
- * Represents a str() function that stringizes any underlying data.
- * This operation is made to look like a SimpleLiteral.
- *
- * @created Mar 17, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class StrFn extends AbstractAccessorFn {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 5983891032753800787L;
-
-  /**
-   * Create a new string extractor function.
-   * @param operand The operand for the function.
-   */
-  public StrFn(RDFTerm operand) {
-    super(operand);
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
-   * @return Always empty, as the result of this operation is a simple literal, which has no type.
-   */
-  public SimpleLiteral getLang() throws QueryException {
-    return SimpleLiteral.EMPTY;
-  }
-
-  /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
-  public boolean isSimple() throws QueryException {
-    return ((ValueLiteral)resolve()).isSimple();
-  }
-
-  /**
-   * @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
-   * @throws QueryException if the operand does not resolve
-   */
-  public String getLexical() throws QueryException {
-    Object value = operand.getValue();
-    // Works fine without this test, but the SPARQL spec wants to prevent it
-    if (value instanceof BlankNode) throw new QueryException("Not permitted to convert a blank node to a String in SPARQL");
-    return operand.getValue().toString();
-  }
-
-  /**
-   * Resolve the value of the operand, and create a literal for it.
-   * @return The operand
-   * @throws QueryException if the operand does not resolve
-   */
-  protected RDFTerm resolve() throws QueryException {
-    return new SimpleLiteral(getLexical());
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFn.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,72 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.jrdf.graph.BlankNode;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.RDFTerm;
+
+/**
+ * Represents a str() function that stringizes any underlying data.
+ * This operation is made to look like a SimpleLiteral.
+ *
+ * @created Mar 17, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class StrFn extends AbstractAccessorFn {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 5983891032753800787L;
+
+  /**
+   * Create a new string extractor function.
+   * @param operand The operand for the function.
+   */
+  public StrFn(RDFTerm operand) {
+    super(operand);
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLang()
+   * @return Always empty, as the result of this operation is a simple literal, which has no type.
+   */
+  public SimpleLiteral getLang() throws QueryException {
+    return SimpleLiteral.EMPTY;
+  }
+
+  /** @see org.mulgara.query.filter.AbstractFilterValue#isSimple() */
+  public boolean isSimple() throws QueryException {
+    return ((ValueLiteral)resolve()).isSimple();
+  }
+
+  /**
+   * @see org.mulgara.query.filter.value.ValueLiteral#getLexical()
+   * @throws QueryException if the operand does not resolve
+   */
+  public String getLexical() throws QueryException {
+    Object value = operand.getValue();
+    // Works fine without this test, but the SPARQL spec wants to prevent it
+    if (value instanceof BlankNode) throw new QueryException("Not permitted to convert a blank node to a String in SPARQL");
+    return operand.getValue().toString();
+  }
+
+  /**
+   * Resolve the value of the operand, and create a literal for it.
+   * @return The operand
+   * @throws QueryException if the operand does not resolve
+   */
+  protected RDFTerm resolve() throws QueryException {
+    return new SimpleLiteral(getLexical());
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,142 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import java.net.URI;
-
-import org.jrdf.graph.Node;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.filter.TestContextOwner;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the string function class.
- *
- * @created Apr 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class StrFnUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public StrFnUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new StrFnUnitTest("testValues"));
-    suite.addTest(new StrFnUnitTest("testVar"));
-    return suite;
-  }
-
-
-  public void testValues() throws Exception {
-    String str = "test";
-    SimpleLiteral strLiteral = new SimpleLiteral(str);
-    URI t = URI.create(XSD_NS + "string");
-    ValueLiteral l = TypedLiteral.newLiteral(str, t, null);
-    
-    StrFn fn = new StrFn(l);
-
-    assertTrue(fn.equals(strLiteral));
-    assertFalse(fn.isBlank());
-    assertFalse(fn.isIRI());
-    assertTrue(fn.isLiteral());
-    assertFalse(fn.isURI());
-    assertEquals(SimpleLiteral.STRING_TYPE, fn.getType());
-    assertEquals(SimpleLiteral.EMPTY, fn.getLang());
-
-    l = TypedLiteral.newLiteral(str, null, "en");
-    fn = new StrFn(l);
-    assertTrue(fn.equals(strLiteral));
-    assertFalse(fn.isBlank());
-    assertFalse(fn.isIRI());
-    assertTrue(fn.isLiteral());
-    assertFalse(fn.isURI());
-
-    l = TypedLiteral.newLiteral(new Integer(42));
-    fn = new StrFn(l);
-    assertTrue(fn.equals(new SimpleLiteral("42")));
-    assertFalse(fn.isBlank());
-    assertFalse(fn.isIRI());
-    assertTrue(fn.isLiteral());
-    assertFalse(fn.isURI());
-
-    IRI i = new IRI(URI.create("foo:bar"));
-    fn = new StrFn(i);
-    fn.equals(new SimpleLiteral("foo:bar"));
-  }
-
-  public void testVar() throws Exception {
-    String vName = "foo";
-    Var v = new Var(vName);
-    StrFn fn = new StrFn(v);
-    
-    URI xsdString = URI.create(XSD_NS + "string");
-    URI xsdDouble = URI.create(XSD_NS + "double");
-    URI fooBar = URI.create("foo:bar");
-    Node[][] rows = {
-      new Node[] {new LiteralImpl("foo")},
-      new Node[] {new LiteralImpl("foo", xsdString)},
-      new Node[] {new LiteralImpl("5.0", xsdDouble)},
-      new Node[] {new LiteralImpl("foo", "en")},
-      new Node[] {new LiteralImpl("foo", fooBar)},
-      new Node[] {new URIReferenceImpl(fooBar)},
-      new Node[] {new BlankNodeImpl()},
-    };
-    TestContext c = new TestContext(new String[] {vName}, rows);
-    c.beforeFirst();
-    fn.setContextOwner(new TestContextOwner(c));
-
-    // check the context setting
-    fn.setCurrentContext(c);
-
-    assertTrue(c.next());
-    assertEquals("foo", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("foo", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("5.0", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("foo", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("foo", fn.getValue());
-    assertTrue(c.next());
-    assertEquals("foo:bar", fn.getValue());
-    assertTrue(c.next());
-    try {
-      Object o = fn.getValue();
-      fail("Got the string from a Blank Node: " + o);
-    } catch (QueryException qe) { }
-    assertFalse(c.next());
-  }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/StrFnUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,142 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import java.net.URI;
+
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.filter.TestContextOwner;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the string function class.
+ *
+ * @created Apr 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class StrFnUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public StrFnUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new StrFnUnitTest("testValues"));
+    suite.addTest(new StrFnUnitTest("testVar"));
+    return suite;
+  }
+
+
+  public void testValues() throws Exception {
+    String str = "test";
+    SimpleLiteral strLiteral = new SimpleLiteral(str);
+    URI t = URI.create(XSD_NS + "string");
+    ValueLiteral l = TypedLiteral.newLiteral(str, t, null);
+    
+    StrFn fn = new StrFn(l);
+
+    assertTrue(fn.equals(strLiteral));
+    assertFalse(fn.isBlank());
+    assertFalse(fn.isIRI());
+    assertTrue(fn.isLiteral());
+    assertFalse(fn.isURI());
+    assertEquals(SimpleLiteral.STRING_TYPE, fn.getType());
+    assertEquals(SimpleLiteral.EMPTY, fn.getLang());
+
+    l = TypedLiteral.newLiteral(str, null, "en");
+    fn = new StrFn(l);
+    assertTrue(fn.equals(strLiteral));
+    assertFalse(fn.isBlank());
+    assertFalse(fn.isIRI());
+    assertTrue(fn.isLiteral());
+    assertFalse(fn.isURI());
+
+    l = TypedLiteral.newLiteral(new Integer(42));
+    fn = new StrFn(l);
+    assertTrue(fn.equals(new SimpleLiteral("42")));
+    assertFalse(fn.isBlank());
+    assertFalse(fn.isIRI());
+    assertTrue(fn.isLiteral());
+    assertFalse(fn.isURI());
+
+    IRI i = new IRI(URI.create("foo:bar"));
+    fn = new StrFn(i);
+    fn.equals(new SimpleLiteral("foo:bar"));
+  }
+
+  public void testVar() throws Exception {
+    String vName = "foo";
+    Var v = new Var(vName);
+    StrFn fn = new StrFn(v);
+    
+    URI xsdString = URI.create(XSD_NS + "string");
+    URI xsdDouble = URI.create(XSD_NS + "double");
+    URI fooBar = URI.create("foo:bar");
+    Node[][] rows = {
+      new Node[] {new LiteralImpl("foo")},
+      new Node[] {new LiteralImpl("foo", xsdString)},
+      new Node[] {new LiteralImpl("5.0", xsdDouble)},
+      new Node[] {new LiteralImpl("foo", "en")},
+      new Node[] {new LiteralImpl("foo", fooBar)},
+      new Node[] {new URIReferenceImpl(fooBar)},
+      new Node[] {new BlankNodeImpl()},
+    };
+    TestContext c = new TestContext(new String[] {vName}, rows);
+    c.beforeFirst();
+    fn.setContextOwner(new TestContextOwner(c));
+
+    // check the context setting
+    fn.setCurrentContext(c);
+
+    assertTrue(c.next());
+    assertEquals("foo", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("foo", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("5.0", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("foo", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("foo", fn.getValue());
+    assertTrue(c.next());
+    assertEquals("foo:bar", fn.getValue());
+    assertTrue(c.next());
+    try {
+      Object o = fn.getValue();
+      fail("Got the string from a Blank Node: " + o);
+    } catch (QueryException qe) { }
+    assertFalse(c.next());
+  }
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,342 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.ContextOwner;
-
-
-/**
- * A literal with a URI type and a value.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class TypedLiteral extends AbstractComparableLiteral {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = -4765911650373775807L;
-
-  /** The type URI for this literal */
-  private URI type;
-  
-  /** The lexical representation for this literal */
-  private String lexical;
-
-  /** The namespace for all XSD types */
-  public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema#";
-
-  /**
-   * Creates the value to wrap the string
-   * @param value The data to wrap
-   * @param type The type of the literal
-   */
-  public TypedLiteral(Object value, URI type) {
-    super(value);
-    lexical = value.toString();  // lexical == value if value instanceof String
-    this.type = type;
-  }
-
-  /**
-   * A factory for typed literals.
-   * @param value The literal data in its lexical form. This means it's a String, and can even be invalid
-   * @param type The type of the literal. May be null.
-   * @param lang The language code of the literal. May be null.
-   */
-  public static ValueLiteral newLiteral(String value, URI type, String lang) {
-    if (type != null) {
-      // get the info registered for this type URI
-      TypeInfo info = infoMap.get(type);
-      if (info != null && info.delegatedConstruction()) {
-        try {
-          return newLiteral(info.toData(value));
-        } catch (QueryException e) {  // should not happen
-          throw new AssertionError("Internal type maps are inconsistent for: " + info.getClass().getSimpleName());
-        }
-      }
-      // no type info for the given URI, just pass through as a general typed literal
-      return new TypedLiteral(value, type);
-    }
-    // no type info provided, so it's a simple string
-    if (lang == null || lang.length() == 0) return new SimpleLiteral(value);
-    return new SimpleLiteral(value, lang);
-  }
-
-  /**
-   * A factory for typed literals from raw Java types. This is most likely to come
-   * from literal numbers parsed by a SPARQL parser.
-   * @param value The data as an object. May be a String, or some kind of {@link java.lang.Number}
-   */
-  public static ValueLiteral newLiteral(Object value) throws QueryException {
-    DataCompare dc = typeMap.get(value.getClass());
-    if (dc == null) throw new QueryException("Unrecognized data type: " + value.getClass().getSimpleName());
-    return dc.newLiteral(value);
-  }
-
-  /**
-   * Gets the type of this literal
-   * @return The URI for this literals type
-   */
-  public IRI getType() {
-    return new IRI(type);
-  }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
-  public boolean isSimple() throws QueryException {
-    return false;
-  }
-
-  /**
-   * Gets the language ID of this literal
-   * @return The language ID for this literal
-   */
-  public SimpleLiteral getLang() {
-    return SimpleLiteral.EMPTY;
-  }
-  
-  /** {@inheritDoc} */
-  public String getLexical() {
-    return lexical;
-  }
-
-  /**
-   * No context needed as this is a literal value.
-   * @see org.mulgara.query.filter.RDFTerm#getContextOwner()
-   */
-  public ContextOwner getContextOwner() {
-    return null;
-  }
-
-  /**
-   * A public string representation of this literal.
-   */
-  public String toString() {
-    return "'" + lexical + "'^^<" + type + ">";
-  }
-
-  /**
-   * No context needed as this is a literal value.
-   * @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner)
-   */
-  public void setContextOwner(ContextOwner owner) { }
-
-  /** {@inheritDoc} */
-  public boolean test(Context context) throws QueryException {
-    if (type == null) return ((String)value).length() != 0;
-    TypeInfo test = infoMap.get(type);
-    if (test == null) throw new QueryException("Type Error: no effective boolean value for: " + toString());
-    return test.ebv(value.toString());
-  }
-
-  /** A map of XSD datatypes onto the tests for their types */
-  private static Map<URI,TypeInfo> infoMap = new HashMap<URI,TypeInfo>();
-
-  private static final URI xsd(String s) { return URI.create(XSD_NS + s); }
-
-  /** This interface tests if datatype matches the data to give an EBV of <code>true</code> */
-  public interface TypeInfo {
-    /** Returns an EBV of <code>true</code> iff the data matches the type sufficiently */
-    public boolean ebv(String data) throws QueryException;
-    /** Returns data parsed out of the string literal */
-    public Object toData(String representation);
-    /** Returns the URI for this type */
-    public URI getTypeURI();
-    /** Indicates if construction should be delegated */
-    public boolean delegatedConstruction();
-    /** All the registered types */
-    static final List<TypeInfo> types = new ArrayList<TypeInfo>();
-  }
-
-  /** Simple extension to TypeInfo to store the type URI for all implementing classes  */
-  private static abstract class AbstractXSD implements TypeInfo  {
-    private final URI typeURI;
-    AbstractXSD(String fragment) { typeURI = xsd(fragment); }
-    public URI getTypeURI() { return typeURI; }
-    public boolean delegatedConstruction() { return true; }
-  }
-
-  /**
-   * Helper method for static initialization
-   * @param info The info to add to the infoMap
-   */
-  private static void addDefaultTypeInfo(TypeInfo info) {
-    infoMap.put(info.getTypeURI(), info);
-  }
-
-  // initialize the types
-  static {
-    addDefaultTypeInfo(new XSDString());
-    addDefaultTypeInfo(new XSDBoolean());
-    addDefaultTypeInfo(new XSDDouble());
-    addDefaultTypeInfo(new XSDFloat());
-    addDefaultTypeInfo(new XSDLong());
-    addDefaultTypeInfo(new XSDInteger());
-    addDefaultTypeInfo(new XSDShort());
-    addDefaultTypeInfo(new XSDByte());
-    addDefaultTypeInfo(new XSDDate());
-    infoMap.put(xsd("decimal"), new XSDLong());
-    infoMap.put(xsd("integer"), new XSDLong());
-    infoMap.put(xsd("nonPositiveInteger"), new XSDLong());
-    infoMap.put(xsd("negativeInteger"), new XSDLong());
-    infoMap.put(xsd("nonNegativeInteger"), new XSDLong());
-    infoMap.put(xsd("positiveInteger"), new XSDInteger());
-    infoMap.put(xsd("unsignedLong"), new XSDLong());
-    infoMap.put(xsd("unsignedInt"), new XSDLong());
-    infoMap.put(xsd("unsignedShort"), new XSDInteger());
-    infoMap.put(xsd("unsignedByte"), new XSDShort());
-  }
-
-  //////////////////////////////////////////////////////////////////
-  // Implementing classes
-  //////////////////////////////////////////////////////////////////
-
-  static class XSDString extends AbstractXSD {
-    XSDString() { super("string"); }
-    public boolean ebv(String data) { return data != null && data.length() != 0; }
-    public Object toData(String r) { return r; }
-    public boolean delegatedConstruction() { return false; }
-  }
-
-  private static class XSDBoolean extends AbstractXSD {
-    XSDBoolean() { super("boolean"); }
-    public boolean ebv(String data) { return Boolean.parseBoolean(data); }
-    public Object toData(String r) { return Boolean.parseBoolean(r); }
-  }
-  
-  private static class XSDDouble extends AbstractXSD {
-    XSDDouble() { super("double"); }
-    public boolean ebv(String data) {
-      try {
-        if (data == null) return false;
-        Double d = Double.parseDouble(data);
-        return 0 != Double.parseDouble(data) && !d.isNaN();
-      } catch (NumberFormatException nfe) {
-        return false;
-      }
-    }
-    public Object toData(String r) {
-      try {
-        return Double.parseDouble(r);
-      } catch (NumberFormatException nfe) {
-        return Double.valueOf(0.0);
-      }
-    }
-  }
-  
-  private static class XSDFloat extends AbstractXSD {
-    XSDFloat() { super("float"); }
-    public boolean ebv(String data) {
-      try {
-        if (data == null) return false;
-        Float f = Float.parseFloat(data);
-        return 0 != f && !f.isNaN();
-      } catch (NumberFormatException nfe) {
-        return false;
-      }
-    }
-    public Object toData(String r) {
-      try {
-        return Float.parseFloat(r);
-      } catch (NumberFormatException nfe) {
-        return Float.valueOf(0);
-      }
-    }
-  }
-
-  private static class XSDLong extends AbstractXSD {
-    XSDLong() { super("long"); }
-    public boolean ebv(String data) {
-      try {
-        return data != null && 0 != Long.parseLong(data);
-      } catch (NumberFormatException nfe) {
-        return false;
-      }
-    }
-    public Object toData(String r) {
-      try {
-        return Long.parseLong(r);
-      } catch (NumberFormatException nfe) {
-        return Long.valueOf(0);
-      }
-    }
-  }
-
-  private static class XSDInteger extends AbstractXSD {
-    XSDInteger() { super("int"); }
-    public boolean ebv(String data) {
-      try {
-        return data != null && 0 != Integer.parseInt(data);
-      } catch (NumberFormatException nfe) {
-        return false;
-      }
-    }
-    public Object toData(String r) {
-      try {
-        return Integer.parseInt(r);
-      } catch (NumberFormatException nfe) {
-        return Integer.valueOf(0);
-      }
-    }
-  }
-
-  private static class XSDShort extends AbstractXSD {
-    XSDShort() { super("short"); }
-    public boolean ebv(String data) {
-      try {
-        return data != null && 0 != Short.parseShort(data);
-      } catch (NumberFormatException nfe) {
-        return false;
-      }
-    }
-    public Object toData(String r) {
-      try {
-        return Short.parseShort(r);
-      } catch (NumberFormatException nfe) {
-        return Short.valueOf((short)0);
-      }
-    }
-  }
-
-  private static class XSDByte extends AbstractXSD {
-    XSDByte() { super("byte"); }
-    public boolean ebv(String data) {
-      try {
-        return data != null && 0 != Byte.parseByte(data);
-      } catch (NumberFormatException nfe) {
-        return false;
-      }
-    }
-    public Object toData(String r) {
-      try {
-        return Long.parseLong(r);
-      } catch (NumberFormatException nfe) {
-        return Byte.valueOf((byte)0);
-      }
-    }
-  }
-
-  private static class XSDDate extends AbstractXSD {
-    XSDDate() { super("dateTime"); }
-    public boolean ebv(String data) throws QueryException { throw new QueryException("Unable to convert a date to a boolean"); }
-    public Object toData(String r) { return DateTime.parseDate(r); }
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,342 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.ContextOwner;
+
+
+/**
+ * A literal with a URI type and a value.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TypedLiteral extends AbstractComparableLiteral {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = -4765911650373775807L;
+
+  /** The type URI for this literal */
+  private URI type;
+  
+  /** The lexical representation for this literal */
+  private String lexical;
+
+  /** The namespace for all XSD types */
+  public static final String XSD_NS = "http://www.w3.org/2001/XMLSchema#";
+
+  /**
+   * Creates the value to wrap the string
+   * @param value The data to wrap
+   * @param type The type of the literal
+   */
+  public TypedLiteral(Object value, URI type) {
+    super(value);
+    lexical = value.toString();  // lexical == value if value instanceof String
+    this.type = type;
+  }
+
+  /**
+   * A factory for typed literals.
+   * @param value The literal data in its lexical form. This means it's a String, and can even be invalid
+   * @param type The type of the literal. May be null.
+   * @param lang The language code of the literal. May be null.
+   */
+  public static ValueLiteral newLiteral(String value, URI type, String lang) {
+    if (type != null) {
+      // get the info registered for this type URI
+      TypeInfo info = infoMap.get(type);
+      if (info != null && info.delegatedConstruction()) {
+        try {
+          return newLiteral(info.toData(value));
+        } catch (QueryException e) {  // should not happen
+          throw new AssertionError("Internal type maps are inconsistent for: " + info.getClass().getSimpleName());
+        }
+      }
+      // no type info for the given URI, just pass through as a general typed literal
+      return new TypedLiteral(value, type);
+    }
+    // no type info provided, so it's a simple string
+    if (lang == null || lang.length() == 0) return new SimpleLiteral(value);
+    return new SimpleLiteral(value, lang);
+  }
+
+  /**
+   * A factory for typed literals from raw Java types. This is most likely to come
+   * from literal numbers parsed by a SPARQL parser.
+   * @param value The data as an object. May be a String, or some kind of {@link java.lang.Number}
+   */
+  public static ValueLiteral newLiteral(Object value) throws QueryException {
+    DataCompare dc = typeMap.get(value.getClass());
+    if (dc == null) throw new QueryException("Unrecognized data type: " + value.getClass().getSimpleName());
+    return dc.newLiteral(value);
+  }
+
+  /**
+   * Gets the type of this literal
+   * @return The URI for this literals type
+   */
+  public IRI getType() {
+    return new IRI(type);
+  }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+  public boolean isSimple() throws QueryException {
+    return false;
+  }
+
+  /**
+   * Gets the language ID of this literal
+   * @return The language ID for this literal
+   */
+  public SimpleLiteral getLang() {
+    return SimpleLiteral.EMPTY;
+  }
+  
+  /** {@inheritDoc} */
+  public String getLexical() {
+    return lexical;
+  }
+
+  /**
+   * No context needed as this is a literal value.
+   * @see org.mulgara.query.filter.RDFTerm#getContextOwner()
+   */
+  public ContextOwner getContextOwner() {
+    return null;
+  }
+
+  /**
+   * A public string representation of this literal.
+   */
+  public String toString() {
+    return "'" + lexical + "'^^<" + type + ">";
+  }
+
+  /**
+   * No context needed as this is a literal value.
+   * @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner)
+   */
+  public void setContextOwner(ContextOwner owner) { }
+
+  /** {@inheritDoc} */
+  public boolean test(Context context) throws QueryException {
+    if (type == null) return ((String)value).length() != 0;
+    TypeInfo test = infoMap.get(type);
+    if (test == null) throw new QueryException("Type Error: no effective boolean value for: " + toString());
+    return test.ebv(value.toString());
+  }
+
+  /** A map of XSD datatypes onto the tests for their types */
+  private static Map<URI,TypeInfo> infoMap = new HashMap<URI,TypeInfo>();
+
+  private static final URI xsd(String s) { return URI.create(XSD_NS + s); }
+
+  /** This interface tests if datatype matches the data to give an EBV of <code>true</code> */
+  public interface TypeInfo {
+    /** Returns an EBV of <code>true</code> iff the data matches the type sufficiently */
+    public boolean ebv(String data) throws QueryException;
+    /** Returns data parsed out of the string literal */
+    public Object toData(String representation);
+    /** Returns the URI for this type */
+    public URI getTypeURI();
+    /** Indicates if construction should be delegated */
+    public boolean delegatedConstruction();
+    /** All the registered types */
+    static final List<TypeInfo> types = new ArrayList<TypeInfo>();
+  }
+
+  /** Simple extension to TypeInfo to store the type URI for all implementing classes  */
+  private static abstract class AbstractXSD implements TypeInfo  {
+    private final URI typeURI;
+    AbstractXSD(String fragment) { typeURI = xsd(fragment); }
+    public URI getTypeURI() { return typeURI; }
+    public boolean delegatedConstruction() { return true; }
+  }
+
+  /**
+   * Helper method for static initialization
+   * @param info The info to add to the infoMap
+   */
+  private static void addDefaultTypeInfo(TypeInfo info) {
+    infoMap.put(info.getTypeURI(), info);
+  }
+
+  // initialize the types
+  static {
+    addDefaultTypeInfo(new XSDString());
+    addDefaultTypeInfo(new XSDBoolean());
+    addDefaultTypeInfo(new XSDDouble());
+    addDefaultTypeInfo(new XSDFloat());
+    addDefaultTypeInfo(new XSDLong());
+    addDefaultTypeInfo(new XSDInteger());
+    addDefaultTypeInfo(new XSDShort());
+    addDefaultTypeInfo(new XSDByte());
+    addDefaultTypeInfo(new XSDDate());
+    infoMap.put(xsd("decimal"), new XSDLong());
+    infoMap.put(xsd("integer"), new XSDLong());
+    infoMap.put(xsd("nonPositiveInteger"), new XSDLong());
+    infoMap.put(xsd("negativeInteger"), new XSDLong());
+    infoMap.put(xsd("nonNegativeInteger"), new XSDLong());
+    infoMap.put(xsd("positiveInteger"), new XSDInteger());
+    infoMap.put(xsd("unsignedLong"), new XSDLong());
+    infoMap.put(xsd("unsignedInt"), new XSDLong());
+    infoMap.put(xsd("unsignedShort"), new XSDInteger());
+    infoMap.put(xsd("unsignedByte"), new XSDShort());
+  }
+
+  //////////////////////////////////////////////////////////////////
+  // Implementing classes
+  //////////////////////////////////////////////////////////////////
+
+  static class XSDString extends AbstractXSD {
+    XSDString() { super("string"); }
+    public boolean ebv(String data) { return data != null && data.length() != 0; }
+    public Object toData(String r) { return r; }
+    public boolean delegatedConstruction() { return false; }
+  }
+
+  private static class XSDBoolean extends AbstractXSD {
+    XSDBoolean() { super("boolean"); }
+    public boolean ebv(String data) { return Boolean.parseBoolean(data); }
+    public Object toData(String r) { return Boolean.parseBoolean(r); }
+  }
+  
+  private static class XSDDouble extends AbstractXSD {
+    XSDDouble() { super("double"); }
+    public boolean ebv(String data) {
+      try {
+        if (data == null) return false;
+        Double d = Double.parseDouble(data);
+        return 0 != Double.parseDouble(data) && !d.isNaN();
+      } catch (NumberFormatException nfe) {
+        return false;
+      }
+    }
+    public Object toData(String r) {
+      try {
+        return Double.parseDouble(r);
+      } catch (NumberFormatException nfe) {
+        return Double.valueOf(0.0);
+      }
+    }
+  }
+  
+  private static class XSDFloat extends AbstractXSD {
+    XSDFloat() { super("float"); }
+    public boolean ebv(String data) {
+      try {
+        if (data == null) return false;
+        Float f = Float.parseFloat(data);
+        return 0 != f && !f.isNaN();
+      } catch (NumberFormatException nfe) {
+        return false;
+      }
+    }
+    public Object toData(String r) {
+      try {
+        return Float.parseFloat(r);
+      } catch (NumberFormatException nfe) {
+        return Float.valueOf(0);
+      }
+    }
+  }
+
+  private static class XSDLong extends AbstractXSD {
+    XSDLong() { super("long"); }
+    public boolean ebv(String data) {
+      try {
+        return data != null && 0 != Long.parseLong(data);
+      } catch (NumberFormatException nfe) {
+        return false;
+      }
+    }
+    public Object toData(String r) {
+      try {
+        return Long.parseLong(r);
+      } catch (NumberFormatException nfe) {
+        return Long.valueOf(0);
+      }
+    }
+  }
+
+  private static class XSDInteger extends AbstractXSD {
+    XSDInteger() { super("int"); }
+    public boolean ebv(String data) {
+      try {
+        return data != null && 0 != Integer.parseInt(data);
+      } catch (NumberFormatException nfe) {
+        return false;
+      }
+    }
+    public Object toData(String r) {
+      try {
+        return Integer.parseInt(r);
+      } catch (NumberFormatException nfe) {
+        return Integer.valueOf(0);
+      }
+    }
+  }
+
+  private static class XSDShort extends AbstractXSD {
+    XSDShort() { super("short"); }
+    public boolean ebv(String data) {
+      try {
+        return data != null && 0 != Short.parseShort(data);
+      } catch (NumberFormatException nfe) {
+        return false;
+      }
+    }
+    public Object toData(String r) {
+      try {
+        return Short.parseShort(r);
+      } catch (NumberFormatException nfe) {
+        return Short.valueOf((short)0);
+      }
+    }
+  }
+
+  private static class XSDByte extends AbstractXSD {
+    XSDByte() { super("byte"); }
+    public boolean ebv(String data) {
+      try {
+        return data != null && 0 != Byte.parseByte(data);
+      } catch (NumberFormatException nfe) {
+        return false;
+      }
+    }
+    public Object toData(String r) {
+      try {
+        return Long.parseLong(r);
+      } catch (NumberFormatException nfe) {
+        return Byte.valueOf((byte)0);
+      }
+    }
+  }
+
+  private static class XSDDate extends AbstractXSD {
+    XSDDate() { super("dateTime"); }
+    public boolean ebv(String data) throws QueryException { throw new QueryException("Unable to convert a date to a boolean"); }
+    public Object toData(String r) { return DateTime.parseDate(r); }
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,127 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.TestContext;
-
-import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the typed literal class.
- *
- * @created Mar 31, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class TypedLiteralUnitTest extends TestCase {
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public TypedLiteralUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new TypedLiteralUnitTest("testValues"));
-    suite.addTest(new TypedLiteralUnitTest("testFilter"));
-    suite.addTest(new TypedLiteralUnitTest("testType"));
-    suite.addTest(new TypedLiteralUnitTest("testProperties"));
-    return suite;
-  }
-
-
-  public void testValues() throws Exception {
-    String str = "test";
-    TypedLiteral l = (TypedLiteral)TypedLiteral.newLiteral(str, URI.create(XSD_NS + "string"), null);
-    assertEquals(str, l.getValue());
-
-    l = (TypedLiteral)TypedLiteral.newLiteral(str);
-    assertEquals(str, l.getValue());
-
-    String s2 = "foobar";
-    l = (TypedLiteral)TypedLiteral.newLiteral(s2, URI.create("foo:bar"), null);
-    assertEquals(s2, l.getValue());
-
-    Long v = Long.valueOf(5);
-    l = (TypedLiteral)TypedLiteral.newLiteral(v);
-    assertEquals(v, l.getValue());
-  }
-
-  public void testFilter() throws Exception {
-    Context c = new TestContext();
-    TypedLiteral l = (TypedLiteral)TypedLiteral.newLiteral("test", URI.create(XSD_NS + "string"), null);
-    assertTrue(l.test(c));
-
-    l = (TypedLiteral)TypedLiteral.newLiteral("test");
-    assertTrue(l.test(c));
-    l = (TypedLiteral)TypedLiteral.newLiteral("");
-    assertFalse(l.test(c));
-
-    l = (TypedLiteral)TypedLiteral.newLiteral("foobar", URI.create("foo:bar"), null);
-    try {
-      l.test(c);
-      fail("Got an EBV from an unknown literal type");
-    } catch (QueryException qe) {
-      assertTrue(qe.getMessage().startsWith("Type Error:"));
-    }
-
-    l = (TypedLiteral)TypedLiteral.newLiteral(Long.valueOf(5));
-    assertTrue(l.test(c));
-    l = (TypedLiteral)TypedLiteral.newLiteral(Long.valueOf(0));
-    assertFalse(l.test(c));
-  }
-
-  public void testType() throws Exception {
-    String str = "test";
-    URI t = URI.create(XSD_NS + "string");
-    TypedLiteral l = (TypedLiteral) TypedLiteral.newLiteral(str, t, null);
-    assertTrue(l.getType().isIRI());
-    assertEquals(t, l.getType().getValue());
-
-    l = (TypedLiteral)TypedLiteral.newLiteral(str);
-    assertEquals(t, l.getType().getValue());
-
-    String s2 = "foobar";
-    URI t2 = URI.create(XSD_NS + "foo:bar");
-    l = (TypedLiteral)TypedLiteral.newLiteral(s2, t2, null);
-    assertEquals(t2, l.getType().getValue());
-
-    Long v = Long.valueOf(5);
-    l = (TypedLiteral)TypedLiteral.newLiteral(v);
-    assertEquals(URI.create(XSD_NS + "long"), l.getType().getValue());
-  }
-
-  public void testProperties() throws Exception {
-    TypedLiteral l = (TypedLiteral) TypedLiteral.newLiteral("test", URI.create(XSD_NS + "string"), null);
-    assertFalse(l.isBlank());
-    assertFalse(l.isIRI());
-    assertTrue(l.isLiteral());
-    assertFalse(l.isURI());
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteralUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,127 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.TestContext;
+
+import static org.mulgara.query.filter.value.TypedLiteral.XSD_NS;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the typed literal class.
+ *
+ * @created Mar 31, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TypedLiteralUnitTest extends TestCase {
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public TypedLiteralUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new TypedLiteralUnitTest("testValues"));
+    suite.addTest(new TypedLiteralUnitTest("testFilter"));
+    suite.addTest(new TypedLiteralUnitTest("testType"));
+    suite.addTest(new TypedLiteralUnitTest("testProperties"));
+    return suite;
+  }
+
+
+  public void testValues() throws Exception {
+    String str = "test";
+    TypedLiteral l = (TypedLiteral)TypedLiteral.newLiteral(str, URI.create(XSD_NS + "string"), null);
+    assertEquals(str, l.getValue());
+
+    l = (TypedLiteral)TypedLiteral.newLiteral(str);
+    assertEquals(str, l.getValue());
+
+    String s2 = "foobar";
+    l = (TypedLiteral)TypedLiteral.newLiteral(s2, URI.create("foo:bar"), null);
+    assertEquals(s2, l.getValue());
+
+    Long v = Long.valueOf(5);
+    l = (TypedLiteral)TypedLiteral.newLiteral(v);
+    assertEquals(v, l.getValue());
+  }
+
+  public void testFilter() throws Exception {
+    Context c = new TestContext();
+    TypedLiteral l = (TypedLiteral)TypedLiteral.newLiteral("test", URI.create(XSD_NS + "string"), null);
+    assertTrue(l.test(c));
+
+    l = (TypedLiteral)TypedLiteral.newLiteral("test");
+    assertTrue(l.test(c));
+    l = (TypedLiteral)TypedLiteral.newLiteral("");
+    assertFalse(l.test(c));
+
+    l = (TypedLiteral)TypedLiteral.newLiteral("foobar", URI.create("foo:bar"), null);
+    try {
+      l.test(c);
+      fail("Got an EBV from an unknown literal type");
+    } catch (QueryException qe) {
+      assertTrue(qe.getMessage().startsWith("Type Error:"));
+    }
+
+    l = (TypedLiteral)TypedLiteral.newLiteral(Long.valueOf(5));
+    assertTrue(l.test(c));
+    l = (TypedLiteral)TypedLiteral.newLiteral(Long.valueOf(0));
+    assertFalse(l.test(c));
+  }
+
+  public void testType() throws Exception {
+    String str = "test";
+    URI t = URI.create(XSD_NS + "string");
+    TypedLiteral l = (TypedLiteral) TypedLiteral.newLiteral(str, t, null);
+    assertTrue(l.getType().isIRI());
+    assertEquals(t, l.getType().getValue());
+
+    l = (TypedLiteral)TypedLiteral.newLiteral(str);
+    assertEquals(t, l.getType().getValue());
+
+    String s2 = "foobar";
+    URI t2 = URI.create(XSD_NS + "foo:bar");
+    l = (TypedLiteral)TypedLiteral.newLiteral(s2, t2, null);
+    assertEquals(t2, l.getType().getValue());
+
+    Long v = Long.valueOf(5);
+    l = (TypedLiteral)TypedLiteral.newLiteral(v);
+    assertEquals(URI.create(XSD_NS + "long"), l.getType().getValue());
+  }
+
+  public void testProperties() throws Exception {
+    TypedLiteral l = (TypedLiteral) TypedLiteral.newLiteral("test", URI.create(XSD_NS + "string"), null);
+    assertFalse(l.isBlank());
+    assertFalse(l.isIRI());
+    assertTrue(l.isLiteral());
+    assertFalse(l.isURI());
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,76 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.Filter;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * Represents expressions that can appear in a comparison expression, used by filters
- *
- * @created Mar 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public interface ValueLiteral extends RDFTerm, Filter, ComparableExpression {
-
-  /**
-   * Returns the data represented by this expression.
-   * @return The represented data.
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public Object getValue() throws QueryException;
-
-  /**
-   * Returns the string that represents the value.  This is identical to the value for
-   * simple literals and xsd:string, and should parse to the value for most other types.
-   * However, it will also store incompatible values, in case of bad literal definitions
-   * such as 'abc'^^<xsd:integer>
-   * @return The represented data.
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public String getLexical() throws QueryException;
-
-  /**
-   * Gets the language code for this literal, if it exists.
-   * @return a language code, or an empty string if none is present
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public SimpleLiteral getLang() throws QueryException;
-
-  /**
-   * Tests if this literal is a simple literal. If it is, then the type should be xsd:string.
-   * @return <code>true</code> if this literal is simple.
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public boolean isSimple() throws QueryException;
-
-  /**
-   * Gets the type of this literal
-   * @return The URI for this literals type
-   * @throws QueryException Resolving the data for this value leads to an error.
-   */
-  public IRI getType() throws QueryException;
-
-  /**
-   * Calculates the Effective Boolean Value (EBV) of this literal.
-   * @param context The context to determine this value in. Ignored because this is a literal.
-   * @return <code>true</code> when the EBV conditions are met.
-   * @throws QueryException There was an error during resolving the literal.
-   */
-  public boolean test(Context context) throws QueryException;
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/ValueLiteral.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,76 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * Represents expressions that can appear in a comparison expression, used by filters
+ *
+ * @created Mar 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public interface ValueLiteral extends RDFTerm, Filter, ComparableExpression {
+
+  /**
+   * Returns the data represented by this expression.
+   * @return The represented data.
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public Object getValue() throws QueryException;
+
+  /**
+   * Returns the string that represents the value.  This is identical to the value for
+   * simple literals and xsd:string, and should parse to the value for most other types.
+   * However, it will also store incompatible values, in case of bad literal definitions
+   * such as 'abc'^^<xsd:integer>
+   * @return The represented data.
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public String getLexical() throws QueryException;
+
+  /**
+   * Gets the language code for this literal, if it exists.
+   * @return a language code, or an empty string if none is present
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public SimpleLiteral getLang() throws QueryException;
+
+  /**
+   * Tests if this literal is a simple literal. If it is, then the type should be xsd:string.
+   * @return <code>true</code> if this literal is simple.
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public boolean isSimple() throws QueryException;
+
+  /**
+   * Gets the type of this literal
+   * @return The URI for this literals type
+   * @throws QueryException Resolving the data for this value leads to an error.
+   */
+  public IRI getType() throws QueryException;
+
+  /**
+   * Calculates the Effective Boolean Value (EBV) of this literal.
+   * @param context The context to determine this value in. Ignored because this is a literal.
+   * @return <code>true</code> when the EBV conditions are met.
+   * @throws QueryException There was an error during resolving the literal.
+   */
+  public boolean test(Context context) throws QueryException;
+  
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Var.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,270 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import org.apache.log4j.Logger;
-import org.jrdf.graph.BlankNode;
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.jrdf.graph.URIReference;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.AbstractContextOwner;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.ContextOwner;
-import org.mulgara.query.filter.RDFTerm;
-
-
-/**
- * Marks the use of a variable.
- * This class needs a reference to the calling resolved Tuples to extract the variable
- * bindings for the current row.
- *
- * @created Mar 7, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class Var extends AbstractContextOwner implements ComparableExpression, ValueLiteral, NumericExpression {
-
-  /** Generated Serialization ID for RMI */
-  private static final long serialVersionUID = 7024038517344320135L;
-
-  /** Logger */
-  private static Logger logger = Logger.getLogger(Var.class.getName());
-
-  /** The name of this variable */
-  private String name;
-
-  /** An invalid index to indicate that a variable is not initialized */
-  private static final int NOT_INITIALIZED = -2;
-
-  /** The index of this variable in the context */
-  private int varIndex = NOT_INITIALIZED;
-
-  /** The owner of the current context */
-  private ContextOwner contextOwner = null;
-
-  /**
-   * Instantiate a variable.
-   * @param n The boolean to wrap
-   */
-  public Var(String name) {
-    this.name = name;
-  }
-
-  /**
-   * Tests if this variable is bound.
-   * @return <code>true</code> if the variable is unknown, or known and not bound.
-   */
-  public boolean isBound() throws QueryException {
-    // this will set varIndex if it is not set yet
-    Context context = getLocalContext();
-    // now that varIndex is set, we can use it in the context
-    return context.isBound(varIndex);
-  }
-
-  /** {@inheritDoc} */
-  public Object getValue() throws QueryException {
-    return resolve().getValue();
-  }
-
-  /** {@inheritDoc} */
-  public Number getNumber() throws QueryException {
-    Object result = getValue();
-    if (result instanceof Number) return (Number)result;
-    throw new QueryException("Variable '" + name + "' did not resolve to a number. Got: " + result);
-  }
-
-  /**
-   * {@inheritDoc}
-   * Uses {@link #resolveComparable()} for throwing the QueryException if this variable
-   * does not resolve to a literal, and hence does not have a lexical form.
-   */
-  public String getLexical() throws QueryException {
-    ComparableExpression e = resolveComparable();
-    if (e.isLiteral()) return ((ValueLiteral)e).getLexical();
-    // fall back to getting a string out of a complex expression
-    return e.getValue().toString();
-  }
-
-  /**@see org.mulgara.query.filter.value.ValueLiteral#getType() */
-  public IRI getType() throws QueryException {
-    ComparableExpression e = resolveComparable();
-    if (!e.isLiteral()) throw new QueryException("Only literals are typed");
-    return ((ValueLiteral)e).getType();
-  }
-
-  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
-  public boolean isSimple() throws QueryException {
-    return ((ValueLiteral)resolve()).isSimple();
-  }
-
-  /** {@inheritDoc} */
-  public boolean equals(RDFTerm v) throws QueryException {
-    return resolve().equals(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean notEquals(RDFTerm v) throws QueryException {
-    return resolve().notEquals(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean greaterThan(ComparableExpression v) throws QueryException {
-    return resolveComparable().greaterThan(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
-    return resolveComparable().greaterThanEqualTo(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean lessThan(ComparableExpression v) throws QueryException {
-    return resolveComparable().lessThan(v);
-  }
-
-  /** {@inheritDoc} */
-  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
-    return resolveComparable().lessThanEqualTo(v);
-  }
-
-  /**
-   * Resolve this variable in its current context
-   * @return An expression value wrapping the data bound to this point
-   * @throws QueryException Indicates an error getting data out of the context, or globalizing.
-   */
-  public ComparableExpression resolveComparable() throws QueryException {
-    RDFTerm v = resolve();
-    if (!(v instanceof ComparableExpression)) throw new QueryException("Type Error: Cannot compare against a: " + v.getClass().getSimpleName());
-    return (ComparableExpression)v;
-  }
-
-  /** {@inheritDoc} */
-  public boolean isBlank() throws QueryException {
-    return resolve().isBlank();
-  }
-
-  /** {@inheritDoc} */
-  public boolean isIRI() throws QueryException {
-    return resolve().isIRI();
-  }
-
-  /**
-   * {@inheritDoc}
-   * The operation of this method is depended on the context in which it was called.
-   * If it is called without a context owner, then this means it was called during
-   * Filter construction, and we want to indicate that it is valid to treat this as a literal.
-   * @return <code>true</code> if there is no context, or else it calls isLiteral on the resolved value.
-   */
-  public boolean isLiteral() throws QueryException {
-    return contextOwner == null ? true : resolve().isLiteral();
-  }
-
-  /** {@inheritDoc} */
-  public boolean isURI() throws QueryException {
-    return resolve().isURI();
-  }
-
-  /** {@inheritDoc} */
-  public boolean sameTerm(RDFTerm v) throws QueryException {
-    return resolve().sameTerm(v);
-  }
-
-  /**
-   * {@inheritDoc}
-   * @throws QueryException If there was an error resolving the variable, or the variable does not
-   *         resolve to a literal.
-   */
-  public SimpleLiteral getLang() throws QueryException {
-    RDFTerm term = resolve();
-    if (!term.isLiteral()) throw new QueryException("Cannot get a language tag on a non-literal: " + term.getClass().getSimpleName());
-    return ((ValueLiteral)term).getLang();
-  }
-
-  public boolean test(Context context) throws QueryException {
-    setCurrentContext(context);
-    RDFTerm term = resolve();
-    if (!term.isLiteral()) throw new QueryException("Cannot get an effective boolean value for a non-literal: " + term.getClass().getSimpleName());
-    return ((ComparableExpression)term).test(context);
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
-  public ContextOwner getContextOwner() {
-    return contextOwner;
-  }
-
-  /** @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner) */
-  public void setContextOwner(ContextOwner owner) {
-    this.contextOwner = owner;
-  }
-
-  /**
-   * Resolve this variable in its current context
-   * @return An expression value wrapping the data bound to this point
-   * @throws QueryException Indicates an error getting data out of the context, or globalizing.
-   */
-  public RDFTerm resolve() throws QueryException {
-    long gNode = getLocalContext().getColumnValue(varIndex);
-
-    Node node;
-    try {
-      node = getContextOwner().getCurrentContext().globalize(gNode);
-    } catch (QueryException qe) {
-      throw new QueryException("Unable to globalize variable " + name + " from id <" + gNode + ">", qe.getCause());
-    }
-
-    return convertToExpr(node);
-  }
-
-  /**
-   * Converts a node to an appropriate ExpressionValue
-   * @param node The node to convert
-   * @return A new ExpressionValue
-   */
-  private RDFTerm convertToExpr(Node node) throws QueryException {
-    if (node instanceof BlankNode) return new BlankNodeValue((BlankNode)node);
-    
-    if (node instanceof URIReference) return new IRI(((URIReference)node).getURI());
-    
-    if (!(node instanceof Literal)) throw new QueryException("Unknown type for: " + node);
-
-    Literal l = (Literal)node;
-    return TypedLiteral.newLiteral(l.getLexicalForm(), l.getDatatypeURI(), l.getLanguage());
-  }
-
-  /**
-   * Return the current context, using a test context over that provided by the context owner if possible
-   * Updates the value of varIndex.
-   * @return The current context to use.
-   */
-  private Context getLocalContext() {
-    Context localContext = getCurrentContext();
-    if (localContext == null) {
-      localContext = getContextOwner().getCurrentContext();
-    } else {
-      if (localContext != getContextOwner().getCurrentContext()) logger.warn("Unexpected different local context");
-    }
-    return setVarIndex(localContext);
-  }
-
-  /**
-   * Sets the varIndex if (and only if) it has not been set before.
-   * @param context The context to use to get the variable index.
-   * @return The context used, so it can be reused for the next operation.
-   */
-  private Context setVarIndex(Context context) {
-    if (varIndex == NOT_INITIALIZED) varIndex = context.getInternalColumnIndex(name);
-    return context;
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/Var.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/Var.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,270 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import org.apache.log4j.Logger;
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.jrdf.graph.URIReference;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.AbstractContextOwner;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.RDFTerm;
+
+
+/**
+ * Marks the use of a variable.
+ * This class needs a reference to the calling resolved Tuples to extract the variable
+ * bindings for the current row.
+ *
+ * @created Mar 7, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class Var extends AbstractContextOwner implements ComparableExpression, ValueLiteral, NumericExpression {
+
+  /** Generated Serialization ID for RMI */
+  private static final long serialVersionUID = 7024038517344320135L;
+
+  /** Logger */
+  private static Logger logger = Logger.getLogger(Var.class.getName());
+
+  /** The name of this variable */
+  private String name;
+
+  /** An invalid index to indicate that a variable is not initialized */
+  private static final int NOT_INITIALIZED = -2;
+
+  /** The index of this variable in the context */
+  private int varIndex = NOT_INITIALIZED;
+
+  /** The owner of the current context */
+  private ContextOwner contextOwner = null;
+
+  /**
+   * Instantiate a variable.
+   * @param n The boolean to wrap
+   */
+  public Var(String name) {
+    this.name = name;
+  }
+
+  /**
+   * Tests if this variable is bound.
+   * @return <code>true</code> if the variable is unknown, or known and not bound.
+   */
+  public boolean isBound() throws QueryException {
+    // this will set varIndex if it is not set yet
+    Context context = getLocalContext();
+    // now that varIndex is set, we can use it in the context
+    return context.isBound(varIndex);
+  }
+
+  /** {@inheritDoc} */
+  public Object getValue() throws QueryException {
+    return resolve().getValue();
+  }
+
+  /** {@inheritDoc} */
+  public Number getNumber() throws QueryException {
+    Object result = getValue();
+    if (result instanceof Number) return (Number)result;
+    throw new QueryException("Variable '" + name + "' did not resolve to a number. Got: " + result);
+  }
+
+  /**
+   * {@inheritDoc}
+   * Uses {@link #resolveComparable()} for throwing the QueryException if this variable
+   * does not resolve to a literal, and hence does not have a lexical form.
+   */
+  public String getLexical() throws QueryException {
+    ComparableExpression e = resolveComparable();
+    if (e.isLiteral()) return ((ValueLiteral)e).getLexical();
+    // fall back to getting a string out of a complex expression
+    return e.getValue().toString();
+  }
+
+  /**@see org.mulgara.query.filter.value.ValueLiteral#getType() */
+  public IRI getType() throws QueryException {
+    ComparableExpression e = resolveComparable();
+    if (!e.isLiteral()) throw new QueryException("Only literals are typed");
+    return ((ValueLiteral)e).getType();
+  }
+
+  /** @see org.mulgara.query.filter.value.ValueLiteral#isSimple() */
+  public boolean isSimple() throws QueryException {
+    return ((ValueLiteral)resolve()).isSimple();
+  }
+
+  /** {@inheritDoc} */
+  public boolean equals(RDFTerm v) throws QueryException {
+    return resolve().equals(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean notEquals(RDFTerm v) throws QueryException {
+    return resolve().notEquals(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean greaterThan(ComparableExpression v) throws QueryException {
+    return resolveComparable().greaterThan(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean greaterThanEqualTo(ComparableExpression v) throws QueryException {
+    return resolveComparable().greaterThanEqualTo(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean lessThan(ComparableExpression v) throws QueryException {
+    return resolveComparable().lessThan(v);
+  }
+
+  /** {@inheritDoc} */
+  public boolean lessThanEqualTo(ComparableExpression v) throws QueryException {
+    return resolveComparable().lessThanEqualTo(v);
+  }
+
+  /**
+   * Resolve this variable in its current context
+   * @return An expression value wrapping the data bound to this point
+   * @throws QueryException Indicates an error getting data out of the context, or globalizing.
+   */
+  public ComparableExpression resolveComparable() throws QueryException {
+    RDFTerm v = resolve();
+    if (!(v instanceof ComparableExpression)) throw new QueryException("Type Error: Cannot compare against a: " + v.getClass().getSimpleName());
+    return (ComparableExpression)v;
+  }
+
+  /** {@inheritDoc} */
+  public boolean isBlank() throws QueryException {
+    return resolve().isBlank();
+  }
+
+  /** {@inheritDoc} */
+  public boolean isIRI() throws QueryException {
+    return resolve().isIRI();
+  }
+
+  /**
+   * {@inheritDoc}
+   * The operation of this method is depended on the context in which it was called.
+   * If it is called without a context owner, then this means it was called during
+   * Filter construction, and we want to indicate that it is valid to treat this as a literal.
+   * @return <code>true</code> if there is no context, or else it calls isLiteral on the resolved value.
+   */
+  public boolean isLiteral() throws QueryException {
+    return contextOwner == null ? true : resolve().isLiteral();
+  }
+
+  /** {@inheritDoc} */
+  public boolean isURI() throws QueryException {
+    return resolve().isURI();
+  }
+
+  /** {@inheritDoc} */
+  public boolean sameTerm(RDFTerm v) throws QueryException {
+    return resolve().sameTerm(v);
+  }
+
+  /**
+   * {@inheritDoc}
+   * @throws QueryException If there was an error resolving the variable, or the variable does not
+   *         resolve to a literal.
+   */
+  public SimpleLiteral getLang() throws QueryException {
+    RDFTerm term = resolve();
+    if (!term.isLiteral()) throw new QueryException("Cannot get a language tag on a non-literal: " + term.getClass().getSimpleName());
+    return ((ValueLiteral)term).getLang();
+  }
+
+  public boolean test(Context context) throws QueryException {
+    setCurrentContext(context);
+    RDFTerm term = resolve();
+    if (!term.isLiteral()) throw new QueryException("Cannot get an effective boolean value for a non-literal: " + term.getClass().getSimpleName());
+    return ((ComparableExpression)term).test(context);
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#getContextOwner() */
+  public ContextOwner getContextOwner() {
+    return contextOwner;
+  }
+
+  /** @see org.mulgara.query.filter.RDFTerm#setContextOwner(org.mulgara.query.filter.ContextOwner) */
+  public void setContextOwner(ContextOwner owner) {
+    this.contextOwner = owner;
+  }
+
+  /**
+   * Resolve this variable in its current context
+   * @return An expression value wrapping the data bound to this point
+   * @throws QueryException Indicates an error getting data out of the context, or globalizing.
+   */
+  public RDFTerm resolve() throws QueryException {
+    long gNode = getLocalContext().getColumnValue(varIndex);
+
+    Node node;
+    try {
+      node = getContextOwner().getCurrentContext().globalize(gNode);
+    } catch (QueryException qe) {
+      throw new QueryException("Unable to globalize variable " + name + " from id <" + gNode + ">", qe.getCause());
+    }
+
+    return convertToExpr(node);
+  }
+
+  /**
+   * Converts a node to an appropriate ExpressionValue
+   * @param node The node to convert
+   * @return A new ExpressionValue
+   */
+  private RDFTerm convertToExpr(Node node) throws QueryException {
+    if (node instanceof BlankNode) return new BlankNodeValue((BlankNode)node);
+    
+    if (node instanceof URIReference) return new IRI(((URIReference)node).getURI());
+    
+    if (!(node instanceof Literal)) throw new QueryException("Unknown type for: " + node);
+
+    Literal l = (Literal)node;
+    return TypedLiteral.newLiteral(l.getLexicalForm(), l.getDatatypeURI(), l.getLanguage());
+  }
+
+  /**
+   * Return the current context, using a test context over that provided by the context owner if possible
+   * Updates the value of varIndex.
+   * @return The current context to use.
+   */
+  private Context getLocalContext() {
+    Context localContext = getCurrentContext();
+    if (localContext == null) {
+      localContext = getContextOwner().getCurrentContext();
+    } else {
+      if (localContext != getContextOwner().getCurrentContext()) logger.warn("Unexpected different local context");
+    }
+    return setVarIndex(localContext);
+  }
+
+  /**
+   * Sets the varIndex if (and only if) it has not been set before.
+   * @param context The context to use to get the variable index.
+   * @return The context used, so it can be reused for the next operation.
+   */
+  private Context setVarIndex(Context context) {
+    if (varIndex == NOT_INITIALIZED) varIndex = context.getInternalColumnIndex(name);
+    return context;
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java
===================================================================
--- branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,323 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.query.filter.value;
-
-import java.net.URI;
-
-import org.jrdf.graph.BlankNode;
-import org.jrdf.graph.Literal;
-import org.jrdf.graph.Node;
-import org.jrdf.graph.URIReference;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.Context;
-import org.mulgara.query.filter.ContextOwner;
-import org.mulgara.query.filter.TestContext;
-import org.mulgara.query.rdf.BlankNodeImpl;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-
-import junit.framework.Test;
-import junit.framework.TestCase;
-import junit.framework.TestSuite;
-
-
-/**
- * Tests the variable class.
- *
- * @created Apr 10, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class VarUnitTest extends TestCase implements ContextOwner {
-
-  /** The context for the variables */
-  TestContext context;
-
-  /** A literal used in the context */
-  Literal foo = new LiteralImpl("foo");
-
-  /** A URI used in the context */
-  URIReference foobar = new URIReferenceImpl(URI.create("foo:bar"));
-
-  /** A blank node used in the context */
-  BlankNode bn = new BlankNodeImpl();
-
-  /**
-   * Build the unit test.
-   * @param name The name of the test
-   */
-  public VarUnitTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Hook for test runner to obtain a test suite from.
-   * @return The test suite
-   */
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new VarUnitTest("testLiteral"));
-    suite.addTest(new VarUnitTest("testURI"));
-    suite.addTest(new VarUnitTest("testBN"));
-    suite.addTest(new VarUnitTest("testUnbound"));
-    return suite;
-  }
-
-  public void setUp() throws Exception {
-    String[] vars = new String[] {"x"};
-
-    Node[][] rows = {
-      new Node[] {foo},
-      new Node[] {foobar},
-      new Node[] {bn},
-      new Node[] {null}
-    };
-    context = new TestContext(vars, rows);
-  }
-
-  public void testLiteral() throws Exception {
-    Var v = new Var("x");
-    v.setContextOwner(this);
-    context.beforeFirst();
-    context.next();
-
-    assertTrue(v.isBound());
-    assertEquals(foo.getLexicalForm(), v.getValue());
-    try {
-      v.getNumber();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    assertEquals(foo.getLexicalForm(), v.getLexical());
-    assertEquals(SimpleLiteral.STRING_TYPE, v.getType());
-    assertTrue(v.equals(new SimpleLiteral("foo")));
-    assertFalse(v.notEquals(new SimpleLiteral("foo")));
-    assertTrue(v.greaterThan(new SimpleLiteral("eoo")));
-    assertTrue(v.greaterThanEqualTo(new SimpleLiteral("eoo")));
-    assertTrue(v.lessThan(new SimpleLiteral("goo")));
-    assertTrue(v.lessThanEqualTo(new SimpleLiteral("goo")));
-    assertFalse(v.isBlank());
-    assertFalse(v.isIRI());
-    assertTrue(v.isLiteral());
-    assertFalse(v.isURI());
-    assertTrue(v.sameTerm(new SimpleLiteral("foo")));
-    assertEquals(v.getLang(), SimpleLiteral.EMPTY);
-    assertTrue(v.test(context));
-  }
-
-  public void testURI() throws Exception {
-    Var v = new Var("x");
-    v.setContextOwner(this);
-    context.beforeFirst();
-    context.next();
-    context.next();
-
-    assertTrue(v.isBound());
-    assertEquals(foobar.getURI(), v.getValue());
-    try {
-      v.getNumber();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      assertEquals(foobar.getURI().toString(), v.getLexical());
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.getType();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    IRI i = new IRI(foobar.getURI());
-    assertTrue(v.equals(i));
-    assertFalse(v.notEquals(i));
-
-    SimpleLiteral s = new SimpleLiteral("foobar");
-    try {
-      v.greaterThan(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.greaterThanEqualTo(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.lessThan(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.lessThanEqualTo(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-
-    assertFalse(v.isBlank());
-    assertTrue(v.isIRI());
-    assertFalse(v.isLiteral());
-    assertTrue(v.isURI());
-    assertTrue(v.sameTerm(i));
-    try {
-      v.getLang();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.test(context);
-      assertTrue(false);
-    } catch (QueryException e) { }
-  }
-
-  public void testBN() throws Exception {
-    Var v = new Var("x");
-    v.setContextOwner(this);
-    context.beforeFirst();
-    context.next();
-    context.next();
-    context.next();
-
-    assertTrue(v.isBound());
-    assertEquals(bn, v.getValue());
-    try {
-      v.getNumber();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      assertEquals(bn.toString(), v.getLexical());
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.getType();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    BlankNodeValue b = new BlankNodeValue(bn);
-    assertTrue(v.equals(b));
-    assertFalse(v.notEquals(b));
-
-    SimpleLiteral s = new SimpleLiteral("foobar");
-    try {
-      v.greaterThan(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.greaterThanEqualTo(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.lessThan(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.lessThanEqualTo(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-
-    assertTrue(v.isBlank());
-    assertFalse(v.isIRI());
-    assertFalse(v.isLiteral());
-    assertFalse(v.isURI());
-    assertTrue(v.sameTerm(b));
-    try {
-      v.getLang();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.test(context);
-      assertTrue(false);
-    } catch (QueryException e) { }
-  }
-
-  public void testUnbound() throws Exception {
-    Var v = new Var("x");
-    v.setContextOwner(this);
-    context.beforeFirst();
-    context.next();
-    context.next();
-    context.next();
-    context.next();
-
-    assertFalse(v.isBound());
-    try {
-      v.getValue();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.getNumber();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.getLexical();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.getType();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    BlankNodeValue b = new BlankNodeValue(bn);
-    try {
-      v.equals(b);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.notEquals(b);
-      assertTrue(false);
-    } catch (QueryException e) { }
-
-    SimpleLiteral s = new SimpleLiteral("foobar");
-    try {
-      v.greaterThan(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.greaterThanEqualTo(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.lessThan(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.lessThanEqualTo(s);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.isBlank();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.isIRI();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.isLiteral();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.isURI();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.sameTerm(b);
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.getLang();
-      assertTrue(false);
-    } catch (QueryException e) { }
-    try {
-      v.test(context);
-      assertTrue(false);
-    } catch (QueryException e) { }
-  }
-
-  public Context getCurrentContext() {
-    return context;
-  }
-
-  public void setCurrentContext(Context context) { /* no op */ }
-  
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java (from rev 855, branches/mgr-61-sparql/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/value/VarUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,323 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.query.filter.value;
+
+import java.net.URI;
+
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.jrdf.graph.Node;
+import org.jrdf.graph.URIReference;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.TestContext;
+import org.mulgara.query.rdf.BlankNodeImpl;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+
+
+/**
+ * Tests the variable class.
+ *
+ * @created Apr 10, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class VarUnitTest extends TestCase implements ContextOwner {
+
+  /** The context for the variables */
+  TestContext context;
+
+  /** A literal used in the context */
+  Literal foo = new LiteralImpl("foo");
+
+  /** A URI used in the context */
+  URIReference foobar = new URIReferenceImpl(URI.create("foo:bar"));
+
+  /** A blank node used in the context */
+  BlankNode bn = new BlankNodeImpl();
+
+  /**
+   * Build the unit test.
+   * @param name The name of the test
+   */
+  public VarUnitTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Hook for test runner to obtain a test suite from.
+   * @return The test suite
+   */
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new VarUnitTest("testLiteral"));
+    suite.addTest(new VarUnitTest("testURI"));
+    suite.addTest(new VarUnitTest("testBN"));
+    suite.addTest(new VarUnitTest("testUnbound"));
+    return suite;
+  }
+
+  public void setUp() throws Exception {
+    String[] vars = new String[] {"x"};
+
+    Node[][] rows = {
+      new Node[] {foo},
+      new Node[] {foobar},
+      new Node[] {bn},
+      new Node[] {null}
+    };
+    context = new TestContext(vars, rows);
+  }
+
+  public void testLiteral() throws Exception {
+    Var v = new Var("x");
+    v.setContextOwner(this);
+    context.beforeFirst();
+    context.next();
+
+    assertTrue(v.isBound());
+    assertEquals(foo.getLexicalForm(), v.getValue());
+    try {
+      v.getNumber();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    assertEquals(foo.getLexicalForm(), v.getLexical());
+    assertEquals(SimpleLiteral.STRING_TYPE, v.getType());
+    assertTrue(v.equals(new SimpleLiteral("foo")));
+    assertFalse(v.notEquals(new SimpleLiteral("foo")));
+    assertTrue(v.greaterThan(new SimpleLiteral("eoo")));
+    assertTrue(v.greaterThanEqualTo(new SimpleLiteral("eoo")));
+    assertTrue(v.lessThan(new SimpleLiteral("goo")));
+    assertTrue(v.lessThanEqualTo(new SimpleLiteral("goo")));
+    assertFalse(v.isBlank());
+    assertFalse(v.isIRI());
+    assertTrue(v.isLiteral());
+    assertFalse(v.isURI());
+    assertTrue(v.sameTerm(new SimpleLiteral("foo")));
+    assertEquals(v.getLang(), SimpleLiteral.EMPTY);
+    assertTrue(v.test(context));
+  }
+
+  public void testURI() throws Exception {
+    Var v = new Var("x");
+    v.setContextOwner(this);
+    context.beforeFirst();
+    context.next();
+    context.next();
+
+    assertTrue(v.isBound());
+    assertEquals(foobar.getURI(), v.getValue());
+    try {
+      v.getNumber();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      assertEquals(foobar.getURI().toString(), v.getLexical());
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.getType();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    IRI i = new IRI(foobar.getURI());
+    assertTrue(v.equals(i));
+    assertFalse(v.notEquals(i));
+
+    SimpleLiteral s = new SimpleLiteral("foobar");
+    try {
+      v.greaterThan(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.greaterThanEqualTo(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.lessThan(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.lessThanEqualTo(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+
+    assertFalse(v.isBlank());
+    assertTrue(v.isIRI());
+    assertFalse(v.isLiteral());
+    assertTrue(v.isURI());
+    assertTrue(v.sameTerm(i));
+    try {
+      v.getLang();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.test(context);
+      assertTrue(false);
+    } catch (QueryException e) { }
+  }
+
+  public void testBN() throws Exception {
+    Var v = new Var("x");
+    v.setContextOwner(this);
+    context.beforeFirst();
+    context.next();
+    context.next();
+    context.next();
+
+    assertTrue(v.isBound());
+    assertEquals(bn, v.getValue());
+    try {
+      v.getNumber();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      assertEquals(bn.toString(), v.getLexical());
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.getType();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    BlankNodeValue b = new BlankNodeValue(bn);
+    assertTrue(v.equals(b));
+    assertFalse(v.notEquals(b));
+
+    SimpleLiteral s = new SimpleLiteral("foobar");
+    try {
+      v.greaterThan(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.greaterThanEqualTo(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.lessThan(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.lessThanEqualTo(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+
+    assertTrue(v.isBlank());
+    assertFalse(v.isIRI());
+    assertFalse(v.isLiteral());
+    assertFalse(v.isURI());
+    assertTrue(v.sameTerm(b));
+    try {
+      v.getLang();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.test(context);
+      assertTrue(false);
+    } catch (QueryException e) { }
+  }
+
+  public void testUnbound() throws Exception {
+    Var v = new Var("x");
+    v.setContextOwner(this);
+    context.beforeFirst();
+    context.next();
+    context.next();
+    context.next();
+    context.next();
+
+    assertFalse(v.isBound());
+    try {
+      v.getValue();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.getNumber();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.getLexical();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.getType();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    BlankNodeValue b = new BlankNodeValue(bn);
+    try {
+      v.equals(b);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.notEquals(b);
+      assertTrue(false);
+    } catch (QueryException e) { }
+
+    SimpleLiteral s = new SimpleLiteral("foobar");
+    try {
+      v.greaterThan(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.greaterThanEqualTo(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.lessThan(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.lessThanEqualTo(s);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.isBlank();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.isIRI();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.isLiteral();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.isURI();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.sameTerm(b);
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.getLang();
+      assertTrue(false);
+    } catch (QueryException e) { }
+    try {
+      v.test(context);
+      assertTrue(false);
+    } catch (QueryException e) { }
+  }
+
+  public Context getCurrentContext() {
+    return context;
+  }
+
+  public void setCurrentContext(Context context) { /* no op */ }
+  
+}

Modified: trunk/src/jar/query/java/org/mulgara/query/rdf/XSD.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/rdf/XSD.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/query/java/org/mulgara/query/rdf/XSD.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -31,7 +31,6 @@
 import java.net.URI;
 import java.util.Date;
 import java.util.Locale;
-import java.text.SimpleDateFormat;
 import java.text.ParseException;
 
 // Date utils
@@ -87,6 +86,11 @@
   public final static URI DECIMAL_URI = URI.create(NAMESPACE + "decimal");
 
   /**
+   * URI for the XML Schema <code>xsd:decimal</code> datatype.
+   */
+  public final static URI INT_URI = URI.create(NAMESPACE + "int");
+
+  /**
    * URI for the XML Schema <code>xsd:float</code> datatype;
    */
   public final static URI FLOAT_URI = URI.create(NAMESPACE + "float");

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/ConstraintOperations.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/ConstraintOperations.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/ConstraintOperations.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -148,7 +148,7 @@
       if (op == null) {
         throw new QueryException("Unknown ModelExpression type: " + modelExpr.getClass() + " known types: " + modelResolutionHandlers.keySet());
       }
-        Tuples result = op.resolve(context, modelExpr, constraint);
+      Tuples result = op.resolve(context, modelExpr, constraint);
 
       if (logger.isDebugEnabled()) {
         logger.debug("Resolved " + constraint + " against ModelExpression[" + modelExpr.getClass() + "] to: " + result);

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -54,6 +54,7 @@
 
 // Local packages
 import org.mulgara.query.*;
+import org.mulgara.query.rdf.URIReferenceImpl;
 import org.mulgara.resolver.spi.ConstraintBindingHandler;
 import org.mulgara.resolver.spi.ConstraintLocalization;
 import org.mulgara.resolver.spi.ConstraintModelRewrite;
@@ -70,13 +71,12 @@
  * @created 2007-11-09
  * @author <a href="mailto:andrae at netymon.com">Andrae Muys</a>
  * @company <a href="http://www.netymon.com">Netymon Pty Ltd</a>
- * @copyright &copy;2004 <a href="http://www.tucanatech.com/">Tucana
- *   Technology, Inc</a>
  * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
  */
 class DefaultConstraintHandlers
 {
   /** Logger.  */
+  @SuppressWarnings("unused")
   private static final Logger logger = Logger.getLogger(DefaultConstraintHandlers.class.getName());
 
   static void initializeHandlers() {
@@ -87,6 +87,7 @@
     initializeConstraintLocalizations();
   }
 
+  @SuppressWarnings("unchecked")
   static void initializeModelResolutionHandlers() {
     ConstraintOperations.addModelResolutionHandlers(new NVPair[]
       {
@@ -125,10 +126,17 @@
                                 Constraint constraint) throws Exception {
             return context.resolve((ModelResource)modelExpr, (Constraint)constraint);
           }
+        }),
+        new NVPair(ModelVariable.class, new ModelResolutionHandler() {
+          public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr,
+                                Constraint constraint) throws Exception {
+            return context.resolve(null, ConstraintOperations.rewriteConstraintModel(((ModelVariable)modelExpr).getVariable(), constraint));
+          }
         })
       });
   }
 
+  @SuppressWarnings("unchecked")
   static void initializeConstraintResolutionHandlers() {
     ConstraintOperations.addConstraintResolutionHandlers(new NVPair[]
       {
@@ -172,6 +180,20 @@
             }
           }
         }),
+        new NVPair(ConstraintOptionalJoin.class, new ConstraintResolutionHandler() {
+          public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
+            List<Tuples> args = context.resolveConstraintOperation(modelExpr, (ConstraintOperation)constraintExpr);
+            LinkedList<Tuples> stackedArgs;
+            // we know this is a linked list, but test just in case it is ever changed.
+            if (args instanceof LinkedList) stackedArgs = (LinkedList<Tuples>)args;
+            else stackedArgs = new LinkedList<Tuples>(args);
+            try {
+              return TuplesOperations.optionalJoin(stackedArgs);
+            } finally {
+              for (Tuples t: stackedArgs) t.close();
+            }
+          }
+        }),
         new NVPair(ConstraintIs.class, new ConstraintResolutionHandler() {
           public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
             ConstraintIs constraint = (ConstraintIs)constraintExpr;
@@ -186,14 +208,11 @@
             assert constraintElem != null;
             if (constraintElem.equals(Variable.FROM)) {
               return ConstraintOperations.resolveModelExpression(context, modelExpr, (Constraint)constraintExpr);
-            }
-            else if (constraintElem instanceof URIReference) {
+            } else if (constraintElem instanceof URIReference) {
               return ConstraintOperations.resolveModelExpression(context, new ModelResource(((URIReference)constraintElem).getURI()), (Constraint)constraintExpr);
-            }
-            else if (constraintElem instanceof LocalNode) {
+            } else if (constraintElem instanceof LocalNode) {
               return context.resolve(null, (ConstraintImpl)constraintExpr);
-            }
-            else if (constraintElem instanceof Variable) {
+            } else if (constraintElem instanceof Variable) {
               return context.resolve(null, (ConstraintImpl)constraintExpr);
             }
             else {
@@ -201,22 +220,6 @@
             }
           }
         }),
-/*
-        new NVPair(ConstraintNegation.class, new ConstraintResolutionHandler() {
-          public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
-            if (((ConstraintNegation)constraintExpr).getModel().equals(Variable.FROM)) {
-              return ConstraintOperations.resolveModelExpression(context, modelExpr, (Constraint)constraintExpr);
-            } else {
-              ConstraintElement constraintElem = ((ConstraintNegation)constraintExpr).getElement(3);
-              if (constraintElem instanceof URIReference) {
-                return ConstraintOperations.resolveModelExpression(context, new ModelResource(((URIReference)constraintElem).getURI()), (Constraint)constraintExpr);
-              } else {
-                throw new QueryException("Specified model not a URIReference: " + constraintElem +" is a " + constraintElem.getClass().getName() );
-              }
-            }
-          }
-        }),
-*/
         new NVPair(WalkConstraint.class, new ConstraintResolutionHandler() {
           public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
             return WalkFunction.walk(context, (WalkConstraint)constraintExpr, modelExpr, context.getResolverSession());
@@ -237,9 +240,33 @@
             return ExhaustiveTransitiveFunction.infer(context, (TransitiveConstraint)constraintExpr, modelExpr, context.getResolverSession());
           }
         }),
+        new NVPair(ConstraintFilter.class, new ConstraintResolutionHandler() {
+          public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
+            Tuples unfiltered = ConstraintOperations.resolveConstraintExpression(context, modelExpr, ((ConstraintFilter)constraintExpr).getUnfilteredConstraint());
+            try {
+              return TuplesOperations.filter(unfiltered, ((ConstraintFilter)constraintExpr).getFilter(), context);
+            } finally {
+              unfiltered.close();
+            }
+          }
+        }),
+        new NVPair(ConstraintIn.class, new ConstraintResolutionHandler() {
+          public Tuples resolve(QueryEvaluationContext context, ModelExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
+            ConstraintIn constraint = (ConstraintIn)constraintExpr;
+            ModelExpression graph;
+            if (constraint.getGraph() instanceof URIReferenceImpl) {
+              graph = new ModelResource(((URIReferenceImpl)constraint.getGraph()).getURI());
+            } else {
+              assert constraint.getGraph() instanceof Variable;
+              graph = new ModelVariable((Variable)constraint.getGraph());
+            }
+            return ConstraintOperations.resolveConstraintExpression(context, graph, constraint.getConstraintParam());
+          }
+        }),
       });
   }
 
+  @SuppressWarnings("unchecked")
   static void initializeConstraintBindingHandlers() {
     ConstraintOperations.addConstraintBindingHandlers(new NVPair[]
       {
@@ -282,13 +309,11 @@
                                       ConstraintOperations.replace(bindings, wc.getUnanchoredConstraint()));
           }
         }),
-/*
-        new NVPair(ConstraintNegation.class, new ConstraintBindingHandler() {
+        new NVPair(ConstraintFilter.class, new ConstraintBindingHandler() {
           public ConstraintExpression bindVariables(Map bindings, ConstraintExpression constraintExpr) throws Exception {
-            return new ConstraintNegation(ConstraintOperations.replace(bindings, (Constraint)constraintExpr));
+            return new ConstraintFilter(ConstraintOperations.replace(bindings, (Constraint)constraintExpr), ((ConstraintFilter)constraintExpr).getFilter());
           }
         }),
-*/
         new NVPair(ConstraintConjunction.class, new ConstraintBindingHandler() {
           public ConstraintExpression bindVariables(Map bindings, ConstraintExpression constraintExpr) throws Exception {
             return new ConstraintConjunction(ConstraintOperations.replaceOperationArgs(bindings, (ConstraintOperation)constraintExpr));
@@ -308,6 +333,7 @@
       });
   }
 
+  @SuppressWarnings("unchecked")
   static void initializeConstraintModelRewrites() {
     ConstraintOperations.addConstraintModelRewrites(new NVPair[]
       {
@@ -316,16 +342,10 @@
             return new ConstraintImpl(constraint.getElement(0), constraint.getElement(1), constraint.getElement(2), newModel);
           }
         }),
-/*
-        new NVPair(ConstraintNegation.class, new ConstraintModelRewrite() {
-          public Constraint rewrite(ConstraintElement newModel, Constraint constraint) throws Exception {
-            return new ConstraintNegation(new ConstraintImpl(constraint.getElement(0), constraint.getElement(1), constraint.getElement(2), newModel));
-          }
-        }),
-*/
       });
   }
 
+  @SuppressWarnings("unchecked")
   static void initializeConstraintLocalizations() {
     ConstraintOperations.addConstraintLocalizations(new NVPair[]
       {
@@ -337,17 +357,6 @@
                 context.localize(constraint.getElement(3)));
           }
         }),
-/*
-        new NVPair(ConstraintNegation.class, new ConstraintLocalization() {
-          public Constraint localize(QueryEvaluationContext context, Constraint constraint) throws Exception {
-            return new ConstraintNegation(new ConstraintImpl(
-                context.localize(constraint.getElement(0)),
-                context.localize(constraint.getElement(1)),
-                context.localize(constraint.getElement(2)),
-                context.localize(constraint.getElement(3))));
-          }
-        }),
-*/
       });
   }
 }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -51,26 +51,19 @@
 // Third party packages
 import org.apache.log4j.Logger;
 import org.jrdf.graph.Node;
-import org.jrdf.graph.URIReference;
 
 // Local packages
 import org.mulgara.query.*;
 import org.mulgara.query.rdf.BlankNodeImpl;
 import org.mulgara.query.rdf.LiteralImpl;
 import org.mulgara.query.rdf.URIReferenceImpl;
-import org.mulgara.resolver.spi.ConstraintBindingHandler;
-import org.mulgara.resolver.spi.ConstraintLocalization;
-import org.mulgara.resolver.spi.ConstraintModelRewrite;
-import org.mulgara.resolver.spi.ConstraintResolutionHandler;
 import org.mulgara.resolver.spi.GlobalizeException;
 import org.mulgara.resolver.spi.LocalizeException;
-import org.mulgara.resolver.spi.ModelResolutionHandler;
 import org.mulgara.resolver.spi.QueryEvaluationContext;
 import org.mulgara.resolver.spi.ResolverSession;
 import org.mulgara.store.tuples.RestrictPredicateFactory;
 import org.mulgara.store.tuples.Tuples;
 import org.mulgara.store.tuples.TuplesOperations;
-import org.mulgara.util.NVPair;
 
 /**
  * Localized version of a global {@link Query}.
@@ -109,14 +102,13 @@
     this.resolverSession = resolverSession;
   }
 
-  public List resolveConstraintOperation(ModelExpression modelExpr,
+  public List<Tuples> resolveConstraintOperation(ModelExpression modelExpr,
                                          ConstraintOperation constraintOper)
-      throws QueryException
-  {
-    List result = new ArrayList();
-    Iterator i = constraintOper.getElements().iterator();
-    while (i.hasNext()) {
-      result.add(ConstraintOperations.resolveConstraintExpression(this, modelExpr, (ConstraintExpression)i.next()));
+      throws QueryException {
+
+    LinkedList<Tuples> result = new LinkedList<Tuples>();
+    for (ConstraintExpression constraintExpr: constraintOper.getElements()) {
+      result.add(ConstraintOperations.resolveConstraintExpression(this, modelExpr, constraintExpr));
     }
 
     return result;

Copied: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesContext.java (from rev 855, branches/mgr-61-sparql/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesContext.java)
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesContext.java	                        (rev 0)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/TuplesContext.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,127 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.resolver.spi;
+
+import org.jrdf.graph.Node;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.Variable;
+import org.mulgara.query.filter.Context;
+import org.mulgara.resolver.spi.GlobalizeException;
+import org.mulgara.resolver.spi.ResolverSession;
+import org.mulgara.store.tuples.Tuples;
+
+
+/**
+ * A {@link org.mulgara.query.filter.Context} based on {@link org.mulgara.store.tuples.Tuples}.
+ * This is used to resolve values out of a given Tuples in a given Context. The Tuples used
+ * must be the Tuples being iterated on by the Filter, else synchronization will be lost
+ * and the results will be wrong.
+ *
+ * @created Mar 24, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class TuplesContext implements Context {
+
+  /** The tuples containing variables and bindings. */
+  private Tuples tuples;
+
+  /** The session used for globalizing info. */
+  private ResolverSession session;
+
+  /**
+   * Creates a new context for processing a filter.
+   * @param tuples The variables and bindings to use in filtering. Not all variables need be bound.
+   * @param session The session used for globalizing the local data found in the filter.
+   */
+  public TuplesContext(Tuples tuples, ResolverSession session) {
+    this.tuples = tuples;
+    this.session = session;
+  }
+
+
+  /**
+   * Creates a new context for processing a filter, based on an existing context and a new Tuples.
+   * @param tuples The variables and bindings to use in filtering. Not all variables need be bound.
+   * @param TuplesContext An existing context to get session information from.
+   */
+  public TuplesContext(Tuples tuples, TuplesContext otherContext) {
+    this.tuples = tuples;
+    this.session = otherContext.session;
+  }
+
+
+  /**
+   * Updates the Tuples that this context applies to. Usually done when a clone of the original
+   * tuples is about to be used.
+   * @param tuples The tuples to set
+   */
+  public void setTuples(Tuples tuples) {
+    this.tuples = tuples;
+  }
+
+
+  /**
+   * Gets the current binding to a local value (a long) for a given internal column number.
+   * @return the value in the column number specified in the current context.
+   */
+  public long getColumnValue(int columnNumber) throws QueryException {
+    try {
+      return tuples.getColumnValue(columnNumber);
+    } catch (Exception te) {  // TuplesException
+      throw new QueryException("Error resolving value", te);
+    }
+  }
+
+  
+  /**
+   * Tests if a given column is bound in the current context.
+   * @return <code>true</code> iff the column exists and is bound.
+   */
+  public boolean isBound(int columnNumber) throws QueryException {
+    try {
+      return columnNumber != NOT_BOUND && tuples.getColumnValue(columnNumber) != Tuples.UNBOUND;
+    } catch (Exception te) {  // TuplesException
+      throw new QueryException("Error resolving column", te);
+    }
+  }
+
+  
+  /**
+   * Gets the internal column number for a column with the given name
+   * @param name The name of the column to search for.
+   * @return The column number for the column with the given name.
+   */
+  public int getInternalColumnIndex(String name) {
+    try {
+      return tuples.getColumnIndex(new Variable(name));
+    } catch (Exception te) {  // TuplesException
+      return NOT_BOUND;
+    }
+  }
+
+  /**
+   * Globalize a gNode into a data object.
+   * @param gNode The graph node to globalize
+   * @return A {@link org.jrdf.graph.Node} for the given graph node.
+   * @throws QueryException If a globalize exception is encountered.
+   */
+  public Node globalize(long gNode) throws QueryException {
+    try {
+      return session.globalize(gNode);
+    } catch (GlobalizeException te) {
+      throw new QueryException("Unable to globalize id <" + gNode + ">", te);
+    }
+  }
+  
+}

Copied: trunk/src/jar/sparql-interpreter (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter)

Deleted: trunk/src/jar/sparql-interpreter/build.xml
===================================================================
--- branches/mgr-61-sparql/src/jar/sparql-interpreter/build.xml	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/sparql-interpreter/build.xml	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!DOCTYPE project>
-
-<!-- =================================================================== -->
-<!--                       Project definition                            -->
-<!-- =================================================================== -->
-<project name="sparql-interpreter" default="sparql-int-jar" basedir="../../..">
-
-  <!-- =================================================================== -->
-  <!--                      Property Definitions                           -->
-  <!-- =================================================================== -->
-
-  <!-- =================================================================== -->
-  <!--                              Imports                                -->
-  <!-- =================================================================== -->
-
-  <!-- =================================================================== -->
-  <!--                          Path Definitions                           -->
-  <!-- =================================================================== -->
-  <path id="sparql-int-classpath">
-
-    <path refid="common-classpath"/>
-    <fileset file="${query.dist.dir}/${query.jar}"/>
-  </path>
-
-  <path id="sparql-int-test-classpath">
-
-    <path refid="sparql-int-classpath"/>
-
-    <fileset file="${sparql-int.dist.dir}/${sparql-int.jar}"/>
-  </path>
-
-  <target name="sparql-int-clean"
-          description="Removes all compile generated files for the rules">
-
-    <tstamp/>
-
-    <delete dir="${sparql-int.obj.dir}"/>
-    <delete dir="${sparql-int.test.dir}"/>
-    <delete dir="${sparql-int.dist.dir}"/>
-  </target>
-
-  <target name="-sparql-int-prepare"
-          description="Creates all directories associated with the SPARQL interpreter compilation"
-          depends="-prepare-build">
-
-    <mkdir dir="${sparql-int.obj.dir}"/>
-    <mkdir dir="${sparql-int.test.dir}"/>
-    <mkdir dir="${sparql-int.dist.dir}"/>
-    <mkdir dir="${sparql-int.obj.dir}/classes"/>
-    <mkdir dir="${sparql-int.obj.dir}/classes/conf"/>
-    <mkdir dir="${sparql-int.obj.dir}/java"/>
-  </target>
-
-  <target name="-sparql-int-unjar-config"
-          depends="-sparql-int-unjar-config-uptodate"
-          unless="sparql-int.unjar.config.uptodate">
-
-    <unjar src="${bin.dir}/${config.jar}" dest="${sparql-int.obj.dir}/classes"/>
-  </target>
-
-  <target name="-sparql-int-unjar-config-uptodate">
-
-    <available file="${sparql-int.obj.dir}/classes/org/mulgara/config/MulgaraConfig.class"
-               property="sparql-int.unjar.config.uptodate"/>
-  </target>
-
-  <target name="sparql-int-compile"
-          depends="-sparql-int-prepare, util-jar, config-jar, -sparql-int-unjar-config"
-          description="Compiles all SPARQL interpreter related files"
-          unless="sparql-int.classes.uptodate">
-
-    <javac destdir="${sparql-int.obj.dir}/classes" debug="on"
-           deprecation="on" source="1.5">
-
-      <classpath refid="sparql-int-classpath"/>
-
-      <src path="${sparql-int.src.dir}/java"/>
-    </javac>
-
-  </target>
-
-  <target name="sparql-int-jar"
-          depends="sparql-int-compile, config-database, -sparql-int-jar-uptodate"
-          unless="sparql-int.jar.uptodate"
-          description="Creates the SPARQL interpreter's jar">
-
-    <jar jarfile="${sparql-int.dist.dir}/${sparql-int.jar}">
-
-      <fileset dir="${sparql-int.obj.dir}/classes"/>
-      <fileset dir="${sparql-int.obj.dir}/java" includes="**/*.dat"/>
-    </jar>
-  </target>
-
-  <target name="-sparql-int-jar-uptodate">
-
-    <uptodate property="sparql-int.jar.uptodate"
-              targetfile="${sparql-int.dist.dir}/${sparql-int.jar}">
-      <srcfiles dir="${sparql-int.obj.dir}" includes="**/*"/>
-    </uptodate>
-  </target>
-
-  <target name="sparql-int-dist"
-          depends="sparql-int-jar"
-          unless="sparql-int.uptodate"
-          description="Performs all tasks related to finalising this SPARQL Interpreter and readying it for distribution">
-
-    <!-- All that's involved in the final version of the rules library
-         is the jar so we don't need to do anything because the dependencies
-         take care of the work. -->
-  </target>
-
-  <target name="sparql-int-test"
-          depends="sparql-int-jar"
-          description="Carries out unit testing for this rules">
-
-    <antcall target="component-test">
-
-      <param name="classpath.id" value="sparql-int-test-classpath"/>
-      <param name="dir" value="${sparql-int.src.dir}"/>
-      <param name="jar" value="${sparql-int.jar}"/>
-    </antcall>
-  </target>
-
-  <target name="sparql-int-javadoc"
-          depends="sparql-int-jar"
-          description="Creates the javadoc for this SPARQL Interpreter module">
-
-    <antcall target="javadoc">
-
-      <param name="javadoc.package" value="org.mulgara.sparql.*"/>
-      <param name="javadoc.classpath" value="sparql-int-classpath"/>
-      <param name="javadoc.sourcepath" value="${sparql-int.src.dir}/java"/>
-    </antcall>
-  </target>
-
-  <target name="sparql-int-help"
-          description="Displays the help information for this SPARQL Interpreter module">
-
-    <!-- This is similar to the main project's help except the information
-         is specific to this module -->
-
-    <echo message="Welcome to the build script for ${name}."/>
-    <echo message=""/>
-    <echo message="These targets can be invoked as follows:"/>
-    <echo message="  ./build.sh &lt;target&gt;"/>
-    <echo message=""/>
-
-    <java fork="false" classname="org.apache.tools.ant.Main" newenvironment="false">
-      <jvmarg value="${arch.bits}"/>
-      <arg line="-buildfile ${sparql-int.src.dir}/build.xml -projecthelp"/>
-    </java>
-
-  </target>
-</project>

Copied: trunk/src/jar/sparql-interpreter/build.xml (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/build.xml)
===================================================================
--- trunk/src/jar/sparql-interpreter/build.xml	                        (rev 0)
+++ trunk/src/jar/sparql-interpreter/build.xml	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE project>
+
+<!-- =================================================================== -->
+<!--                       Project definition                            -->
+<!-- =================================================================== -->
+<project name="sparql-interpreter" default="sparql-int-jar" basedir="../../..">
+
+  <!-- =================================================================== -->
+  <!--                      Property Definitions                           -->
+  <!-- =================================================================== -->
+
+  <!-- =================================================================== -->
+  <!--                              Imports                                -->
+  <!-- =================================================================== -->
+
+  <!-- =================================================================== -->
+  <!--                          Path Definitions                           -->
+  <!-- =================================================================== -->
+  <path id="sparql-int-classpath">
+
+    <path refid="common-classpath"/>
+    <fileset file="${query.dist.dir}/${query.jar}"/>
+  </path>
+
+  <path id="sparql-int-test-classpath">
+
+    <path refid="sparql-int-classpath"/>
+
+    <fileset file="${sparql-int.dist.dir}/${sparql-int.jar}"/>
+  </path>
+
+  <target name="sparql-int-clean"
+          description="Removes all compile generated files for the rules">
+
+    <tstamp/>
+
+    <delete dir="${sparql-int.obj.dir}"/>
+    <delete dir="${sparql-int.test.dir}"/>
+    <delete dir="${sparql-int.dist.dir}"/>
+  </target>
+
+  <target name="-sparql-int-prepare"
+          description="Creates all directories associated with the SPARQL interpreter compilation"
+          depends="-prepare-build">
+
+    <mkdir dir="${sparql-int.obj.dir}"/>
+    <mkdir dir="${sparql-int.test.dir}"/>
+    <mkdir dir="${sparql-int.dist.dir}"/>
+    <mkdir dir="${sparql-int.obj.dir}/classes"/>
+    <mkdir dir="${sparql-int.obj.dir}/classes/conf"/>
+    <mkdir dir="${sparql-int.obj.dir}/java"/>
+  </target>
+
+  <target name="-sparql-int-unjar-config"
+          depends="-sparql-int-unjar-config-uptodate"
+          unless="sparql-int.unjar.config.uptodate">
+
+    <unjar src="${bin.dir}/${config.jar}" dest="${sparql-int.obj.dir}/classes"/>
+  </target>
+
+  <target name="-sparql-int-unjar-config-uptodate">
+
+    <available file="${sparql-int.obj.dir}/classes/org/mulgara/config/MulgaraConfig.class"
+               property="sparql-int.unjar.config.uptodate"/>
+  </target>
+
+  <target name="sparql-int-compile"
+          depends="-sparql-int-prepare, util-jar, config-jar, -sparql-int-unjar-config"
+          description="Compiles all SPARQL interpreter related files"
+          unless="sparql-int.classes.uptodate">
+
+    <javac destdir="${sparql-int.obj.dir}/classes" debug="on"
+           deprecation="on" source="1.5">
+
+      <classpath refid="sparql-int-classpath"/>
+
+      <src path="${sparql-int.src.dir}/java"/>
+    </javac>
+
+  </target>
+
+  <target name="sparql-int-jar"
+          depends="sparql-int-compile, config-database, -sparql-int-jar-uptodate"
+          unless="sparql-int.jar.uptodate"
+          description="Creates the SPARQL interpreter's jar">
+
+    <jar jarfile="${sparql-int.dist.dir}/${sparql-int.jar}">
+
+      <fileset dir="${sparql-int.obj.dir}/classes"/>
+      <fileset dir="${sparql-int.obj.dir}/java" includes="**/*.dat"/>
+    </jar>
+  </target>
+
+  <target name="-sparql-int-jar-uptodate">
+
+    <uptodate property="sparql-int.jar.uptodate"
+              targetfile="${sparql-int.dist.dir}/${sparql-int.jar}">
+      <srcfiles dir="${sparql-int.obj.dir}" includes="**/*"/>
+    </uptodate>
+  </target>
+
+  <target name="sparql-int-dist"
+          depends="sparql-int-jar"
+          unless="sparql-int.uptodate"
+          description="Performs all tasks related to finalising this SPARQL Interpreter and readying it for distribution">
+
+    <!-- All that's involved in the final version of the rules library
+         is the jar so we don't need to do anything because the dependencies
+         take care of the work. -->
+  </target>
+
+  <target name="sparql-int-test"
+          depends="sparql-int-jar"
+          description="Carries out unit testing for this rules">
+
+    <antcall target="component-test">
+
+      <param name="classpath.id" value="sparql-int-test-classpath"/>
+      <param name="dir" value="${sparql-int.src.dir}"/>
+      <param name="jar" value="${sparql-int.jar}"/>
+    </antcall>
+  </target>
+
+  <target name="sparql-int-javadoc"
+          depends="sparql-int-jar"
+          description="Creates the javadoc for this SPARQL Interpreter module">
+
+    <antcall target="javadoc">
+
+      <param name="javadoc.package" value="org.mulgara.sparql.*"/>
+      <param name="javadoc.classpath" value="sparql-int-classpath"/>
+      <param name="javadoc.sourcepath" value="${sparql-int.src.dir}/java"/>
+    </antcall>
+  </target>
+
+  <target name="sparql-int-help"
+          description="Displays the help information for this SPARQL Interpreter module">
+
+    <!-- This is similar to the main project's help except the information
+         is specific to this module -->
+
+    <echo message="Welcome to the build script for ${name}."/>
+    <echo message=""/>
+    <echo message="These targets can be invoked as follows:"/>
+    <echo message="  ./build.sh &lt;target&gt;"/>
+    <echo message=""/>
+
+    <java fork="false" classname="org.apache.tools.ant.Main" newenvironment="false">
+      <jvmarg value="${arch.bits}"/>
+      <arg line="-buildfile ${sparql-int.src.dir}/build.xml -projecthelp"/>
+    </java>
+
+  </target>
+</project>

Copied: trunk/src/jar/sparql-interpreter/java (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java)

Copied: trunk/src/jar/sparql-interpreter/java/org (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org)

Copied: trunk/src/jar/sparql-interpreter/java/org/mulgara (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara)

Copied: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql)

Deleted: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java
===================================================================
--- branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,520 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.sparql;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.mulgara.sparql.parser.cst.AndExpression;
-import org.mulgara.sparql.parser.cst.BicBound;
-import org.mulgara.sparql.parser.cst.BicDatatype;
-import org.mulgara.sparql.parser.cst.BicIsBlank;
-import org.mulgara.sparql.parser.cst.BicIsIri;
-import org.mulgara.sparql.parser.cst.BicIsLiteral;
-import org.mulgara.sparql.parser.cst.BicIsUri;
-import org.mulgara.sparql.parser.cst.BicLang;
-import org.mulgara.sparql.parser.cst.BicLangMatches;
-import org.mulgara.sparql.parser.cst.BicRegEx;
-import org.mulgara.sparql.parser.cst.BicSameTerm;
-import org.mulgara.sparql.parser.cst.BicStr;
-import org.mulgara.sparql.parser.cst.BooleanLiteral;
-import org.mulgara.sparql.parser.cst.DecimalLiteral;
-import org.mulgara.sparql.parser.cst.DoubleLiteral;
-import org.mulgara.sparql.parser.cst.Equals;
-import org.mulgara.sparql.parser.cst.Expression;
-import org.mulgara.sparql.parser.cst.FunctionCall;
-import org.mulgara.sparql.parser.cst.GreaterThan;
-import org.mulgara.sparql.parser.cst.GreaterThanEqual;
-import org.mulgara.sparql.parser.cst.IRIReference;
-import org.mulgara.sparql.parser.cst.IntegerLiteral;
-import org.mulgara.sparql.parser.cst.Divide;
-import org.mulgara.sparql.parser.cst.LessThan;
-import org.mulgara.sparql.parser.cst.LessThanEqual;
-import org.mulgara.sparql.parser.cst.LogicExpression;
-import org.mulgara.sparql.parser.cst.Minus;
-import org.mulgara.sparql.parser.cst.Multiply;
-import org.mulgara.sparql.parser.cst.Not;
-import org.mulgara.sparql.parser.cst.NotEquals;
-import org.mulgara.sparql.parser.cst.OrExpression;
-import org.mulgara.sparql.parser.cst.Plus;
-import org.mulgara.sparql.parser.cst.RDFLiteral;
-import org.mulgara.sparql.parser.cst.UnaryMinus;
-import org.mulgara.sparql.parser.cst.UnaryPlus;
-import org.mulgara.sparql.parser.cst.Variable;
-import org.mulgara.parser.MulgaraParserException;
-import org.mulgara.query.filter.And;
-import org.mulgara.query.filter.BoundFn;
-import org.mulgara.query.filter.Filter;
-import org.mulgara.query.filter.GreaterThanEqualTo;
-import org.mulgara.query.filter.IsBlankFn;
-import org.mulgara.query.filter.IsIriFn;
-import org.mulgara.query.filter.IsLiteralFn;
-import org.mulgara.query.filter.IsUriFn;
-import org.mulgara.query.filter.LangMatches;
-import org.mulgara.query.filter.LessThanEqualTo;
-import org.mulgara.query.filter.Or;
-import org.mulgara.query.filter.RDFTerm;
-import org.mulgara.query.filter.RegexFn;
-import org.mulgara.query.filter.SameTerm;
-import org.mulgara.query.filter.arithmetic.AddOperation;
-import org.mulgara.query.filter.arithmetic.DivideOperation;
-import org.mulgara.query.filter.arithmetic.MinusOperation;
-import org.mulgara.query.filter.arithmetic.MultiplyOperation;
-import org.mulgara.query.filter.value.Bool;
-import org.mulgara.query.filter.value.DataTypeFn;
-import org.mulgara.query.filter.value.ExternalFn;
-import org.mulgara.query.filter.value.IRI;
-import org.mulgara.query.filter.value.LangFn;
-import org.mulgara.query.filter.value.NumericExpression;
-import org.mulgara.query.filter.value.NumericLiteral;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.filter.value.StrFn;
-import org.mulgara.query.filter.value.TypedLiteral;
-import org.mulgara.query.filter.value.ValueLiteral;
-import org.mulgara.query.filter.value.Var;
-
-
-/**
- * This object maps a constraint from an {@link org.mulgara.sparql.parser.cst.Expression} into a
- * {@link org.mulgara.query.filter.Filter}.
- *
- * @created Apr 22, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class FilterMapper {
-
-  /** Represents the CST Filter expression that is to be mapped. */
-  private Expression cstFilter;
-
-  public FilterMapper(Expression cstFilter) {
-    this.cstFilter = cstFilter;
-  }
-
-  /**
-   * Get the Filter object described by the expression.
-   * @return A new Filter for use in a query.
-   * @throws MulgaraParserException If the mapping could not be performed due to structural errors in the CST.
-   */
-  public Filter getFilter() throws MulgaraParserException {
-    RDFTerm term = mapExpression(cstFilter);
-    if (!(term instanceof Filter)) throw new MulgaraParserException("Bad structure in the FILTER");
-    return (Filter)term;
-  }
-
-  /**
-   * The internal method for mapping a CST expression into an AST term.
-   * @param expr The expression to be mapped.
-   * @return A new AST term.
-   * @throws MulgaraParserException If the mapping could not be performed due to structural errors in the CST.
-   */
-  static private RDFTerm mapExpression(Expression expr) throws MulgaraParserException {
-    ExpressionToTerm<? extends Expression> mapper = mappers.get(expr.getClass());
-    if (mapper == null) throw new UnsupportedOperationException("Unable to handle expression: \"" + expr.getImage() + "\" (" + expr.getClass().getSimpleName() + ")");
-    return mapper.map(expr);
-  }
-
-  /**
-   * Converts a CST NumericExpression into an AST NumericExpression.
-   * @param operand The CST numeric expression.
-   * @return An AST numeric expression.
-   * @throws MulgaraParserException If the value was not mapped to an AST numeric expression.
-   */
-  static private NumericExpression mapNumber(Expression operand) throws MulgaraParserException {
-    RDFTerm op = mapExpression(operand);
-    if (!(op instanceof NumericExpression)) throw new MulgaraParserException("Non-numeric value in arithmetic operation: " + op.getClass().getSimpleName());
-    return (NumericExpression)op;
-  }
-
-  /**
-   * Converts a list of CST NumericExpressions into a list of AST NumericExpressions.
-   * @param operands The list of CST numeric expressions.
-   * @return A list of AST numeric expressions.
-   * @throws MulgaraParserException If one of the values was not mapped to an AST numeric expression.
-   */
-  static private List<NumericExpression> mapNumbers(List<org.mulgara.sparql.parser.cst.NumericExpression> operands) throws MulgaraParserException {
-    List<NumericExpression> numbers = new ArrayList<NumericExpression>(operands.size());
-    for (org.mulgara.sparql.parser.cst.NumericExpression e: operands) numbers.add(mapNumber(e));
-    return numbers;
-  }
-
-  /**
-   * Converts a CST NumericExpression into an AST NumericExpression.
-   * @param operand The CST numeric expression.
-   * @return An AST numeric expression.
-   * @throws MulgaraParserException If the value was not mapped to an AST numeric expression.
-   */
-  static private Filter mapLogic(Expression operand) throws MulgaraParserException {
-    RDFTerm op = mapExpression(operand);
-    if (!(op instanceof Filter)) throw new MulgaraParserException("Value without an Effective Boolean Value in a logic expression: " + op.getClass().getSimpleName());
-    return (Filter)op;
-  }
-
-  /**
-   * Converts a list of CST LogicExpressions into a list of AST Filters.
-   * @param operands The list of CST logic expressions.
-   * @return A list of AST filter expressions.
-   * @throws MulgaraParserException If one of the values was not mapped to an AST expression with an EBV.
-   */
-  static private Filter[] mapLogicListArr(List<LogicExpression> operands) throws MulgaraParserException {
-    List<Filter> logicOps = new ArrayList<Filter>(operands.size());
-    for (LogicExpression e: operands) logicOps.add(mapLogic(e));
-    return logicOps.toArray(new Filter[logicOps.size()]);
-  }
-
-  /**
-   * Converts a CST Expression into an AST value that resolves to a literal ({@link ValueLiteral}).
-   * @param operand The CST expression.
-   * @return An AST value expression.
-   * @throws MulgaraParserException If the value was not mapped to an AST ValueLiteral.
-   */
-  static private ValueLiteral mapValue(Expression operand) throws MulgaraParserException {
-    RDFTerm op = mapExpression(operand);
-    try {
-      if (!op.isLiteral()) throw new MulgaraParserException("Non-literal resolution when a value is required from: " + op.getClass().getSimpleName());
-    } catch (Exception qe) {  // this is a QueryException
-      throw new MulgaraParserException("Unexpected error getting value type from: " + op.getClass().getSimpleName() + ". " + qe.getMessage());
-    }
-    return (ValueLiteral)op;
-  }
-
-  //////////////////////////////////
-  // The internal mapping structures
-  //////////////////////////////////
-
-  /** Defines an interface for mapping expressions into an equivalent Filter operation. */
-  private static interface ExpressionToTerm<T extends Expression> {
-    /**
-     * A main entry point for the mapper, which will do the casting into {@link #typedMap(Expression, FilterMapper)}.
-     * @param expr The expression to map to an RDFTerm.
-     * @param parent The surrounding FilterMapper class.
-     * @return A {@link RDFTerm} that is the equivalent to the given expression.
-     */
-    public RDFTerm map(Expression expr) throws MulgaraParserException;
-    /**
-     * Convert an Expression to a RDFTerm for Mulgara.
-     * @param expr The Expression to convert. Should be specific to the mapper.
-     * @return The RDFTerm relevant to the mapper.
-     */
-    RDFTerm typedMap(T pattern) throws MulgaraParserException;
-    /** Identify the class to be mapped by the extension. */
-    public Class<T> getMapType();
-  }
-
-  /**
-   * An abstract root for all the mappers, which provides a {@link #map(Expression)} implementation
-   * that handles the casting to the generics type.
-   */
-  private static abstract class AbstractExprToFilter<T extends Expression> implements ExpressionToTerm<T> {
-    /** Call the {@link ExpressionToTerm#typedMap(Expression)} method with an appropriate cast for the parameter. */
-    @SuppressWarnings("unchecked")
-    public RDFTerm map(Expression expr) throws MulgaraParserException { return typedMap((T)expr); }
-  }
-
-  /** A mapping of Expression types to constructors for the Filters they map to. */
-  private static Map<Class<? extends Expression>,ExpressionToTerm<? extends Expression>> mappers = new HashMap<Class<? extends Expression>,ExpressionToTerm<? extends Expression>>();
-
-  /**
-   * A utility method to add ExpressionToFilter mappers to the {@link #mappers} map.
-   * @param mapper The mapper to add.
-   */
-  private static void addToMap(ExpressionToTerm<? extends Expression> mapper) {
-    mappers.put(mapper.getMapType(), mapper);
-  }
-
-  // initialize the mappers
-  static {
-    addToMap(new BooleanMap());
-    addToMap(new IntegerMap());
-    addToMap(new DecimalMap());
-    addToMap(new DoubleMap());
-    addToMap(new VariableMap());
-    addToMap(new RDFLiteralMap());
-    addToMap(new IRIReferenceMap());
-    addToMap(new FunctionCallMap());
-    addToMap(new UnaryPlusMap());
-    addToMap(new UnaryMinusMap());
-    addToMap(new PlusMap());
-    addToMap(new MinusMap());
-    addToMap(new MultiplyMap());
-    addToMap(new DivideMap());
-    addToMap(new EqualsMap());
-    addToMap(new NotEqualsMap());
-    addToMap(new GreaterThanMap());
-    addToMap(new GreaterThanEqualMap());
-    addToMap(new LessThanMap());
-    addToMap(new LessThanEqualMap());
-    addToMap(new NotMap());
-    addToMap(new AndMap());
-    addToMap(new OrMap());
-    addToMap(new BoundFnMap());
-    addToMap(new DataTypeFnMap());
-    addToMap(new IsBlankFnMap());
-    addToMap(new IsIriFnMap());
-    addToMap(new IsLiteralFnMap());
-    addToMap(new IsUriFnMap());
-    addToMap(new LangFnMap());
-    addToMap(new LangMatchesFnMap());
-    addToMap(new RegexFnMap());
-    addToMap(new SameTermMap());
-    addToMap(new StrFnMap());
-  }
-
-  private static class BooleanMap extends AbstractExprToFilter<BooleanLiteral> {
-    public Class<BooleanLiteral> getMapType() { return BooleanLiteral.class; }
-    public RDFTerm typedMap(BooleanLiteral expr) {
-      return expr == BooleanLiteral.TRUE ? Bool.TRUE : Bool.FALSE;
-    }
-  }
-
-  private static class IntegerMap extends AbstractExprToFilter<IntegerLiteral> {
-    public Class<IntegerLiteral> getMapType() { return IntegerLiteral.class; }
-    public RDFTerm typedMap(IntegerLiteral expr) {
-      return new NumericLiteral(expr.getInteger());
-    }
-  }
-
-  private static class DecimalMap extends AbstractExprToFilter<DecimalLiteral> {
-    public Class<DecimalLiteral> getMapType() { return DecimalLiteral.class; }
-    public RDFTerm typedMap(DecimalLiteral expr) {
-      return new NumericLiteral(expr.getFloat());
-    }
-  }
-
-  private static class DoubleMap extends AbstractExprToFilter<DoubleLiteral> {
-    public Class<DoubleLiteral> getMapType() { return DoubleLiteral.class; }
-    public RDFTerm typedMap(DoubleLiteral expr) {
-      return new NumericLiteral(expr.getDouble());
-    }
-  }
-
-  private static class VariableMap extends AbstractExprToFilter<Variable> {
-    public Class<Variable> getMapType() { return Variable.class; }
-    public RDFTerm typedMap(Variable expr) {
-      return new Var(expr.getName());
-    }
-  }
-
-  private static class RDFLiteralMap extends AbstractExprToFilter<RDFLiteral> {
-    public Class<RDFLiteral> getMapType() { return RDFLiteral.class; }
-    public RDFTerm typedMap(RDFLiteral expr) {
-      if (expr.isTyped()) return TypedLiteral.newLiteral(expr.getValue(), expr.getDatatype().getUri(), null);
-      if (expr.isLanguageCoded()) return new SimpleLiteral(expr.getValue(), expr.getLanguage());
-      return new SimpleLiteral(expr.getValue());
-    }
-  }
-
-  private static class IRIReferenceMap extends AbstractExprToFilter<IRIReference> {
-    public Class<IRIReference> getMapType() { return IRIReference.class; }
-    public RDFTerm typedMap(IRIReference expr) {
-      return new IRI(expr.getUri());
-    }
-  }
-
-  private static class FunctionCallMap extends AbstractExprToFilter<FunctionCall> {
-    public Class<FunctionCall> getMapType() { return FunctionCall.class; }
-    public RDFTerm typedMap(FunctionCall expr) throws MulgaraParserException {
-      List<Expression> exprArgs = expr.getArgs();
-      RDFTerm[] operands = new RDFTerm[exprArgs.size()];
-      for (int i = 0; i < operands.length; i++) operands[i] = mapExpression(exprArgs.get(i));
-      return new ExternalFn(new IRI(expr.getName().getUri()), operands);
-    }
-  }
-
-  private static class UnaryPlusMap extends AbstractExprToFilter<UnaryPlus> {
-    public Class<UnaryPlus> getMapType() { return UnaryPlus.class; }
-    public RDFTerm typedMap(UnaryPlus expr) throws MulgaraParserException {
-      return mapExpression(expr.getOperand());
-    }
-  }
-
-  private static class UnaryMinusMap extends AbstractExprToFilter<UnaryMinus> {
-    public Class<UnaryMinus> getMapType() { return UnaryMinus.class; }
-    public RDFTerm typedMap(UnaryMinus expr) throws MulgaraParserException {
-      RDFTerm param = mapExpression(expr.getOperand());
-      if (!(param instanceof NumericLiteral)) throw new MulgaraParserException("Cannot negate a non-number: " + param.getClass().getSimpleName());
-      return new org.mulgara.query.filter.arithmetic.UnaryMinus((NumericLiteral)param);
-    }
-  }
-
-  private static class PlusMap extends AbstractExprToFilter<Plus> {
-    public Class<Plus> getMapType() { return Plus.class; }
-    public RDFTerm typedMap(Plus expr) throws MulgaraParserException {
-      return AddOperation.newAddOperation(mapNumbers(expr.getOperands()));
-    }
-  }
-
-  private static class MinusMap extends AbstractExprToFilter<Minus> {
-    public Class<Minus> getMapType() { return Minus.class; }
-    public RDFTerm typedMap(Minus expr) throws MulgaraParserException {
-      return MinusOperation.newMinusOperation(mapNumbers(expr.getOperands()));
-    }
-  }
-
-  private static class MultiplyMap extends AbstractExprToFilter<Multiply> {
-    public Class<Multiply> getMapType() { return Multiply.class; }
-    public RDFTerm typedMap(Multiply expr) throws MulgaraParserException {
-      return MultiplyOperation.newMultiplyOperation(mapNumbers(expr.getOperands()));
-    }
-  }
-
-  private static class DivideMap extends AbstractExprToFilter<Divide> {
-    public Class<Divide> getMapType() { return Divide.class; }
-    public RDFTerm typedMap(Divide expr) throws MulgaraParserException {
-      return DivideOperation.newDivideOperation(mapNumbers(expr.getOperands()));
-    }
-  }
-
-  private static class EqualsMap extends AbstractExprToFilter<Equals> {
-    public Class<Equals> getMapType() { return Equals.class; }
-    public RDFTerm typedMap(Equals expr) throws MulgaraParserException {
-      return new org.mulgara.query.filter.Equals(mapExpression(expr.getLhs()), mapExpression(expr.getRhs()));
-    }
-  }
-
-  private static class NotEqualsMap extends AbstractExprToFilter<NotEquals> {
-    public Class<NotEquals> getMapType() { return NotEquals.class; }
-    public RDFTerm typedMap(NotEquals expr) throws MulgaraParserException {
-      return new org.mulgara.query.filter.NotEquals(mapExpression(expr.getLhs()), mapExpression(expr.getRhs()));
-    }
-  }
-
-  private static class GreaterThanMap extends AbstractExprToFilter<GreaterThan> {
-    public Class<GreaterThan> getMapType() { return GreaterThan.class; }
-    public RDFTerm typedMap(GreaterThan expr) throws MulgaraParserException {
-      return new org.mulgara.query.filter.GreaterThan(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
-    }
-  }
-
-  private static class GreaterThanEqualMap extends AbstractExprToFilter<GreaterThanEqual> {
-    public Class<GreaterThanEqual> getMapType() { return GreaterThanEqual.class; }
-    public RDFTerm typedMap(GreaterThanEqual expr) throws MulgaraParserException {
-      return new GreaterThanEqualTo(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
-    }
-  }
-
-  private static class LessThanMap extends AbstractExprToFilter<LessThan> {
-    public Class<LessThan> getMapType() { return LessThan.class; }
-    public RDFTerm typedMap(LessThan expr) throws MulgaraParserException {
-      return new org.mulgara.query.filter.LessThan(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
-    }
-  }
-
-  private static class LessThanEqualMap extends AbstractExprToFilter<LessThanEqual> {
-    public Class<LessThanEqual> getMapType() { return LessThanEqual.class; }
-    public RDFTerm typedMap(LessThanEqual expr) throws MulgaraParserException {
-      return new LessThanEqualTo(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
-    }
-  }
-
-  private static class NotMap extends AbstractExprToFilter<Not> {
-    public Class<Not> getMapType() { return Not.class; }
-    public RDFTerm typedMap(Not expr) throws MulgaraParserException {
-      return new org.mulgara.query.filter.Not(mapLogic(expr.getOperand()));
-    }
-  }
-
-  private static class AndMap extends AbstractExprToFilter<AndExpression> {
-    public Class<AndExpression> getMapType() { return AndExpression.class; }
-    public RDFTerm typedMap(AndExpression expr) throws MulgaraParserException {
-      return new And(mapLogicListArr(expr.getOperands()));
-    }
-  }
-
-  private static class OrMap extends AbstractExprToFilter<OrExpression> {
-    public Class<OrExpression> getMapType() { return OrExpression.class; }
-    public RDFTerm typedMap(OrExpression expr) throws MulgaraParserException {
-      return new Or(mapLogicListArr(expr.getOperands()));
-    }
-  }
-
-  private static class BoundFnMap extends AbstractExprToFilter<BicBound> {
-    public Class<BicBound> getMapType() { return BicBound.class; }
-    public RDFTerm typedMap(BicBound expr) throws MulgaraParserException {
-      return new BoundFn((Var)mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class DataTypeFnMap extends AbstractExprToFilter<BicDatatype> {
-    public Class<BicDatatype> getMapType() { return BicDatatype.class; }
-    public RDFTerm typedMap(BicDatatype expr) throws MulgaraParserException {
-      return new DataTypeFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class IsBlankFnMap extends AbstractExprToFilter<BicIsBlank> {
-    public Class<BicIsBlank> getMapType() { return BicIsBlank.class; }
-    public RDFTerm typedMap(BicIsBlank expr) throws MulgaraParserException {
-      return new IsBlankFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class IsIriFnMap extends AbstractExprToFilter<BicIsIri> {
-    public Class<BicIsIri> getMapType() { return BicIsIri.class; }
-    public RDFTerm typedMap(BicIsIri expr) throws MulgaraParserException {
-      return new IsIriFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class IsLiteralFnMap extends AbstractExprToFilter<BicIsLiteral> {
-    public Class<BicIsLiteral> getMapType() { return BicIsLiteral.class; }
-    public RDFTerm typedMap(BicIsLiteral expr) throws MulgaraParserException {
-      return new IsLiteralFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class IsUriFnMap extends AbstractExprToFilter<BicIsUri> {
-    public Class<BicIsUri> getMapType() { return BicIsUri.class; }
-    public RDFTerm typedMap(BicIsUri expr) throws MulgaraParserException {
-      return new IsUriFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class LangFnMap extends AbstractExprToFilter<BicLang> {
-    public Class<BicLang> getMapType() { return BicLang.class; }
-    public RDFTerm typedMap(BicLang expr) throws MulgaraParserException {
-      return new LangFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-  private static class LangMatchesFnMap extends AbstractExprToFilter<BicLangMatches> {
-    public Class<BicLangMatches> getMapType() { return BicLangMatches.class; }
-    public RDFTerm typedMap(BicLangMatches expr) throws MulgaraParserException {
-      return new LangMatches(mapValue(expr.getFirstOperand()), mapValue(expr.getSecondOperand()));
-    }
-  }
-
-  private static class RegexFnMap extends AbstractExprToFilter<BicRegEx> {
-    public Class<BicRegEx> getMapType() { return BicRegEx.class; }
-    public RDFTerm typedMap(BicRegEx expr) throws MulgaraParserException {
-      return new RegexFn(mapValue(expr.getExpr()), mapValue(expr.getPattern()), mapValue(expr.getFlags()));
-    }
-  }
-
-  private static class SameTermMap extends AbstractExprToFilter<BicSameTerm> {
-    public Class<BicSameTerm> getMapType() { return BicSameTerm.class; }
-    public RDFTerm typedMap(BicSameTerm expr) throws MulgaraParserException {
-      return new SameTerm(mapExpression(expr.getFirstOperand()), mapExpression(expr.getSecondOperand()));
-    }
-  }
-
-  private static class StrFnMap extends AbstractExprToFilter<BicStr> {
-    public Class<BicStr> getMapType() { return BicStr.class; }
-    public RDFTerm typedMap(BicStr expr) throws MulgaraParserException {
-      return new StrFn(mapExpression(expr.getOperand()));
-    }
-  }
-
-}

Copied: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java)
===================================================================
--- trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java	                        (rev 0)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/FilterMapper.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,520 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.sparql;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.mulgara.sparql.parser.cst.AndExpression;
+import org.mulgara.sparql.parser.cst.BicBound;
+import org.mulgara.sparql.parser.cst.BicDatatype;
+import org.mulgara.sparql.parser.cst.BicIsBlank;
+import org.mulgara.sparql.parser.cst.BicIsIri;
+import org.mulgara.sparql.parser.cst.BicIsLiteral;
+import org.mulgara.sparql.parser.cst.BicIsUri;
+import org.mulgara.sparql.parser.cst.BicLang;
+import org.mulgara.sparql.parser.cst.BicLangMatches;
+import org.mulgara.sparql.parser.cst.BicRegEx;
+import org.mulgara.sparql.parser.cst.BicSameTerm;
+import org.mulgara.sparql.parser.cst.BicStr;
+import org.mulgara.sparql.parser.cst.BooleanLiteral;
+import org.mulgara.sparql.parser.cst.DecimalLiteral;
+import org.mulgara.sparql.parser.cst.DoubleLiteral;
+import org.mulgara.sparql.parser.cst.Equals;
+import org.mulgara.sparql.parser.cst.Expression;
+import org.mulgara.sparql.parser.cst.FunctionCall;
+import org.mulgara.sparql.parser.cst.GreaterThan;
+import org.mulgara.sparql.parser.cst.GreaterThanEqual;
+import org.mulgara.sparql.parser.cst.IRIReference;
+import org.mulgara.sparql.parser.cst.IntegerLiteral;
+import org.mulgara.sparql.parser.cst.Divide;
+import org.mulgara.sparql.parser.cst.LessThan;
+import org.mulgara.sparql.parser.cst.LessThanEqual;
+import org.mulgara.sparql.parser.cst.LogicExpression;
+import org.mulgara.sparql.parser.cst.Minus;
+import org.mulgara.sparql.parser.cst.Multiply;
+import org.mulgara.sparql.parser.cst.Not;
+import org.mulgara.sparql.parser.cst.NotEquals;
+import org.mulgara.sparql.parser.cst.OrExpression;
+import org.mulgara.sparql.parser.cst.Plus;
+import org.mulgara.sparql.parser.cst.RDFLiteral;
+import org.mulgara.sparql.parser.cst.UnaryMinus;
+import org.mulgara.sparql.parser.cst.UnaryPlus;
+import org.mulgara.sparql.parser.cst.Variable;
+import org.mulgara.parser.MulgaraParserException;
+import org.mulgara.query.filter.And;
+import org.mulgara.query.filter.BoundFn;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.query.filter.GreaterThanEqualTo;
+import org.mulgara.query.filter.IsBlankFn;
+import org.mulgara.query.filter.IsIriFn;
+import org.mulgara.query.filter.IsLiteralFn;
+import org.mulgara.query.filter.IsUriFn;
+import org.mulgara.query.filter.LangMatches;
+import org.mulgara.query.filter.LessThanEqualTo;
+import org.mulgara.query.filter.Or;
+import org.mulgara.query.filter.RDFTerm;
+import org.mulgara.query.filter.RegexFn;
+import org.mulgara.query.filter.SameTerm;
+import org.mulgara.query.filter.arithmetic.AddOperation;
+import org.mulgara.query.filter.arithmetic.DivideOperation;
+import org.mulgara.query.filter.arithmetic.MinusOperation;
+import org.mulgara.query.filter.arithmetic.MultiplyOperation;
+import org.mulgara.query.filter.value.Bool;
+import org.mulgara.query.filter.value.DataTypeFn;
+import org.mulgara.query.filter.value.ExternalFn;
+import org.mulgara.query.filter.value.IRI;
+import org.mulgara.query.filter.value.LangFn;
+import org.mulgara.query.filter.value.NumericExpression;
+import org.mulgara.query.filter.value.NumericLiteral;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.filter.value.StrFn;
+import org.mulgara.query.filter.value.TypedLiteral;
+import org.mulgara.query.filter.value.ValueLiteral;
+import org.mulgara.query.filter.value.Var;
+
+
+/**
+ * This object maps a constraint from an {@link org.mulgara.sparql.parser.cst.Expression} into a
+ * {@link org.mulgara.query.filter.Filter}.
+ *
+ * @created Apr 22, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class FilterMapper {
+
+  /** Represents the CST Filter expression that is to be mapped. */
+  private Expression cstFilter;
+
+  public FilterMapper(Expression cstFilter) {
+    this.cstFilter = cstFilter;
+  }
+
+  /**
+   * Get the Filter object described by the expression.
+   * @return A new Filter for use in a query.
+   * @throws MulgaraParserException If the mapping could not be performed due to structural errors in the CST.
+   */
+  public Filter getFilter() throws MulgaraParserException {
+    RDFTerm term = mapExpression(cstFilter);
+    if (!(term instanceof Filter)) throw new MulgaraParserException("Bad structure in the FILTER");
+    return (Filter)term;
+  }
+
+  /**
+   * The internal method for mapping a CST expression into an AST term.
+   * @param expr The expression to be mapped.
+   * @return A new AST term.
+   * @throws MulgaraParserException If the mapping could not be performed due to structural errors in the CST.
+   */
+  static private RDFTerm mapExpression(Expression expr) throws MulgaraParserException {
+    ExpressionToTerm<? extends Expression> mapper = mappers.get(expr.getClass());
+    if (mapper == null) throw new UnsupportedOperationException("Unable to handle expression: \"" + expr.getImage() + "\" (" + expr.getClass().getSimpleName() + ")");
+    return mapper.map(expr);
+  }
+
+  /**
+   * Converts a CST NumericExpression into an AST NumericExpression.
+   * @param operand The CST numeric expression.
+   * @return An AST numeric expression.
+   * @throws MulgaraParserException If the value was not mapped to an AST numeric expression.
+   */
+  static private NumericExpression mapNumber(Expression operand) throws MulgaraParserException {
+    RDFTerm op = mapExpression(operand);
+    if (!(op instanceof NumericExpression)) throw new MulgaraParserException("Non-numeric value in arithmetic operation: " + op.getClass().getSimpleName());
+    return (NumericExpression)op;
+  }
+
+  /**
+   * Converts a list of CST NumericExpressions into a list of AST NumericExpressions.
+   * @param operands The list of CST numeric expressions.
+   * @return A list of AST numeric expressions.
+   * @throws MulgaraParserException If one of the values was not mapped to an AST numeric expression.
+   */
+  static private List<NumericExpression> mapNumbers(List<org.mulgara.sparql.parser.cst.NumericExpression> operands) throws MulgaraParserException {
+    List<NumericExpression> numbers = new ArrayList<NumericExpression>(operands.size());
+    for (org.mulgara.sparql.parser.cst.NumericExpression e: operands) numbers.add(mapNumber(e));
+    return numbers;
+  }
+
+  /**
+   * Converts a CST NumericExpression into an AST NumericExpression.
+   * @param operand The CST numeric expression.
+   * @return An AST numeric expression.
+   * @throws MulgaraParserException If the value was not mapped to an AST numeric expression.
+   */
+  static private Filter mapLogic(Expression operand) throws MulgaraParserException {
+    RDFTerm op = mapExpression(operand);
+    if (!(op instanceof Filter)) throw new MulgaraParserException("Value without an Effective Boolean Value in a logic expression: " + op.getClass().getSimpleName());
+    return (Filter)op;
+  }
+
+  /**
+   * Converts a list of CST LogicExpressions into a list of AST Filters.
+   * @param operands The list of CST logic expressions.
+   * @return A list of AST filter expressions.
+   * @throws MulgaraParserException If one of the values was not mapped to an AST expression with an EBV.
+   */
+  static private Filter[] mapLogicListArr(List<LogicExpression> operands) throws MulgaraParserException {
+    List<Filter> logicOps = new ArrayList<Filter>(operands.size());
+    for (LogicExpression e: operands) logicOps.add(mapLogic(e));
+    return logicOps.toArray(new Filter[logicOps.size()]);
+  }
+
+  /**
+   * Converts a CST Expression into an AST value that resolves to a literal ({@link ValueLiteral}).
+   * @param operand The CST expression.
+   * @return An AST value expression.
+   * @throws MulgaraParserException If the value was not mapped to an AST ValueLiteral.
+   */
+  static private ValueLiteral mapValue(Expression operand) throws MulgaraParserException {
+    RDFTerm op = mapExpression(operand);
+    try {
+      if (!op.isLiteral()) throw new MulgaraParserException("Non-literal resolution when a value is required from: " + op.getClass().getSimpleName());
+    } catch (Exception qe) {  // this is a QueryException
+      throw new MulgaraParserException("Unexpected error getting value type from: " + op.getClass().getSimpleName() + ". " + qe.getMessage());
+    }
+    return (ValueLiteral)op;
+  }
+
+  //////////////////////////////////
+  // The internal mapping structures
+  //////////////////////////////////
+
+  /** Defines an interface for mapping expressions into an equivalent Filter operation. */
+  private static interface ExpressionToTerm<T extends Expression> {
+    /**
+     * A main entry point for the mapper, which will do the casting into {@link #typedMap(Expression, FilterMapper)}.
+     * @param expr The expression to map to an RDFTerm.
+     * @param parent The surrounding FilterMapper class.
+     * @return A {@link RDFTerm} that is the equivalent to the given expression.
+     */
+    public RDFTerm map(Expression expr) throws MulgaraParserException;
+    /**
+     * Convert an Expression to a RDFTerm for Mulgara.
+     * @param expr The Expression to convert. Should be specific to the mapper.
+     * @return The RDFTerm relevant to the mapper.
+     */
+    RDFTerm typedMap(T pattern) throws MulgaraParserException;
+    /** Identify the class to be mapped by the extension. */
+    public Class<T> getMapType();
+  }
+
+  /**
+   * An abstract root for all the mappers, which provides a {@link #map(Expression)} implementation
+   * that handles the casting to the generics type.
+   */
+  private static abstract class AbstractExprToFilter<T extends Expression> implements ExpressionToTerm<T> {
+    /** Call the {@link ExpressionToTerm#typedMap(Expression)} method with an appropriate cast for the parameter. */
+    @SuppressWarnings("unchecked")
+    public RDFTerm map(Expression expr) throws MulgaraParserException { return typedMap((T)expr); }
+  }
+
+  /** A mapping of Expression types to constructors for the Filters they map to. */
+  private static Map<Class<? extends Expression>,ExpressionToTerm<? extends Expression>> mappers = new HashMap<Class<? extends Expression>,ExpressionToTerm<? extends Expression>>();
+
+  /**
+   * A utility method to add ExpressionToFilter mappers to the {@link #mappers} map.
+   * @param mapper The mapper to add.
+   */
+  private static void addToMap(ExpressionToTerm<? extends Expression> mapper) {
+    mappers.put(mapper.getMapType(), mapper);
+  }
+
+  // initialize the mappers
+  static {
+    addToMap(new BooleanMap());
+    addToMap(new IntegerMap());
+    addToMap(new DecimalMap());
+    addToMap(new DoubleMap());
+    addToMap(new VariableMap());
+    addToMap(new RDFLiteralMap());
+    addToMap(new IRIReferenceMap());
+    addToMap(new FunctionCallMap());
+    addToMap(new UnaryPlusMap());
+    addToMap(new UnaryMinusMap());
+    addToMap(new PlusMap());
+    addToMap(new MinusMap());
+    addToMap(new MultiplyMap());
+    addToMap(new DivideMap());
+    addToMap(new EqualsMap());
+    addToMap(new NotEqualsMap());
+    addToMap(new GreaterThanMap());
+    addToMap(new GreaterThanEqualMap());
+    addToMap(new LessThanMap());
+    addToMap(new LessThanEqualMap());
+    addToMap(new NotMap());
+    addToMap(new AndMap());
+    addToMap(new OrMap());
+    addToMap(new BoundFnMap());
+    addToMap(new DataTypeFnMap());
+    addToMap(new IsBlankFnMap());
+    addToMap(new IsIriFnMap());
+    addToMap(new IsLiteralFnMap());
+    addToMap(new IsUriFnMap());
+    addToMap(new LangFnMap());
+    addToMap(new LangMatchesFnMap());
+    addToMap(new RegexFnMap());
+    addToMap(new SameTermMap());
+    addToMap(new StrFnMap());
+  }
+
+  private static class BooleanMap extends AbstractExprToFilter<BooleanLiteral> {
+    public Class<BooleanLiteral> getMapType() { return BooleanLiteral.class; }
+    public RDFTerm typedMap(BooleanLiteral expr) {
+      return expr == BooleanLiteral.TRUE ? Bool.TRUE : Bool.FALSE;
+    }
+  }
+
+  private static class IntegerMap extends AbstractExprToFilter<IntegerLiteral> {
+    public Class<IntegerLiteral> getMapType() { return IntegerLiteral.class; }
+    public RDFTerm typedMap(IntegerLiteral expr) {
+      return new NumericLiteral(expr.getInteger());
+    }
+  }
+
+  private static class DecimalMap extends AbstractExprToFilter<DecimalLiteral> {
+    public Class<DecimalLiteral> getMapType() { return DecimalLiteral.class; }
+    public RDFTerm typedMap(DecimalLiteral expr) {
+      return new NumericLiteral(expr.getFloat());
+    }
+  }
+
+  private static class DoubleMap extends AbstractExprToFilter<DoubleLiteral> {
+    public Class<DoubleLiteral> getMapType() { return DoubleLiteral.class; }
+    public RDFTerm typedMap(DoubleLiteral expr) {
+      return new NumericLiteral(expr.getDouble());
+    }
+  }
+
+  private static class VariableMap extends AbstractExprToFilter<Variable> {
+    public Class<Variable> getMapType() { return Variable.class; }
+    public RDFTerm typedMap(Variable expr) {
+      return new Var(expr.getName());
+    }
+  }
+
+  private static class RDFLiteralMap extends AbstractExprToFilter<RDFLiteral> {
+    public Class<RDFLiteral> getMapType() { return RDFLiteral.class; }
+    public RDFTerm typedMap(RDFLiteral expr) {
+      if (expr.isTyped()) return TypedLiteral.newLiteral(expr.getValue(), expr.getDatatype().getUri(), null);
+      if (expr.isLanguageCoded()) return new SimpleLiteral(expr.getValue(), expr.getLanguage());
+      return new SimpleLiteral(expr.getValue());
+    }
+  }
+
+  private static class IRIReferenceMap extends AbstractExprToFilter<IRIReference> {
+    public Class<IRIReference> getMapType() { return IRIReference.class; }
+    public RDFTerm typedMap(IRIReference expr) {
+      return new IRI(expr.getUri());
+    }
+  }
+
+  private static class FunctionCallMap extends AbstractExprToFilter<FunctionCall> {
+    public Class<FunctionCall> getMapType() { return FunctionCall.class; }
+    public RDFTerm typedMap(FunctionCall expr) throws MulgaraParserException {
+      List<Expression> exprArgs = expr.getArgs();
+      RDFTerm[] operands = new RDFTerm[exprArgs.size()];
+      for (int i = 0; i < operands.length; i++) operands[i] = mapExpression(exprArgs.get(i));
+      return new ExternalFn(new IRI(expr.getName().getUri()), operands);
+    }
+  }
+
+  private static class UnaryPlusMap extends AbstractExprToFilter<UnaryPlus> {
+    public Class<UnaryPlus> getMapType() { return UnaryPlus.class; }
+    public RDFTerm typedMap(UnaryPlus expr) throws MulgaraParserException {
+      return mapExpression(expr.getOperand());
+    }
+  }
+
+  private static class UnaryMinusMap extends AbstractExprToFilter<UnaryMinus> {
+    public Class<UnaryMinus> getMapType() { return UnaryMinus.class; }
+    public RDFTerm typedMap(UnaryMinus expr) throws MulgaraParserException {
+      RDFTerm param = mapExpression(expr.getOperand());
+      if (!(param instanceof NumericLiteral)) throw new MulgaraParserException("Cannot negate a non-number: " + param.getClass().getSimpleName());
+      return new org.mulgara.query.filter.arithmetic.UnaryMinus((NumericLiteral)param);
+    }
+  }
+
+  private static class PlusMap extends AbstractExprToFilter<Plus> {
+    public Class<Plus> getMapType() { return Plus.class; }
+    public RDFTerm typedMap(Plus expr) throws MulgaraParserException {
+      return AddOperation.newAddOperation(mapNumbers(expr.getOperands()));
+    }
+  }
+
+  private static class MinusMap extends AbstractExprToFilter<Minus> {
+    public Class<Minus> getMapType() { return Minus.class; }
+    public RDFTerm typedMap(Minus expr) throws MulgaraParserException {
+      return MinusOperation.newMinusOperation(mapNumbers(expr.getOperands()));
+    }
+  }
+
+  private static class MultiplyMap extends AbstractExprToFilter<Multiply> {
+    public Class<Multiply> getMapType() { return Multiply.class; }
+    public RDFTerm typedMap(Multiply expr) throws MulgaraParserException {
+      return MultiplyOperation.newMultiplyOperation(mapNumbers(expr.getOperands()));
+    }
+  }
+
+  private static class DivideMap extends AbstractExprToFilter<Divide> {
+    public Class<Divide> getMapType() { return Divide.class; }
+    public RDFTerm typedMap(Divide expr) throws MulgaraParserException {
+      return DivideOperation.newDivideOperation(mapNumbers(expr.getOperands()));
+    }
+  }
+
+  private static class EqualsMap extends AbstractExprToFilter<Equals> {
+    public Class<Equals> getMapType() { return Equals.class; }
+    public RDFTerm typedMap(Equals expr) throws MulgaraParserException {
+      return new org.mulgara.query.filter.Equals(mapExpression(expr.getLhs()), mapExpression(expr.getRhs()));
+    }
+  }
+
+  private static class NotEqualsMap extends AbstractExprToFilter<NotEquals> {
+    public Class<NotEquals> getMapType() { return NotEquals.class; }
+    public RDFTerm typedMap(NotEquals expr) throws MulgaraParserException {
+      return new org.mulgara.query.filter.NotEquals(mapExpression(expr.getLhs()), mapExpression(expr.getRhs()));
+    }
+  }
+
+  private static class GreaterThanMap extends AbstractExprToFilter<GreaterThan> {
+    public Class<GreaterThan> getMapType() { return GreaterThan.class; }
+    public RDFTerm typedMap(GreaterThan expr) throws MulgaraParserException {
+      return new org.mulgara.query.filter.GreaterThan(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
+    }
+  }
+
+  private static class GreaterThanEqualMap extends AbstractExprToFilter<GreaterThanEqual> {
+    public Class<GreaterThanEqual> getMapType() { return GreaterThanEqual.class; }
+    public RDFTerm typedMap(GreaterThanEqual expr) throws MulgaraParserException {
+      return new GreaterThanEqualTo(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
+    }
+  }
+
+  private static class LessThanMap extends AbstractExprToFilter<LessThan> {
+    public Class<LessThan> getMapType() { return LessThan.class; }
+    public RDFTerm typedMap(LessThan expr) throws MulgaraParserException {
+      return new org.mulgara.query.filter.LessThan(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
+    }
+  }
+
+  private static class LessThanEqualMap extends AbstractExprToFilter<LessThanEqual> {
+    public Class<LessThanEqual> getMapType() { return LessThanEqual.class; }
+    public RDFTerm typedMap(LessThanEqual expr) throws MulgaraParserException {
+      return new LessThanEqualTo(mapNumber(expr.getLhs()), mapNumber(expr.getRhs()));
+    }
+  }
+
+  private static class NotMap extends AbstractExprToFilter<Not> {
+    public Class<Not> getMapType() { return Not.class; }
+    public RDFTerm typedMap(Not expr) throws MulgaraParserException {
+      return new org.mulgara.query.filter.Not(mapLogic(expr.getOperand()));
+    }
+  }
+
+  private static class AndMap extends AbstractExprToFilter<AndExpression> {
+    public Class<AndExpression> getMapType() { return AndExpression.class; }
+    public RDFTerm typedMap(AndExpression expr) throws MulgaraParserException {
+      return new And(mapLogicListArr(expr.getOperands()));
+    }
+  }
+
+  private static class OrMap extends AbstractExprToFilter<OrExpression> {
+    public Class<OrExpression> getMapType() { return OrExpression.class; }
+    public RDFTerm typedMap(OrExpression expr) throws MulgaraParserException {
+      return new Or(mapLogicListArr(expr.getOperands()));
+    }
+  }
+
+  private static class BoundFnMap extends AbstractExprToFilter<BicBound> {
+    public Class<BicBound> getMapType() { return BicBound.class; }
+    public RDFTerm typedMap(BicBound expr) throws MulgaraParserException {
+      return new BoundFn((Var)mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class DataTypeFnMap extends AbstractExprToFilter<BicDatatype> {
+    public Class<BicDatatype> getMapType() { return BicDatatype.class; }
+    public RDFTerm typedMap(BicDatatype expr) throws MulgaraParserException {
+      return new DataTypeFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class IsBlankFnMap extends AbstractExprToFilter<BicIsBlank> {
+    public Class<BicIsBlank> getMapType() { return BicIsBlank.class; }
+    public RDFTerm typedMap(BicIsBlank expr) throws MulgaraParserException {
+      return new IsBlankFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class IsIriFnMap extends AbstractExprToFilter<BicIsIri> {
+    public Class<BicIsIri> getMapType() { return BicIsIri.class; }
+    public RDFTerm typedMap(BicIsIri expr) throws MulgaraParserException {
+      return new IsIriFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class IsLiteralFnMap extends AbstractExprToFilter<BicIsLiteral> {
+    public Class<BicIsLiteral> getMapType() { return BicIsLiteral.class; }
+    public RDFTerm typedMap(BicIsLiteral expr) throws MulgaraParserException {
+      return new IsLiteralFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class IsUriFnMap extends AbstractExprToFilter<BicIsUri> {
+    public Class<BicIsUri> getMapType() { return BicIsUri.class; }
+    public RDFTerm typedMap(BicIsUri expr) throws MulgaraParserException {
+      return new IsUriFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class LangFnMap extends AbstractExprToFilter<BicLang> {
+    public Class<BicLang> getMapType() { return BicLang.class; }
+    public RDFTerm typedMap(BicLang expr) throws MulgaraParserException {
+      return new LangFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+  private static class LangMatchesFnMap extends AbstractExprToFilter<BicLangMatches> {
+    public Class<BicLangMatches> getMapType() { return BicLangMatches.class; }
+    public RDFTerm typedMap(BicLangMatches expr) throws MulgaraParserException {
+      return new LangMatches(mapValue(expr.getFirstOperand()), mapValue(expr.getSecondOperand()));
+    }
+  }
+
+  private static class RegexFnMap extends AbstractExprToFilter<BicRegEx> {
+    public Class<BicRegEx> getMapType() { return BicRegEx.class; }
+    public RDFTerm typedMap(BicRegEx expr) throws MulgaraParserException {
+      return new RegexFn(mapValue(expr.getExpr()), mapValue(expr.getPattern()), mapValue(expr.getFlags()));
+    }
+  }
+
+  private static class SameTermMap extends AbstractExprToFilter<BicSameTerm> {
+    public Class<BicSameTerm> getMapType() { return BicSameTerm.class; }
+    public RDFTerm typedMap(BicSameTerm expr) throws MulgaraParserException {
+      return new SameTerm(mapExpression(expr.getFirstOperand()), mapExpression(expr.getSecondOperand()));
+    }
+  }
+
+  private static class StrFnMap extends AbstractExprToFilter<BicStr> {
+    public Class<BicStr> getMapType() { return BicStr.class; }
+    public RDFTerm typedMap(BicStr expr) throws MulgaraParserException {
+      return new StrFn(mapExpression(expr.getOperand()));
+    }
+  }
+
+}

Deleted: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java
===================================================================
--- branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,292 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.sparql;
-
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import org.mulgara.sparql.parser.cst.BlankNode;
-import org.mulgara.sparql.parser.cst.BooleanLiteral;
-import org.mulgara.sparql.parser.cst.DecimalLiteral;
-import org.mulgara.sparql.parser.cst.DoubleLiteral;
-import org.mulgara.sparql.parser.cst.EmptyGraphPattern;
-import org.mulgara.sparql.parser.cst.Expression;
-import org.mulgara.sparql.parser.cst.GraphPatternConjunction;
-import org.mulgara.sparql.parser.cst.GraphPatternDisjunction;
-import org.mulgara.sparql.parser.cst.GraphPatternOptional;
-import org.mulgara.sparql.parser.cst.GroupGraphPattern;
-import org.mulgara.sparql.parser.cst.IRIReference;
-import org.mulgara.sparql.parser.cst.IntegerLiteral;
-import org.mulgara.sparql.parser.cst.Node;
-import org.mulgara.sparql.parser.cst.RDFLiteral;
-import org.mulgara.sparql.parser.cst.Triple;
-import org.mulgara.sparql.parser.cst.TripleList;
-import org.mulgara.parser.MulgaraParserException;
-import org.mulgara.query.ConstraintConjunction;
-import org.mulgara.query.ConstraintDisjunction;
-import org.mulgara.query.ConstraintElement;
-import org.mulgara.query.ConstraintExpression;
-import org.mulgara.query.ConstraintFalse;
-import org.mulgara.query.ConstraintFilter;
-import org.mulgara.query.ConstraintImpl;
-import org.mulgara.query.ConstraintIn;
-import org.mulgara.query.ConstraintOptionalJoin;
-import org.mulgara.query.Variable;
-import org.mulgara.query.rdf.LiteralImpl;
-import org.mulgara.query.rdf.URIReferenceImpl;
-import org.mulgara.query.rdf.XSD;
-
-/**
- * This object maps a {@link GroupGraphPattern} into a {@link ConstraintExpresion}.
- *
- * @created Apr 21, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class PatternMapper {
-
-  /** The pattern to start the mapping on. */
-  GroupGraphPattern startPattern;
-
-  /** An accumulating list of variables that are used in GRAPH patterns. */
-  Set<Variable> graphVars = new HashSet<Variable>();
-
-  /** An accumulating list of URIs that are used in GRAPH patterns. */
-  Set<URI> graphUris = new HashSet<URI>();
-
-  /**
-   * Create a new mapper for a given graph pattern.
-   * @param pattern The graph pattern to be mapped.
-   */
-  PatternMapper(GroupGraphPattern pattern) {
-    startPattern = pattern;
-  }
-
-  /**
-   * Get the set of variables that were employed as graphs in GRAPH patterns.
-   * @return The set of variables used in GRAPH expressions.
-   */
-  Set<Variable> getGraphVars() {
-    return graphVars;
-  }
-
-  /**
-   * Perform the mapping of the graph pattern and return the results as a {@link ConstraintExpression}.
-   * @return The mapped constraint expression.
-   */
-  ConstraintExpression mapToConstraints() throws MulgaraParserException {
-    return mapPattern(startPattern);
-  }
-
-  /**
-   * Converts a pattern to the matching constraint type.
-   * @param pattern The pattern to convert.
-   * @return The new ConstraintExpression which matches the pattern.
-   */
-  private ConstraintExpression mapPattern(GroupGraphPattern pattern) throws MulgaraParserException {
-    PatternToConstraintMapper<? extends GroupGraphPattern> cons = constructors.get(pattern.getClass());
-    if (cons == null) throw new UnsupportedOperationException("Unknown SPARQL pattern: " + pattern.getClass().getSimpleName());
-    ConstraintExpression result = cons.map(pattern, this);
-    result = applyFilter(result, pattern.getFilter());
-    result = applyGraph(result, pattern.getGraph());
-    return result;
-  }
-
-  /**
-   * Apply a FILTER to a constraint expression.
-   * @param constraint The expression to be filtered.
-   * @param filter The filter to be wrapped around this constraint.
-   * @return The filtered version of the constraint.
-   */
-  private ConstraintExpression applyFilter(ConstraintExpression constraint, Expression filter) throws MulgaraParserException {
-    if (filter == null) return constraint;
-    FilterMapper filterMapper = new FilterMapper(filter);
-    return new ConstraintFilter(constraint, filterMapper.getFilter());
-  }
-
-  /**
-   * Apply the parameter of a GRAPH modifier to a constraint expression.
-   * @param constraint The expression to be updated.
-   * @param graph The parameter of the GRAPH expression that is to be propagated through the constraint.
-   * @return The modified version of the constraint.
-   */
-  private ConstraintExpression applyGraph(ConstraintExpression constraint, Expression graph) {
-    if (graph == null) return constraint;
-    // graph is a Variable or IRIReference
-    if (graph instanceof org.mulgara.sparql.parser.cst.Variable) {
-      org.mulgara.sparql.parser.cst.Variable v = (org.mulgara.sparql.parser.cst.Variable)graph;
-      if (v.getName().equals("_from"));
-      Variable var = new Variable(v.getName());
-      // remember this is variable to be bound to the FROM NAMED values
-      graphVars.add(var);
-      constraint = new ConstraintIn(constraint, var);
-    } else if (graph instanceof IRIReference) {
-      // store this reference as a value that should be in the FROM NAMED list
-      URI ref = ((IRIReference)graph).getUri();
-      graphUris.add(ref);
-      constraint = new ConstraintIn(constraint, new URIReferenceImpl(ref));
-    } else {
-      throw new IllegalArgumentException("Illegal argument in a GRAPH expression: " + graph.getClass().getSimpleName());
-    }
-    return constraint;
-  }
-
-  /**
-   * A case analysis to convert simple types into {@link ConstraintElement}s.
-   * @param n The {@link Node} to convert to a ConstraintElement.
-   * @return A new constraint element that matches the node n.
-   */
-  private static ConstraintElement convertElement(Node n) {
-    if (n instanceof org.mulgara.sparql.parser.cst.Variable) {
-      return new Variable(((org.mulgara.sparql.parser.cst.Variable)n).getName());
-    }
-    if (n instanceof IRIReference) return new URIReferenceImpl(((IRIReference)n).getUri());
-    if (n instanceof BlankNode) return new Variable(((BlankNode)n).getLabel());
-    if (n instanceof RDFLiteral) {
-      RDFLiteral lit = (RDFLiteral)n;
-      if (lit.isTyped()) return new LiteralImpl(lit.getValue(), lit.getDatatype().getUri());
-      if (lit.isLanguageCoded()) return new LiteralImpl(lit.getValue(), lit.getLanguage());
-      return new LiteralImpl(lit.getValue());
-    }
-    // integer, decimal, double, boolean
-    if (n instanceof IntegerLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.INT_URI);
-    if (n instanceof DecimalLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.DECIMAL_URI);
-    if (n instanceof DoubleLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.DOUBLE_URI);
-    if (n instanceof BooleanLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.BOOLEAN_URI);
-    // don't know what to make of this
-    throw new UnsupportedOperationException("Unhandled data type in triple: " + n.getClass().getSimpleName());
-  }
-
-  /**
-   * Converts a Triple from the CST into a ConstraintImpl in the AST.
-   * @param t The triple to convert.
-   * @return The new constraint.
-   */
-  private static ConstraintImpl newConstraintImpl(Triple t) {
-    ConstraintElement s = convertElement(t.getSubject());
-    ConstraintElement p = convertElement(t.getPredicate());
-    ConstraintElement o = convertElement(t.getObject());
-    return new ConstraintImpl(s, p, o);
-  }
-
-  /** A mapping of pattern types to constructors for the objects they map to. */
-  private static Map<Class<? extends GroupGraphPattern>,PatternToConstraintMapper<? extends GroupGraphPattern>> constructors = new HashMap<Class<? extends GroupGraphPattern>,PatternToConstraintMapper<? extends GroupGraphPattern>>();
-
-  /**
-   * The class for the mapping of {@link GroupGraphPattern}s to {@link ConstraintExpression}s.
-   * This class and extending classes are not static, as the classes will be call back into the
-   * outer class to recurse down the CST.
-   * The reason this is an abstract class instead of an interface is so map(T) can be set
-   * to accept the general GroupGraphPattern and do the cast. This was not possible outside
-   * of the context of the generic type T.
-   */
-  private static abstract class PatternToConstraintMapper<T extends GroupGraphPattern> {
-    /** An entry point for the map operation. This method handles casting to be compatible with the generic template. */
-    @SuppressWarnings("unchecked")
-    public ConstraintExpression map(GroupGraphPattern pattern, PatternMapper mapper) throws MulgaraParserException { return typedMap((T)pattern, mapper); }
-    /**
-     * Convert a GroupGraphPattern to a ConstraintExpression for Mulgara.
-     * @param pattern The pattern to convert. Should be specific to the mapper.
-     * @return The constraint expression relevant to the mapper.
-     */
-    abstract ConstraintExpression typedMap(T pattern, PatternMapper mapper) throws MulgaraParserException;
-    /** Identify the class to be mapped by the extension. */
-    public abstract Class<T> getMapType();
-  }
-
-  /**
-   * Utility method to add a pattern mapper to the map, keyed on the class it maps.
-   * @param mapper The mapper to add to the map.
-   */
-  static void addToMap(PatternToConstraintMapper<? extends GroupGraphPattern> mapper) {
-    constructors.put(mapper.getMapType(), mapper);
-  }
-
-  /**
-   * Initialize the mapping of patterns to the constraint builders.
-   * This is not static in order to avoid passing "this" through to the methods
-   * on each of the implementing mapper classes.
-   */
-  static {
-    addToMap(new EmptyGraphPatternToConstraint());
-    addToMap(new GraphPatternConjunctionToConstraint());
-    addToMap(new GraphPatternDisjunctionToConstraint());
-    addToMap(new GraphPatternOptionalToConstraint());
-    addToMap(new TripleToConstraint());
-    addToMap(new TripleListToConstraint());
-  }
-
-  /** Map the empty graph pattern to a constraint that always resolves to nothing. */
-  private static class EmptyGraphPatternToConstraint extends PatternToConstraintMapper<EmptyGraphPattern> {
-    public Class<EmptyGraphPattern> getMapType() { return EmptyGraphPattern.class; }
-    ConstraintExpression typedMap(EmptyGraphPattern pattern, PatternMapper mapper) {
-      return ConstraintFalse.INSTANCE;
-    }
-  }
-
-  /** Map the conjunctions to ConstraintConjunction. */
-  private static class GraphPatternConjunctionToConstraint extends PatternToConstraintMapper<GraphPatternConjunction> {
-    public Class<GraphPatternConjunction> getMapType() { return GraphPatternConjunction.class; }
-    ConstraintExpression typedMap(GraphPatternConjunction pattern, PatternMapper mapper) throws MulgaraParserException {
-      List<GroupGraphPattern> list = pattern.getElements();
-      List<ConstraintExpression> newList = new ArrayList<ConstraintExpression>(list.size());
-      for (GroupGraphPattern p: list) newList.add(mapper.mapPattern(p));
-      return new ConstraintConjunction(newList);
-    }
-  }
-
-  /** Map the disjunctions to ConstraintConjunction. */
-  private static class GraphPatternDisjunctionToConstraint extends PatternToConstraintMapper<GraphPatternDisjunction> {
-    public Class<GraphPatternDisjunction> getMapType() { return GraphPatternDisjunction.class; }
-    ConstraintExpression typedMap(GraphPatternDisjunction pattern, PatternMapper mapper) throws MulgaraParserException {
-      List<GroupGraphPattern> list = pattern.getElements();
-      List<ConstraintExpression> newList = new ArrayList<ConstraintExpression>(list.size());
-      for (GroupGraphPattern p: list) newList.add(mapper.mapPattern(p));
-      return new ConstraintDisjunction(newList);
-    }
-  }
-
-  /** Map the optional patterns to ConstraintOptional. */
-  private static class GraphPatternOptionalToConstraint extends PatternToConstraintMapper<GraphPatternOptional> {
-    public Class<GraphPatternOptional> getMapType() { return GraphPatternOptional.class; }
-    ConstraintExpression typedMap(GraphPatternOptional pattern, PatternMapper mapper) throws MulgaraParserException {
-      return new ConstraintOptionalJoin(mapper.mapPattern(pattern.getMain()), mapper.mapPattern(pattern.getOptional()));
-    }
-  }
-
-  /** Map the triple patterns to ConstraintImpl. */
-  private static class TripleToConstraint extends PatternToConstraintMapper<Triple> {
-    public Class<Triple> getMapType() { return Triple.class; }
-    ConstraintExpression typedMap(Triple pattern, PatternMapper mapper) {
-      return newConstraintImpl(pattern);
-    }
-  }
-
-  /** Map the lists of triple patterns to ConstraintConjunctions on ConstraintImpl. */
-  private static class TripleListToConstraint extends PatternToConstraintMapper<TripleList> {
-    public Class<TripleList> getMapType() { return TripleList.class; }
-    @SuppressWarnings("unchecked")
-    ConstraintExpression typedMap(TripleList pattern, PatternMapper mapper) {
-      List<Triple> triples = (List<Triple>)pattern.getElements();
-      List<ConstraintExpression> constraints = new ArrayList<ConstraintExpression>(triples.size());
-      for (Triple t: triples) constraints.add(newConstraintImpl(t));
-      return new ConstraintConjunction(constraints);
-    }
-  }
-
-}

Copied: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java)
===================================================================
--- trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java	                        (rev 0)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/PatternMapper.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,292 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.sparql;
+
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.mulgara.sparql.parser.cst.BlankNode;
+import org.mulgara.sparql.parser.cst.BooleanLiteral;
+import org.mulgara.sparql.parser.cst.DecimalLiteral;
+import org.mulgara.sparql.parser.cst.DoubleLiteral;
+import org.mulgara.sparql.parser.cst.EmptyGraphPattern;
+import org.mulgara.sparql.parser.cst.Expression;
+import org.mulgara.sparql.parser.cst.GraphPatternConjunction;
+import org.mulgara.sparql.parser.cst.GraphPatternDisjunction;
+import org.mulgara.sparql.parser.cst.GraphPatternOptional;
+import org.mulgara.sparql.parser.cst.GroupGraphPattern;
+import org.mulgara.sparql.parser.cst.IRIReference;
+import org.mulgara.sparql.parser.cst.IntegerLiteral;
+import org.mulgara.sparql.parser.cst.Node;
+import org.mulgara.sparql.parser.cst.RDFLiteral;
+import org.mulgara.sparql.parser.cst.Triple;
+import org.mulgara.sparql.parser.cst.TripleList;
+import org.mulgara.parser.MulgaraParserException;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.ConstraintElement;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintFalse;
+import org.mulgara.query.ConstraintFilter;
+import org.mulgara.query.ConstraintImpl;
+import org.mulgara.query.ConstraintIn;
+import org.mulgara.query.ConstraintOptionalJoin;
+import org.mulgara.query.Variable;
+import org.mulgara.query.rdf.LiteralImpl;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.query.rdf.XSD;
+
+/**
+ * This object maps a {@link GroupGraphPattern} into a {@link ConstraintExpresion}.
+ *
+ * @created Apr 21, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class PatternMapper {
+
+  /** The pattern to start the mapping on. */
+  GroupGraphPattern startPattern;
+
+  /** An accumulating list of variables that are used in GRAPH patterns. */
+  Set<Variable> graphVars = new HashSet<Variable>();
+
+  /** An accumulating list of URIs that are used in GRAPH patterns. */
+  Set<URI> graphUris = new HashSet<URI>();
+
+  /**
+   * Create a new mapper for a given graph pattern.
+   * @param pattern The graph pattern to be mapped.
+   */
+  PatternMapper(GroupGraphPattern pattern) {
+    startPattern = pattern;
+  }
+
+  /**
+   * Get the set of variables that were employed as graphs in GRAPH patterns.
+   * @return The set of variables used in GRAPH expressions.
+   */
+  Set<Variable> getGraphVars() {
+    return graphVars;
+  }
+
+  /**
+   * Perform the mapping of the graph pattern and return the results as a {@link ConstraintExpression}.
+   * @return The mapped constraint expression.
+   */
+  ConstraintExpression mapToConstraints() throws MulgaraParserException {
+    return mapPattern(startPattern);
+  }
+
+  /**
+   * Converts a pattern to the matching constraint type.
+   * @param pattern The pattern to convert.
+   * @return The new ConstraintExpression which matches the pattern.
+   */
+  private ConstraintExpression mapPattern(GroupGraphPattern pattern) throws MulgaraParserException {
+    PatternToConstraintMapper<? extends GroupGraphPattern> cons = constructors.get(pattern.getClass());
+    if (cons == null) throw new UnsupportedOperationException("Unknown SPARQL pattern: " + pattern.getClass().getSimpleName());
+    ConstraintExpression result = cons.map(pattern, this);
+    result = applyFilter(result, pattern.getFilter());
+    result = applyGraph(result, pattern.getGraph());
+    return result;
+  }
+
+  /**
+   * Apply a FILTER to a constraint expression.
+   * @param constraint The expression to be filtered.
+   * @param filter The filter to be wrapped around this constraint.
+   * @return The filtered version of the constraint.
+   */
+  private ConstraintExpression applyFilter(ConstraintExpression constraint, Expression filter) throws MulgaraParserException {
+    if (filter == null) return constraint;
+    FilterMapper filterMapper = new FilterMapper(filter);
+    return new ConstraintFilter(constraint, filterMapper.getFilter());
+  }
+
+  /**
+   * Apply the parameter of a GRAPH modifier to a constraint expression.
+   * @param constraint The expression to be updated.
+   * @param graph The parameter of the GRAPH expression that is to be propagated through the constraint.
+   * @return The modified version of the constraint.
+   */
+  private ConstraintExpression applyGraph(ConstraintExpression constraint, Expression graph) {
+    if (graph == null) return constraint;
+    // graph is a Variable or IRIReference
+    if (graph instanceof org.mulgara.sparql.parser.cst.Variable) {
+      org.mulgara.sparql.parser.cst.Variable v = (org.mulgara.sparql.parser.cst.Variable)graph;
+      if (v.getName().equals("_from"));
+      Variable var = new Variable(v.getName());
+      // remember this is variable to be bound to the FROM NAMED values
+      graphVars.add(var);
+      constraint = new ConstraintIn(constraint, var);
+    } else if (graph instanceof IRIReference) {
+      // store this reference as a value that should be in the FROM NAMED list
+      URI ref = ((IRIReference)graph).getUri();
+      graphUris.add(ref);
+      constraint = new ConstraintIn(constraint, new URIReferenceImpl(ref));
+    } else {
+      throw new IllegalArgumentException("Illegal argument in a GRAPH expression: " + graph.getClass().getSimpleName());
+    }
+    return constraint;
+  }
+
+  /**
+   * A case analysis to convert simple types into {@link ConstraintElement}s.
+   * @param n The {@link Node} to convert to a ConstraintElement.
+   * @return A new constraint element that matches the node n.
+   */
+  private static ConstraintElement convertElement(Node n) {
+    if (n instanceof org.mulgara.sparql.parser.cst.Variable) {
+      return new Variable(((org.mulgara.sparql.parser.cst.Variable)n).getName());
+    }
+    if (n instanceof IRIReference) return new URIReferenceImpl(((IRIReference)n).getUri());
+    if (n instanceof BlankNode) return new Variable(((BlankNode)n).getLabel());
+    if (n instanceof RDFLiteral) {
+      RDFLiteral lit = (RDFLiteral)n;
+      if (lit.isTyped()) return new LiteralImpl(lit.getValue(), lit.getDatatype().getUri());
+      if (lit.isLanguageCoded()) return new LiteralImpl(lit.getValue(), lit.getLanguage());
+      return new LiteralImpl(lit.getValue());
+    }
+    // integer, decimal, double, boolean
+    if (n instanceof IntegerLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.INT_URI);
+    if (n instanceof DecimalLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.DECIMAL_URI);
+    if (n instanceof DoubleLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.DOUBLE_URI);
+    if (n instanceof BooleanLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.BOOLEAN_URI);
+    // don't know what to make of this
+    throw new UnsupportedOperationException("Unhandled data type in triple: " + n.getClass().getSimpleName());
+  }
+
+  /**
+   * Converts a Triple from the CST into a ConstraintImpl in the AST.
+   * @param t The triple to convert.
+   * @return The new constraint.
+   */
+  private static ConstraintImpl newConstraintImpl(Triple t) {
+    ConstraintElement s = convertElement(t.getSubject());
+    ConstraintElement p = convertElement(t.getPredicate());
+    ConstraintElement o = convertElement(t.getObject());
+    return new ConstraintImpl(s, p, o);
+  }
+
+  /** A mapping of pattern types to constructors for the objects they map to. */
+  private static Map<Class<? extends GroupGraphPattern>,PatternToConstraintMapper<? extends GroupGraphPattern>> constructors = new HashMap<Class<? extends GroupGraphPattern>,PatternToConstraintMapper<? extends GroupGraphPattern>>();
+
+  /**
+   * The class for the mapping of {@link GroupGraphPattern}s to {@link ConstraintExpression}s.
+   * This class and extending classes are not static, as the classes will be call back into the
+   * outer class to recurse down the CST.
+   * The reason this is an abstract class instead of an interface is so map(T) can be set
+   * to accept the general GroupGraphPattern and do the cast. This was not possible outside
+   * of the context of the generic type T.
+   */
+  private static abstract class PatternToConstraintMapper<T extends GroupGraphPattern> {
+    /** An entry point for the map operation. This method handles casting to be compatible with the generic template. */
+    @SuppressWarnings("unchecked")
+    public ConstraintExpression map(GroupGraphPattern pattern, PatternMapper mapper) throws MulgaraParserException { return typedMap((T)pattern, mapper); }
+    /**
+     * Convert a GroupGraphPattern to a ConstraintExpression for Mulgara.
+     * @param pattern The pattern to convert. Should be specific to the mapper.
+     * @return The constraint expression relevant to the mapper.
+     */
+    abstract ConstraintExpression typedMap(T pattern, PatternMapper mapper) throws MulgaraParserException;
+    /** Identify the class to be mapped by the extension. */
+    public abstract Class<T> getMapType();
+  }
+
+  /**
+   * Utility method to add a pattern mapper to the map, keyed on the class it maps.
+   * @param mapper The mapper to add to the map.
+   */
+  static void addToMap(PatternToConstraintMapper<? extends GroupGraphPattern> mapper) {
+    constructors.put(mapper.getMapType(), mapper);
+  }
+
+  /**
+   * Initialize the mapping of patterns to the constraint builders.
+   * This is not static in order to avoid passing "this" through to the methods
+   * on each of the implementing mapper classes.
+   */
+  static {
+    addToMap(new EmptyGraphPatternToConstraint());
+    addToMap(new GraphPatternConjunctionToConstraint());
+    addToMap(new GraphPatternDisjunctionToConstraint());
+    addToMap(new GraphPatternOptionalToConstraint());
+    addToMap(new TripleToConstraint());
+    addToMap(new TripleListToConstraint());
+  }
+
+  /** Map the empty graph pattern to a constraint that always resolves to nothing. */
+  private static class EmptyGraphPatternToConstraint extends PatternToConstraintMapper<EmptyGraphPattern> {
+    public Class<EmptyGraphPattern> getMapType() { return EmptyGraphPattern.class; }
+    ConstraintExpression typedMap(EmptyGraphPattern pattern, PatternMapper mapper) {
+      return ConstraintFalse.INSTANCE;
+    }
+  }
+
+  /** Map the conjunctions to ConstraintConjunction. */
+  private static class GraphPatternConjunctionToConstraint extends PatternToConstraintMapper<GraphPatternConjunction> {
+    public Class<GraphPatternConjunction> getMapType() { return GraphPatternConjunction.class; }
+    ConstraintExpression typedMap(GraphPatternConjunction pattern, PatternMapper mapper) throws MulgaraParserException {
+      List<GroupGraphPattern> list = pattern.getElements();
+      List<ConstraintExpression> newList = new ArrayList<ConstraintExpression>(list.size());
+      for (GroupGraphPattern p: list) newList.add(mapper.mapPattern(p));
+      return new ConstraintConjunction(newList);
+    }
+  }
+
+  /** Map the disjunctions to ConstraintConjunction. */
+  private static class GraphPatternDisjunctionToConstraint extends PatternToConstraintMapper<GraphPatternDisjunction> {
+    public Class<GraphPatternDisjunction> getMapType() { return GraphPatternDisjunction.class; }
+    ConstraintExpression typedMap(GraphPatternDisjunction pattern, PatternMapper mapper) throws MulgaraParserException {
+      List<GroupGraphPattern> list = pattern.getElements();
+      List<ConstraintExpression> newList = new ArrayList<ConstraintExpression>(list.size());
+      for (GroupGraphPattern p: list) newList.add(mapper.mapPattern(p));
+      return new ConstraintDisjunction(newList);
+    }
+  }
+
+  /** Map the optional patterns to ConstraintOptional. */
+  private static class GraphPatternOptionalToConstraint extends PatternToConstraintMapper<GraphPatternOptional> {
+    public Class<GraphPatternOptional> getMapType() { return GraphPatternOptional.class; }
+    ConstraintExpression typedMap(GraphPatternOptional pattern, PatternMapper mapper) throws MulgaraParserException {
+      return new ConstraintOptionalJoin(mapper.mapPattern(pattern.getMain()), mapper.mapPattern(pattern.getOptional()));
+    }
+  }
+
+  /** Map the triple patterns to ConstraintImpl. */
+  private static class TripleToConstraint extends PatternToConstraintMapper<Triple> {
+    public Class<Triple> getMapType() { return Triple.class; }
+    ConstraintExpression typedMap(Triple pattern, PatternMapper mapper) {
+      return newConstraintImpl(pattern);
+    }
+  }
+
+  /** Map the lists of triple patterns to ConstraintConjunctions on ConstraintImpl. */
+  private static class TripleListToConstraint extends PatternToConstraintMapper<TripleList> {
+    public Class<TripleList> getMapType() { return TripleList.class; }
+    @SuppressWarnings("unchecked")
+    ConstraintExpression typedMap(TripleList pattern, PatternMapper mapper) {
+      List<Triple> triples = (List<Triple>)pattern.getElements();
+      List<ConstraintExpression> constraints = new ArrayList<ConstraintExpression>(triples.size());
+      for (Triple t: triples) constraints.add(newConstraintImpl(t));
+      return new ConstraintConjunction(constraints);
+    }
+  }
+
+}

Deleted: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java
===================================================================
--- branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,279 +0,0 @@
-/**
- * The contents of this file are subject to the Open Software License
- * Version 3.0 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License at
- * http://www.opensource.org/licenses/osl-3.0.txt
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and limitations
- * under the License.
- */
-package org.mulgara.sparql;
-
-import java.io.IOException;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-import org.mulgara.parser.Interpreter;
-import org.mulgara.parser.MulgaraLexerException;
-import org.mulgara.parser.MulgaraParserException;
-import org.mulgara.query.ConstraintConjunction;
-import org.mulgara.query.ConstraintDisjunction;
-import org.mulgara.query.ConstraintExpression;
-import org.mulgara.query.ConstraintIs;
-import org.mulgara.query.ModelExpression;
-import org.mulgara.query.ModelResource;
-import org.mulgara.query.ModelUnion;
-import org.mulgara.query.Order;
-import org.mulgara.query.Query;
-import org.mulgara.query.SelectElement;
-import org.mulgara.query.UnconstrainedAnswer;
-import org.mulgara.query.Variable;
-import org.mulgara.query.operation.Command;
-import org.mulgara.query.rdf.URIReferenceImpl;
-import org.mulgara.sparql.parser.ParseException;
-import org.mulgara.sparql.parser.QueryStructure;
-import org.mulgara.sparql.parser.SparqlParser;
-import org.mulgara.sparql.parser.cst.Expression;
-import org.mulgara.sparql.parser.cst.GroupGraphPattern;
-import org.mulgara.sparql.parser.cst.IRIReference;
-import org.mulgara.sparql.parser.cst.Node;
-import org.mulgara.sparql.parser.cst.Ordering;
-
-
-/**
- * Converts a parsed SPARQL query into a Command for execution.
- *
- * @created Apr 18, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
- * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
- */
-public class SparqlInterpreter implements Interpreter {
-
-  /** The default graph to use if none has been set. */
-  private static final URI INTERNAL_DEFAULT_GRAPH_URI = URI.create("local:null");
-
-  /** The default graph to use when none has been parsed. */
-  private URI defaultGraphUri = null;
-
-  /**
-   * Sets the default graph to use in parsed queries.
-   * @param graph The graph URI to use as the default graph.
-   */
-  public void setDefaultGraphUri(URI graphUri) {
-    defaultGraphUri = graphUri;
-  }
-
-  /**
-   * Gets the default graph to use when none has been parsed from the query.
-   * @return The graph that parsed queries will default to when no FROM graph is supplied.
-   */
-  public URI getDefaultGraphUri() {
-    return (defaultGraphUri != null) ? defaultGraphUri : INTERNAL_DEFAULT_GRAPH_URI;
-  }
-
-  /**
-   * @see org.mulgara.parser.Interpreter#parseCommand(java.lang.String)
-   * The only commands that SPARQL current handles are queries.
-   */
-  public Command parseCommand(String command) throws MulgaraParserException, MulgaraLexerException, IllegalArgumentException, IOException {
-    return parseQuery(command);
-  }
-
-  /**
-   * @see org.mulgara.parser.Interpreter#parseCommands(java.lang.String)
-   * Since SPARQL has no separator character, there can only be one command per string.
-   */
-  public List<Command> parseCommands(String command) throws MulgaraParserException, MulgaraLexerException, IOException, IllegalArgumentException {
-    return Collections.singletonList(parseCommand(command));
-  }
-
-  /**
-   * @see org.mulgara.parser.Interpreter#parseQuery(java.lang.String)
-   */
-  public Query parseQuery(String queryString) throws IOException, MulgaraLexerException, MulgaraParserException {
-    QueryStructure struct;
-    try {
-      struct = SparqlParser.parse(queryString);
-    } catch (ParseException pe) {
-      throw new MulgaraParserException(pe);
-    }
-    switch (struct.getType()) {
-      case select:
-        return buildSelectQuery(struct);
-      case construct:
-        return unhandledType(struct);
-      case describe:
-        return unhandledType(struct);
-      case ask:
-        return unhandledType(struct);
-      default:
-        throw new MulgaraParserException("Unknown query type: " + struct.getType().name());
-    }
-  }
-
-  /**
-   * Respond to an unhandled query type.
-   * @param struct The structure representing the query
-   * @return Nothing. An exception is always thrown.
-   * @throws UnsupportedOperationException An exception explaining that this query type is not handled.
-   */
-  private Query unhandledType(QueryStructure struct) throws UnsupportedOperationException {
-    throw new UnsupportedOperationException("Query type not yet supported: " + struct.getType().name());
-  }
-
-  /**
-   * Converts the elements of a {@link QueryStructure} into a Mulgara {@link Query}.
-   * @param queryStruct The structure to analyze and convert.
-   * @return A new query that can be run as a {@link org.mulgara.query.operation.Command} on a connection.
-   * @throws MulgaraParserException If the query structure contains elements that are not supported by Mulgara.
-   */
-  Query buildSelectQuery(QueryStructure queryStruct) throws MulgaraParserException {
-    List<? extends SelectElement> selection = getSelection(queryStruct);
-    ModelExpression defaultGraphs = getFrom(queryStruct);
-    ConstraintExpression whereClause = getWhere(queryStruct);
-    List<Order> orderBy = getOrdering(queryStruct);
-    Integer limit = getLimit(queryStruct);
-    int offset = queryStruct.getOffset();
-    // null having, unconstrained answer
-    return new Query(selection, defaultGraphs, whereClause, null, orderBy, limit, offset, new UnconstrainedAnswer());
-  }
-
-  /**
-   * Extract the requested variables from this query into a list.
-   * @param queryStruct The query to get the selected variables from.
-   * @return A new list containing Mulgara {@link Variable}s.
-   * @throws MulgaraParserException If and selected elements are not variables.
-   */
-  List<? extends SelectElement> getSelection(QueryStructure queryStruct) throws MulgaraParserException {
-    List<Variable> result = new ArrayList<Variable>();
-    if (queryStruct.isSelectAll()) {
-      Collection<org.mulgara.sparql.parser.cst.Variable> allVars = queryStruct.getAllVariables();
-      for (org.mulgara.sparql.parser.cst.Variable v: allVars) result.add(new Variable(v.getName()));
-    } else {
-      List<? extends Node> selection = queryStruct.getSelection();
-      for (Node n: selection) {
-        // SPARQL only permits variables
-        if (!(n instanceof org.mulgara.sparql.parser.cst.Variable)) throw new MulgaraParserException("Unexpected non-variable in the SELECT clause");
-        org.mulgara.sparql.parser.cst.Variable cv = (org.mulgara.sparql.parser.cst.Variable)n;
-        result.add(new Variable(cv.getName()));
-      }
-    }
-    return result;
-  }
-
-  /**
-   * Gets the graph expression ({@link ModelExpression}) the represents the FROM clause, or the default
-   * graph if none was provided.
-   * @param queryStruct The structure to query for the FROM clause.
-   * @return A ModelExpression containing all the required graphs as a union. TODO: this should be a merge.
-   */
-  ModelExpression getFrom(QueryStructure queryStruct) {
-    List<IRIReference> iris = queryStruct.getDefaultFroms();
-    // if there were no named graphs, then use the default
-    if (iris.isEmpty()) return new ModelResource(getDefaultGraphUri());
-    // accumulate the remaining graphs as a union
-    return graphUnion(iris);
-  }
-
-  /**
-   * Convert a list of IRIs into a model resource union of minimal depth. This recurses through construction
-   * of a tree of binary unions, rather than creating a linear linked list of unions.
-   * @param iris The list to convert.
-   * @return A ModelExpression which is a union of all the elements in the list,
-   *   or a {@link ModelResource} if the list contains only one element.
-   */
-  private ModelExpression graphUnion(List<IRIReference> iris) {
-    int listSize = iris.size();
-    // terminate on singleton lists
-    if (listSize == 1) return new ModelResource(iris.get(0).getUri());
-    // short circuit for 2 element lists - optimization
-    if (listSize == 2) return new ModelUnion(new ModelResource(iris.get(0).getUri()), new ModelResource(iris.get(1).getUri()));
-    // general case
-    return new ModelUnion(graphUnion(iris.subList(0, listSize / 2)), graphUnion(iris.subList(listSize / 2, listSize)));
-  }
-
-  /**
-   * Creates a list of the ordering to apply to the results. While SPARQL permits ordering by complex
-   * expressions, this is not supported.
-   * @param queryStruct The query structure.
-   * @return A list of {@link Order}, which are each ordered ascending or descending by variable.
-   * @throws MulgaraParserException If the ORDER BY expression was more complex than a simple variable.
-   */
-  List<Order> getOrdering(QueryStructure queryStruct) throws MulgaraParserException {
-    List<Ordering> orderings = queryStruct.getOrderings();
-    List<Order> result = new ArrayList<Order>(orderings.size());
-    for (Ordering order: orderings) {
-      Expression v = order.getExpr();
-      if (!(v instanceof org.mulgara.sparql.parser.cst.Variable)) throw new MulgaraParserException("Unable to support arbitrarily complex ORDER BY clauses.");
-      org.mulgara.sparql.parser.cst.Variable var = (org.mulgara.sparql.parser.cst.Variable)v;
-      result.add(new Order(new Variable(var.getName()), order.isAscending()));
-    }
-    return result;
-  }
-
-  /**
-   * Get the limit described by the query.
-   * @param queryStruct The structure of the query.
-   * @return A {@link java.lang.Integer} containing the limit, or <code>null</code> if there is no limit.
-   */
-  Integer getLimit(QueryStructure queryStruct) {
-    int limit = queryStruct.getLimit();
-    return limit == -1 ? null : limit;
-  }
-
-  /**
-   * Build a WHERE clause for a Mulgara query out of a SPARQL WHERE clause.
-   * @param queryStruct The SPARQL query structure to analyze for the WHERE clause.
-   * @return A Mulgara WHERE clause, as a {@link ConstraintExpression}.
-   * @throws MulgaraParserException The structure of the pattern was incorrect.
-   */
-  ConstraintExpression getWhere(QueryStructure queryStruct) throws MulgaraParserException {
-    // get the basic pattern
-    GroupGraphPattern pattern = queryStruct.getWhereClause();
-    PatternMapper patternMapper = new PatternMapper(pattern);
-    ConstraintExpression result = patternMapper.mapToConstraints();
-    // apply the FROM NAMED expression
-    // TODO: This needs to become a Constraint that wraps LiteralTuples.
-    List<IRIReference> namedFroms = queryStruct.getNamedFroms();
-    if (!namedFroms.isEmpty()) result = addNamedFroms(result, namedFroms, patternMapper.getGraphVars());
-    // possible to ask for non-variables that were employed in GRAPH statements as a parser check.
-    return result;
-  }
-
-  /**
-   * Add in the FROM NAMED values to provide a binding list for each variable used in GRAPH statements.
-   * @param expr The total expression to be modified. This is the WHERE clause.
-   * @param graphs The list of graphs given in the FROM NAMED clauses.
-   * @param graphVars The variables that are used in GRAPH statements.
-   * @return A modified form of expr, with all the graph variables pre-bound.
-   */
-  ConstraintExpression addNamedFroms(ConstraintExpression expr, List<IRIReference> graphs, Set<Variable> graphVars) {
-    List<ConstraintExpression> params = new ArrayList<ConstraintExpression>(graphVars.size() + 1);
-    params.add(expr);
-    for (Variable var: graphVars) params.add(newListConstraint(var, graphs));
-    return new ConstraintConjunction(params);
-  }
-
-  /**
-   * Construct a constraint expression that binds a variable to a list of values.
-   * TODO: This needs to be represented by a new Constraint that gets converted to a LiteralTuples.
-   * @param var The variable to bind.
-   * @param bindingList The list of values to bind the variable to.
-   * @return A new {@link org.mulgara.query.Constraint} that represents the variable binding.
-   */
-  ConstraintExpression newListConstraint(Variable var, List<IRIReference> bindingList) {
-    List<ConstraintExpression> isConstraints = new ArrayList<ConstraintExpression>(bindingList.size());
-    for (IRIReference iri: bindingList) {
-      // does this need a graph node that isn't variable?
-      isConstraints.add(new ConstraintIs(var, new URIReferenceImpl(iri.getUri())));
-    }
-    return new ConstraintDisjunction(isConstraints);
-  }
-}

Copied: trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java)
===================================================================
--- trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java	                        (rev 0)
+++ trunk/src/jar/sparql-interpreter/java/org/mulgara/sparql/SparqlInterpreter.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,279 @@
+/**
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+package org.mulgara.sparql;
+
+import java.io.IOException;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import org.mulgara.parser.Interpreter;
+import org.mulgara.parser.MulgaraLexerException;
+import org.mulgara.parser.MulgaraParserException;
+import org.mulgara.query.ConstraintConjunction;
+import org.mulgara.query.ConstraintDisjunction;
+import org.mulgara.query.ConstraintExpression;
+import org.mulgara.query.ConstraintIs;
+import org.mulgara.query.ModelExpression;
+import org.mulgara.query.ModelResource;
+import org.mulgara.query.ModelUnion;
+import org.mulgara.query.Order;
+import org.mulgara.query.Query;
+import org.mulgara.query.SelectElement;
+import org.mulgara.query.UnconstrainedAnswer;
+import org.mulgara.query.Variable;
+import org.mulgara.query.operation.Command;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.sparql.parser.ParseException;
+import org.mulgara.sparql.parser.QueryStructure;
+import org.mulgara.sparql.parser.SparqlParser;
+import org.mulgara.sparql.parser.cst.Expression;
+import org.mulgara.sparql.parser.cst.GroupGraphPattern;
+import org.mulgara.sparql.parser.cst.IRIReference;
+import org.mulgara.sparql.parser.cst.Node;
+import org.mulgara.sparql.parser.cst.Ordering;
+
+
+/**
+ * Converts a parsed SPARQL query into a Command for execution.
+ *
+ * @created Apr 18, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.topazproject.org/">The Topaz Project</a>
+ * @licence <a href="{@docRoot}/../../LICENCE.txt">Open Software License v3.0</a>
+ */
+public class SparqlInterpreter implements Interpreter {
+
+  /** The default graph to use if none has been set. */
+  private static final URI INTERNAL_DEFAULT_GRAPH_URI = URI.create("local:null");
+
+  /** The default graph to use when none has been parsed. */
+  private URI defaultGraphUri = null;
+
+  /**
+   * Sets the default graph to use in parsed queries.
+   * @param graph The graph URI to use as the default graph.
+   */
+  public void setDefaultGraphUri(URI graphUri) {
+    defaultGraphUri = graphUri;
+  }
+
+  /**
+   * Gets the default graph to use when none has been parsed from the query.
+   * @return The graph that parsed queries will default to when no FROM graph is supplied.
+   */
+  public URI getDefaultGraphUri() {
+    return (defaultGraphUri != null) ? defaultGraphUri : INTERNAL_DEFAULT_GRAPH_URI;
+  }
+
+  /**
+   * @see org.mulgara.parser.Interpreter#parseCommand(java.lang.String)
+   * The only commands that SPARQL current handles are queries.
+   */
+  public Command parseCommand(String command) throws MulgaraParserException, MulgaraLexerException, IllegalArgumentException, IOException {
+    return parseQuery(command);
+  }
+
+  /**
+   * @see org.mulgara.parser.Interpreter#parseCommands(java.lang.String)
+   * Since SPARQL has no separator character, there can only be one command per string.
+   */
+  public List<Command> parseCommands(String command) throws MulgaraParserException, MulgaraLexerException, IOException, IllegalArgumentException {
+    return Collections.singletonList(parseCommand(command));
+  }
+
+  /**
+   * @see org.mulgara.parser.Interpreter#parseQuery(java.lang.String)
+   */
+  public Query parseQuery(String queryString) throws IOException, MulgaraLexerException, MulgaraParserException {
+    QueryStructure struct;
+    try {
+      struct = SparqlParser.parse(queryString);
+    } catch (ParseException pe) {
+      throw new MulgaraParserException(pe);
+    }
+    switch (struct.getType()) {
+      case select:
+        return buildSelectQuery(struct);
+      case construct:
+        return unhandledType(struct);
+      case describe:
+        return unhandledType(struct);
+      case ask:
+        return unhandledType(struct);
+      default:
+        throw new MulgaraParserException("Unknown query type: " + struct.getType().name());
+    }
+  }
+
+  /**
+   * Respond to an unhandled query type.
+   * @param struct The structure representing the query
+   * @return Nothing. An exception is always thrown.
+   * @throws UnsupportedOperationException An exception explaining that this query type is not handled.
+   */
+  private Query unhandledType(QueryStructure struct) throws UnsupportedOperationException {
+    throw new UnsupportedOperationException("Query type not yet supported: " + struct.getType().name());
+  }
+
+  /**
+   * Converts the elements of a {@link QueryStructure} into a Mulgara {@link Query}.
+   * @param queryStruct The structure to analyze and convert.
+   * @return A new query that can be run as a {@link org.mulgara.query.operation.Command} on a connection.
+   * @throws MulgaraParserException If the query structure contains elements that are not supported by Mulgara.
+   */
+  Query buildSelectQuery(QueryStructure queryStruct) throws MulgaraParserException {
+    List<? extends SelectElement> selection = getSelection(queryStruct);
+    ModelExpression defaultGraphs = getFrom(queryStruct);
+    ConstraintExpression whereClause = getWhere(queryStruct);
+    List<Order> orderBy = getOrdering(queryStruct);
+    Integer limit = getLimit(queryStruct);
+    int offset = queryStruct.getOffset();
+    // null having, unconstrained answer
+    return new Query(selection, defaultGraphs, whereClause, null, orderBy, limit, offset, new UnconstrainedAnswer());
+  }
+
+  /**
+   * Extract the requested variables from this query into a list.
+   * @param queryStruct The query to get the selected variables from.
+   * @return A new list containing Mulgara {@link Variable}s.
+   * @throws MulgaraParserException If and selected elements are not variables.
+   */
+  List<? extends SelectElement> getSelection(QueryStructure queryStruct) throws MulgaraParserException {
+    List<Variable> result = new ArrayList<Variable>();
+    if (queryStruct.isSelectAll()) {
+      Collection<org.mulgara.sparql.parser.cst.Variable> allVars = queryStruct.getAllVariables();
+      for (org.mulgara.sparql.parser.cst.Variable v: allVars) result.add(new Variable(v.getName()));
+    } else {
+      List<? extends Node> selection = queryStruct.getSelection();
+      for (Node n: selection) {
+        // SPARQL only permits variables
+        if (!(n instanceof org.mulgara.sparql.parser.cst.Variable)) throw new MulgaraParserException("Unexpected non-variable in the SELECT clause");
+        org.mulgara.sparql.parser.cst.Variable cv = (org.mulgara.sparql.parser.cst.Variable)n;
+        result.add(new Variable(cv.getName()));
+      }
+    }
+    return result;
+  }
+
+  /**
+   * Gets the graph expression ({@link ModelExpression}) the represents the FROM clause, or the default
+   * graph if none was provided.
+   * @param queryStruct The structure to query for the FROM clause.
+   * @return A ModelExpression containing all the required graphs as a union. TODO: this should be a merge.
+   */
+  ModelExpression getFrom(QueryStructure queryStruct) {
+    List<IRIReference> iris = queryStruct.getDefaultFroms();
+    // if there were no named graphs, then use the default
+    if (iris.isEmpty()) return new ModelResource(getDefaultGraphUri());
+    // accumulate the remaining graphs as a union
+    return graphUnion(iris);
+  }
+
+  /**
+   * Convert a list of IRIs into a model resource union of minimal depth. This recurses through construction
+   * of a tree of binary unions, rather than creating a linear linked list of unions.
+   * @param iris The list to convert.
+   * @return A ModelExpression which is a union of all the elements in the list,
+   *   or a {@link ModelResource} if the list contains only one element.
+   */
+  private ModelExpression graphUnion(List<IRIReference> iris) {
+    int listSize = iris.size();
+    // terminate on singleton lists
+    if (listSize == 1) return new ModelResource(iris.get(0).getUri());
+    // short circuit for 2 element lists - optimization
+    if (listSize == 2) return new ModelUnion(new ModelResource(iris.get(0).getUri()), new ModelResource(iris.get(1).getUri()));
+    // general case
+    return new ModelUnion(graphUnion(iris.subList(0, listSize / 2)), graphUnion(iris.subList(listSize / 2, listSize)));
+  }
+
+  /**
+   * Creates a list of the ordering to apply to the results. While SPARQL permits ordering by complex
+   * expressions, this is not supported.
+   * @param queryStruct The query structure.
+   * @return A list of {@link Order}, which are each ordered ascending or descending by variable.
+   * @throws MulgaraParserException If the ORDER BY expression was more complex than a simple variable.
+   */
+  List<Order> getOrdering(QueryStructure queryStruct) throws MulgaraParserException {
+    List<Ordering> orderings = queryStruct.getOrderings();
+    List<Order> result = new ArrayList<Order>(orderings.size());
+    for (Ordering order: orderings) {
+      Expression v = order.getExpr();
+      if (!(v instanceof org.mulgara.sparql.parser.cst.Variable)) throw new MulgaraParserException("Unable to support arbitrarily complex ORDER BY clauses.");
+      org.mulgara.sparql.parser.cst.Variable var = (org.mulgara.sparql.parser.cst.Variable)v;
+      result.add(new Order(new Variable(var.getName()), order.isAscending()));
+    }
+    return result;
+  }
+
+  /**
+   * Get the limit described by the query.
+   * @param queryStruct The structure of the query.
+   * @return A {@link java.lang.Integer} containing the limit, or <code>null</code> if there is no limit.
+   */
+  Integer getLimit(QueryStructure queryStruct) {
+    int limit = queryStruct.getLimit();
+    return limit == -1 ? null : limit;
+  }
+
+  /**
+   * Build a WHERE clause for a Mulgara query out of a SPARQL WHERE clause.
+   * @param queryStruct The SPARQL query structure to analyze for the WHERE clause.
+   * @return A Mulgara WHERE clause, as a {@link ConstraintExpression}.
+   * @throws MulgaraParserException The structure of the pattern was incorrect.
+   */
+  ConstraintExpression getWhere(QueryStructure queryStruct) throws MulgaraParserException {
+    // get the basic pattern
+    GroupGraphPattern pattern = queryStruct.getWhereClause();
+    PatternMapper patternMapper = new PatternMapper(pattern);
+    ConstraintExpression result = patternMapper.mapToConstraints();
+    // apply the FROM NAMED expression
+    // TODO: This needs to become a Constraint that wraps LiteralTuples.
+    List<IRIReference> namedFroms = queryStruct.getNamedFroms();
+    if (!namedFroms.isEmpty()) result = addNamedFroms(result, namedFroms, patternMapper.getGraphVars());
+    // possible to ask for non-variables that were employed in GRAPH statements as a parser check.
+    return result;
+  }
+
+  /**
+   * Add in the FROM NAMED values to provide a binding list for each variable used in GRAPH statements.
+   * @param expr The total expression to be modified. This is the WHERE clause.
+   * @param graphs The list of graphs given in the FROM NAMED clauses.
+   * @param graphVars The variables that are used in GRAPH statements.
+   * @return A modified form of expr, with all the graph variables pre-bound.
+   */
+  ConstraintExpression addNamedFroms(ConstraintExpression expr, List<IRIReference> graphs, Set<Variable> graphVars) {
+    List<ConstraintExpression> params = new ArrayList<ConstraintExpression>(graphVars.size() + 1);
+    params.add(expr);
+    for (Variable var: graphVars) params.add(newListConstraint(var, graphs));
+    return new ConstraintConjunction(params);
+  }
+
+  /**
+   * Construct a constraint expression that binds a variable to a list of values.
+   * TODO: This needs to be represented by a new Constraint that gets converted to a LiteralTuples.
+   * @param var The variable to bind.
+   * @param bindingList The list of values to bind the variable to.
+   * @return A new {@link org.mulgara.query.Constraint} that represents the variable binding.
+   */
+  ConstraintExpression newListConstraint(Variable var, List<IRIReference> bindingList) {
+    List<ConstraintExpression> isConstraints = new ArrayList<ConstraintExpression>(bindingList.size());
+    for (IRIReference iri: bindingList) {
+      // does this need a graph node that isn't variable?
+      isConstraints.add(new ConstraintIs(var, new URIReferenceImpl(iri.getUri())));
+    }
+    return new ConstraintDisjunction(isConstraints);
+  }
+}

Deleted: trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties
===================================================================
--- branches/mgr-61-sparql/src/jar/sparql-interpreter/sparql-interpreter-build.properties	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,15 +0,0 @@
-#
-# Properties used by the SPARQL interpreter module
-#
-
-# Module Name
-sparql-interpreter.name = SPARQL-Interpreter
-
-# General module properties
-sparql-int.conf.dir      = ${conf.dir}
-sparql-int.src.dir       = ${jar.src.dir}/sparql-interpreter
-sparql-int.obj.dir       = ${jar.obj.dir}/sparql-interpreter
-sparql-int.dist.dir      = ${bin.dir}
-sparql-int.test.dir      = ${test.dir}/sparql-interpreter
-sparql-int.jxtest.dir    = ${jxtest.dir}/sparql-interpreter
-sparql-int.jar           = sparql-int-base-${mulgara-version}.jar

Copied: trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties (from rev 855, branches/mgr-61-sparql/src/jar/sparql-interpreter/sparql-interpreter-build.properties)
===================================================================
--- trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties	                        (rev 0)
+++ trunk/src/jar/sparql-interpreter/sparql-interpreter-build.properties	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,15 @@
+#
+# Properties used by the SPARQL interpreter module
+#
+
+# Module Name
+sparql-interpreter.name = SPARQL-Interpreter
+
+# General module properties
+sparql-int.conf.dir      = ${conf.dir}
+sparql-int.src.dir       = ${jar.src.dir}/sparql-interpreter
+sparql-int.obj.dir       = ${jar.obj.dir}/sparql-interpreter
+sparql-int.dist.dir      = ${bin.dir}
+sparql-int.test.dir      = ${test.dir}/sparql-interpreter
+sparql-int.jxtest.dir    = ${jxtest.dir}/sparql-interpreter
+sparql-int.jar           = sparql-int-base-${mulgara-version}.jar

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/Difference.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,35 +1,19 @@
 /*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
  * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
+ * http://www.opensource.org/licenses/osl-3.0.txt
  *
  * Software distributed under the License is distributed on an "AS IS"
  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  * the License for the specific language governing rights and limitations
  * under the License.
- *
- * The Original Code is the Kowari Metadata Store.
- *
- * The Initial Developer of the Original Code is Plugged In Software Pty
- * Ltd (http://www.pisoftware.com, mailto:info at pisoftware.com). Portions
- * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
- * Plugged In Software Pty Ltd. All Rights Reserved.
- *
- * Contributor(s): N/A.
- *
- * [NOTE: The text of this Exhibit A may differ slightly from the text
- * of the notices in the Source Code files of the Original Code. You
- * should use the text of this Exhibit A rather than the text found in the
- * Original Code Source Code for Your Modifications.]
- *
  */
 
 package org.mulgara.store.tuples;
 
 // Java 2 standard packages
 import java.util.*;
-import java.math.BigInteger;
 
 // Third party packages
 import org.apache.log4j.*;
@@ -53,22 +37,14 @@
  * ensuring the sort order of the subtrahend; that responsibility falls to
  * {@link TuplesOperations#subtract}.
  *
- * @created 2003-09-01
- *
+ * @created 2005-03
  * @author <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- *
- * @version $Revision: 1.2 $
- *
- * @modified $Date: 2005/05/02 20:08:00 $
- *
- * @maintenanceAuthor $Author: raboczi $
- *
- * @copyright &copy; 2005 <A href="mailto:pgearon at users.sourceforge.net">Paul Gearon</A>
- *
- * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
+ * @copyright &copy; 2008 <A href="http://www.topazproject.org/">The Topaz Project</A>
+ * @licence <a href="{@docRoot}/../../LICENCE">Open Software License v3.0</a>
  */
 public class Difference extends AbstractTuples {
 
+  @SuppressWarnings("unused")
   private static Logger logger = Logger.getLogger(Difference.class.getName());
 
   /** The set of tuples to subtract from. */
@@ -78,7 +54,7 @@
   protected Tuples subtrahend;
 
   /** The set of variables common to both the minuend and the subtrahend. */
-  protected Set commonVars;
+  protected Set<Variable> commonVars;
 
   /** An array of the matching variables' columns within the minuend, indexed by the subtrahend position. */
   protected int[] varMap;
@@ -91,13 +67,14 @@
    * @throws IllegalArgumentException If the <var>minuend</var> and  <var>subtrahend</var>
    *         contain no variables in common.
    */
+  @SuppressWarnings("unchecked")
   Difference(Tuples minuend, Tuples subtrahend) throws TuplesException, IllegalArgumentException {
     // store the operands
     this.minuend = (Tuples)minuend.clone();
     this.subtrahend = (Tuples)subtrahend.clone();
 
-    // get the variables to subtract with
-    commonVars = Collections.unmodifiableSet(TuplesOperations.getMatchingVars(minuend, subtrahend));
+    // get the variables to subtract with. TODO: get the correct type back from getMatchingVars
+    commonVars = Collections.unmodifiableSet((Set<Variable>)TuplesOperations.getMatchingVars(minuend, subtrahend));
 
     if (commonVars.isEmpty()) {
       throw new IllegalArgumentException("tuples must have variables in common for subtraction to occur");
@@ -106,9 +83,7 @@
     // initialise the mapping of minuend columns to subtrahend columns
     varMap = new int[commonVars.size()];
     // iterate over the variables to do the mapping
-    Iterator iVar = commonVars.iterator();
-    while (iVar.hasNext()) {
-      Variable var = (Variable)iVar.next();
+    for (Variable var: commonVars) {
       // get the index of the variable in the subtrahend
       int si = subtrahend.getColumnIndex(var);
       // check that it is within the prefix columns. If not, then the subtrahend is not properly sorted.
@@ -206,7 +181,7 @@
   /**
    * {@inheritDoc}
    */
-  public List getOperands() {
+  public List<Tuples> getOperands() {
     return Collections.unmodifiableList(Arrays.asList(new Tuples[] {minuend, subtrahend}));
   }
 

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java	2008-04-25 22:50:58 UTC (rev 855)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -1,28 +1,13 @@
 /*
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
  * compliance with the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
+ * http://www.opensource.org/licenses/osl-3.0.txt
  *
  * Software distributed under the License is distributed on an "AS IS"
  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  * the License for the specific language governing rights and limitations
  * under the License.
- *
- * The Original Code is the Kowari Metadata Store.
- *
- * The Initial Developer of the Original Code is Plugged In Software Pty
- * Ltd (http://www.pisoftware.com, mailto:info at pisoftware.com). Portions
- * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
- * Plugged In Software Pty Ltd. All Rights Reserved.
- *
- * Contributor(s): N/A.
- *
- * [NOTE: The text of this Exhibit A may differ slightly from the text
- * of the notices in the Source Code files of the Original Code. You
- * should use the text of this Exhibit A rather than the text found in the
- * Original Code Source Code for Your Modifications.]
- *
  */
 
 package org.mulgara.store.tuples;
@@ -39,25 +24,14 @@
  * Test case for {@link Difference}.
  *
  * @created 2005-03-31
- *
  * @author <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
- *
- * @version $Revision: 1.1 $
- *
- * @modified $Date: 2005/04/10 09:21:22 $
- *
- * @maintenanceAuthor $Author: pgearon $
- *
- * @copyright &copy; 2003 <A href="http://www.PIsoftware.com/">Plugged In
- *      Software Pty Ltd</A>
- *
- * @licence <a href="{@docRoot}/../../LICENCE">Mozilla Public License v1.1</a>
+ * @copyright &copy; 2003 <A href="http://www.topazproject.org/">The Topaz Project</A>
+ * @licence <a href="{@docRoot}/../../LICENCE">Open Software License v3.0</a>
  */
 public class DifferenceUnitTest extends TestCase {
 
-  /**
-   * Logger.
-   */
+  /** Logger. */
+  @SuppressWarnings("unused")
   private static final Logger logger = Logger.getLogger(DifferenceUnitTest.class);
 
   /** Test variable. */
@@ -162,7 +136,7 @@
         8));
 
     try {
-      Tuples joined = new Difference(lhs, rhs);
+      new Difference(lhs, rhs);
       assertTrue(false);
     } catch (IllegalArgumentException e) {
       /* no-op */
@@ -446,6 +420,13 @@
     TuplesTestingUtil.closeTuples(new Tuples[] { actual, lhs, rhs });
   }
 
+  /**
+   * Internal method used during debugging. This method writes the contents of a tuples
+   * to STDOUT.
+   * @param t The tuples to dump
+   * @throws TuplesException If there was an exception accessing the tuples.
+   */
+  @SuppressWarnings("unused")
   private void dumpTuples(Tuples t) throws TuplesException {
     Variable[] v = t.getVariables();
     for (int i = 0; i < v.length; i++) {

Copied: trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java (from rev 855, branches/mgr-61-sparql/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java)
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java	                        (rev 0)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/FilteredTuples.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,222 @@
+/*
+ * The contents of this file are subject to the Mozilla Public License
+ * Version 1.1 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * The Original Code is the Kowari Metadata Store.
+ *
+ * The Initial Developer of the Original Code is Plugged In Software Pty
+ * Ltd (http://www.pisoftware.com, mailto:info at pisoftware.com). Portions
+ * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
+ * Plugged In Software Pty Ltd. All Rights Reserved.
+ *
+ * Contributor(s): N/A.
+ *
+ * [NOTE: The text of this Exhibit A may differ slightly from the text
+ * of the notices in the Source Code files of the Original Code. You
+ * should use the text of this Exhibit A rather than the text found in the
+ * Original Code Source Code for Your Modifications.]
+ *
+ */
+
+package org.mulgara.store.tuples;
+
+// Java 2 standard packages
+import java.util.*;
+
+// Third party packages
+import org.apache.log4j.*;
+
+// Locally written packages
+import org.mulgara.query.Constraint;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.Variable;
+import org.mulgara.query.filter.Context;
+import org.mulgara.query.filter.ContextOwner;
+import org.mulgara.query.filter.Filter;
+import org.mulgara.resolver.spi.QueryEvaluationContext;
+import org.mulgara.resolver.spi.TuplesContext;
+import org.mulgara.store.tuples.AbstractTuples;
+
+/**
+ * Filtering operation. This class wraps another Tuples, removing those elements that don't
+ * pass the filter.
+ */
+public class FilteredTuples extends AbstractTuples implements ContextOwner {
+
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(FilteredTuples.class.getName());
+
+  /** The inner tuples to filter. */
+  protected Tuples unfiltered;
+
+  /** The filter to apply. */
+  protected Filter filter;
+
+  /** The tuples context */
+  protected TuplesContext context;
+
+  /**
+   * Configure a tuples for filtering.
+   *
+   * @param unfiltered The original tuples.
+   * @param filter The filter to apply.
+   * @param queryContext The context to evaluate the tuples in.
+   * @throws IllegalArgumentException If the <var>unfiltered</var> tuples is null.
+   */
+  FilteredTuples(Tuples unfiltered, Filter filter, QueryEvaluationContext queryContext) throws IllegalArgumentException {
+    // store the operands
+    this.filter = filter;
+    this.unfiltered = (Tuples)unfiltered.clone();
+    this.context = new TuplesContext(this.unfiltered, queryContext.getResolverSession());
+    filter.setContextOwner(this);
+    setVariables(this.unfiltered.getVariables());
+  }
+
+
+  /** {@inheritDoc} */
+  public long getColumnValue(int column) throws TuplesException {
+    return unfiltered.getColumnValue(column);
+  }
+
+
+  /** {@inheritDoc} */
+  public long getRowUpperBound() throws TuplesException {
+    return unfiltered.getRowUpperBound();
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean isColumnEverUnbound(int column) throws TuplesException {
+    return unfiltered.isColumnEverUnbound(column);
+  }
+
+
+  /** {@inheritDoc} */
+  public Variable[] getVariables() {
+    return unfiltered.getVariables();
+  }
+
+
+  /** {@inheritDoc} */
+  public int getColumnIndex(Variable variable) throws TuplesException {
+    return unfiltered.getColumnIndex(variable);
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean isMaterialized() {
+    return false;
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean hasNoDuplicates() throws TuplesException {
+    return unfiltered.hasNoDuplicates();
+  }
+
+
+  /** {@inheritDoc} */
+  public RowComparator getComparator() {
+    return unfiltered.getComparator();
+  }
+
+
+  /** {@inheritDoc} */
+  public List<Tuples> getOperands() {
+    return Collections.unmodifiableList(Arrays.asList(new Tuples[] {unfiltered}));
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean isUnconstrained() throws TuplesException {
+    return unfiltered.isUnconstrained();
+  }
+
+
+  /** {@inheritDoc} */
+  public void renameVariables(Constraint constraint) {
+    unfiltered.renameVariables(constraint);
+  }
+
+
+  /** {@inheritDoc} */
+  public void beforeFirst(long[] prefix, int suffixTruncation) throws TuplesException {
+    unfiltered.beforeFirst(prefix, suffixTruncation);
+  }
+
+  
+  /**
+   * @return {@inheritDoc}
+   * @throws TuplesException {@inheritDoc}
+   */
+  public boolean next() throws TuplesException {
+    try {
+      do {
+        // move to the next on the unfiltered
+        boolean currentNext = unfiltered.next();
+        // Short-circuit execution if this tuples' cursor is after the last row
+        if (!currentNext) return false;
+        // check if the filter passes the current row on the unfiltered
+      } while (!testFilter());
+    } catch (QueryException qe) {
+      throw new TuplesException("Unable to iterate to the next tuples element while filtering", qe);
+    }
+
+    return true;
+  }
+
+
+  /** {@inheritDoc} */
+  public void close() throws TuplesException {
+    unfiltered.close();
+  }
+
+
+  /** @return {@inheritDoc} */
+  public Object clone() {
+    FilteredTuples cloned = (FilteredTuples)super.clone();
+
+    // Clone the mutable fields as well
+    cloned.unfiltered = (Tuples)unfiltered.clone();
+    cloned.context = new TuplesContext(cloned.unfiltered, context);
+    return cloned;
+  }
+
+
+  /**
+   * Tells a filter what the current context is.
+   * @see org.mulgara.query.filter.ContextOwner#getCurrentContext()
+   */
+  public Context getCurrentContext() {
+    return context;
+  }
+
+
+  /**
+   * Allows the context to be set manually. This is not expected.
+   * @see org.mulgara.query.filter.ContextOwner#setCurrentContext(org.mulgara.query.filter.Context)
+   */
+  public void setCurrentContext(Context context) {
+    if (!(context instanceof TuplesContext)) throw new IllegalArgumentException("FilteredTuples can only accept a TuplesContext.");
+    this.context = (TuplesContext)context;
+  }
+
+  /**
+   * Tests a filter using the current context.
+   * @return The test result.
+   * @throws QueryException If there was an error accessing data needed for the test.
+   */
+  private boolean testFilter() throws QueryException {
+    // re-root the filter expression to this Tuples
+    filter.setContextOwner(this);
+    return filter.test(context);
+  }
+}

Copied: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java (from rev 855, branches/mgr-61-sparql/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java)
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java	                        (rev 0)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java	2008-04-26 02:17:54 UTC (rev 856)
@@ -0,0 +1,610 @@
+/*
+ * The contents of this file are subject to the Open Software License
+ * Version 3.0 (the "License"); you may not use this file except in
+ * compliance with the License. You may obtain a copy of the License at
+ * http://www.opensource.org/licenses/osl-3.0.txt
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ */
+
+package org.mulgara.store.tuples;
+
+// Java 2 standard packages
+import java.math.BigInteger;
+import java.util.*;
+
+// Third party packages
+import org.apache.log4j.*;
+
+// Locally written packages
+import org.mulgara.query.Constraint;
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.Variable;
+import org.mulgara.store.tuples.AbstractTuples;
+
+/**
+ * Left Join operation.
+ *
+ * This operation is similar to a subtraction, only it returns every row from the LHS,
+ * while returning rows from the RHS when available, and <code>null</code> otherwise.
+ *
+ * The join is performed by iterating over the lhs, and searching on the
+ * RHS for matching rows.  For efficient searching, the RHS must be
+ * ordered according to the matching variables.  This class is not responsible for
+ * ensuring the sort order of the RHS; that responsibility falls to
+ * {@link TuplesOperations#optionalJoin(Tuples, Tuples)}.
+ *
+ * @created 2008-04-04
+ * @author <a href="mailto:pgearon at users.sourceforge.net">Paul Gearon</a>
+ * @copyright &copy; 2005 <A href="mailto:pgearon at users.sourceforge.net">Paul Gearon</A>
+ * @licence <a href="{@docRoot}/../../LICENCE">Open Software License v3.0</a>
+ */
+public class LeftJoin extends AbstractTuples {
+
+  @SuppressWarnings("unused")
+  private static Logger logger = Logger.getLogger(LeftJoin.class.getName());
+
+  /** The set of tuples to return all row from. */
+  protected Tuples lhs;
+
+  /** The set of tuples to add to the lhs. */
+  protected Tuples rhs;
+
+  /** The set of variables common to both the lhs and the rhs. */
+  protected Set<Variable> commonVars;
+
+  /** An array of the matching variables' columns within the lhs, indexed by the rhs position. */
+  protected int[] varMap;
+
+  /** Indicates if the RHS is currently sitting on a match. */
+  private boolean rightMatches = false;
+  
+  /** A collection of the variables on the LHS */
+  private ArrayList<Variable> lhsVars;
+
+  /** The offset for indexing into the RHS, while avoiding LHS variables */
+  private int rhsOffset;
+
+  /** Indicates that the current row is OK, and {@link #next()} will return true. */
+  private boolean currentRowValid = false;
+
+  /** The prefix currently in use on the right */
+  private long[] currentRightPrefix = Tuples.NO_PREFIX;
+
+  /**
+   * Configure a subtraction operation for lazy evaluation.
+   *
+   * @param lhs The original tuples, including the rows to be removed.
+   * @param rhs The tuples defining the rows to be removed from the lhs.
+   * @throws IllegalArgumentException If the <var>lhs</var> and  <var>rhs</var>
+   *         contain no variables in common.
+   */
+  @SuppressWarnings("unchecked")
+  LeftJoin(Tuples lhs, Tuples rhs) throws TuplesException, IllegalArgumentException {
+    // store the operands
+    this.lhs = (Tuples)lhs.clone();
+    this.rhs = (Tuples)rhs.clone();
+
+    // get the variables to merge on
+    commonVars = Collections.unmodifiableSet((Set<Variable>)TuplesOperations.getMatchingVars(lhs, rhs));
+
+    if (commonVars.isEmpty()) logger.warn("Tuples should have variables in common for optional join to occur");
+
+    // initialise the mapping of lhs columns to rhs columns
+    varMap = new int[commonVars.size()];
+    // iterate over the variables to do the mapping
+    for (Variable var: commonVars) {
+      // get the index of the variable in the rhs
+      int si = rhs.getColumnIndex(var);
+      // check that it is within the prefix columns. If not, then the rhs is not properly sorted.
+      if (si >= varMap.length) {
+        String op = "common= " + commonVars.toString();
+        op += "; var= " + var + "; index in left= " + si +"; optional= [ ";
+        Variable[] v = rhs.getVariables();
+        for (int k = 0; k < v.length; k++) {
+          op += v[k] + " ";
+        }
+        op += "]";
+        // usually this would be an assertion, but it's too important to miss
+        throw new IllegalArgumentException("Subtracted tuples not sorted correctly: " + op);
+      }
+      // map the rhs index of the variable to the lhs index
+      varMap[si] = lhs.getColumnIndex(var);
+    }
+
+    // set the variables for this optional conjunction
+    lhsVars = new ArrayList<Variable>(Arrays.asList(lhs.getVariables()));
+    ArrayList<Variable> vars = (ArrayList<Variable>)lhsVars.clone();
+    ArrayList<Variable> rhsVars = new ArrayList<Variable>(Arrays.asList(rhs.getVariables()));
+    rhsVars.removeAll(commonVars);
+    vars.addAll(rhsVars);
+    setVariables(vars);
+    
+    // set the column offset for indexing into the RHS
+    rhsOffset = lhsVars.size() - varMap.length;
+    assert rhsOffset >= 0;
+  }
+
+
+  //
+  // Methods implementing Tuples
+  //
+
+  /** {@inheritDoc} */
+  public long getColumnValue(int column) throws TuplesException {
+    int nrLeftVars = lhs.getNumberOfVariables();
+    if (column < nrLeftVars) return lhs.getColumnValue(column);
+    // return the column minus the LHS columns, and then skip over the matching vars
+    return rightMatches ? rhs.getColumnValue(column - rhsOffset) : UNBOUND;
+  }
+
+
+  /** {@inheritDoc} */
+  public long getRowUpperBound() throws TuplesException {
+    BigInteger rowCount = BigInteger.valueOf(lhs.getRowUpperBound());
+    rowCount = rowCount.multiply(BigInteger.valueOf(rhs.getRowUpperBound()));
+    return rowCount.longValue();
+  }
+
+
+  /** {@inheritDoc}  Relies on the lhs of the optional. */
+  public boolean isColumnEverUnbound(int column) throws TuplesException {
+    int nrLeftVars = lhs.getNumberOfVariables();
+    if (column < nrLeftVars) return lhs.isColumnEverUnbound(column);
+    // If there are rows on the left that are not in the right, then this columns will be unbound
+
+    // Can't know for sure if the column is unbound without iterating through
+    if (rhs.isColumnEverUnbound(column - rhsOffset)) return true;
+    // err on the side of caution
+    return true;
+  }
+
+
+  /** {@inheritDoc} */
+  public int getColumnIndex(Variable variable) throws TuplesException {
+    if (lhsVars.contains(variable)) return lhs.getColumnIndex(variable);
+    return rhs.getColumnIndex(variable) + rhsOffset;
+  }
+
+
+  /**
+   * {@inheritDoc}
+   * @return Always <code>false</code>.
+   */
+  public boolean isMaterialized() {
+    return false;
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean hasNoDuplicates() throws TuplesException {
+    return lhs.hasNoDuplicates();
+  }
+
+
+  /** {@inheritDoc} */
+  public RowComparator getComparator() {
+    RowComparator lhsComp = lhs.getComparator();
+    RowComparator rhsComp = lhs.getComparator();
+    // build a new comparator, if both left and right have comparators, else null
+    if (lhsComp == null || rhsComp == null) return null;
+    return new MergedComparator(lhsComp, rhsComp);
+  }
+
+
+  /** {@inheritDoc} */
+  public List<Tuples> getOperands() {
+    return Collections.unmodifiableList(Arrays.asList(new Tuples[] {lhs, rhs}));
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean isUnconstrained() throws TuplesException {
+    return lhs.isUnconstrained();
+  }
+
+
+  /** {@inheritDoc} */
+  public void renameVariables(Constraint constraint) {
+    lhs.renameVariables(constraint);
+    rhs.renameVariables(constraint);
+  }
+
+
+  /**
+   * {@inheritDoc}
+   * This method matches what it can on the LHS, and saves the rest for later searches
+   * on the RHS. Searches on the RHS only happen when the LHS iterates to valid data.
+   */
+  public void beforeFirst(long[] prefix, int suffixTruncation) throws TuplesException {
+    int lhsVars = lhs.getNumberOfVariables();
+    // The tail of the prefix is the part that searches on the RHS
+    int lhsOnlyVars = (lhsVars - commonVars.size());
+    int tailLen = prefix.length - lhsOnlyVars;
+    if (tailLen <= 0) {
+      // search on the LHS only
+      lhs.beforeFirst(prefix, suffixTruncation);
+      // store the prefix for use on the right
+      currentRightPrefix = Tuples.NO_PREFIX;
+    } else {
+      // search on the LHS, and do the remainder of the search of the RHS
+      lhs.beforeFirst(reduce(prefix, lhsVars), suffixTruncation);
+      // store the data to search on the right
+      currentRightPrefix = reduce(prefix, lhsOnlyVars, tailLen);
+    }
+    currentRowValid = false;
+    rightMatches = false;
+  }
+
+
+  /** {@inheritDoc} */
+  public boolean next() throws TuplesException {
+    // check if we are already on a matched line
+    if (rightMatches) {
+      // we are, so move on the right
+      rightMatches = rhs.next();
+      // if we moved off on the right, then we need to move on the left
+      if (!rightMatches) {
+        currentRowValid = lhs.next();
+        // now that the left has moved, need to search on the right
+        updateRight();
+      }
+      return currentRowValid;
+    }
+    // There was no current match on the right, so always move on the left
+    currentRowValid = lhs.next();
+    // now that the left has moved, need to search on the right
+    updateRight();
+    return currentRowValid;
+  }
+
+
+  /**
+   * Moves the RHS to data matching the LHS, if the LHS is valid.
+   * Sets the value of {@link #rightMatches} to indicate if the RHS has matching data.
+   * @throws TuplesException If there is an error searching the RHS or moving to the first matching row.
+   */
+  private void updateRight() throws TuplesException {
+    // for a valid row on the left, search on the right
+    if (currentRowValid) {
+      long[] prefix = calculateRHSPrefix();
+      // always doing a bound search, so a null search means no common vars
+      if (prefix.length > 0) {
+        rhs.beforeFirst(prefix, 0);
+        // and see if the rhs data was found
+        rightMatches = rhs.next();
+      } else {
+        // no search required
+        assert commonVars.isEmpty();
+        rightMatches = false;
+      }
+    } else {
+      // since the left is not valid, neither is the right
+      rightMatches = false;
+    }
+  }
+
+
+  /**
+   * Determine the prefix to use on the RHS, given a possible search already set for this tuples.
+   * @return The prefix to be used for finding a current RHS row.
+   * @throws TuplesException If the LHS could not be accessed.
+   */
+  private long[] calculateRHSPrefix() throws TuplesException {
+    // if the currentRightPrefix is longer than the matching vars, then just return it
+    if (currentRightPrefix.length >= commonVars.size()) return currentRightPrefix;
+    // fill in a prefix with the currentRightPrefix
+    long[] prefix = new long[commonVars.size()];
+    for (int c = 0; c < currentRightPrefix.length; c++) {
+      prefix[c] = currentRightPrefix[c];
+      assert prefix[c] == lhs.getColumnValue(varMap[c]);
+    }
+    // finish the prefix with the columns that are supposed to match
+    for (int c = currentRightPrefix.length; c < prefix.length; c++) {
+      prefix[c] = lhs.getColumnValue(varMap[c]);
+    }
+    return prefix;
+  }
+
+  /**
+   * Closes all the operands.
+   * @throws TuplesException If either the lhs or the rhs can't be closed.
+   */
+  public void close() throws TuplesException {
+    lhs.close();
+    rhs.close();
+  }
+
+
+  /**
+   * @return {@inheritDoc}
+   */
+  public Object clone() {
+    LeftJoin cloned = (LeftJoin)super.clone();
+
+    // Copy mutable fields by value
+    cloned.lhs = (Tuples)lhs.clone();
+    cloned.rhs = (Tuples)rhs.clone();
+
+    return cloned;
+  }
+
+
+  //
+  // Internal methods and classes
+  //
+
+
+  /**
+   * A comparator that is only relevant to the LeftJoin operation. Orders first on the left, then on the right
+   * This comparator passes portions of the comparison down to the left and the right.
+   */
+  class MergedComparator implements RowComparator {
+
+    /** The LHS comparator */
+    private RowComparator left;
+
+    /** The RHS comparator */
+    private RowComparator right;
+
+    /**
+     * Constructs a merging of the two comparators.
+     * @param l The comparator for the LHS.
+     * @param r The comparator for the RHS.
+     */ 
+    MergedComparator(RowComparator l, RowComparator r) {
+      left = l;
+      right = r;
+    }
+
+    /**
+     * Compares tuples with the presumption that they are both LeftJoin operations.
+     * @see org.mulgara.store.tuples.RowComparator#compare(org.mulgara.store.tuples.Tuples, org.mulgara.store.tuples.Tuples)
+     */
+    public int compare(Tuples first, Tuples second) throws TuplesException {
+      if (!(first instanceof LeftJoin) || !(second instanceof LeftJoin)) throw new IllegalArgumentException("Merged Comparators can only operate on LeftJoins");
+      int nrVars = lhs.getNumberOfVariables();
+      int result = left.compare(new ReducedTuples(first, nrVars), new ReducedTuples(second, nrVars));
+      if (result != 0) return result;
+      nrVars = rhs.getNumberOfVariables() - commonVars.size();
+      return right.compare(new ReducedTuples(first, rhsOffset, nrVars), new ReducedTuples(second, rhsOffset, nrVars));
+    }
+
+    /**
+     * Compares an array and a tuples, part at a time. Makes the presumption that the
+     * tuples is a LeftJoin operation. 
+     * @see org.mulgara.store.tuples.RowComparator#compare(long[], org.mulgara.store.tuples.Tuples)
+     */
+    public int compare(long[] array, Tuples tuples) throws TuplesException {
+      if (!(tuples instanceof LeftJoin)) throw new IllegalArgumentException("Merged Comparators can only operate on LeftJoins");
+      int nrVars = lhs.getNumberOfVariables();
+      int result = left.compare(reduce(array, nrVars), reduce(tuples, nrVars));
+      if (result != 0) return result;
+      nrVars = rhs.getNumberOfVariables() - commonVars.size();
+      return right.compare(reduce(array, rhsOffset, nrVars), reduce(tuples, rhsOffset, nrVars));
+    }
+
+    /**
+     * Compares two arrays, part at a time.
+     * @see org.mulgara.store.tuples.RowComparator#compare(long[], long[])
+     */
+    public int compare(long[] first, long[] second) throws TuplesException {
+      int nrVars = lhs.getNumberOfVariables();
+      int result = left.compare(reduce(first, nrVars), reduce(second, nrVars));
+      if (result != 0) return result;
+      nrVars = rhs.getNumberOfVariables() - commonVars.size();
+      return right.compare(reduce(first, rhsOffset, nrVars), reduce(second, rhsOffset, nrVars));
+    }
+  }
+
+  /**
+   * Truncates an array to a given width.
+   * @param array The array to truncate.
+   * @param width The width to reduce to.
+   * @return If width is smaller than the array length,
+   *   then a truncated array, else the original array.
+   */
+  private static long[] reduce(long[] array, int width) {
+    if (width < array.length) {
+      long[] tmp = new long[width];
+      System.arraycopy(array, 0, tmp, 0, width);
+      array = tmp;
+    }
+    return array;
+  }
+
+  /**
+   * Slices an array down to a subarray.
+   * @param array The array to truncate.
+   * @param offset The offset for the slice.
+   * @param width The width of the slice.
+   * @return If width is smaller than the array length,
+   *   then a truncated array, else the original array.
+   */
+  private static long[] reduce(long[] array, int offset, int width) {
+    if (width < array.length || offset > 0) {
+      if (offset + width > array.length) throw new IllegalArgumentException("Cannot slice an array outside of its bounds");
+      long[] tmp = new long[width];
+      System.arraycopy(array, offset, tmp, 0, width);
+      array = tmp;
+    }
+    return array;
+  }
+
+  /**
+   * Truncates a Tuples to a given width.
+   * @param tuples The tuples to truncate.
+   * @param width The width to reduce to.
+   * @return A new Tuples