[Mulgara-svn] r2033 - in trunk: . src/jar/query/java/org/mulgara/query src/jar/query/java/org/mulgara/query/filter src/jar/querylang/java/org/mulgara/itql src/jar/querylang/java/org/mulgara/protocol src/jar/resolver/java/org/mulgara/resolver src/jar/resolver-spi/java/org/mulgara/store/statement src/jar/resolver-store/java/org/mulgara/store/statement/xa src/jar/resolver-store/java/org/mulgara/store/statement/xa11 src/jar/resolver-test/java/org/mulgara/resolver/test src/jar/server-rmi/java/org/mulgara/server/rmi src/jar/tuples/java/org/mulgara/store/tuples src/jar/util/java/org/mulgara/util src/jar/util/java/org/mulgara/util/io

pag at mulgara.org pag at mulgara.org
Sat Sep 17 03:01:26 UTC 2011


Author: pag
Date: 2011-09-17 03:01:25 +0000 (Sat, 17 Sep 2011)
New Revision: 2033

Added:
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTstFilter.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneIntTst.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesFactory.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesUnitTest.java
   trunk/src/jar/util/java/org/mulgara/util/BooleanOp.java
   trunk/src/jar/util/java/org/mulgara/util/BooleanOp2.java
   trunk/src/jar/util/java/org/mulgara/util/MemoryResultSet.java
   trunk/src/jar/util/java/org/mulgara/util/MemoryResultSetTest.java
   trunk/src/jar/util/java/org/mulgara/util/io/IOUtil.java
Removed:
   trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesFactory.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesUnitTest.java
   trunk/src/jar/util/java/org/mulgara/util/TestResultSet.java
   trunk/src/jar/util/java/org/mulgara/util/TestResultSetTest.java
   trunk/src/jar/util/java/org/mulgara/util/Tester.java
   trunk/src/jar/util/java/org/mulgara/util/Tester2.java
Modified:
   trunk/build.xml
   trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java
   trunk/src/jar/query/java/org/mulgara/query/AnswerOperationsUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/AnswerUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java
   trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java
   trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java
   trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
   trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java
   trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java
   trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java
   trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSessionUI.java
   trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java
   trunk/src/jar/querylang/java/org/mulgara/itql/TqlSessionUI.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswerUnitTest.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswerUnitTest.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswerUnitTest.java
   trunk/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java
   trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java
   trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java
   trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolution.java
   trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/JRDFFactoryImpl.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/NTriples.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/RestoreOperation.java
   trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerPageImplUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuplesUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoinUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppendUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjectionUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesFactory.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoinUnitTest.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppendUnitTest.java
   trunk/src/jar/util/java/org/mulgara/util/Reflect.java
   trunk/src/jar/util/java/org/mulgara/util/ResultSetRow.java
   trunk/src/jar/util/java/org/mulgara/util/io/LMappedBufferedFile.java
Log:
More Fortify updates. Includes a new utility method to replace BufferedReader.readLine, and removal of all tests from distributions

Modified: trunk/build.xml
===================================================================
--- trunk/build.xml	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/build.xml	2011-09-17 03:01:25 UTC (rev 2033)
@@ -549,54 +549,54 @@
       <zipfileset src="${lib.dir}/${xalan.jar}" excludes="META-INF/**"/>
 
 
-      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
+      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*Test*"/>
 
 
       <!-- Schemas -->
@@ -995,10 +995,10 @@
 
     <jar jarfile="${bin.dir}/${rmi.jar}">
 
-      <fileset dir="${obj.dir}/jar/query/classes" excludes="**/*UnitTest*"/>
-      <fileset dir="${obj.dir}/jar/driver/classes" excludes="**/*UnitTest*"/>
-      <fileset dir="${obj.dir}/jar/server/classes" excludes="**/*UnitTest*"/>
-      <fileset dir="${obj.dir}/jar/util/classes" excludes="**/*UnitTest*"/>
+      <fileset dir="${obj.dir}/jar/query/classes" excludes="**/*Test*"/>
+      <fileset dir="${obj.dir}/jar/driver/classes" excludes="**/*Test*"/>
+      <fileset dir="${obj.dir}/jar/server/classes" excludes="**/*Test*"/>
+      <fileset dir="${obj.dir}/jar/util/classes" excludes="**/*Test*"/>
     </jar>
   </target>
 
@@ -1741,57 +1741,57 @@
       <zipfileset src="${jsp-lib.dir}/${jsp-glassfish-taglibs.jar}" excludes="META-INF/**"/>
 
       <!-- core libraries -->
-      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**, **/*UnitTest*"/>
+      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**, **/*Test*"/>
 
 
       <!-- include pre-bundled webapps -->
@@ -1883,57 +1883,57 @@
 
       <zipfileset dir="${conf.dir}" prefix="conf" includes="log4j-mulgara.xml, webdefault.xml, mulgara-rmi.policy, mulgara.policy"/>
 
-      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**, **/*UnitTest*"/>
+      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**, **/*Test*"/>
 
 
       <!-- include pre-bundled webapps -->
@@ -2011,55 +2011,55 @@
     <jar jarfile="${dist.dir}/${mulgara-core.jar}">
       <zipfileset dir="${conf.dir}" prefix="conf" includes="mulgara-config-core.xml, log4j-mulgara.xml, mulgara-rmi.policy, mulgara.policy"/>
       <zipfileset file="${conf.dir}/core/mulgara-x-config.xml" prefix="conf"/>
-      <zipfileset src="${bin.dir}/${client-jrdf.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${query.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${driver.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${config.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${krule.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="**/*.xml, META-INF/**, **/*UnitTest*"/>
+      <zipfileset src="${bin.dir}/${client-jrdf.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${query.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${driver.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${config.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${krule.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="**/*.xml, META-INF/**, **/*Test*"/>
 
       <!-- Schemas -->
       <fileset dir="${src.dir}/jar/dtd" includes="DTD/**"/>
@@ -2125,10 +2125,10 @@
 
     <!-- build the executable jar file -->
     <jar jarfile="${dist.dir}/${minimal.jar}">
-      <fileset dir="${jar.obj.dir}/query/classes" includes="**/*.class" excludes="**/*UnitTest*"/>
-      <fileset dir="${jar.obj.dir}/querylang/classes" includes="org/mulgara/sparql/**/*.class" excludes="**/*UnitTest*"/>
-      <fileset dir="${jar.obj.dir}/util/classes" includesfile="${conf.dir}/util.minfiles" excludes="**/*UnitTest*"/>
-      <fileset dir="${jar.obj.dir}/server-rmi/classes" includes="**/*.class" excludes="**/*UnitTest*"/>
+      <fileset dir="${jar.obj.dir}/query/classes" includes="**/*.class" excludes="**/*Test*"/>
+      <fileset dir="${jar.obj.dir}/querylang/classes" includes="org/mulgara/sparql/**/*.class" excludes="**/*Test*"/>
+      <fileset dir="${jar.obj.dir}/util/classes" includesfile="${conf.dir}/util.minfiles" excludes="**/*Test*"/>
+      <fileset dir="${jar.obj.dir}/server-rmi/classes" includes="**/*.class" excludes="**/*Test*"/>
     </jar>
   </target>
 
@@ -2262,57 +2262,57 @@
       <zipfileset src="${lib.dir}/${xalan.jar}" excludes="META-INF/**"/>
 
       <!-- core libraries -->
-      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
-      <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**, **/*.xml, **/*UnitTest*"/>
+      <zipfileset src="${bin.dir}/${query.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${driver.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${querylang.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${rmi.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-rmi.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${config.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${descriptor.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${server-local.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-spi.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-filesystem.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-xa.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-memory.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-nodepool-xa.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-memory.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${store-stringpool-xa11.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${util-xa.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-null.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-file.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-http.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-lucene.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-memory.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-store.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-url.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-view.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${tuples-hybrid.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mp3.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-n3.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-mbox.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfa.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rdfxml.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${content-rlog.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-nodetype.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-prefix.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-relational.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-distributed.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-xsd.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-test.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${resolver-jar.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${dtd.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${jrdf.base.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${krule.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${swrl.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
+      <zipfileset src="${bin.dir}/${web.jar}" excludes="META-INF/**, **/*.xml, **/*Test*"/>
 
 
       <zipfileset file="${obj.dir}/mulgara-x-config.xml" prefix="conf" />

Modified: trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/AnswerImpl.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -35,7 +35,7 @@
 // Third party packages
 import org.apache.log4j.Logger;
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * ITQL answer. An answer is a set of solutions, where a solution is a mapping
@@ -69,7 +69,7 @@
    static final long serialVersionUID = -8022357347937695884L;
 
   /** Description of the Field */
-  private final static TestResultSet ZERO;
+  private final static MemoryResultSet ZERO;
 
   /** Description of the Field */
   public final static Answer EMPTY;
@@ -79,7 +79,7 @@
 
   static {
     try {
-      ZERO  = new TestResultSet(new String[] {});
+      ZERO  = new MemoryResultSet(new String[] {});
       EMPTY = new AnswerImpl(ZERO);
     } catch (TuplesException e) {
       throw new ExceptionInInitializerError(e);
@@ -117,7 +117,7 @@
     if (logger.isDebugEnabled()) logger.debug("Adding "+answer.getRowCount()+" rows");
 
     try {
-      resultSet = new TestResultSet(columnNames);
+      resultSet = new MemoryResultSet(columnNames);
       answer.beforeFirst();
       logger.debug("Reset source / Iterating Answer");
       while (answer.next()) {
@@ -146,7 +146,7 @@
           throw re;
         }
         logger.debug("Adding a row");
-        ((TestResultSet)resultSet).addRow(new ResultSetRow(columnNames, columnValues));
+        ((MemoryResultSet)resultSet).addRow(new ResultSetRow(columnNames, columnValues));
       }
       logger.debug("Finished iterating answer");
     } catch (SQLException e) {
@@ -173,7 +173,7 @@
     }
 
     try {
-      resultSet = new TestResultSet(columns);
+      resultSet = new MemoryResultSet(columns);
     } catch (SQLException e) {
       throw new Error("Inexplicable constructor failure", e);
     }
@@ -191,7 +191,7 @@
 
     try {
       this.variables = resultSetToVariables(resultSet);
-      // this.resultSet = new TestResultSet(resultSet);
+      // this.resultSet = new MemoryResultSet(resultSet);
       this.resultSet = resultSet;
     } catch (SQLException e) {
       throw new TuplesException("Couldn't create answer", e);
@@ -451,7 +451,7 @@
   public Object clone() {
     try {
       AnswerImpl a = (AnswerImpl)super.clone();
-      a.resultSet = new TestResultSet(resultSet);
+      a.resultSet = new MemoryResultSet(resultSet);
       return a;
     } catch (SQLException e) {
       throw new RuntimeException(e);

Modified: trunk/src/jar/query/java/org/mulgara/query/AnswerOperationsUnitTest.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/AnswerOperationsUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/AnswerOperationsUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -38,7 +38,7 @@
 
 // Locally written packages
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * Test case for {@link AnswerOperations}.
@@ -120,7 +120,7 @@
    */
   public void test1Equal() throws Exception {
     /*
-         TestResultSet expected = new TestResultSet(new String[] { "x", "y" });
+         MemoryResultSet expected = new MemoryResultSet(new String[] { "x", "y" });
          ResultSetRow row = new ResultSetRow(expected);
          row.setObject("x", "X2");
          row.setObject("y", "Y2");
@@ -143,7 +143,7 @@
    */
   protected void setUp() throws TuplesException, SQLException {
 
-    TestResultSet trs1 = new TestResultSet(new String[] {
+    MemoryResultSet trs1 = new MemoryResultSet(new String[] {
         "x", "y"});
     ResultSetRow row;
     row = new ResultSetRow(trs1);

Modified: trunk/src/jar/query/java/org/mulgara/query/AnswerUnitTest.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/AnswerUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/AnswerUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -40,7 +40,7 @@
 
 // Locally written packages
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * Purpose: Test case for {@link Answer}.
@@ -158,9 +158,9 @@
        TODO: Figure out the exact meaning of null, zero column, and zero row Answers
      public void test1getDependentResultSet() throws Exception
      {
-    TestResultSet expected = new TestResultSet(new String[] {});
+    MemoryResultSet expected = new MemoryResultSet(new String[] {});
     Set variables = new HashSet();
-    TestResultSet result = answer.getDependentResultSet(variables);
+    MemoryResultSet result = answer.getDependentResultSet(variables);
     assertEqualsIgnoreOrder(expected, result);
      }
    */
@@ -174,8 +174,8 @@
   /*
      public void test2getDependentResultSet() throws Exception
      {
-    TestResultSet expected = new TestResultSet(new String[] {"x", "y"});
-    TestResultSet.Row row;
+    MemoryResultSet expected = new MemoryResultSet(new String[] {"x", "y"});
+    MemoryResultSet.Row row;
     row = expected.new Row();
       row.setObject("x", "X2");
       row.setObject("y", "Y2");
@@ -184,7 +184,7 @@
       row.setObject("y", "Y1");
     Set variables = new HashSet();
     variables.add(new Variable("x"));
-    TestResultSet result = answer.getDependentResultSet(variables);
+    MemoryResultSet result = answer.getDependentResultSet(variables);
     assertEqualsIgnoreOrder(expected, result);
      }
    */
@@ -198,8 +198,8 @@
   /*
      public void test3getDependentResultSet() throws Exception
      {
-    TestResultSet expected = new TestResultSet(new String[] {"x", "y"});
-    TestResultSet.Row row;
+    MemoryResultSet expected = new MemoryResultSet(new String[] {"x", "y"});
+    MemoryResultSet.Row row;
     row = expected.new Row();
       row.setObject("x", "X2");
       row.setObject("y", "Y2");
@@ -209,7 +209,7 @@
     Set variables = new HashSet();
     variables.add(new Variable("y"));
     variables.add(new Variable("x"));
-    TestResultSet result = answer.getDependentResultSet(variables);
+    MemoryResultSet result = answer.getDependentResultSet(variables);
     assertEqualsIgnoreOrder(expected, result);
      }
    */
@@ -223,8 +223,8 @@
   /*
      public void test4getDependentResultSet() throws Exception
      {
-    TestResultSet expected = new TestResultSet(new String[] {"x", "y"});
-    TestResultSet.Row row;
+    MemoryResultSet expected = new MemoryResultSet(new String[] {"x", "y"});
+    MemoryResultSet.Row row;
     row = expected.new Row();
       row.setObject("x", "X2");
       row.setObject("y", "Y2");
@@ -235,7 +235,7 @@
     variables.add(new Variable("z"));
     variables.add(new Variable("y"));
     variables.add(new Variable("x"));
-    TestResultSet result = answer.getDependentResultSet(variables);
+    MemoryResultSet result = answer.getDependentResultSet(variables);
     assertEqualsIgnoreOrder(expected, result);
      }
    */
@@ -273,7 +273,7 @@
   /*
   public void test1getResultSet() throws Exception {
 
-    TestResultSet expected = new TestResultSet(new String[] { "x", "y" });
+    MemoryResultSet expected = new MemoryResultSet(new String[] { "x", "y" });
     ResultSetRow row = new ResultSetRow(expected);
     row.setObject("x", "X2");
     row.setObject("y", "Y2");
@@ -299,7 +299,7 @@
    */
   protected void setUp() throws TuplesException, SQLException {
 
-    TestResultSet trs1 = new TestResultSet(new String[] { "x", "y" });
+    MemoryResultSet trs1 = new MemoryResultSet(new String[] { "x", "y" });
     ResultSetRow row;
     row = new ResultSetRow(trs1);
     row.setObject("x", "X1");

Modified: trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/UnconstrainedAnswer.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -246,7 +246,7 @@
 
   /**
    * This currently tries to mimic the
-   * {@link org.mulgara.util.TestResultSet#toString} method.
+   * {@link org.mulgara.util.MemoryResultSet#toString} method.
    *
    * @return <code>"0 columns: (1 rows)"</code>
    */

Deleted: trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,68 +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 © 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 {
-
-  /** Serialization ID */
-  private static final long serialVersionUID = 6169856559090192157L;
-
-  /** 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(Context)
-   */
-  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/BinaryTstFilter.java (from rev 2032, trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTestFilter.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTstFilter.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/BinaryTstFilter.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -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;
+
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.Bool;
+
+
+/**
+ * A test operation for general RDF Terms, specifically equality or inequality.
+ * Named with "Tst" instead of "Test" to avoid filters for the codebase tests.
+ *
+ * @created Mar 14, 2008
+ * @author Paul Gearon
+ * @copyright © 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 BinaryTstFilter extends AbstractFilterValue implements Filter {
+
+  /** Serialization ID */
+  private static final long serialVersionUID = 6169856559090192157L;
+
+  /** 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
+   */
+  BinaryTstFilter(RDFTerm lhs, RDFTerm rhs) {
+    super(lhs, rhs);
+    this.lhs = lhs;
+    this.rhs = rhs;
+  }
+
+  /**
+   * @see org.mulgara.query.filter.Filter#test(Context)
+   */
+  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;
+
+}

Modified: trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/Equals.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -22,7 +22,7 @@
  * @copyright © 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 {
+public class Equals extends BinaryTstFilter {
 
   /** Generated Serialization ID for RMI */
   private static final long serialVersionUID = -7289754671291518073L;
@@ -36,7 +36,7 @@
     super(lhs, rhs);
   }
 
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  /** @see org.mulgara.query.filter.BinaryTstFilter#testCmp() */
   boolean testCmp() throws QueryException {
     return lhs.equals(rhs);
   }

Modified: trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/LangMatches.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -25,7 +25,7 @@
  * @copyright © 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 {
+public class LangMatches extends BinaryTstFilter {
 
   /** Generated Serialization ID for RMI */
   private static final long serialVersionUID = 7483330484341360061L;
@@ -39,7 +39,7 @@
     super(lhs, rhs);
   }
 
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  /** @see org.mulgara.query.filter.BinaryTstFilter#testCmp() */
   boolean testCmp() throws QueryException {
     testSimple(lhs);
     testSimple(rhs);

Modified: trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/NotEquals.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -22,7 +22,7 @@
  * @copyright © 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 {
+public class NotEquals extends BinaryTstFilter {
 
   /** Generated Serialization ID for RMI */
   private static final long serialVersionUID = -7091505891438740349L;
@@ -31,7 +31,7 @@
     super(lhs, rhs);
   }
 
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  /** @see org.mulgara.query.filter.BinaryTstFilter#testCmp() */
   boolean testCmp() throws QueryException {
     return !lhs.equals(rhs);
   }

Modified: trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/RegexFn.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -24,7 +24,7 @@
  * @copyright © 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 {
+public class RegexFn extends BinaryTstFilter {
 
   /** Generated Serialization ID for RMI */
   private static final long serialVersionUID = 6785353529347360357L;
@@ -62,7 +62,7 @@
     if (flagExpression != null) flagExpression.setContextOwner(this);
   }
 
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  /** @see org.mulgara.query.filter.BinaryTstFilter#testCmp() */
   boolean testCmp() throws QueryException {
     return regex().matches(str());
   }

Modified: trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/query/java/org/mulgara/query/filter/SameTerm.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -22,7 +22,7 @@
  * @copyright © 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 {
+public class SameTerm extends BinaryTstFilter {
 
   /** Generated Serialization ID for RMI */
   private static final long serialVersionUID = -5260593869711335738L;
@@ -36,7 +36,7 @@
     super(lhs, rhs);
   }
 
-  /** @see org.mulgara.query.filter.BinaryTestFilter#testCmp() */
+  /** @see org.mulgara.query.filter.BinaryTstFilter#testCmp() */
   boolean testCmp() throws QueryException {
     return lhs.sameTerm(rhs);
   }

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -885,7 +885,7 @@
           }
 
           String lastMessage = itqlBean.getLastMessage();
-          if ((lastMessage != null) && (lastMessage != "") && (ui != null)) {
+          if ((lastMessage != null) && (!lastMessage.equals("")) && (ui != null)) {
 
             System.out.println(lastMessage);
           }

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSessionUI.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSessionUI.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSessionUI.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -844,7 +844,7 @@
           error("Failed to get answer");
         }
 
-        if ((lastMessage != null) && (lastMessage != "")) {
+        if ((lastMessage != null) && (!lastMessage.equals(""))) {
 
           print(lastMessage, new Font("Monospaced", Font.BOLD, 12),
               Color.BLACK);

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -340,7 +340,7 @@
           }
 
           String lastMessage = autoTql.getLastMessage();
-          if ((lastMessage != null) && (lastMessage != "") && (gui != null)) System.out.println(lastMessage);
+          if ((lastMessage != null) && !lastMessage.equals("") && (gui != null)) System.out.println(lastMessage);
 
           Exception e = autoTql.getLastException();
           if (e != null) log.warn("Couldn't execute command", e);

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/TqlSessionUI.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/TqlSessionUI.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/TqlSessionUI.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -761,7 +761,7 @@
             error("Failed to get answer");
           }
   
-          if ((lastMessage != null) && (lastMessage != "")) print(lastMessage, boldFont, Color.BLACK);
+          if ((lastMessage != null) && (!lastMessage.equals(""))) print(lastMessage, boldFont, Color.BLACK);
   
           // If there's more than one answer add a new line.
           if (answers.size() > 1)  println();

Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswerUnitTest.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswerUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswerUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -34,7 +34,7 @@
 import org.mulgara.query.rdf.LiteralImpl;
 import org.mulgara.query.rdf.URIReferenceImpl;
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * Test case for {@link StreamedSparqlJSONAnswer}.
@@ -176,7 +176,7 @@
    * @throws Exception Error setting up the ResultSet
    */
   protected void setUp() throws Exception {
-    TestResultSet trs1 = new TestResultSet(new String[] { "x", "y" });
+    MemoryResultSet trs1 = new MemoryResultSet(new String[] { "x", "y" });
     ResultSetRow row;
     row = new ResultSetRow(trs1);
     row.setObject("x", new LiteralImpl("X1"));

Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswerUnitTest.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswerUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswerUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -36,7 +36,7 @@
 import org.mulgara.query.rdf.LiteralImpl;
 import org.mulgara.query.rdf.URIReferenceImpl;
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * Test case for {@link StreamedSparqlXMLAnswer}.
@@ -510,7 +510,7 @@
    * @throws Exception Error setting up the ResultSet
    */
   protected void setUp() throws Exception {
-    TestResultSet trs1 = new TestResultSet(new String[] { "x", "y" });
+    MemoryResultSet trs1 = new MemoryResultSet(new String[] { "x", "y" });
     ResultSetRow row;
     row = new ResultSetRow(trs1);
     row.setObject("x", new LiteralImpl("X1"));

Modified: trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswerUnitTest.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswerUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedTqlXMLAnswerUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -34,7 +34,7 @@
 import org.mulgara.query.rdf.LiteralImpl;
 import org.mulgara.query.rdf.URIReferenceImpl;
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * Test case for {@link StreamedTqlXMLAnswer}.
@@ -178,7 +178,7 @@
    * @throws Exception Error setting up the ResultSet
    */
   protected void setUp() throws Exception {
-    TestResultSet trs1 = new TestResultSet(new String[] { "x", "y" });
+    MemoryResultSet trs1 = new MemoryResultSet(new String[] { "x", "y" });
     ResultSetRow row;
     row = new ResultSetRow(trs1);
     row.setObject("x", new LiteralImpl("X1"));

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/JRDFFactoryImpl.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/JRDFFactoryImpl.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/JRDFFactoryImpl.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -41,7 +41,6 @@
 import com.hp.hpl.jena.graph.impl.*;
 
 // Local packages
-import org.mulgara.jrdf.*;
 import org.mulgara.server.*;
 
 /**
@@ -69,13 +68,14 @@
   /**
    * Logger. This is named after the class.
    */
+  @SuppressWarnings("unused")
   private final static Logger logger =
       Logger.getLogger(JRDFFactory.class.getName());
 
   /**
    * An in memory hash map of anonymous node keys to node objects.
    */
-  private HashMap anonMap = new HashMap();
+  private Map<String,SubjectNode> anonMap = new HashMap<String,SubjectNode>();
 
   /**
    * Constructs a JRDF Factory that is not tied to a Jena Factory.
@@ -187,9 +187,9 @@
       // Determine if language, datatype or neither are specified
       String language = label.language();
 
-      //cannot have noth a language and datatype
-      if (((language != null) && (language != "")) &&
-          ((dataTypeURI != null) && (dataTypeURI.toString() != ""))) {
+      // cannot have both a language and datatype
+      if (((language != null) && !language.equals("")) &&
+          ((dataTypeURI != null) && !dataTypeURI.toString().equals(""))) {
         throw new GraphElementFactoryException("Node cannot have both " +
             "Datatype and Language specified.  Node: " + node + ", " +
             "language: [" + language + "], datatype: [" + dataTypeURI + "]");
@@ -276,8 +276,7 @@
 
     if (anonMap.containsKey(key.toString())) {
       return (BlankNode) anonMap.get(key.toString());
-    }
-    else {
+    } else {
       return null;
     }
   }

Copied: trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneIntTst.java (from rev 2032, trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java)
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneIntTst.java	                        (rev 0)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneIntTst.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,1604 @@
+/*
+ * Copyright 2008 The Topaz Foundation 
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ *
+ * Contributions:
+ */
+package org.mulgara.resolver;
+
+// Java 2 standard packages
+import java.io.File;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import javax.transaction.xa.XAException;
+import javax.transaction.xa.XAResource;
+import javax.transaction.xa.Xid;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.RollbackException;
+import javax.transaction.Transaction;
+import javax.transaction.TransactionManager;
+
+// Third party packages
+import junit.framework.*;        // JUnit
+import org.apache.log4j.Logger;  // Log4J
+import org.jrdf.graph.ObjectNode;
+import org.jrdf.graph.PredicateNode;
+import org.jrdf.graph.SubjectNode;
+import org.objectweb.jotm.Jotm;
+import org.objectweb.transaction.jta.TMService;
+
+// Locally written packages
+import org.mulgara.query.*;
+import org.mulgara.query.rdf.URIReferenceImpl;
+import org.mulgara.query.rdf.TripleImpl;
+import org.mulgara.server.Session;
+
+import org.mulgara.server.SessionFactory;
+import org.mulgara.server.driver.SessionFactoryFinder;
+
+/**
+ * Regression test to test JTA integration with external JOTM instance.
+ *
+ * @created 2008-01-11
+ * @author <a href="mailto:andrae at netymon.com">Andrae Muys</a>
+ * @company <A href="mailto:mail at netymon.com">Netymon Pty Ltd</A>
+ * @copyright ©2008 <a href="http://www.topazproject.org/">The Topaz Foundation</a>
+ * @licence Apache License v2.0
+ */
+public class JotmTransactionStandaloneIntTst extends TestCase {
+  /** Logger.  */
+  private static Logger logger =
+    Logger.getLogger(JotmTransactionStandaloneIntTst.class.getName());
+
+  private static final URI databaseURI;
+
+
+  private static final URI modelURI;
+  private static final URI model2URI;
+
+  static {
+    try {
+      databaseURI    = new URI("rmi://localhost/server1");
+      modelURI       = new URI("rmi://localhost/server1#jotmmodel");
+      model2URI      = new URI("rmi://localhost/server1#jotmmodel2");
+    } catch (URISyntaxException e) {
+      throw new Error("Bad hardcoded URI", e);
+    }
+  }
+
+  private static SessionFactory sessionFactory;
+  private static TMService txService;
+  private static TransactionManager txManager;
+
+  public JotmTransactionStandaloneIntTst(String name) {
+    super(name);
+  }
+
+  public static Test suite() {
+    TestSuite suite = new TestSuite();
+    suite.addTest(new JotmTransactionStandaloneIntTst("setup"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testTrivalExplicit"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testSessionCloseRollback"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testTrivialExplicitAgain"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testBasicQuery"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testMultipleEnlist"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testMultipleQuery"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testBasicReadOnlyQuery"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testConcurrentQuery"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testRepeatGetXAQuery"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testConcurrentReadWrite"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testSubqueryQuery"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("testTrivalImplicit"));
+    suite.addTest(new JotmTransactionStandaloneIntTst("cleanup"));
+
+    return suite;
+  }
+
+
+  public void setup() throws Exception {
+    logger.info("Doing setup");
+    sessionFactory = SessionFactoryFinder.newSessionFactory(databaseURI);
+    txService = new Jotm(true, false); // local, unbound.
+    txManager = txService.getTransactionManager();
+  }
+
+  public void cleanup() throws Exception {
+    logger.info("Doing cleanup");
+    txService.stop();
+  }
+
+  //
+  // Test cases
+  //
+
+  @SuppressWarnings("unused")
+  private static class TestXid implements Xid {
+    private int xid;
+    public TestXid(int xid) {
+      this.xid = xid;
+    }
+    
+    public int getFormatId() {
+      return 'X';
+    }
+
+    public byte[] getBranchQualifier() {
+      return new byte[] {
+        (byte)(xid >> 0x00),
+        (byte)(xid >> 0x08)
+      };
+    }
+
+    public byte[] getGlobalTransactionId() {
+      return new byte[] {
+        (byte)(xid >> 0x10),
+        (byte)(xid >> 0x18)
+      };
+    }
+  }
+
+  /**
+   * Test explicit transaction.
+   * As a side-effect, creates the model required by the next tests.
+   */
+  public void testTrivalExplicit() throws URISyntaxException {
+    logger.info("testTrivalExplicit");
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      txManager.getTransaction().enlistResource(session.getXAResource());
+
+      try {
+        session.createModel(modelURI, null);
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
+  public void testSessionCloseRollback() throws URISyntaxException {
+    logger.info("testSessionCloseRollback");
+    try {
+      URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      txManager.getTransaction().enlistResource(session.getXAResource());
+
+      try {
+        try {
+          session.setModel(modelURI, fileURI);
+        } finally {
+          session.close();
+        }
+      } finally {
+        try {
+          txManager.commit();
+        } catch (HeuristicRollbackException eh) { // This is my expectation.
+          logger.warn("HeuristicRollback detected successfully", eh);
+        } catch (RollbackException er) {          // This would also meet the spec.
+          logger.warn("Rollback detected successfully", er);
+        } catch (Exception e) {
+          logger.warn("Exception from Jotm", e);
+          throw e;
+        }
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testTrivialExplicitAgain() throws URISyntaxException {
+    logger.info("testTrivialExplicitAgain");
+    try {
+      URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      txManager.getTransaction().enlistResource(session.getXAResource());
+
+      try {
+        session.setModel(modelURI, fileURI);
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testBasicQuery() throws URISyntaxException {
+    logger.info("testBasicQuery");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      try {
+        txManager.getTransaction().enlistResource(session.getXAResource());
+
+        // Evaluate the query
+        Answer answer = session.query(createQuery(modelURI));
+        compareResults(expectedResults(), answer);
+        answer.close();
+
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
+  public void testMultipleEnlist() throws URISyntaxException {
+    logger.info("testMultipleEnlist");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      try {
+        txManager.getTransaction().enlistResource(session.getXAResource());
+        txManager.getTransaction().enlistResource(session.getXAResource());
+        txManager.getTransaction().enlistResource(session.getXAResource());
+
+        // Evaluate the query
+        Answer answer = session.query(createQuery(modelURI));
+        compareResults(expectedResults(), answer);
+        answer.close();
+
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
+  public void testMultipleQuery() throws URISyntaxException {
+    logger.info("testMultipleQuery");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      txManager.getTransaction().enlistResource(session.getXAResource());
+      try {
+        // Evaluate the query
+        Answer answer1 = session.query(createQuery(modelURI));
+
+        Answer answer2 = session.query(createQuery(modelURI));
+
+        compareResults(answer1, answer2);
+
+        answer1.close();
+        answer2.close();
+
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testBasicReadOnlyQuery() throws URISyntaxException {
+    logger.info("testBasicReadOnlyQuery");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      try {
+        txManager.getTransaction().enlistResource(session.getReadOnlyXAResource());
+
+        // Evaluate the query
+        Answer answer = session.query(createQuery(modelURI));
+        compareResults(expectedResults(), answer);
+        answer.close();
+
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testConcurrentQuery() throws URISyntaxException {
+    logger.info("testConcurrentQuery");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      XAResource roResource = session.getReadOnlyXAResource();
+      Transaction tx1 = txManager.getTransaction();
+      tx1.enlistResource(roResource);
+
+      try {
+        // Evaluate the query
+        Answer answer1 = session.query(createQuery(modelURI));
+
+        tx1 = txManager.suspend();
+
+        txManager.begin();
+        Transaction tx2 = txManager.getTransaction();
+        tx2.enlistResource(roResource);
+
+        Answer answer2 = session.query(createQuery(modelURI));
+
+        tx2 = txManager.suspend();
+
+        compareResults(answer1, answer2);
+
+        answer1.close();
+        answer2.close();
+
+        txManager.resume(tx1);
+        txManager.commit();
+        // I believe JTA requires me to call end here - our implementation doesn't care.
+        tx2.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testRepeatGetXAQuery() throws URISyntaxException {
+    logger.info("testRepeatGetXAQuery");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      Transaction tx1 = txManager.getTransaction();
+      tx1.enlistResource(session.getReadOnlyXAResource());
+
+      try {
+        // Evaluate the query
+        Answer answer1 = session.query(createQuery(modelURI));
+
+        tx1 = txManager.suspend();
+
+        txManager.begin();
+        Transaction tx2 = txManager.getTransaction();
+        tx2.enlistResource(session.getReadOnlyXAResource());
+
+        Answer answer2 = session.query(createQuery(modelURI));
+
+        tx2 = txManager.suspend();
+
+        compareResults(answer1, answer2);
+
+        answer1.close();
+        answer2.close();
+
+        txManager.resume(tx1);
+        txManager.commit();
+        // I believe JTA requires me to call end here - our implementation doesn't care.
+        tx2.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  //
+  // Note: What this test does is a really bad idea - there is no
+  //       isolation provided as each operation is within its own
+  //       transaction.  It does however provide a good test.
+  //
+  public void testConcurrentReadWrite() throws URISyntaxException {
+    logger.info("testConcurrentReadWrite");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      XAResource roResource = session.getReadOnlyXAResource();
+      XAResource rwResource = session.getXAResource();
+
+      txManager.getTransaction().enlistResource(rwResource);
+      session.createModel(model2URI, null);
+      Transaction tx1 = txManager.suspend();
+
+      try {
+        txManager.begin();
+        txManager.getTransaction().enlistResource(roResource);
+
+        // Evaluate the query
+        Answer answer = session.query(createQuery(modelURI));
+
+        Transaction tx2 = txManager.suspend();
+
+        answer.beforeFirst();
+        while (answer.next()) {
+          txManager.resume(tx1);
+          session.insert(model2URI, Collections.singleton(new TripleImpl(
+              (SubjectNode)answer.getObject(0),
+              (PredicateNode)answer.getObject(1),
+              (ObjectNode)answer.getObject(2))));
+          tx1 = txManager.suspend();
+        }
+        answer.close();
+
+        txManager.resume(tx1);
+        txManager.commit();
+
+        txManager.begin();
+        txManager.getTransaction().enlistResource(roResource);
+
+        Answer answer2 = session.query(createQuery(model2URI));
+
+        Transaction tx3 = txManager.suspend();
+
+        compareResults(expectedResults(), answer2);
+        answer2.close();
+
+        txManager.begin();
+        txManager.getTransaction().enlistResource(rwResource);
+        session.removeModel(model2URI);
+        txManager.commit();
+
+        txManager.resume(tx2);
+        txManager.commit();
+        txManager.resume(tx3);
+        txManager.commit();
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testSubqueryQuery() throws URISyntaxException {
+    logger.info("testSubqueryQuery");
+
+    try {
+      txManager.begin();
+      Session session = sessionFactory.newSession();
+      txManager.getTransaction().enlistResource(session.getReadOnlyXAResource());
+
+      try {
+        Variable subjectVariable   = new Variable("subject");
+        Variable predicateVariable = new Variable("predicate");
+        Variable objectVariable    = new Variable("object");
+
+        List<SelectElement> selectList = new ArrayList<SelectElement>(3);
+        selectList.add(subjectVariable);
+        selectList.add(new Subquery(new Variable("k0"), new Query(
+          Collections.singletonList(objectVariable),
+          new GraphResource(modelURI),                      // FROM
+          new ConstraintImpl(subjectVariable,               // WHERE
+                         predicateVariable,
+                         objectVariable),
+          null,                                             // HAVING
+          Collections.singletonList(                        // ORDER BY
+            new Order(objectVariable, true)
+          ),
+          null,                                             // LIMIT
+          0,                                                // OFFSET
+          true,                                             // DISTINCT
+          new UnconstrainedAnswer()                         // GIVEN
+        )));
+
+
+        // Evaluate the query
+        Answer answer = session.query(new Query(
+          selectList,                                       // SELECT
+          new GraphResource(modelURI),                      // FROM
+          new ConstraintImpl(subjectVariable,               // WHERE
+              new URIReferenceImpl(new URI("test:p03")),
+              objectVariable),
+          null,                                             // HAVING
+          Collections.singletonList(                        // ORDER BY
+            new Order(subjectVariable, true)
+          ),
+          null,                                             // LIMIT
+          0,                                                // OFFSET
+          true,                                             // DISTINCT
+          new UnconstrainedAnswer()                         // GIVEN
+        ));
+
+        txManager.suspend();
+
+        answer.beforeFirst();
+
+        assertTrue(answer.next());
+        assertEquals(new URIReferenceImpl(new URI("test:s01")),
+            answer.getObject(0));
+        Answer sub1 = (Answer)answer.getObject(1);
+        compareResults(new String[][] { new String[] { "test:o01" },
+                                        new String[] { "test:o02" } }, sub1);
+        sub1.close();
+
+        assertTrue(answer.next());
+        assertEquals(new URIReferenceImpl(new URI("test:s02")),
+            answer.getObject(0));
+        Answer sub2 = (Answer)answer.getObject(1);
+        compareResults(new String[][] { new String[] { "test:o02" },
+                                        new String[] { "test:o03" } }, sub2);
+        // Leave sub2 open.
+
+        assertFalse(answer.next());
+        answer.close();
+        sub2.close();
+
+        // Leave transaction to be closed on session close.
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+/*
+
+  public void testConcurrentSubqueryQuery() throws URISyntaxException {
+    logger.info("testConcurrentSubqueryQuery");
+
+    try {
+      Session session = database.newSession();
+      XAResource rwResource = session.getXAResource();
+      Xid xid1 = new TestXid(1);
+      rwResource.start(xid1, XAResource.TMNOFLAGS);
+
+      try {
+        Variable subjectVariable   = new Variable("subject");
+        Variable predicateVariable = new Variable("predicate");
+        Variable objectVariable    = new Variable("object");
+
+        List selectList = new ArrayList(3);
+        selectList.add(subjectVariable);
+        selectList.add(new Subquery(new Variable("k0"), new Query(
+          Collections.singletonList(objectVariable),
+          new GraphResource(modelURI),                      // FROM
+          new ConstraintImpl(subjectVariable,               // WHERE
+                         predicateVariable,
+                         objectVariable),
+          null,                                             // HAVING
+          Collections.singletonList(                        // ORDER BY
+            new Order(objectVariable, true)
+          ),
+          null,                                             // LIMIT
+          0,                                                // OFFSET
+          new UnconstrainedAnswer()                         // GIVEN
+        )));
+
+
+        // Evaluate the query
+        Answer answer = session.query(new Query(
+          selectList,                                       // SELECT
+          new GraphResource(modelURI),                      // FROM
+          new ConstraintImpl(subjectVariable,               // WHERE
+              new URIReferenceImpl(new URI("test:p03")),
+              objectVariable),
+          null,                                             // HAVING
+          Collections.singletonList(                        // ORDER BY
+            new Order(subjectVariable, true)
+          ),
+          null,                                             // LIMIT
+          0,                                                // OFFSET
+          new UnconstrainedAnswer()                         // GIVEN
+        ));
+
+        answer.beforeFirst();
+
+        assertTrue(answer.next());
+        assertEquals(new URIReferenceImpl(new URI("test:s01")),
+            answer.getObject(0));
+        Answer sub1 = (Answer)answer.getObject(1);
+        assertTrue(answer.next());
+        assertEquals(new URIReferenceImpl(new URI("test:s02")),
+            answer.getObject(0));
+        Answer sub2 = (Answer)answer.getObject(1);
+        assertFalse(answer.next());
+
+        assertEquals(1, sub1.getNumberOfVariables());
+        assertEquals(1, sub2.getNumberOfVariables());
+        sub1.beforeFirst();
+        sub2.beforeFirst();
+        assertTrue(sub1.next());
+        assertTrue(sub2.next());
+        assertEquals(new URIReferenceImpl(new URI("test:o01")), sub1.getObject(0));
+        assertEquals(new URIReferenceImpl(new URI("test:o02")), sub2.getObject(0));
+
+        rwResource.end(xid1, XAResource.TMSUSPEND);
+
+        assertTrue(sub1.next());
+        assertTrue(sub2.next());
+        assertEquals(new URIReferenceImpl(new URI("test:o02")), sub1.getObject(0));
+        assertEquals(new URIReferenceImpl(new URI("test:o03")), sub2.getObject(0));
+        assertFalse(sub1.next());
+        assertFalse(sub2.next());
+
+        answer.close();
+
+        rwResource.end(xid1, XAResource.TMSUCCESS);
+        rwResource.commit(xid1, true);
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testExplicitIsolationQuerySingleSession() throws URISyntaxException {
+    logger.info("testExplicitIsolationQuery");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session = database.newSession();
+      try {
+        XAResource roResource = session.getReadOnlyXAResource();
+        XAResource rwResource = session.getXAResource();
+        Xid xid1 = new TestXid(1); // Initial create model.
+        Xid xid2 = new TestXid(2); // Started before setModel.
+        Xid xid3 = new TestXid(3); // setModel.
+        Xid xid4 = new TestXid(4); // Started before setModel prepares
+        Xid xid5 = new TestXid(5); // Started before setModel commits
+        Xid xid6 = new TestXid(6); // Started after setModel commits
+        Xid xid7 = new TestXid(7); // Final remove model.
+
+        rwResource.start(xid1, XAResource.TMNOFLAGS);
+        session.createModel(model3URI, null);
+        rwResource.end(xid1, XAResource.TMSUCCESS);
+        rwResource.commit(xid1, true);
+
+        // Nothing visible.
+        roResource.start(xid2, XAResource.TMNOFLAGS);
+        assertChangeNotVisible(session);
+        roResource.end(xid2, XAResource.TMSUSPEND);
+
+        // Perform update
+        rwResource.start(xid3, XAResource.TMNOFLAGS);
+        session.setModel(model3URI, new GraphResource(fileURI));
+        rwResource.end(xid3, XAResource.TMSUSPEND);
+
+        // Check uncommitted change not visible
+        roResource.start(xid4, XAResource.TMNOFLAGS);
+        assertChangeNotVisible(session);
+        roResource.end(xid4, XAResource.TMSUSPEND);
+
+        // Check original phase unaffected.
+        roResource.start(xid2, XAResource.TMRESUME);
+        assertChangeNotVisible(session);
+        roResource.end(xid2, XAResource.TMSUSPEND);
+
+        // Check micro-commit visible to current-phase
+        rwResource.start(xid3, XAResource.TMRESUME);
+        assertChangeVisible(session);
+        // Perform prepare
+        rwResource.end(xid3, XAResource.TMSUCCESS);
+        rwResource.prepare(xid3);
+
+        // Check original phase unaffected
+        roResource.start(xid2, XAResource.TMRESUME);
+        assertChangeNotVisible(session);
+        roResource.end(xid2, XAResource.TMSUSPEND);
+
+        // Check pre-prepare phase unaffected
+        roResource.start(xid4, XAResource.TMRESUME);
+        assertChangeNotVisible(session);
+        roResource.end(xid4, XAResource.TMSUSPEND);
+
+        // Check committed phase unaffected.
+        roResource.start(xid5, XAResource.TMNOFLAGS);
+        assertChangeNotVisible(session);
+        roResource.end(xid5, XAResource.TMSUSPEND);
+
+        // Do commit
+        rwResource.commit(xid3, false);
+
+        // Check original phase
+        roResource.start(xid2, XAResource.TMRESUME);
+        assertChangeNotVisible(session);
+        roResource.end(xid2, XAResource.TMSUSPEND);
+
+        // Check pre-prepare
+        roResource.start(xid4, XAResource.TMRESUME);
+        assertChangeNotVisible(session);
+        roResource.end(xid4, XAResource.TMSUSPEND);
+
+        // Check pre-commit
+        roResource.start(xid5, XAResource.TMRESUME);
+        assertChangeNotVisible(session);
+        roResource.end(xid5, XAResource.TMSUSPEND);
+
+        // Check committed phase is now updated
+        roResource.start(xid6, XAResource.TMNOFLAGS);
+        assertChangeVisible(session);
+
+        // Cleanup transactions.
+        roResource.end(xid6, XAResource.TMSUCCESS);
+        roResource.end(xid2, XAResource.TMSUCCESS);
+        roResource.end(xid4, XAResource.TMSUCCESS);
+        roResource.end(xid5, XAResource.TMSUCCESS);
+        roResource.commit(xid2, true);
+        roResource.commit(xid4, true);
+        roResource.commit(xid5, true);
+        roResource.commit(xid6, true);
+
+        // Cleanup database
+        rwResource.start(xid7, XAResource.TMNOFLAGS);
+        session.removeModel(model3URI);
+        rwResource.end(xid7, XAResource.TMSUCCESS);
+        rwResource.commit(xid7, true);
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testExternalInternalIsolation() throws URISyntaxException {
+    logger.info("testExplicitIsolationQuery");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        Session session2 = database.newSession();
+        try {
+          XAResource roResource = session1.getReadOnlyXAResource();
+          XAResource rwResource = session1.getXAResource();
+          Xid xid1 = new TestXid(1); // Initial create model.
+          Xid xid2 = new TestXid(2); // Main Test.
+          Xid xid3 = new TestXid(3); // Cleanup test.
+
+          rwResource.start(xid1, XAResource.TMNOFLAGS);
+          session1.createModel(model3URI, null);
+          rwResource.end(xid1, XAResource.TMSUCCESS);
+          rwResource.commit(xid1, true);
+
+          // Nothing visible.
+          assertChangeNotVisible(session2);
+
+          // Perform update
+          rwResource.start(xid2, XAResource.TMNOFLAGS);
+          session1.setModel(model3URI, new GraphResource(fileURI));
+          rwResource.end(xid2, XAResource.TMSUSPEND);
+
+          // Check uncommitted change not visible
+          assertChangeNotVisible(session2);
+
+          // Check micro-commit visible to current-phase
+          rwResource.start(xid2, XAResource.TMRESUME);
+          assertChangeVisible(session1);
+          // Perform prepare
+          rwResource.end(xid2, XAResource.TMSUCCESS);
+          rwResource.prepare(xid2);
+
+          // Check original phase unaffected
+          assertChangeNotVisible(session2);
+
+          // Do commit
+          rwResource.commit(xid2, false);
+
+          // Check committed phase is now updated
+          assertChangeVisible(session2);
+
+          // Cleanup database
+          session2.removeModel(model3URI);
+        } finally {
+          session2.close();
+        }
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  public void testInternalExternalIsolation() throws URISyntaxException {
+    logger.info("testExplicitIsolationQuery");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        Session session2 = database.newSession();
+        try {
+          XAResource roResource = session2.getReadOnlyXAResource();
+          XAResource rwResource = session2.getXAResource();
+          Xid xid1 = new TestXid(1); // Pre-update
+          Xid xid2 = new TestXid(2); // Post-update/Pre-commit
+          Xid xid3 = new TestXid(3); // Post-commit
+
+          session1.createModel(model3URI, null);
+
+          // Nothing visible.
+          roResource.start(xid1, XAResource.TMNOFLAGS);
+          assertChangeNotVisible(session2);
+          roResource.end(xid1, XAResource.TMSUSPEND);
+
+          // Perform update with autocommit off
+          session1.setAutoCommit(false);
+          session1.setModel(model3URI, new GraphResource(fileURI));
+
+          // Check uncommitted change not visible
+          roResource.start(xid2, XAResource.TMNOFLAGS);
+          assertChangeNotVisible(session2);
+          roResource.end(xid2, XAResource.TMSUSPEND);
+
+          // Check original phase unaffected.
+          roResource.start(xid1, XAResource.TMRESUME);
+          assertChangeNotVisible(session2);
+          roResource.end(xid1, XAResource.TMSUSPEND);
+
+          // Check micro-commit visible to current-phase
+          assertChangeVisible(session1);
+          session1.setAutoCommit(true);
+
+          // Check original phase unaffected
+          roResource.start(xid1, XAResource.TMRESUME);
+          assertChangeNotVisible(session2);
+          roResource.end(xid1, XAResource.TMSUSPEND);
+
+          // Check pre-commit phase unaffected
+          roResource.start(xid2, XAResource.TMRESUME);
+          assertChangeNotVisible(session2);
+          roResource.end(xid2, XAResource.TMSUSPEND);
+
+          // Check committed phase is now updated and write-lock available
+          rwResource.start(xid3, XAResource.TMNOFLAGS);
+          assertChangeVisible(session2);
+          
+          // Check internal transaction read-only
+          assertChangeVisible(session1);
+
+          // Cleanup transactions.
+          rwResource.end(xid3, XAResource.TMSUCCESS);
+          roResource.end(xid2, XAResource.TMSUCCESS);
+          roResource.end(xid1, XAResource.TMSUCCESS);
+          roResource.commit(xid1, true);
+          roResource.commit(xid2, true);
+          rwResource.commit(xid3, true);
+
+          // Cleanup database (check write-lock available again)
+          session1.removeModel(model3URI);
+        } finally {
+          session2.close();
+        }
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  private void assertChangeVisible(Session session) throws Exception {
+    // Evaluate the query
+    Answer answer = session.query(createQuery(model3URI));
+
+    compareResults(expectedResults(), answer);
+    answer.close();
+  }
+
+  private void assertChangeNotVisible(Session session) throws Exception {
+    // Evaluate the query
+    Answer answer = session.query(createQuery(model3URI));
+    answer.beforeFirst();
+    assertFalse(answer.next());
+    answer.close();
+  }
+
+  //
+  // Test two simultaneous, explicit transactions, in two threads. The second one should block
+  // until the first one sets auto-commit back to true.
+  //
+  public void testConcurrentExplicitTxn() throws URISyntaxException {
+    logger.info("testConcurrentExplicitTxn");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        XAResource resource1 = session1.getXAResource();
+        resource1.start(new TestXid(1), XAResource.TMNOFLAGS);
+        session1.createModel(model3URI, null);
+        resource1.end(new TestXid(1), XAResource.TMSUCCESS);
+        resource1.commit(new TestXid(1), true);
+
+        resource1.start(new TestXid(2), XAResource.TMNOFLAGS);
+        session1.setModel(model3URI, new GraphResource(fileURI));
+
+        final boolean[] tx2Started = new boolean[] { false };
+
+        Thread t2 = new Thread("tx2Test") {
+          public void run() {
+            try {
+              Session session2 = database.newSession();
+              XAResource resource2 = session2.getXAResource();
+              try {
+                resource2.start(new TestXid(3), XAResource.TMNOFLAGS);
+
+                synchronized (tx2Started) {
+                  tx2Started[0] = true;
+                  tx2Started.notify();
+                }
+
+                // Evaluate the query
+                Answer answer = session2.query(createQuery(model3URI));
+
+                compareResults(expectedResults(), answer);
+                answer.close();
+
+                resource2.end(new TestXid(3), XAResource.TMSUCCESS);
+                resource2.commit(new TestXid(3), true);
+              } finally {
+                session2.close();
+              }
+            } catch (Exception e) {
+              fail(e);
+            }
+          }
+        };
+        t2.start();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        resource1.commit(new TestXid(2), true);
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+            assertTrue("second transaction should've started", tx2Started[0]);
+          }
+        }
+
+        try {
+          t2.join(2000L);
+        } catch (InterruptedException ie) {
+          logger.error("wait for tx2-terminated interrupted", ie);
+          fail(ie);
+        }
+        assertFalse("second transaction should've terminated", t2.isAlive());
+
+        resource1.start(new TestXid(4), XAResource.TMNOFLAGS);
+        session1.removeModel(model3URI);
+        resource1.end(new TestXid(4), XAResource.TMSUCCESS);
+        resource1.commit(new TestXid(4), true);
+
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  //*
+  // Test two simultaneous transactions, in two threads. The second one should block
+  // until the first one sets auto-commit back to true.
+  ///
+  public void testExternalInternalConcurrentTxn() throws URISyntaxException {
+    logger.info("testExternalInternalConcurrentTxn");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        XAResource resource1 = session1.getXAResource();
+        resource1.start(new TestXid(1), XAResource.TMNOFLAGS);
+        session1.createModel(model3URI, null);
+        resource1.end(new TestXid(1), XAResource.TMSUCCESS);
+        resource1.commit(new TestXid(1), true);
+
+        resource1.start(new TestXid(2), XAResource.TMNOFLAGS);
+        session1.setModel(model3URI, new GraphResource(fileURI));
+
+        final boolean[] tx2Started = new boolean[] { false };
+
+        Thread t2 = new Thread("tx2Test") {
+          public void run() {
+            try {
+              Session session2 = database.newSession();
+              try {
+                session2.setAutoCommit(false);
+
+                synchronized (tx2Started) {
+                  tx2Started[0] = true;
+                  tx2Started.notify();
+                }
+
+                // Evaluate the query
+                Answer answer = session2.query(createQuery(model3URI));
+
+                compareResults(expectedResults(), answer);
+                answer.close();
+
+                session2.setAutoCommit(true);
+              } finally {
+                session2.close();
+              }
+            } catch (Exception e) {
+              fail(e);
+            }
+          }
+        };
+        t2.start();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        resource1.commit(new TestXid(2), true);
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+            assertTrue("second transaction should've started", tx2Started[0]);
+          }
+        }
+
+        try {
+          t2.join(2000L);
+        } catch (InterruptedException ie) {
+          logger.error("wait for tx2-terminated interrupted", ie);
+          fail(ie);
+        }
+        assertFalse("second transaction should've terminated", t2.isAlive());
+
+        resource1.start(new TestXid(4), XAResource.TMNOFLAGS);
+        session1.removeModel(model3URI);
+        resource1.end(new TestXid(4), XAResource.TMSUCCESS);
+        resource1.commit(new TestXid(4), true);
+
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
+  //*
+  // Test two simultaneous transactions, in two threads. The second one should block
+  // until the first one sets auto-commit back to true.
+  ///
+  public void testInternalExternalConcurrentTxn() throws URISyntaxException {
+    logger.info("testInternalExternalConcurrentTxn");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        session1.createModel(model3URI, null);
+
+        session1.setAutoCommit(false);
+        session1.setModel(model3URI, new GraphResource(fileURI));
+
+        final boolean[] tx2Started = new boolean[] { false };
+
+        Thread t2 = new Thread("tx2Test") {
+          public void run() {
+            try {
+              Session session2 = database.newSession();
+              try {
+                XAResource resource = session2.getXAResource();
+                resource.start(new TestXid(1), XAResource.TMNOFLAGS);
+
+                synchronized (tx2Started) {
+                  tx2Started[0] = true;
+                  tx2Started.notify();
+                }
+
+                // Evaluate the query
+                Answer answer = session2.query(createQuery(model3URI));
+
+                compareResults(expectedResults(), answer);
+                answer.close();
+
+                resource.end(new TestXid(1), XAResource.TMSUCCESS);
+                resource.rollback(new TestXid(1));
+              } finally {
+                session2.close();
+              }
+            } catch (Exception e) {
+              fail(e);
+            }
+          }
+        };
+        t2.start();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        session1.commit();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        session1.setAutoCommit(true);
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+            assertTrue("second transaction should've started", tx2Started[0]);
+          }
+        }
+
+        try {
+          t2.join(2000L);
+        } catch (InterruptedException ie) {
+          logger.error("wait for tx2-terminated interrupted", ie);
+          fail(ie);
+        }
+        assertFalse("second transaction should've terminated", t2.isAlive());
+
+        session1.removeModel(model3URI);
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  //*
+  // Test two simultaneous transactions, in two threads. The second one should block
+  // until the first one sets auto-commit back to true.
+  ///
+  public void testExternalInternalConcurrentTxnRollback() throws URISyntaxException {
+    logger.info("testExternalInternalConcurrentTxnRollback");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        XAResource resource1 = session1.getXAResource();
+        resource1.start(new TestXid(1), XAResource.TMNOFLAGS);
+        session1.createModel(model3URI, null);
+        resource1.end(new TestXid(1), XAResource.TMSUCCESS);
+        resource1.commit(new TestXid(1), true);
+
+        resource1.start(new TestXid(2), XAResource.TMNOFLAGS);
+        session1.setModel(model3URI, new GraphResource(fileURI));
+
+        final boolean[] tx2Started = new boolean[] { false };
+
+        Thread t2 = new Thread("tx2Test") {
+          public void run() {
+            try {
+              Session session2 = database.newSession();
+              try {
+                session2.setAutoCommit(false);
+
+                synchronized (tx2Started) {
+                  tx2Started[0] = true;
+                  tx2Started.notify();
+                }
+
+                // Evaluate the query
+                Answer answer = session2.query(createQuery(model3URI));
+
+                answer.beforeFirst();
+                assertFalse(answer.next());
+                answer.close();
+
+                session2.setAutoCommit(true);
+              } finally {
+                session2.close();
+              }
+            } catch (Exception e) {
+              fail(e);
+            }
+          }
+        };
+        t2.start();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        resource1.rollback(new TestXid(2));
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+            assertTrue("second transaction should've started", tx2Started[0]);
+          }
+        }
+
+        try {
+          t2.join(2000L);
+        } catch (InterruptedException ie) {
+          logger.error("wait for tx2-terminated interrupted", ie);
+          fail(ie);
+        }
+        assertFalse("second transaction should've terminated", t2.isAlive());
+
+        resource1.start(new TestXid(4), XAResource.TMNOFLAGS);
+        session1.removeModel(model3URI);
+        resource1.end(new TestXid(4), XAResource.TMSUCCESS);
+        resource1.commit(new TestXid(4), true);
+
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
+  //*
+  // Test two simultaneous transactions, in two threads. The second one should block
+  // until the first one sets auto-commit back to true.
+  ///
+  public void testInternalExternalConcurrentTxnRollback() throws URISyntaxException {
+    logger.info("testInternalExternalConcurrentTxnRollback");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session1 = database.newSession();
+      try {
+        session1.createModel(model3URI, null);
+
+        session1.setAutoCommit(false);
+        session1.setModel(model3URI, new GraphResource(fileURI));
+
+        final boolean[] tx2Started = new boolean[] { false };
+
+        Thread t2 = new Thread("tx2Test") {
+          public void run() {
+            try {
+              Session session2 = database.newSession();
+              try {
+                XAResource resource = session2.getXAResource();
+                resource.start(new TestXid(1), XAResource.TMNOFLAGS);
+
+                synchronized (tx2Started) {
+                  tx2Started[0] = true;
+                  tx2Started.notify();
+                }
+
+                // Evaluate the query
+                Answer answer = session2.query(createQuery(model3URI));
+
+                answer.beforeFirst();
+                assertFalse(answer.next());
+                answer.close();
+
+                resource.end(new TestXid(1), XAResource.TMFAIL);
+                resource.rollback(new TestXid(1));
+              } finally {
+                session2.close();
+              }
+            } catch (Exception e) {
+              fail(e);
+            }
+          }
+        };
+        t2.start();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        session1.rollback();
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+          }
+          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
+        }
+
+        session1.setAutoCommit(true);
+
+        synchronized (tx2Started) {
+          if (!tx2Started[0]) {
+            try {
+              tx2Started.wait(2000L);
+            } catch (InterruptedException ie) {
+              logger.error("wait for tx2-started interrupted", ie);
+              fail(ie);
+            }
+            assertTrue("second transaction should've started", tx2Started[0]);
+          }
+        }
+
+        try {
+          t2.join(2000L);
+        } catch (InterruptedException ie) {
+          logger.error("wait for tx2-terminated interrupted", ie);
+          fail(ie);
+        }
+        assertFalse("second transaction should've terminated", t2.isAlive());
+
+        session1.removeModel(model3URI);
+      } finally {
+        session1.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+
+  public void testExplicitRollbackIsolationQuery() throws URISyntaxException {
+    logger.info("testExplicitRollbackIsolationQuery");
+    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
+
+    try {
+      Session session = database.newSession();
+      XAResource roResource = session.getReadOnlyXAResource();
+      XAResource rwResource = session.getXAResource();
+      try {
+        rwResource.start(new TestXid(1), XAResource.TMNOFLAGS);
+        session.createModel(model3URI, null);
+        rwResource.end(new TestXid(1), XAResource.TMSUCCESS);
+        rwResource.commit(new TestXid(1), true);
+
+        rwResource.start(new TestXid(2), XAResource.TMNOFLAGS);
+        session.setModel(model3URI, new GraphResource(fileURI));
+        rwResource.end(new TestXid(2), XAResource.TMSUSPEND);
+
+        roResource.start(new TestXid(3), XAResource.TMNOFLAGS);
+
+        // Evaluate the query
+        Answer answer = session.query(createQuery(model3URI));
+        answer.beforeFirst();
+        assertFalse(answer.next());
+        answer.close();
+
+        roResource.end(new TestXid(3), XAResource.TMSUCCESS);
+        roResource.commit(new TestXid(3), true);
+
+        rwResource.end(new TestXid(2), XAResource.TMFAIL);
+        rwResource.rollback(new TestXid(2));
+
+        roResource.start(new TestXid(4), XAResource.TMNOFLAGS);
+        selectList = new ArrayList(3);
+        selectList.add(subjectVariable);
+        selectList.add(predicateVariable);
+        selectList.add(objectVariable);
+
+        // Evaluate the query
+        answer = session.query(createQuery(model3URI));
+
+        answer.beforeFirst();
+        assertFalse(answer.next());
+        answer.close();
+
+        roResource.end(new TestXid(4), XAResource.TMFAIL);
+        roResource.rollback(new TestXid(4));
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+*/
+
+  public void testTrivalImplicit() throws URISyntaxException {
+    logger.info("testTrivialImplicit");
+    try {
+      Session session = sessionFactory.newSession();
+
+      try {
+        session.removeModel(modelURI);
+      } finally {
+        session.close();
+      }
+    } catch (Exception e) {
+      fail(e);
+    }
+  }
+
+  //
+  // Internal methods
+  //
+
+  private Query createQuery(URI model) {
+    Variable subjectVariable   = new Variable("subject");
+    Variable predicateVariable = new Variable("predicate");
+    Variable objectVariable    = new Variable("object");
+
+    List<SelectElement> selectList = new ArrayList<SelectElement>(3);
+    selectList.add(subjectVariable);
+    selectList.add(predicateVariable);
+    selectList.add(objectVariable);
+
+    return new Query(
+      selectList,                                       // SELECT
+      new GraphResource(model),                         // FROM
+      new ConstraintImpl(subjectVariable,               // WHERE
+                     predicateVariable,
+                     objectVariable),
+      null,                                             // HAVING
+      Arrays.asList(new Order[] {                       // ORDER BY
+        new Order(subjectVariable, true),
+        new Order(predicateVariable, true),
+        new Order(objectVariable, true)
+      }),
+      null,                                             // LIMIT
+      0,                                                // OFFSET
+      true,                                             // DISTINCT
+      new UnconstrainedAnswer()                         // GIVEN
+    );
+  }
+
+  private String[][] expectedResults() {
+    return new String[][] {
+          { "test:s01", "test:p01", "test:o01" },
+          { "test:s01", "test:p02", "test:o01" },
+          { "test:s01", "test:p02", "test:o02" },
+          { "test:s01", "test:p03", "test:o02" },
+          { "test:s02", "test:p03", "test:o02" },
+          { "test:s02", "test:p04", "test:o02" },
+          { "test:s02", "test:p04", "test:o03" },
+          { "test:s02", "test:p05", "test:o03" },
+          { "test:s03", "test:p01", "test:o01" },
+          { "test:s03", "test:p05", "test:o03" },
+          { "test:s03", "test:p06", "test:o01" },
+          { "test:s03", "test:p06", "test:o03" },
+        };
+  }
+
+  private void compareResults(String[][] expected, Answer answer) throws Exception {
+    try {
+      answer.beforeFirst();
+      for (int i = 0; i < expected.length; i++) {
+        assertTrue("Answer short at row " + i, answer.next());
+        assertEquals(expected[i].length, answer.getNumberOfVariables());
+        for (int j = 0; j < expected[i].length; j++) {
+          URIReferenceImpl uri = new URIReferenceImpl(new URI(expected[i][j]));
+          assertEquals(uri, answer.getObject(j));
+        }
+      }
+      assertFalse(answer.next());
+    } catch (Exception e) {
+      logger.info("Failed test - " + answer);
+      answer.close();
+      throw e;
+    }
+  }
+
+  private void compareResults(Answer answer1, Answer answer2) throws Exception {
+    answer1.beforeFirst();
+    answer2.beforeFirst();
+    assertEquals(answer1.getNumberOfVariables(), answer2.getNumberOfVariables());
+    while (answer1.next()) {
+      assertTrue(answer2.next());
+      for (int i = 0; i < answer1.getNumberOfVariables(); i++) {
+        assertEquals(answer1.getObject(i), answer2.getObject(i));
+      }
+    }
+    assertFalse(answer2.next());
+  }
+
+  /**
+   * Fail with an unexpected exception
+   */
+  private void fail(Throwable throwable) {
+    StringWriter stringWriter = new StringWriter();
+    throwable.printStackTrace(new PrintWriter(stringWriter));
+    fail(stringWriter.toString());
+  }
+
+  @SuppressWarnings("unused")
+  private static class DummyXAResource implements XAResource {
+    public void end(Xid xid, int flags) throws XAException {}
+    public void forget(Xid xid) throws XAException {}
+    public int getTransactionTimeout() throws XAException { return 0; }
+    public int prepare(Xid xid) throws XAException { return 0; }
+    public Xid[] recover(int flag) throws XAException { return new Xid[] {}; }
+    public void rollback(Xid xid) throws XAException {}
+    public boolean setTransactionTimeout(int seconds) throws XAException { return false; }
+    public void start(Xid xid, int flags) throws XAException {}
+    public void commit(Xid xid, boolean twophase) throws XAException {}
+    public boolean isSameRM(XAResource xa) { return xa == this; }
+  }
+}

Deleted: trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,1604 +0,0 @@
-/*
- * Copyright 2008 The Topaz Foundation 
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not
- * use this file except in compliance with the License. You may obtain a copy of
- * the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations under
- * the License.
- *
- * Contributions:
- */
-package org.mulgara.resolver;
-
-// Java 2 standard packages
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
-import javax.transaction.xa.XAException;
-import javax.transaction.xa.XAResource;
-import javax.transaction.xa.Xid;
-import javax.transaction.HeuristicRollbackException;
-import javax.transaction.RollbackException;
-import javax.transaction.Transaction;
-import javax.transaction.TransactionManager;
-
-// Third party packages
-import junit.framework.*;        // JUnit
-import org.apache.log4j.Logger;  // Log4J
-import org.jrdf.graph.ObjectNode;
-import org.jrdf.graph.PredicateNode;
-import org.jrdf.graph.SubjectNode;
-import org.objectweb.jotm.Jotm;
-import org.objectweb.transaction.jta.TMService;
-
-// Locally written packages
-import org.mulgara.query.*;
-import org.mulgara.query.rdf.URIReferenceImpl;
-import org.mulgara.query.rdf.TripleImpl;
-import org.mulgara.server.Session;
-
-import org.mulgara.server.SessionFactory;
-import org.mulgara.server.driver.SessionFactoryFinder;
-
-/**
- * Regression test to test JTA integration with external JOTM instance.
- *
- * @created 2008-01-11
- * @author <a href="mailto:andrae at netymon.com">Andrae Muys</a>
- * @company <A href="mailto:mail at netymon.com">Netymon Pty Ltd</A>
- * @copyright ©2008 <a href="http://www.topazproject.org/">The Topaz Foundation</a>
- * @licence Apache License v2.0
- */
-public class JotmTransactionStandaloneTest extends TestCase {
-  /** Logger.  */
-  private static Logger logger =
-    Logger.getLogger(JotmTransactionStandaloneTest.class.getName());
-
-  private static final URI databaseURI;
-
-
-  private static final URI modelURI;
-  private static final URI model2URI;
-
-  static {
-    try {
-      databaseURI    = new URI("rmi://localhost/server1");
-      modelURI       = new URI("rmi://localhost/server1#jotmmodel");
-      model2URI      = new URI("rmi://localhost/server1#jotmmodel2");
-    } catch (URISyntaxException e) {
-      throw new Error("Bad hardcoded URI", e);
-    }
-  }
-
-  private static SessionFactory sessionFactory;
-  private static TMService txService;
-  private static TransactionManager txManager;
-
-  public JotmTransactionStandaloneTest(String name) {
-    super(name);
-  }
-
-  public static Test suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTest(new JotmTransactionStandaloneTest("setup"));
-    suite.addTest(new JotmTransactionStandaloneTest("testTrivalExplicit"));
-    suite.addTest(new JotmTransactionStandaloneTest("testSessionCloseRollback"));
-    suite.addTest(new JotmTransactionStandaloneTest("testTrivialExplicitAgain"));
-    suite.addTest(new JotmTransactionStandaloneTest("testBasicQuery"));
-    suite.addTest(new JotmTransactionStandaloneTest("testMultipleEnlist"));
-    suite.addTest(new JotmTransactionStandaloneTest("testMultipleQuery"));
-    suite.addTest(new JotmTransactionStandaloneTest("testBasicReadOnlyQuery"));
-    suite.addTest(new JotmTransactionStandaloneTest("testConcurrentQuery"));
-    suite.addTest(new JotmTransactionStandaloneTest("testRepeatGetXAQuery"));
-    suite.addTest(new JotmTransactionStandaloneTest("testConcurrentReadWrite"));
-    suite.addTest(new JotmTransactionStandaloneTest("testSubqueryQuery"));
-    suite.addTest(new JotmTransactionStandaloneTest("testTrivalImplicit"));
-    suite.addTest(new JotmTransactionStandaloneTest("cleanup"));
-
-    return suite;
-  }
-
-
-  public void setup() throws Exception {
-    logger.info("Doing setup");
-    sessionFactory = SessionFactoryFinder.newSessionFactory(databaseURI);
-    txService = new Jotm(true, false); // local, unbound.
-    txManager = txService.getTransactionManager();
-  }
-
-  public void cleanup() throws Exception {
-    logger.info("Doing cleanup");
-    txService.stop();
-  }
-
-  //
-  // Test cases
-  //
-
-  @SuppressWarnings("unused")
-  private static class TestXid implements Xid {
-    private int xid;
-    public TestXid(int xid) {
-      this.xid = xid;
-    }
-    
-    public int getFormatId() {
-      return 'X';
-    }
-
-    public byte[] getBranchQualifier() {
-      return new byte[] {
-        (byte)(xid >> 0x00),
-        (byte)(xid >> 0x08)
-      };
-    }
-
-    public byte[] getGlobalTransactionId() {
-      return new byte[] {
-        (byte)(xid >> 0x10),
-        (byte)(xid >> 0x18)
-      };
-    }
-  }
-
-  /**
-   * Test explicit transaction.
-   * As a side-effect, creates the model required by the next tests.
-   */
-  public void testTrivalExplicit() throws URISyntaxException {
-    logger.info("testTrivalExplicit");
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      txManager.getTransaction().enlistResource(session.getXAResource());
-
-      try {
-        session.createModel(modelURI, null);
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-
-  public void testSessionCloseRollback() throws URISyntaxException {
-    logger.info("testSessionCloseRollback");
-    try {
-      URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      txManager.getTransaction().enlistResource(session.getXAResource());
-
-      try {
-        try {
-          session.setModel(modelURI, fileURI);
-        } finally {
-          session.close();
-        }
-      } finally {
-        try {
-          txManager.commit();
-        } catch (HeuristicRollbackException eh) { // This is my expectation.
-          logger.warn("HeuristicRollback detected successfully", eh);
-        } catch (RollbackException er) {          // This would also meet the spec.
-          logger.warn("Rollback detected successfully", er);
-        } catch (Exception e) {
-          logger.warn("Exception from Jotm", e);
-          throw e;
-        }
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testTrivialExplicitAgain() throws URISyntaxException {
-    logger.info("testTrivialExplicitAgain");
-    try {
-      URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      txManager.getTransaction().enlistResource(session.getXAResource());
-
-      try {
-        session.setModel(modelURI, fileURI);
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testBasicQuery() throws URISyntaxException {
-    logger.info("testBasicQuery");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      try {
-        txManager.getTransaction().enlistResource(session.getXAResource());
-
-        // Evaluate the query
-        Answer answer = session.query(createQuery(modelURI));
-        compareResults(expectedResults(), answer);
-        answer.close();
-
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-
-  public void testMultipleEnlist() throws URISyntaxException {
-    logger.info("testMultipleEnlist");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      try {
-        txManager.getTransaction().enlistResource(session.getXAResource());
-        txManager.getTransaction().enlistResource(session.getXAResource());
-        txManager.getTransaction().enlistResource(session.getXAResource());
-
-        // Evaluate the query
-        Answer answer = session.query(createQuery(modelURI));
-        compareResults(expectedResults(), answer);
-        answer.close();
-
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-
-  public void testMultipleQuery() throws URISyntaxException {
-    logger.info("testMultipleQuery");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      txManager.getTransaction().enlistResource(session.getXAResource());
-      try {
-        // Evaluate the query
-        Answer answer1 = session.query(createQuery(modelURI));
-
-        Answer answer2 = session.query(createQuery(modelURI));
-
-        compareResults(answer1, answer2);
-
-        answer1.close();
-        answer2.close();
-
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testBasicReadOnlyQuery() throws URISyntaxException {
-    logger.info("testBasicReadOnlyQuery");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      try {
-        txManager.getTransaction().enlistResource(session.getReadOnlyXAResource());
-
-        // Evaluate the query
-        Answer answer = session.query(createQuery(modelURI));
-        compareResults(expectedResults(), answer);
-        answer.close();
-
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testConcurrentQuery() throws URISyntaxException {
-    logger.info("testConcurrentQuery");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      XAResource roResource = session.getReadOnlyXAResource();
-      Transaction tx1 = txManager.getTransaction();
-      tx1.enlistResource(roResource);
-
-      try {
-        // Evaluate the query
-        Answer answer1 = session.query(createQuery(modelURI));
-
-        tx1 = txManager.suspend();
-
-        txManager.begin();
-        Transaction tx2 = txManager.getTransaction();
-        tx2.enlistResource(roResource);
-
-        Answer answer2 = session.query(createQuery(modelURI));
-
-        tx2 = txManager.suspend();
-
-        compareResults(answer1, answer2);
-
-        answer1.close();
-        answer2.close();
-
-        txManager.resume(tx1);
-        txManager.commit();
-        // I believe JTA requires me to call end here - our implementation doesn't care.
-        tx2.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testRepeatGetXAQuery() throws URISyntaxException {
-    logger.info("testRepeatGetXAQuery");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      Transaction tx1 = txManager.getTransaction();
-      tx1.enlistResource(session.getReadOnlyXAResource());
-
-      try {
-        // Evaluate the query
-        Answer answer1 = session.query(createQuery(modelURI));
-
-        tx1 = txManager.suspend();
-
-        txManager.begin();
-        Transaction tx2 = txManager.getTransaction();
-        tx2.enlistResource(session.getReadOnlyXAResource());
-
-        Answer answer2 = session.query(createQuery(modelURI));
-
-        tx2 = txManager.suspend();
-
-        compareResults(answer1, answer2);
-
-        answer1.close();
-        answer2.close();
-
-        txManager.resume(tx1);
-        txManager.commit();
-        // I believe JTA requires me to call end here - our implementation doesn't care.
-        tx2.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  //
-  // Note: What this test does is a really bad idea - there is no
-  //       isolation provided as each operation is within its own
-  //       transaction.  It does however provide a good test.
-  //
-  public void testConcurrentReadWrite() throws URISyntaxException {
-    logger.info("testConcurrentReadWrite");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      XAResource roResource = session.getReadOnlyXAResource();
-      XAResource rwResource = session.getXAResource();
-
-      txManager.getTransaction().enlistResource(rwResource);
-      session.createModel(model2URI, null);
-      Transaction tx1 = txManager.suspend();
-
-      try {
-        txManager.begin();
-        txManager.getTransaction().enlistResource(roResource);
-
-        // Evaluate the query
-        Answer answer = session.query(createQuery(modelURI));
-
-        Transaction tx2 = txManager.suspend();
-
-        answer.beforeFirst();
-        while (answer.next()) {
-          txManager.resume(tx1);
-          session.insert(model2URI, Collections.singleton(new TripleImpl(
-              (SubjectNode)answer.getObject(0),
-              (PredicateNode)answer.getObject(1),
-              (ObjectNode)answer.getObject(2))));
-          tx1 = txManager.suspend();
-        }
-        answer.close();
-
-        txManager.resume(tx1);
-        txManager.commit();
-
-        txManager.begin();
-        txManager.getTransaction().enlistResource(roResource);
-
-        Answer answer2 = session.query(createQuery(model2URI));
-
-        Transaction tx3 = txManager.suspend();
-
-        compareResults(expectedResults(), answer2);
-        answer2.close();
-
-        txManager.begin();
-        txManager.getTransaction().enlistResource(rwResource);
-        session.removeModel(model2URI);
-        txManager.commit();
-
-        txManager.resume(tx2);
-        txManager.commit();
-        txManager.resume(tx3);
-        txManager.commit();
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testSubqueryQuery() throws URISyntaxException {
-    logger.info("testSubqueryQuery");
-
-    try {
-      txManager.begin();
-      Session session = sessionFactory.newSession();
-      txManager.getTransaction().enlistResource(session.getReadOnlyXAResource());
-
-      try {
-        Variable subjectVariable   = new Variable("subject");
-        Variable predicateVariable = new Variable("predicate");
-        Variable objectVariable    = new Variable("object");
-
-        List<SelectElement> selectList = new ArrayList<SelectElement>(3);
-        selectList.add(subjectVariable);
-        selectList.add(new Subquery(new Variable("k0"), new Query(
-          Collections.singletonList(objectVariable),
-          new GraphResource(modelURI),                      // FROM
-          new ConstraintImpl(subjectVariable,               // WHERE
-                         predicateVariable,
-                         objectVariable),
-          null,                                             // HAVING
-          Collections.singletonList(                        // ORDER BY
-            new Order(objectVariable, true)
-          ),
-          null,                                             // LIMIT
-          0,                                                // OFFSET
-          true,                                             // DISTINCT
-          new UnconstrainedAnswer()                         // GIVEN
-        )));
-
-
-        // Evaluate the query
-        Answer answer = session.query(new Query(
-          selectList,                                       // SELECT
-          new GraphResource(modelURI),                      // FROM
-          new ConstraintImpl(subjectVariable,               // WHERE
-              new URIReferenceImpl(new URI("test:p03")),
-              objectVariable),
-          null,                                             // HAVING
-          Collections.singletonList(                        // ORDER BY
-            new Order(subjectVariable, true)
-          ),
-          null,                                             // LIMIT
-          0,                                                // OFFSET
-          true,                                             // DISTINCT
-          new UnconstrainedAnswer()                         // GIVEN
-        ));
-
-        txManager.suspend();
-
-        answer.beforeFirst();
-
-        assertTrue(answer.next());
-        assertEquals(new URIReferenceImpl(new URI("test:s01")),
-            answer.getObject(0));
-        Answer sub1 = (Answer)answer.getObject(1);
-        compareResults(new String[][] { new String[] { "test:o01" },
-                                        new String[] { "test:o02" } }, sub1);
-        sub1.close();
-
-        assertTrue(answer.next());
-        assertEquals(new URIReferenceImpl(new URI("test:s02")),
-            answer.getObject(0));
-        Answer sub2 = (Answer)answer.getObject(1);
-        compareResults(new String[][] { new String[] { "test:o02" },
-                                        new String[] { "test:o03" } }, sub2);
-        // Leave sub2 open.
-
-        assertFalse(answer.next());
-        answer.close();
-        sub2.close();
-
-        // Leave transaction to be closed on session close.
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-/*
-
-  public void testConcurrentSubqueryQuery() throws URISyntaxException {
-    logger.info("testConcurrentSubqueryQuery");
-
-    try {
-      Session session = database.newSession();
-      XAResource rwResource = session.getXAResource();
-      Xid xid1 = new TestXid(1);
-      rwResource.start(xid1, XAResource.TMNOFLAGS);
-
-      try {
-        Variable subjectVariable   = new Variable("subject");
-        Variable predicateVariable = new Variable("predicate");
-        Variable objectVariable    = new Variable("object");
-
-        List selectList = new ArrayList(3);
-        selectList.add(subjectVariable);
-        selectList.add(new Subquery(new Variable("k0"), new Query(
-          Collections.singletonList(objectVariable),
-          new GraphResource(modelURI),                      // FROM
-          new ConstraintImpl(subjectVariable,               // WHERE
-                         predicateVariable,
-                         objectVariable),
-          null,                                             // HAVING
-          Collections.singletonList(                        // ORDER BY
-            new Order(objectVariable, true)
-          ),
-          null,                                             // LIMIT
-          0,                                                // OFFSET
-          new UnconstrainedAnswer()                         // GIVEN
-        )));
-
-
-        // Evaluate the query
-        Answer answer = session.query(new Query(
-          selectList,                                       // SELECT
-          new GraphResource(modelURI),                      // FROM
-          new ConstraintImpl(subjectVariable,               // WHERE
-              new URIReferenceImpl(new URI("test:p03")),
-              objectVariable),
-          null,                                             // HAVING
-          Collections.singletonList(                        // ORDER BY
-            new Order(subjectVariable, true)
-          ),
-          null,                                             // LIMIT
-          0,                                                // OFFSET
-          new UnconstrainedAnswer()                         // GIVEN
-        ));
-
-        answer.beforeFirst();
-
-        assertTrue(answer.next());
-        assertEquals(new URIReferenceImpl(new URI("test:s01")),
-            answer.getObject(0));
-        Answer sub1 = (Answer)answer.getObject(1);
-        assertTrue(answer.next());
-        assertEquals(new URIReferenceImpl(new URI("test:s02")),
-            answer.getObject(0));
-        Answer sub2 = (Answer)answer.getObject(1);
-        assertFalse(answer.next());
-
-        assertEquals(1, sub1.getNumberOfVariables());
-        assertEquals(1, sub2.getNumberOfVariables());
-        sub1.beforeFirst();
-        sub2.beforeFirst();
-        assertTrue(sub1.next());
-        assertTrue(sub2.next());
-        assertEquals(new URIReferenceImpl(new URI("test:o01")), sub1.getObject(0));
-        assertEquals(new URIReferenceImpl(new URI("test:o02")), sub2.getObject(0));
-
-        rwResource.end(xid1, XAResource.TMSUSPEND);
-
-        assertTrue(sub1.next());
-        assertTrue(sub2.next());
-        assertEquals(new URIReferenceImpl(new URI("test:o02")), sub1.getObject(0));
-        assertEquals(new URIReferenceImpl(new URI("test:o03")), sub2.getObject(0));
-        assertFalse(sub1.next());
-        assertFalse(sub2.next());
-
-        answer.close();
-
-        rwResource.end(xid1, XAResource.TMSUCCESS);
-        rwResource.commit(xid1, true);
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testExplicitIsolationQuerySingleSession() throws URISyntaxException {
-    logger.info("testExplicitIsolationQuery");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session = database.newSession();
-      try {
-        XAResource roResource = session.getReadOnlyXAResource();
-        XAResource rwResource = session.getXAResource();
-        Xid xid1 = new TestXid(1); // Initial create model.
-        Xid xid2 = new TestXid(2); // Started before setModel.
-        Xid xid3 = new TestXid(3); // setModel.
-        Xid xid4 = new TestXid(4); // Started before setModel prepares
-        Xid xid5 = new TestXid(5); // Started before setModel commits
-        Xid xid6 = new TestXid(6); // Started after setModel commits
-        Xid xid7 = new TestXid(7); // Final remove model.
-
-        rwResource.start(xid1, XAResource.TMNOFLAGS);
-        session.createModel(model3URI, null);
-        rwResource.end(xid1, XAResource.TMSUCCESS);
-        rwResource.commit(xid1, true);
-
-        // Nothing visible.
-        roResource.start(xid2, XAResource.TMNOFLAGS);
-        assertChangeNotVisible(session);
-        roResource.end(xid2, XAResource.TMSUSPEND);
-
-        // Perform update
-        rwResource.start(xid3, XAResource.TMNOFLAGS);
-        session.setModel(model3URI, new GraphResource(fileURI));
-        rwResource.end(xid3, XAResource.TMSUSPEND);
-
-        // Check uncommitted change not visible
-        roResource.start(xid4, XAResource.TMNOFLAGS);
-        assertChangeNotVisible(session);
-        roResource.end(xid4, XAResource.TMSUSPEND);
-
-        // Check original phase unaffected.
-        roResource.start(xid2, XAResource.TMRESUME);
-        assertChangeNotVisible(session);
-        roResource.end(xid2, XAResource.TMSUSPEND);
-
-        // Check micro-commit visible to current-phase
-        rwResource.start(xid3, XAResource.TMRESUME);
-        assertChangeVisible(session);
-        // Perform prepare
-        rwResource.end(xid3, XAResource.TMSUCCESS);
-        rwResource.prepare(xid3);
-
-        // Check original phase unaffected
-        roResource.start(xid2, XAResource.TMRESUME);
-        assertChangeNotVisible(session);
-        roResource.end(xid2, XAResource.TMSUSPEND);
-
-        // Check pre-prepare phase unaffected
-        roResource.start(xid4, XAResource.TMRESUME);
-        assertChangeNotVisible(session);
-        roResource.end(xid4, XAResource.TMSUSPEND);
-
-        // Check committed phase unaffected.
-        roResource.start(xid5, XAResource.TMNOFLAGS);
-        assertChangeNotVisible(session);
-        roResource.end(xid5, XAResource.TMSUSPEND);
-
-        // Do commit
-        rwResource.commit(xid3, false);
-
-        // Check original phase
-        roResource.start(xid2, XAResource.TMRESUME);
-        assertChangeNotVisible(session);
-        roResource.end(xid2, XAResource.TMSUSPEND);
-
-        // Check pre-prepare
-        roResource.start(xid4, XAResource.TMRESUME);
-        assertChangeNotVisible(session);
-        roResource.end(xid4, XAResource.TMSUSPEND);
-
-        // Check pre-commit
-        roResource.start(xid5, XAResource.TMRESUME);
-        assertChangeNotVisible(session);
-        roResource.end(xid5, XAResource.TMSUSPEND);
-
-        // Check committed phase is now updated
-        roResource.start(xid6, XAResource.TMNOFLAGS);
-        assertChangeVisible(session);
-
-        // Cleanup transactions.
-        roResource.end(xid6, XAResource.TMSUCCESS);
-        roResource.end(xid2, XAResource.TMSUCCESS);
-        roResource.end(xid4, XAResource.TMSUCCESS);
-        roResource.end(xid5, XAResource.TMSUCCESS);
-        roResource.commit(xid2, true);
-        roResource.commit(xid4, true);
-        roResource.commit(xid5, true);
-        roResource.commit(xid6, true);
-
-        // Cleanup database
-        rwResource.start(xid7, XAResource.TMNOFLAGS);
-        session.removeModel(model3URI);
-        rwResource.end(xid7, XAResource.TMSUCCESS);
-        rwResource.commit(xid7, true);
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testExternalInternalIsolation() throws URISyntaxException {
-    logger.info("testExplicitIsolationQuery");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        Session session2 = database.newSession();
-        try {
-          XAResource roResource = session1.getReadOnlyXAResource();
-          XAResource rwResource = session1.getXAResource();
-          Xid xid1 = new TestXid(1); // Initial create model.
-          Xid xid2 = new TestXid(2); // Main Test.
-          Xid xid3 = new TestXid(3); // Cleanup test.
-
-          rwResource.start(xid1, XAResource.TMNOFLAGS);
-          session1.createModel(model3URI, null);
-          rwResource.end(xid1, XAResource.TMSUCCESS);
-          rwResource.commit(xid1, true);
-
-          // Nothing visible.
-          assertChangeNotVisible(session2);
-
-          // Perform update
-          rwResource.start(xid2, XAResource.TMNOFLAGS);
-          session1.setModel(model3URI, new GraphResource(fileURI));
-          rwResource.end(xid2, XAResource.TMSUSPEND);
-
-          // Check uncommitted change not visible
-          assertChangeNotVisible(session2);
-
-          // Check micro-commit visible to current-phase
-          rwResource.start(xid2, XAResource.TMRESUME);
-          assertChangeVisible(session1);
-          // Perform prepare
-          rwResource.end(xid2, XAResource.TMSUCCESS);
-          rwResource.prepare(xid2);
-
-          // Check original phase unaffected
-          assertChangeNotVisible(session2);
-
-          // Do commit
-          rwResource.commit(xid2, false);
-
-          // Check committed phase is now updated
-          assertChangeVisible(session2);
-
-          // Cleanup database
-          session2.removeModel(model3URI);
-        } finally {
-          session2.close();
-        }
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  public void testInternalExternalIsolation() throws URISyntaxException {
-    logger.info("testExplicitIsolationQuery");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        Session session2 = database.newSession();
-        try {
-          XAResource roResource = session2.getReadOnlyXAResource();
-          XAResource rwResource = session2.getXAResource();
-          Xid xid1 = new TestXid(1); // Pre-update
-          Xid xid2 = new TestXid(2); // Post-update/Pre-commit
-          Xid xid3 = new TestXid(3); // Post-commit
-
-          session1.createModel(model3URI, null);
-
-          // Nothing visible.
-          roResource.start(xid1, XAResource.TMNOFLAGS);
-          assertChangeNotVisible(session2);
-          roResource.end(xid1, XAResource.TMSUSPEND);
-
-          // Perform update with autocommit off
-          session1.setAutoCommit(false);
-          session1.setModel(model3URI, new GraphResource(fileURI));
-
-          // Check uncommitted change not visible
-          roResource.start(xid2, XAResource.TMNOFLAGS);
-          assertChangeNotVisible(session2);
-          roResource.end(xid2, XAResource.TMSUSPEND);
-
-          // Check original phase unaffected.
-          roResource.start(xid1, XAResource.TMRESUME);
-          assertChangeNotVisible(session2);
-          roResource.end(xid1, XAResource.TMSUSPEND);
-
-          // Check micro-commit visible to current-phase
-          assertChangeVisible(session1);
-          session1.setAutoCommit(true);
-
-          // Check original phase unaffected
-          roResource.start(xid1, XAResource.TMRESUME);
-          assertChangeNotVisible(session2);
-          roResource.end(xid1, XAResource.TMSUSPEND);
-
-          // Check pre-commit phase unaffected
-          roResource.start(xid2, XAResource.TMRESUME);
-          assertChangeNotVisible(session2);
-          roResource.end(xid2, XAResource.TMSUSPEND);
-
-          // Check committed phase is now updated and write-lock available
-          rwResource.start(xid3, XAResource.TMNOFLAGS);
-          assertChangeVisible(session2);
-          
-          // Check internal transaction read-only
-          assertChangeVisible(session1);
-
-          // Cleanup transactions.
-          rwResource.end(xid3, XAResource.TMSUCCESS);
-          roResource.end(xid2, XAResource.TMSUCCESS);
-          roResource.end(xid1, XAResource.TMSUCCESS);
-          roResource.commit(xid1, true);
-          roResource.commit(xid2, true);
-          rwResource.commit(xid3, true);
-
-          // Cleanup database (check write-lock available again)
-          session1.removeModel(model3URI);
-        } finally {
-          session2.close();
-        }
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  private void assertChangeVisible(Session session) throws Exception {
-    // Evaluate the query
-    Answer answer = session.query(createQuery(model3URI));
-
-    compareResults(expectedResults(), answer);
-    answer.close();
-  }
-
-  private void assertChangeNotVisible(Session session) throws Exception {
-    // Evaluate the query
-    Answer answer = session.query(createQuery(model3URI));
-    answer.beforeFirst();
-    assertFalse(answer.next());
-    answer.close();
-  }
-
-  //
-  // Test two simultaneous, explicit transactions, in two threads. The second one should block
-  // until the first one sets auto-commit back to true.
-  //
-  public void testConcurrentExplicitTxn() throws URISyntaxException {
-    logger.info("testConcurrentExplicitTxn");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        XAResource resource1 = session1.getXAResource();
-        resource1.start(new TestXid(1), XAResource.TMNOFLAGS);
-        session1.createModel(model3URI, null);
-        resource1.end(new TestXid(1), XAResource.TMSUCCESS);
-        resource1.commit(new TestXid(1), true);
-
-        resource1.start(new TestXid(2), XAResource.TMNOFLAGS);
-        session1.setModel(model3URI, new GraphResource(fileURI));
-
-        final boolean[] tx2Started = new boolean[] { false };
-
-        Thread t2 = new Thread("tx2Test") {
-          public void run() {
-            try {
-              Session session2 = database.newSession();
-              XAResource resource2 = session2.getXAResource();
-              try {
-                resource2.start(new TestXid(3), XAResource.TMNOFLAGS);
-
-                synchronized (tx2Started) {
-                  tx2Started[0] = true;
-                  tx2Started.notify();
-                }
-
-                // Evaluate the query
-                Answer answer = session2.query(createQuery(model3URI));
-
-                compareResults(expectedResults(), answer);
-                answer.close();
-
-                resource2.end(new TestXid(3), XAResource.TMSUCCESS);
-                resource2.commit(new TestXid(3), true);
-              } finally {
-                session2.close();
-              }
-            } catch (Exception e) {
-              fail(e);
-            }
-          }
-        };
-        t2.start();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        resource1.commit(new TestXid(2), true);
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-            assertTrue("second transaction should've started", tx2Started[0]);
-          }
-        }
-
-        try {
-          t2.join(2000L);
-        } catch (InterruptedException ie) {
-          logger.error("wait for tx2-terminated interrupted", ie);
-          fail(ie);
-        }
-        assertFalse("second transaction should've terminated", t2.isAlive());
-
-        resource1.start(new TestXid(4), XAResource.TMNOFLAGS);
-        session1.removeModel(model3URI);
-        resource1.end(new TestXid(4), XAResource.TMSUCCESS);
-        resource1.commit(new TestXid(4), true);
-
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  //*
-  // Test two simultaneous transactions, in two threads. The second one should block
-  // until the first one sets auto-commit back to true.
-  ///
-  public void testExternalInternalConcurrentTxn() throws URISyntaxException {
-    logger.info("testExternalInternalConcurrentTxn");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        XAResource resource1 = session1.getXAResource();
-        resource1.start(new TestXid(1), XAResource.TMNOFLAGS);
-        session1.createModel(model3URI, null);
-        resource1.end(new TestXid(1), XAResource.TMSUCCESS);
-        resource1.commit(new TestXid(1), true);
-
-        resource1.start(new TestXid(2), XAResource.TMNOFLAGS);
-        session1.setModel(model3URI, new GraphResource(fileURI));
-
-        final boolean[] tx2Started = new boolean[] { false };
-
-        Thread t2 = new Thread("tx2Test") {
-          public void run() {
-            try {
-              Session session2 = database.newSession();
-              try {
-                session2.setAutoCommit(false);
-
-                synchronized (tx2Started) {
-                  tx2Started[0] = true;
-                  tx2Started.notify();
-                }
-
-                // Evaluate the query
-                Answer answer = session2.query(createQuery(model3URI));
-
-                compareResults(expectedResults(), answer);
-                answer.close();
-
-                session2.setAutoCommit(true);
-              } finally {
-                session2.close();
-              }
-            } catch (Exception e) {
-              fail(e);
-            }
-          }
-        };
-        t2.start();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        resource1.commit(new TestXid(2), true);
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-            assertTrue("second transaction should've started", tx2Started[0]);
-          }
-        }
-
-        try {
-          t2.join(2000L);
-        } catch (InterruptedException ie) {
-          logger.error("wait for tx2-terminated interrupted", ie);
-          fail(ie);
-        }
-        assertFalse("second transaction should've terminated", t2.isAlive());
-
-        resource1.start(new TestXid(4), XAResource.TMNOFLAGS);
-        session1.removeModel(model3URI);
-        resource1.end(new TestXid(4), XAResource.TMSUCCESS);
-        resource1.commit(new TestXid(4), true);
-
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-
-  //*
-  // Test two simultaneous transactions, in two threads. The second one should block
-  // until the first one sets auto-commit back to true.
-  ///
-  public void testInternalExternalConcurrentTxn() throws URISyntaxException {
-    logger.info("testInternalExternalConcurrentTxn");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        session1.createModel(model3URI, null);
-
-        session1.setAutoCommit(false);
-        session1.setModel(model3URI, new GraphResource(fileURI));
-
-        final boolean[] tx2Started = new boolean[] { false };
-
-        Thread t2 = new Thread("tx2Test") {
-          public void run() {
-            try {
-              Session session2 = database.newSession();
-              try {
-                XAResource resource = session2.getXAResource();
-                resource.start(new TestXid(1), XAResource.TMNOFLAGS);
-
-                synchronized (tx2Started) {
-                  tx2Started[0] = true;
-                  tx2Started.notify();
-                }
-
-                // Evaluate the query
-                Answer answer = session2.query(createQuery(model3URI));
-
-                compareResults(expectedResults(), answer);
-                answer.close();
-
-                resource.end(new TestXid(1), XAResource.TMSUCCESS);
-                resource.rollback(new TestXid(1));
-              } finally {
-                session2.close();
-              }
-            } catch (Exception e) {
-              fail(e);
-            }
-          }
-        };
-        t2.start();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        session1.commit();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        session1.setAutoCommit(true);
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-            assertTrue("second transaction should've started", tx2Started[0]);
-          }
-        }
-
-        try {
-          t2.join(2000L);
-        } catch (InterruptedException ie) {
-          logger.error("wait for tx2-terminated interrupted", ie);
-          fail(ie);
-        }
-        assertFalse("second transaction should've terminated", t2.isAlive());
-
-        session1.removeModel(model3URI);
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  //*
-  // Test two simultaneous transactions, in two threads. The second one should block
-  // until the first one sets auto-commit back to true.
-  ///
-  public void testExternalInternalConcurrentTxnRollback() throws URISyntaxException {
-    logger.info("testExternalInternalConcurrentTxnRollback");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        XAResource resource1 = session1.getXAResource();
-        resource1.start(new TestXid(1), XAResource.TMNOFLAGS);
-        session1.createModel(model3URI, null);
-        resource1.end(new TestXid(1), XAResource.TMSUCCESS);
-        resource1.commit(new TestXid(1), true);
-
-        resource1.start(new TestXid(2), XAResource.TMNOFLAGS);
-        session1.setModel(model3URI, new GraphResource(fileURI));
-
-        final boolean[] tx2Started = new boolean[] { false };
-
-        Thread t2 = new Thread("tx2Test") {
-          public void run() {
-            try {
-              Session session2 = database.newSession();
-              try {
-                session2.setAutoCommit(false);
-
-                synchronized (tx2Started) {
-                  tx2Started[0] = true;
-                  tx2Started.notify();
-                }
-
-                // Evaluate the query
-                Answer answer = session2.query(createQuery(model3URI));
-
-                answer.beforeFirst();
-                assertFalse(answer.next());
-                answer.close();
-
-                session2.setAutoCommit(true);
-              } finally {
-                session2.close();
-              }
-            } catch (Exception e) {
-              fail(e);
-            }
-          }
-        };
-        t2.start();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        resource1.rollback(new TestXid(2));
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-            assertTrue("second transaction should've started", tx2Started[0]);
-          }
-        }
-
-        try {
-          t2.join(2000L);
-        } catch (InterruptedException ie) {
-          logger.error("wait for tx2-terminated interrupted", ie);
-          fail(ie);
-        }
-        assertFalse("second transaction should've terminated", t2.isAlive());
-
-        resource1.start(new TestXid(4), XAResource.TMNOFLAGS);
-        session1.removeModel(model3URI);
-        resource1.end(new TestXid(4), XAResource.TMSUCCESS);
-        resource1.commit(new TestXid(4), true);
-
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-
-  //*
-  // Test two simultaneous transactions, in two threads. The second one should block
-  // until the first one sets auto-commit back to true.
-  ///
-  public void testInternalExternalConcurrentTxnRollback() throws URISyntaxException {
-    logger.info("testInternalExternalConcurrentTxnRollback");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session1 = database.newSession();
-      try {
-        session1.createModel(model3URI, null);
-
-        session1.setAutoCommit(false);
-        session1.setModel(model3URI, new GraphResource(fileURI));
-
-        final boolean[] tx2Started = new boolean[] { false };
-
-        Thread t2 = new Thread("tx2Test") {
-          public void run() {
-            try {
-              Session session2 = database.newSession();
-              try {
-                XAResource resource = session2.getXAResource();
-                resource.start(new TestXid(1), XAResource.TMNOFLAGS);
-
-                synchronized (tx2Started) {
-                  tx2Started[0] = true;
-                  tx2Started.notify();
-                }
-
-                // Evaluate the query
-                Answer answer = session2.query(createQuery(model3URI));
-
-                answer.beforeFirst();
-                assertFalse(answer.next());
-                answer.close();
-
-                resource.end(new TestXid(1), XAResource.TMFAIL);
-                resource.rollback(new TestXid(1));
-              } finally {
-                session2.close();
-              }
-            } catch (Exception e) {
-              fail(e);
-            }
-          }
-        };
-        t2.start();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        session1.rollback();
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-          }
-          assertFalse("second transaction should still be waiting for write lock", tx2Started[0]);
-        }
-
-        session1.setAutoCommit(true);
-
-        synchronized (tx2Started) {
-          if (!tx2Started[0]) {
-            try {
-              tx2Started.wait(2000L);
-            } catch (InterruptedException ie) {
-              logger.error("wait for tx2-started interrupted", ie);
-              fail(ie);
-            }
-            assertTrue("second transaction should've started", tx2Started[0]);
-          }
-        }
-
-        try {
-          t2.join(2000L);
-        } catch (InterruptedException ie) {
-          logger.error("wait for tx2-terminated interrupted", ie);
-          fail(ie);
-        }
-        assertFalse("second transaction should've terminated", t2.isAlive());
-
-        session1.removeModel(model3URI);
-      } finally {
-        session1.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-
-  public void testExplicitRollbackIsolationQuery() throws URISyntaxException {
-    logger.info("testExplicitRollbackIsolationQuery");
-    URI fileURI  = new File("data/xatest-model1.rdf").toURI();
-
-    try {
-      Session session = database.newSession();
-      XAResource roResource = session.getReadOnlyXAResource();
-      XAResource rwResource = session.getXAResource();
-      try {
-        rwResource.start(new TestXid(1), XAResource.TMNOFLAGS);
-        session.createModel(model3URI, null);
-        rwResource.end(new TestXid(1), XAResource.TMSUCCESS);
-        rwResource.commit(new TestXid(1), true);
-
-        rwResource.start(new TestXid(2), XAResource.TMNOFLAGS);
-        session.setModel(model3URI, new GraphResource(fileURI));
-        rwResource.end(new TestXid(2), XAResource.TMSUSPEND);
-
-        roResource.start(new TestXid(3), XAResource.TMNOFLAGS);
-
-        // Evaluate the query
-        Answer answer = session.query(createQuery(model3URI));
-        answer.beforeFirst();
-        assertFalse(answer.next());
-        answer.close();
-
-        roResource.end(new TestXid(3), XAResource.TMSUCCESS);
-        roResource.commit(new TestXid(3), true);
-
-        rwResource.end(new TestXid(2), XAResource.TMFAIL);
-        rwResource.rollback(new TestXid(2));
-
-        roResource.start(new TestXid(4), XAResource.TMNOFLAGS);
-        selectList = new ArrayList(3);
-        selectList.add(subjectVariable);
-        selectList.add(predicateVariable);
-        selectList.add(objectVariable);
-
-        // Evaluate the query
-        answer = session.query(createQuery(model3URI));
-
-        answer.beforeFirst();
-        assertFalse(answer.next());
-        answer.close();
-
-        roResource.end(new TestXid(4), XAResource.TMFAIL);
-        roResource.rollback(new TestXid(4));
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-*/
-
-  public void testTrivalImplicit() throws URISyntaxException {
-    logger.info("testTrivialImplicit");
-    try {
-      Session session = sessionFactory.newSession();
-
-      try {
-        session.removeModel(modelURI);
-      } finally {
-        session.close();
-      }
-    } catch (Exception e) {
-      fail(e);
-    }
-  }
-
-  //
-  // Internal methods
-  //
-
-  private Query createQuery(URI model) {
-    Variable subjectVariable   = new Variable("subject");
-    Variable predicateVariable = new Variable("predicate");
-    Variable objectVariable    = new Variable("object");
-
-    List<SelectElement> selectList = new ArrayList<SelectElement>(3);
-    selectList.add(subjectVariable);
-    selectList.add(predicateVariable);
-    selectList.add(objectVariable);
-
-    return new Query(
-      selectList,                                       // SELECT
-      new GraphResource(model),                         // FROM
-      new ConstraintImpl(subjectVariable,               // WHERE
-                     predicateVariable,
-                     objectVariable),
-      null,                                             // HAVING
-      Arrays.asList(new Order[] {                       // ORDER BY
-        new Order(subjectVariable, true),
-        new Order(predicateVariable, true),
-        new Order(objectVariable, true)
-      }),
-      null,                                             // LIMIT
-      0,                                                // OFFSET
-      true,                                             // DISTINCT
-      new UnconstrainedAnswer()                         // GIVEN
-    );
-  }
-
-  private String[][] expectedResults() {
-    return new String[][] {
-          { "test:s01", "test:p01", "test:o01" },
-          { "test:s01", "test:p02", "test:o01" },
-          { "test:s01", "test:p02", "test:o02" },
-          { "test:s01", "test:p03", "test:o02" },
-          { "test:s02", "test:p03", "test:o02" },
-          { "test:s02", "test:p04", "test:o02" },
-          { "test:s02", "test:p04", "test:o03" },
-          { "test:s02", "test:p05", "test:o03" },
-          { "test:s03", "test:p01", "test:o01" },
-          { "test:s03", "test:p05", "test:o03" },
-          { "test:s03", "test:p06", "test:o01" },
-          { "test:s03", "test:p06", "test:o03" },
-        };
-  }
-
-  private void compareResults(String[][] expected, Answer answer) throws Exception {
-    try {
-      answer.beforeFirst();
-      for (int i = 0; i < expected.length; i++) {
-        assertTrue("Answer short at row " + i, answer.next());
-        assertEquals(expected[i].length, answer.getNumberOfVariables());
-        for (int j = 0; j < expected[i].length; j++) {
-          URIReferenceImpl uri = new URIReferenceImpl(new URI(expected[i][j]));
-          assertEquals(uri, answer.getObject(j));
-        }
-      }
-      assertFalse(answer.next());
-    } catch (Exception e) {
-      logger.info("Failed test - " + answer);
-      answer.close();
-      throw e;
-    }
-  }
-
-  private void compareResults(Answer answer1, Answer answer2) throws Exception {
-    answer1.beforeFirst();
-    answer2.beforeFirst();
-    assertEquals(answer1.getNumberOfVariables(), answer2.getNumberOfVariables());
-    while (answer1.next()) {
-      assertTrue(answer2.next());
-      for (int i = 0; i < answer1.getNumberOfVariables(); i++) {
-        assertEquals(answer1.getObject(i), answer2.getObject(i));
-      }
-    }
-    assertFalse(answer2.next());
-  }
-
-  /**
-   * Fail with an unexpected exception
-   */
-  private void fail(Throwable throwable) {
-    StringWriter stringWriter = new StringWriter();
-    throwable.printStackTrace(new PrintWriter(stringWriter));
-    fail(stringWriter.toString());
-  }
-
-  @SuppressWarnings("unused")
-  private static class DummyXAResource implements XAResource {
-    public void end(Xid xid, int flags) throws XAException {}
-    public void forget(Xid xid) throws XAException {}
-    public int getTransactionTimeout() throws XAException { return 0; }
-    public int prepare(Xid xid) throws XAException { return 0; }
-    public Xid[] recover(int flag) throws XAException { return new Xid[] {}; }
-    public void rollback(Xid xid) throws XAException {}
-    public boolean setTransactionTimeout(int seconds) throws XAException { return false; }
-    public void start(Xid xid, int flags) throws XAException {}
-    public void commit(Xid xid, boolean twophase) throws XAException {}
-    public boolean isSameRM(XAResource xa) { return xa == this; }
-  }
-}

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/NTriples.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/NTriples.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/NTriples.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -267,8 +267,9 @@
             .append('"');
 
       // Language code
-      if (literal.getLanguage() != null && literal.getLanguage() != "") {
-        buffer.append('@').append(literal.getLanguage());
+      String lang = literal.getLanguage();
+      if (lang != null && !lang.equals("")) {
+        buffer.append('@').append(lang);
       }
 
       // Datatype URI

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/RestoreOperation.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/RestoreOperation.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/RestoreOperation.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -164,7 +164,7 @@
       DatabaseMetadata metadata, BufferedReader br
   ) throws Exception {
     // Check the header of the backup file.
-    String line = br.readLine();
+    String line = readLine(br);
     if (line == null || !line.startsWith(BACKUP_FILE_HEADER)) {
       throw new QueryException("Not a backup file");
     }
@@ -200,14 +200,14 @@
     if (logger.isInfoEnabled()) {
       logger.info(
           "Loading V4 backup " + sourceURI + " which was created on: " +
-          br.readLine()
+          readLine(br)
       );
     }
 
     // Skip to the start of the RDFNODES section.
     String line;
     do {
-      line = br.readLine();
+      line = readLine(br);
       if (line == null) throw new QueryException("Unexpected EOF in header section while restoring from backup file: " + sourceURI);
     } while (!line.equals("RDFNODES"));
 
@@ -261,7 +261,7 @@
       long tksIntModelNode = BackupRestoreSession.NONE;
 
       // Load the strings.
-      while (((line = br.readLine()) != null) && !line.equals("TRIPLES")) {
+      while (((line = readLine(br)) != null) && !line.equals("TRIPLES")) {
         int nrLen = line.indexOf(' ');
         long gNode = Long.parseLong(line.substring(0, nrLen));
         String str = line.substring(nrLen + 1);
@@ -342,7 +342,7 @@
 
       for (;;) {
         try {
-          if ((line = br.readLine()) == null) {
+          if ((line = readLine(br)) == null) {
             throw new QueryException(
                 "Unexpected EOF in TRIPLES section while restoring from " +
                 "backup file: " + sourceURI
@@ -518,14 +518,14 @@
     if (logger.isInfoEnabled()) {
       logger.info(
           "Loading V6 backup " + sourceURI + " which was created on: " +
-          br.readLine()
+          readLine(br)
       );
     }
 
     // Skip to the start of the RDFNODES section.
     String line;
     do {
-      line = br.readLine();
+      line = readLine(br);
       if (line == null) throw new QueryException("Unexpected EOF in header section while restoring from backup file: " + sourceURI);
     } while (!line.equals("RDFNODES"));
 
@@ -569,7 +569,7 @@
       SPObjectFactory spof = resolverSession.getSPObjectFactory();
 
       // Load the strings.
-      while (((line = br.readLine()) != null) && !line.equals("TRIPLES")) {
+      while (((line = readLine(br)) != null) && !line.equals("TRIPLES")) {
         int nrLen = line.indexOf(' ');
         long gNode = Long.parseLong(line.substring(0, nrLen));
         String str = line.substring(nrLen + 1);
@@ -593,7 +593,7 @@
       // Load the triples.
       for (;;) {
         try {
-          if ((line = br.readLine()) == null) {
+          if ((line = readLine(br)) == null) {
             throw new QueryException(
                 "Unexpected EOF in TRIPLES section while restoring from " +
                 "backup file: " + sourceURI
@@ -673,7 +673,21 @@
     return newNode;
   }
 
+  /** Need to maintain compatibility with the largest possible items */
+  private static final int MAX_LINE = 3 * org.mulgara.util.io.LMappedBufferedFile.PAGE_SIZE;
+
   /**
+   * A wrapper around the {@link org.mulgara.util.io.IOUtil#readLine(BufferedReader, int)}
+   * utility function, to provide a default buffer size.
+   * @param br The BufferedReader to read the line from.
+   * @return The string read from the reader, representing a line of text.
+   * @throws IOException If there was an exception accessing the stream.
+   */
+  private static final String readLine(BufferedReader br) throws IOException {
+    return org.mulgara.util.io.IOUtil.readLine(br, MAX_LINE);
+  }
+
+  /**
    * @return <code>true</code>
    */
   public boolean isWriteOperation() {

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -36,7 +36,7 @@
 // Locally written packages
 import org.mulgara.query.Variable;
 import org.mulgara.store.nodepool.NodePool;
-import org.mulgara.store.tuples.TestTuples;
+import org.mulgara.store.tuples.MemoryTuples;
 import org.mulgara.store.tuples.Tuples;
 import org.mulgara.store.tuples.TuplesOperations;
 import org.mulgara.store.xa.XAStatementStore;
@@ -182,7 +182,7 @@
    */
   public void testDump() throws Exception {
 
-    TestTuples expected = getDump();
+    MemoryTuples expected = getDump();
 
     Tuples t = store.findTuples(NodePool.NONE, NodePool.NONE, NodePool.NONE, NodePool.NONE);
     Tuples r = TuplesOperations.project(t, Arrays.asList(StatementStore.VARIABLES), true);
@@ -222,7 +222,7 @@
    */
   public void testFindTriplesByNode0() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars =
         new Variable[] {StatementStore.VARIABLES[1], StatementStore.VARIABLES[2], StatementStore.VARIABLES[3]};
     add(expected, vars, new long[] {2, 3, 1});
@@ -240,7 +240,7 @@
       expected.close();
     }
 
-    expected = new TestTuples();
+    expected = new MemoryTuples();
     add(expected, vars, new long[] {5, 6, 2});
 
     Tuples t = store.findTuples(2, NodePool.NONE, NodePool.NONE, NodePool.NONE);
@@ -257,7 +257,7 @@
    */
   public void testFindTriplesByNode1() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[2], StatementStore.VARIABLES[0], StatementStore.VARIABLES[3]};
     add(expected, vars, new long[] {3, 1, 1});
     add(expected, vars, new long[] {4, 1, 2});
@@ -279,7 +279,7 @@
    */
   public void testFindTriplesByNode2() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[0], StatementStore.VARIABLES[1], StatementStore.VARIABLES[3]};
     add(expected, vars, new long[] {1, 2, 1});
 
@@ -300,7 +300,7 @@
    */
   public void testFindTriplesByNode3() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[0], StatementStore.VARIABLES[1], StatementStore.VARIABLES[2]};
     add(expected, vars, new long[] {1, 2, 4});
     add(expected, vars, new long[] {2, 5, 6});
@@ -316,7 +316,7 @@
    */
   public void testFindTriplesByNode01() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[2], StatementStore.VARIABLES[3]};
     add(expected, vars, new long[] {3, 1});
     add(expected, vars, new long[] {4, 2});
@@ -340,7 +340,7 @@
    */
   public void testFindTriplesByNode02() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[1], StatementStore.VARIABLES[3]};
     add(expected, vars, new long[] {2, 1});
 
@@ -363,7 +363,7 @@
    */
   public void testFindTriplesByNode03() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[1], StatementStore.VARIABLES[2]};
     add(expected, vars, new long[] {2, 4});
 
@@ -378,7 +378,7 @@
    */
   public void testFindTriplesByNode12() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[0], StatementStore.VARIABLES[3]};
     add(expected, vars, new long[] {1, 1});
 
@@ -401,7 +401,7 @@
    */
   public void testFindTriplesByNode13() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[2], StatementStore.VARIABLES[0]};
     add(expected, vars, new long[] {4, 1});
 
@@ -416,7 +416,7 @@
    */
   public void testFindTriplesByNode23() throws Exception {
 
-    TestTuples expected = new TestTuples();
+    MemoryTuples expected = new MemoryTuples();
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[0], StatementStore.VARIABLES[1]};
     add(expected, vars, new long[] {2, 5});
 
@@ -431,7 +431,7 @@
    */
   public void testFindTriplesByNode013() throws Exception {
 
-    TestTuples expected = new TestTuples(StatementStore.VARIABLES[2]);
+    MemoryTuples expected = new MemoryTuples(StatementStore.VARIABLES[2]);
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[2]};
     Tuples t = store.findTuples(2, 6, NodePool.NONE, 1);
     assertEquals(expected, t);
@@ -453,7 +453,7 @@
    */
   public void testFindTriplesByNode023() throws Exception {
 
-    TestTuples expected = new TestTuples(StatementStore.VARIABLES[1]);
+    MemoryTuples expected = new MemoryTuples(StatementStore.VARIABLES[1]);
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[1]};
     Tuples t = store.findTuples(1, NodePool.NONE, 3, 4);
     assertEquals(expected, t);
@@ -471,7 +471,7 @@
    */
   public void testFindTriplesByNode123() throws Exception {
 
-    TestTuples expected = new TestTuples(StatementStore.VARIABLES[0]);
+    MemoryTuples expected = new MemoryTuples(StatementStore.VARIABLES[0]);
     Variable[] vars = new Variable[] {StatementStore.VARIABLES[0]};
     Tuples t = store.findTuples(NodePool.NONE, 2, 3, 4);
     assertEquals(expected, t);
@@ -502,9 +502,9 @@
 
   /**
    * Return a dump of all tuples, sorted by the primary index.
-   * @return a new TestTuples containing all the {@link #setUp()} triples, according to the natural ordering of the store.
+   * @return a new MemoryTuples containing all the {@link #setUp()} triples, according to the natural ordering of the store.
    */
-  protected abstract TestTuples getDump();
+  protected abstract MemoryTuples getDump();
 
   /**
    * Close the test store.
@@ -525,7 +525,7 @@
    * @param vars The column names in the tuples
    * @param nodes The values to bind to
    */
-  protected void add(TestTuples tt, Variable[] vars, long[] nodes) {
+  protected void add(MemoryTuples tt, Variable[] vars, long[] nodes) {
 
     if (vars.length != nodes.length) throw new AssertionError();
 

Modified: trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java
===================================================================
--- trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -39,7 +39,7 @@
 // locally written packages
 import org.mulgara.store.nodepool.*;
 import org.mulgara.store.statement.*;
-import org.mulgara.store.tuples.TestTuples;
+import org.mulgara.store.tuples.MemoryTuples;
 import org.mulgara.util.*;
 
 
@@ -211,8 +211,8 @@
    * Return a dump of all tuples, sorted by the primary index: 0123.
    * @see org.mulgara.store.statement.StatementStoreAbstractUnitTest#getDump()
    */
-  protected TestTuples getDump() {
-    TestTuples expected = new TestTuples();
+  protected MemoryTuples getDump() {
+    MemoryTuples expected = new MemoryTuples();
     add(expected, StatementStore.VARIABLES, new long[] {1, 2, 3, 1});
     add(expected, StatementStore.VARIABLES, new long[] {1, 2, 4, 2});
     add(expected, StatementStore.VARIABLES, new long[] {1, RDF_TYPE, GRAPH_TYPE, SYSTEM_GRAPH});

Modified: trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java
===================================================================
--- trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImplUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -37,7 +37,7 @@
 
 // locally written packages
 import org.mulgara.store.statement.*;
-import org.mulgara.store.tuples.TestTuples;
+import org.mulgara.store.tuples.MemoryTuples;
 import org.mulgara.util.*;
 
 
@@ -152,8 +152,8 @@
    * Return a dump of all tuples, sorted by the primary index: 3012.
    * @see org.mulgara.store.statement.StatementStoreAbstractUnitTest#getDump()
    */
-  protected TestTuples getDump() {
-    TestTuples expected = new TestTuples();
+  protected MemoryTuples getDump() {
+    MemoryTuples expected = new MemoryTuples();
     add(expected, StatementStore.VARIABLES, new long[] {1, 2, 3, 1});
     add(expected, StatementStore.VARIABLES, new long[] {1, 2, 4, 2});
     add(expected, StatementStore.VARIABLES, new long[] {2, 5, 6, 2});

Modified: trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolution.java
===================================================================
--- trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolution.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolution.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -74,9 +74,9 @@
   /** The constraint this instance resolves */
   private final TestConstraint constraint;
 
-  private static Map tests = new HashMap();
+  private static Map<String,Tuples> tests = new HashMap<String,Tuples>();
 
-  private Set mandatoryBindings;
+  private Set<Variable> mandatoryBindings;
   private boolean nullAnnotation;
 
   static void initializeResults(ResolverFactoryInitializer initializer) {
@@ -122,7 +122,7 @@
       logger.debug("result = " + result + " from " + tests);
     }
 
-    mandatoryBindings = new HashSet();
+    mandatoryBindings = new HashSet<Variable>();
     String bindingString = this.constraint.getTestParam();
     Variable[] variables = result.getVariables();
     nullAnnotation = false;
@@ -168,7 +168,7 @@
     super.beforeFirst(prefix, suffixTruncation);
   }
 
-  public Annotation getAnnotation(Class annotationClass) throws TuplesException {
+  public Annotation getAnnotation(Class<? extends Annotation> annotationClass) throws TuplesException {
     if (annotationClass.equals(MandatoryBindingAnnotation.class) && !nullAnnotation) {
       return new MandatoryBindingAnnotation(mandatoryBindings);
     }

Modified: trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java
===================================================================
--- trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolver.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -37,20 +37,14 @@
 
 // Java 2 standard packages;
 import java.net.*;
-import java.util.*;
 
 // Third party packages
 import org.apache.log4j.Logger;
 import javax.transaction.xa.XAResource;
 
 // Locally written packages
-import org.mulgara.content.Content;
 import org.mulgara.query.*;
 import org.mulgara.resolver.spi.*;
-import org.mulgara.store.stringpool.*;
-import org.mulgara.store.stringpool.SPObject.TypeCategory;
-import org.mulgara.store.tuples.Tuples;
-import org.mulgara.store.tuples.TuplesOperations;
 
 /**
  * @created 2005-05-03
@@ -65,13 +59,13 @@
 public class TestResolver implements Resolver {
 
   /** Logger */
+  @SuppressWarnings("unused")
   private static Logger logger = Logger.getLogger(TestResolver.class);
 
   /** The session that this resolver is associated with */
+  @SuppressWarnings("unused")
   private final ResolverSession resolverSession;
 
-  private URI testModelTypeURI;
-
   /**
    * Construct a local query.
    *

Modified: trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerPageImplUnitTest.java
===================================================================
--- trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerPageImplUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/server-rmi/java/org/mulgara/server/rmi/AnswerPageImplUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -42,7 +42,7 @@
 import org.mulgara.query.*;
 import org.mulgara.query.rdf.LiteralImpl;
 import org.mulgara.util.ResultSetRow;
-import org.mulgara.util.TestResultSet;
+import org.mulgara.util.MemoryResultSet;
 
 /**
  * Purpose: Test case for {@link AnswerPage}.

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/DifferenceUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -126,12 +126,12 @@
   public void testNoCommonVars() throws Exception {
 
     Tuples lhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(x, 1).and(y, 2)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(x, 1).and(y, 2)
         .or(x, 3).and(y,
         4));
 
     Tuples rhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(z, 5).and(w, 6)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(z, 5).and(w, 6)
         .or(z, 7).and(w,
         8));
 

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuplesUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuplesUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/DistinctTuplesUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -117,24 +117,24 @@
 
     Variable x = new Variable("x");
 
-    assertEquals(new TestTuples(TuplesOperations.empty()),
-        new TestTuples(TuplesOperations.removeDuplicates(TuplesOperations.empty())));
+    assertEquals(new MemoryTuples(TuplesOperations.empty()),
+        new MemoryTuples(TuplesOperations.removeDuplicates(TuplesOperations.empty())));
 
-    assertEquals(new TestTuples(TuplesOperations.unconstrained()),
-        new TestTuples(TuplesOperations.removeDuplicates(
+    assertEquals(new MemoryTuples(TuplesOperations.unconstrained()),
+        new MemoryTuples(TuplesOperations.removeDuplicates(
         TuplesOperations.unconstrained())));
 
-    TestTuples expectedTuples = new TestTuples(x, 2).or(x, 4);
+    MemoryTuples expectedTuples = new MemoryTuples(x, 2).or(x, 4);
 
-    TestTuples test1 = new TestTuples(x,2).or(x,4);
-    TestTuples test2 = new TestTuples(x,2).or(x,2).or(x, 4);
+    MemoryTuples test1 = new MemoryTuples(x,2).or(x,4);
+    MemoryTuples test2 = new MemoryTuples(x,2).or(x,2).or(x, 4);
 
     Tuples undup1 = TuplesOperations.removeDuplicates(test1);
-    assertEquals(expectedTuples, new TestTuples(undup1));
+    assertEquals(expectedTuples, new MemoryTuples(undup1));
     undup1.close();
 
     Tuples undup2 = TuplesOperations.removeDuplicates(test2);
-    assertEquals(expectedTuples, new TestTuples(undup2));
+    assertEquals(expectedTuples, new MemoryTuples(undup2));
     undup2.close();
   }
 }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/EmptyTuples.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -107,7 +107,7 @@
   }
 
   /**
-   * Gets the ColumnValue attribute of the TestTuples object
+   * Gets the ColumnValue attribute of the MemoryTuples object
    *
    * @param column PARAMETER TO DO
    * @return The ColumnValue value

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoinUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoinUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoinUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -108,10 +108,10 @@
   public void testNoCommonVars() throws Exception {
 
     Tuples lhs = TuplesFactory.newInstance().newTuples(
-            new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4));
+            new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4));
 
     Tuples rhs = TuplesFactory.newInstance().newTuples(
-            new TestTuples(z, 5).and(w, 6).or(z, 7).and(w, 8));
+            new MemoryTuples(z, 5).and(w, 6).or(z, 7).and(w, 8));
 
     Tuples tuples = new LeftJoin(lhs, rhs, TRUE, null);
     tuples.beforeFirst();

Copied: trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuples.java (from rev 2032, trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java)
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuples.java	                        (rev 0)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuples.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,428 @@
+/*
+ * 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.*;
+
+// Locally written packages
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.Variable;
+
+/**
+ * {@link Tuples} materialized in memory. Especially convenient for use in test cases.
+ *
+ * @created 2003-01-10
+ *
+ * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
+ *
+ * @version $Revision: 1.9 $
+ *
+ * @modified $Date: 2005/01/05 04:59:10 $
+ *
+ * @maintenanceAuthor $Author: newmana $
+ *
+ * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
+ *
+ * @copyright © 2003 <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 MemoryTuples extends AbstractTuples {
+
+  /**
+   * A tuples with zero rows and zero columns.
+   */
+  static Tuples EMPTY = new MemoryTuples();
+
+  /**
+   * Description of the Field
+   */
+  private int row = 0;
+
+  /**
+   * Description of the Field
+   */
+  private final List<Map<Variable,Long>> termList;
+
+  /**
+   * Description of the Field
+   */
+  private final List<Variable> variableList;
+
+  /**
+   * Description of the Field
+   */
+  private Map<Variable,Long> rowMap = null;
+
+  /**
+   * Description of the Field
+   */
+  private Map<Variable,Long> lastMap = new HashMap<Variable,Long>();
+
+  /**
+   * The number of columns in common for sort order.
+   */
+  private long[] prefix;
+
+  private Tuples tuples;
+
+  /**
+   * Generate an empty expression.
+   */
+  public MemoryTuples() {
+
+    termList = new ArrayList<Map<Variable,Long>>();
+    variableList = new ArrayList<Variable>();
+  }
+
+  /**
+   * Generate a new tuples.
+   *
+   * @param variable Variable variable
+   */
+  public MemoryTuples(Variable variable) {
+
+    this();
+
+    // Add the variables to the list if it doesn't already.
+    if (!variableList.contains(variable)) {
+
+      variableList.add(variable);
+      setVariables(variableList);
+    }
+  }
+
+  /**
+   * Generate a new assignment.
+   *
+   * @param variable PARAMETER TO DO
+   * @param value PARAMETER TO DO
+   */
+  public MemoryTuples(Variable variable, long value) {
+    this();
+    or(variable, value);
+  }
+
+  /**
+   * Copy constructor.
+   *
+   * @param tuples the instance to copy
+   * @throws TuplesException if the <var>tuples</var> can't be read
+   */
+  MemoryTuples(Tuples tuples) throws TuplesException {
+    this();
+
+    Variable[] v = tuples.getVariables();
+    assert v != null;
+    tuples.beforeFirst();
+
+    boolean hasNext = tuples.next();
+
+    while (hasNext) {
+
+      or();
+
+      for (int i = 0; i < v.length; i++) {
+
+        long l = tuples.getColumnValue(i);
+
+        if (l != Tuples.UNBOUND) {
+
+          and(v[i], l);
+        }
+      }
+
+      hasNext = tuples.next();
+    }
+
+    this.tuples = tuples;
+  }
+
+  /**
+   * Clone constructor.
+   *
+   * @param testTuples PARAMETER TO DO
+   */
+  private MemoryTuples(MemoryTuples testTuples) {
+
+    row = testTuples.row;
+    termList = testTuples.termList;
+    variableList = testTuples.variableList;
+
+    if (testTuples.getVariables() != null) {
+
+      setVariables(testTuples.getVariables());
+    }
+
+    rowMap = testTuples.rowMap;
+    lastMap = testTuples.lastMap;
+    this.tuples = null;
+  }
+
+  /**
+   * Test tuples are always materialized as they represent in memory tuples.
+   *
+   * @return always true as test tuples are represented in memory.
+   */
+  public boolean isMaterialized() {
+
+    return true;
+  }
+
+  public List<Tuples> getOperands() {
+    if (tuples != null) {
+      return Collections.singletonList(tuples);
+    } else {
+      return Collections.emptyList();
+    }
+  }
+
+  /**
+   * Gets the ColumnValue attribute of the MemoryTuples object
+   *
+   * @param column PARAMETER TO DO
+   * @return The ColumnValue value
+   * @throws TuplesException EXCEPTION TO DO
+   */
+  public long getColumnValue(int column) throws TuplesException {
+
+    if (rowMap == null) {
+
+      throw new TuplesException("No column values; not on a row");
+    }
+
+    if ( (column < 0) || (column >= variableList.size())) {
+
+      throw new TuplesException("Invalid column: " + column);
+    }
+
+    Long value = (Long) rowMap.get(variableList.get(column));
+
+    return (value == null) ? Tuples.UNBOUND : value.longValue();
+  }
+
+  /**
+   * Gets the RowCount attribute of the MemoryTuples object
+   *
+   * @return The RowCount value
+   */
+  public long getRowCount() {
+    return termList.size();
+  }
+
+  public long getRowUpperBound() {
+    return getRowCount();
+  }
+
+  public long getRowExpectedCount() {
+    return getRowCount();
+  }
+
+  public boolean isEmpty() throws TuplesException {
+    return termList.isEmpty();
+  }
+
+  /**
+  * This method isn't really implemented; it just assumes all columns might be
+  * unbound.
+  * @return <code>true</code>
+  */
+  public boolean isColumnEverUnbound(int column) throws TuplesException {
+
+    return true;
+  }
+
+  /**
+   * Generate a new assignment and conjoin it with the current final term.
+   *
+   * @param variable PARAMETER TO DO
+   * @param value PARAMETER TO DO
+   * @return RETURNED VALUE TO DO
+   */
+  public MemoryTuples and(Variable variable, long value) {
+
+    if (value == Tuples.UNBOUND) {
+
+      // do nothing
+      return this;
+    }
+
+    if (lastMap.containsKey(variable)) {
+
+      throw new IllegalArgumentException(variable + " already assigned!");
+    }
+
+    // Add the variables to the list if it doesn't already.
+    if (!variableList.contains(variable)) {
+
+      variableList.add(variable);
+      setVariables(variableList);
+    }
+
+    assert value != Tuples.UNBOUND;
+    lastMap.put(variable, new Long(value));
+
+    return this;
+  }
+
+  /**
+   * METHOD TO DO
+   *
+   * @param variable PARAMETER TO DO
+   * @param value PARAMETER TO DO
+   * @return RETURNED VALUE TO DO
+   */
+  public MemoryTuples or(Variable variable, long value) {
+
+    return or().and(variable, value);
+  }
+
+  //
+  // Methods implementing Tuples interface
+  //
+
+  /**
+   * METHOD TO DO
+   *
+   * @param prefix PARAMETER TO DO
+   * @param suffixTruncation PARAMETER TO DO
+   * @throws TuplesException EXCEPTION TO DO
+   */
+  public void beforeFirst(long[] prefix,
+      int suffixTruncation) throws TuplesException {
+
+    if (suffixTruncation != 0) {
+
+      throw new TuplesException("Suffix truncation not supported");
+    }
+
+    row = 0;
+    rowMap = null;
+    this.prefix = prefix;
+  }
+
+  /**
+   * METHOD TO DO
+   *
+   * @return RETURNED VALUE TO DO
+   * @throws TuplesException EXCEPTION TO DO
+   */
+  public boolean next() throws TuplesException {
+
+    A:while (advance()) {
+
+      for (int i = 0; i < prefix.length; i++) {
+
+        assert prefix[i] != Tuples.UNBOUND;
+
+        if (prefix[i] != getColumnValue(getColumnIndex(getVariables()[i]))) {
+
+          continue A;
+        }
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
+  public boolean hasNoDuplicates() {
+    return false;
+  }
+
+  //
+  // Methods overriding the Object class
+  //
+
+  /**
+   * METHOD TO DO
+   *
+   * @return RETURNED VALUE TO DO
+   */
+  public Object clone() {
+
+    return new MemoryTuples(this);
+  }
+
+  /**
+   * METHOD TO DO
+   *
+   */
+  public void close() {
+
+    // NO-OP
+  }
+
+  /**
+   * METHOD TO DO
+   *
+   * @return RETURNED VALUE TO DO
+   */
+  public int hashCode() {
+
+    return termList.hashCode();
+  }
+
+  /**
+   * Generate a new assignment and disjoin it as the new final term.
+   *
+   * @return RETURNED VALUE TO DO
+   */
+  private MemoryTuples or() {
+
+    lastMap = new HashMap<Variable,Long>();
+    termList.add(lastMap);
+
+    return this;
+  }
+
+  /**
+   * METHOD TO DO
+   *
+   * @return RETURNED VALUE TO DO
+   */
+  private boolean advance() {
+
+    assert row >= 0;
+    assert row <= termList.size();
+
+    if (row == termList.size()) {
+      rowMap = null;
+      return false;
+    } else {
+      assert row < termList.size();
+      rowMap = (Map<Variable,Long>) termList.get(row);
+      row++;
+
+      return true;
+    }
+  }
+}

Copied: trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesFactory.java (from rev 2032, trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesFactory.java)
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesFactory.java	                        (rev 0)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesFactory.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,81 @@
+/*
+ * 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;
+
+// Locally written packages
+import org.mulgara.query.TuplesException;
+
+/**
+ * Centralizes the generation of {@link MemoryTuples} instances.
+ *
+ * @created 2003-02-03
+ *
+ * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
+ *
+ * @version $Revision: 1.9 $
+ *
+ * @modified $Date: 2005/01/05 04:59:10 $
+ *
+ * @maintenanceAuthor $Author: newmana $
+ *
+ * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
+ *
+ * @copyright © 2003 <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 MemoryTuplesFactory extends TuplesFactory {
+
+  /**
+   * Copy constructor.
+   *
+   * @param tuples an existing instance, whose contents will be copied into the
+   *      new instance
+   * @return a new {@link MemoryTuples} instance
+   * @throws TuplesException EXCEPTION TO DO
+   */
+  public Tuples newTuples(Tuples tuples) throws TuplesException {
+
+    return new MemoryTuples(tuples);
+  }
+
+  /**
+   * METHOD TO DO
+   *
+   * @param tuples PARAMETER TO DO
+   * @param rowComparator PARAMETER TO DO
+   * @return RETURNED VALUE TO DO
+   * @throws TuplesException EXCEPTION TO DO
+   */
+  public Tuples newTuples(Tuples tuples, RowComparator rowComparator)
+    throws TuplesException {
+
+    throw new TuplesException("MemoryTuples doesn't support sorting");
+  }
+}

Copied: trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesUnitTest.java (from rev 2032, trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesUnitTest.java)
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesUnitTest.java	                        (rev 0)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/MemoryTuplesUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,253 @@
+/*
+ * 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.Logger;  // Apache Log4J
+import junit.framework.*;          // JUnit
+
+// Local packages
+import org.mulgara.query.TuplesException;
+import org.mulgara.query.Variable;
+
+/**
+ * Test case for {@link MemoryTuples}.
+ *
+ * @created 2003-01-10
+ *
+ * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
+ *
+ * @version $Revision: 1.9 $
+ *
+ * @modified $Date: 2005/01/05 04:59:10 $
+ *
+ * @maintenanceAuthor $Author: newmana $
+ *
+ * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
+ *
+ * @copyright © 2003 <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 MemoryTuplesUnitTest extends TestCase {
+
+  /** Logger. */
+  @SuppressWarnings("unused")
+  private static final Logger logger = Logger.getLogger(MemoryTuplesUnitTest.class);
+
+  /**
+   * Constructs a new test with the given name.
+   *
+   * @param name the name of the test
+   */
+  public MemoryTuplesUnitTest(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 MemoryTuplesUnitTest("test1equals"));
+    suite.addTest(new MemoryTuplesUnitTest("test2equals"));
+    suite.addTest(new MemoryTuplesUnitTest("test1unequals"));
+    suite.addTest(new MemoryTuplesUnitTest("test2unequals"));
+    suite.addTest(new MemoryTuplesUnitTest("testCtor"));
+
+    return suite;
+  }
+
+  /**
+   * Default text runner.
+   *
+   * @param args The command line arguments
+   */
+  public static void main(String[] args) {
+
+    junit.textui.TestRunner.run(suite());
+  }
+
+  /**
+   * Create test instance.
+   *
+   * @throws Exception EXCEPTION TO DO
+   */
+  public void setUp() throws Exception {
+
+    // null implementation
+  }
+
+  //
+  // Test cases
+  //
+
+  /**
+   * Test {@link MemoryTuples}. When passed a list of zero arguments, the result
+   * of a join should be unconstrained.
+   *
+   * @throws Exception if query fails when it should have succeeded
+   */
+  public void testCtor() throws Exception {
+
+    Variable x = new Variable("x");
+    Variable y = new Variable("y");
+
+    Tuples operand = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
+
+    assertEquals(new HashSet<Variable>(Arrays.asList(new Variable[] {
+        x, y})),
+        new HashSet<Variable>(Arrays.asList(operand.getVariables())));
+
+    try {
+
+      operand.getColumnValue(0);
+      fail("Shouldn't be able to get a value before first row");
+    }
+    catch (TuplesException e) {
+
+      // correct behavior
+    }
+
+    operand.beforeFirst();
+    assertTrue(operand.next());
+    assertEquals(1, operand.getColumnValue(0));
+    assertEquals(2, operand.getColumnValue(1));
+
+    try {
+
+      operand.getColumnValue( -1);
+      fail("Shouldn't be able to get a value before first column");
+    }
+    catch (TuplesException e) {
+
+      // correct behavior
+    }
+
+    try {
+
+      operand.getColumnValue(2);
+      fail("Shouldn't be able to get a value after last column");
+    }
+    catch (TuplesException e) {
+
+      // correct behavior
+    }
+
+    assertTrue(operand.next());
+    assertEquals(3, operand.getColumnValue(0));
+    assertEquals(4, operand.getColumnValue(1));
+
+    assertTrue(!operand.next());
+
+    try {
+
+      operand.getColumnValue(0);
+      fail("Shouldn't be able to get a value after last row");
+    }
+    catch (TuplesException e) {
+
+      // correct behavior
+    }
+  }
+
+  /**
+   * A unit test for JUnit
+   *
+   * @throws Exception EXCEPTION TO DO
+   */
+  public void test1equals() throws Exception {
+
+    Variable x = new Variable("x");
+    Variable y = new Variable("y");
+
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
+    Tuples rhs = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
+
+    assertEquals(lhs, rhs);
+  }
+
+  /**
+   * A unit test for JUnit
+   *
+   * @throws Exception EXCEPTION TO DO
+   */
+  public void test2equals() throws Exception {
+
+    Variable x = new Variable("x");
+    Variable y = new Variable("y");
+
+    Tuples lhs = new MemoryTuples(x, 1).or(x, 3).and(y, 4);
+    Tuples rhs = new MemoryTuples(x, 1).or(x, 3).and(y, 4);
+
+    assertEquals(lhs, rhs);
+  }
+
+  /**
+   * A unit test for JUnit
+   *
+   * @throws Exception EXCEPTION TO DO
+   */
+  public void test1unequals() throws Exception {
+
+    Variable x = new Variable("x");
+    Variable y = new Variable("y");
+
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 3).or(x, 2).and(y, 4);
+    Tuples rhs = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
+
+    assertTrue("Tuples: " + lhs + " and " + rhs + " should be unequal",
+        !lhs.equals(rhs));
+  }
+
+  /**
+   * A unit test for JUnit
+   *
+   * @throws Exception EXCEPTION TO DO
+   */
+  public void test2unequals() throws Exception {
+
+    Variable x = new Variable("x");
+    Variable y = new Variable("y");
+    Variable z = new Variable("z");
+
+    Tuples lhs = new MemoryTuples(x, 1).or(x, 3).and(y, 4).or(z, 5);
+    Tuples rhs = new MemoryTuples(x, 1).or(x, 3).and(y, 4).or(z, 4);
+
+    assertTrue("Tuples: " + lhs + " and " + rhs + " should be unequal",
+        !lhs.equals(rhs));
+  }
+}

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppendUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppendUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedAppendUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -102,15 +102,15 @@
      {
     Variable x = new Variable("x");
     Variable y = new Variable("y");
-    Tuples lhs = new TestTuples(x, 1).and(y, Tuples.UNBOUND)
+    Tuples lhs = new MemoryTuples(x, 1).and(y, Tuples.UNBOUND)
                             .or(x, 3);
-    Tuples rhs = new TestTuples(x, 2).and(y, 6)
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6)
                             .or(x, 4).and(y, 5);
-    assertEquals(new TestTuples(x, 1)
+    assertEquals(new MemoryTuples(x, 1)
                             .or(x, 2).and(y, 6)
                             .or(x, 3)
                             .or(x, 4).and(y, 5),
-                 new TestTuples(new OrderedAppend(new Tuples[] {lhs, rhs})));
+                 new MemoryTuples(new OrderedAppend(new Tuples[] {lhs, rhs})));
      }
    */
 
@@ -147,7 +147,7 @@
   public void testZeroOperands() throws Exception {
 
     Tuples appendedTuples = new OrderedAppend(new Tuples[] {});
-    assertEquals(new TestTuples(), new TestTuples(appendedTuples));
+    assertEquals(new MemoryTuples(), new MemoryTuples(appendedTuples));
   }
 
   /**
@@ -161,12 +161,12 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples operand = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
+    Tuples operand = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
 
     Tuples appendedTuples = new OrderedAppend(new Tuples[] {
         operand});
 
-    Tuples test = new TestTuples(appendedTuples);
+    Tuples test = new MemoryTuples(appendedTuples);
     assertEquals(operand, test);
 
     operand.close();
@@ -185,14 +185,14 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
 
-    Tuples rhs = new TestTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
 
-    Tuples std = new TestTuples(x, 1).and(y, 8).or(x, 2).and(y, 6).or(x, 3)
+    Tuples std = new MemoryTuples(x, 1).and(y, 8).or(x, 2).and(y, 6).or(x, 3)
         .and(y, 7).or(x, 4).and(y, 5);
     Tuples test = new OrderedAppend(new Tuples[] {lhs, rhs});
-    Tuples wrapper = new TestTuples(test);
+    Tuples wrapper = new MemoryTuples(test);
 
     assertEquals(std, wrapper);
 
@@ -215,14 +215,14 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3);
 
-    Tuples rhs = new TestTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
 
-    Tuples std = new TestTuples(x, 1).and(y, 8).or(x, 2).and(y, 6).or(x, 3)
+    Tuples std = new MemoryTuples(x, 1).and(y, 8).or(x, 2).and(y, 6).or(x, 3)
         .or(x, 4).and(y, 5);
     Tuples test = new OrderedAppend(new Tuples[] {lhs, rhs});
-    Tuples wrapper = new TestTuples(test);
+    Tuples wrapper = new MemoryTuples(test);
 
     assertEquals(std, wrapper);
 
@@ -243,13 +243,13 @@
     Variable subject = StatementStore.VARIABLES[0];
     Variable predicate = StatementStore.VARIABLES[1];
 
-    Tuples lhs = new TestTuples(subject, 1).and(predicate, 8).or(subject, 3);
+    Tuples lhs = new MemoryTuples(subject, 1).and(predicate, 8).or(subject, 3);
 
     Tuples rhs =
-        new TestTuples(subject, 2).and(predicate, 6).or(subject,
+        new MemoryTuples(subject, 2).and(predicate, 6).or(subject,
         4).and(predicate, 5);
 
-    Tuples test = new TestTuples(subject, 1).and(predicate, 8).or(subject, 2).
+    Tuples test = new MemoryTuples(subject, 1).and(predicate, 8).or(subject, 2).
             and(predicate, 6).or(subject, 3).or(subject, 4).and(predicate, 5);
 
     assertEquals(
@@ -294,9 +294,9 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
 
-    Tuples rhs = new TestTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
 
     OrderedAppend oa = new OrderedAppend(new Tuples[] {lhs, rhs});
 
@@ -336,9 +336,9 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
 
-    Tuples rhs = new TestTuples();
+    Tuples rhs = new MemoryTuples();
 
     OrderedAppend oa = new OrderedAppend(new Tuples[] {lhs, rhs});
 

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjectionUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjectionUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/OrderedProjectionUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -110,9 +110,9 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    assertEquals(new TestTuples(y, 2).or(y, 4),
-        new TestTuples(
-        new OrderedProjection(new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4),
+    assertEquals(new MemoryTuples(y, 2).or(y, 4),
+        new MemoryTuples(
+        new OrderedProjection(new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4),
         Arrays.asList(new Variable[] {
         y}))));
   }

Deleted: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuples.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,428 +0,0 @@
-/*
- * 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.*;
-
-// Locally written packages
-import org.mulgara.query.TuplesException;
-import org.mulgara.query.Variable;
-
-/**
- * Convenient {@link Tuples} for use in test cases.
- *
- * @created 2003-01-10
- *
- * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
- *
- * @version $Revision: 1.9 $
- *
- * @modified $Date: 2005/01/05 04:59:10 $
- *
- * @maintenanceAuthor $Author: newmana $
- *
- * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
- *
- * @copyright © 2003 <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 TestTuples extends AbstractTuples {
-
-  /**
-   * A tuples with zero rows and zero columns.
-   */
-  static Tuples EMPTY = new TestTuples();
-
-  /**
-   * Description of the Field
-   */
-  private int row = 0;
-
-  /**
-   * Description of the Field
-   */
-  private final List<Map<Variable,Long>> termList;
-
-  /**
-   * Description of the Field
-   */
-  private final List<Variable> variableList;
-
-  /**
-   * Description of the Field
-   */
-  private Map<Variable,Long> rowMap = null;
-
-  /**
-   * Description of the Field
-   */
-  private Map<Variable,Long> lastMap = new HashMap<Variable,Long>();
-
-  /**
-   * The number of columns in common for sort order.
-   */
-  private long[] prefix;
-
-  private Tuples tuples;
-
-  /**
-   * Generate an empty expression.
-   */
-  public TestTuples() {
-
-    termList = new ArrayList<Map<Variable,Long>>();
-    variableList = new ArrayList<Variable>();
-  }
-
-  /**
-   * Generate a new tuples.
-   *
-   * @param variable Variable variable
-   */
-  public TestTuples(Variable variable) {
-
-    this();
-
-    // Add the variables to the list if it doesn't already.
-    if (!variableList.contains(variable)) {
-
-      variableList.add(variable);
-      setVariables(variableList);
-    }
-  }
-
-  /**
-   * Generate a new assignment.
-   *
-   * @param variable PARAMETER TO DO
-   * @param value PARAMETER TO DO
-   */
-  public TestTuples(Variable variable, long value) {
-    this();
-    or(variable, value);
-  }
-
-  /**
-   * Copy constructor.
-   *
-   * @param tuples the instance to copy
-   * @throws TuplesException if the <var>tuples</var> can't be read
-   */
-  TestTuples(Tuples tuples) throws TuplesException {
-    this();
-
-    Variable[] v = tuples.getVariables();
-    assert v != null;
-    tuples.beforeFirst();
-
-    boolean hasNext = tuples.next();
-
-    while (hasNext) {
-
-      or();
-
-      for (int i = 0; i < v.length; i++) {
-
-        long l = tuples.getColumnValue(i);
-
-        if (l != Tuples.UNBOUND) {
-
-          and(v[i], l);
-        }
-      }
-
-      hasNext = tuples.next();
-    }
-
-    this.tuples = tuples;
-  }
-
-  /**
-   * Clone constructor.
-   *
-   * @param testTuples PARAMETER TO DO
-   */
-  private TestTuples(TestTuples testTuples) {
-
-    row = testTuples.row;
-    termList = testTuples.termList;
-    variableList = testTuples.variableList;
-
-    if (testTuples.getVariables() != null) {
-
-      setVariables(testTuples.getVariables());
-    }
-
-    rowMap = testTuples.rowMap;
-    lastMap = testTuples.lastMap;
-    this.tuples = null;
-  }
-
-  /**
-   * Test tuples are always materialized as they represent in memory tuples.
-   *
-   * @return always true as test tuples are represented in memory.
-   */
-  public boolean isMaterialized() {
-
-    return true;
-  }
-
-  public List<Tuples> getOperands() {
-    if (tuples != null) {
-      return Collections.singletonList(tuples);
-    } else {
-      return Collections.emptyList();
-    }
-  }
-
-  /**
-   * Gets the ColumnValue attribute of the TestTuples object
-   *
-   * @param column PARAMETER TO DO
-   * @return The ColumnValue value
-   * @throws TuplesException EXCEPTION TO DO
-   */
-  public long getColumnValue(int column) throws TuplesException {
-
-    if (rowMap == null) {
-
-      throw new TuplesException("No column values; not on a row");
-    }
-
-    if ( (column < 0) || (column >= variableList.size())) {
-
-      throw new TuplesException("Invalid column: " + column);
-    }
-
-    Long value = (Long) rowMap.get(variableList.get(column));
-
-    return (value == null) ? Tuples.UNBOUND : value.longValue();
-  }
-
-  /**
-   * Gets the RowCount attribute of the TestTuples object
-   *
-   * @return The RowCount value
-   */
-  public long getRowCount() {
-    return termList.size();
-  }
-
-  public long getRowUpperBound() {
-    return getRowCount();
-  }
-
-  public long getRowExpectedCount() {
-    return getRowCount();
-  }
-
-  public boolean isEmpty() throws TuplesException {
-    return termList.isEmpty();
-  }
-
-  /**
-  * This method isn't really implemented; it just assumes all columns might be
-  * unbound.
-  * @return <code>true</code>
-  */
-  public boolean isColumnEverUnbound(int column) throws TuplesException {
-
-    return true;
-  }
-
-  /**
-   * Generate a new assignment and conjoin it with the current final term.
-   *
-   * @param variable PARAMETER TO DO
-   * @param value PARAMETER TO DO
-   * @return RETURNED VALUE TO DO
-   */
-  public TestTuples and(Variable variable, long value) {
-
-    if (value == Tuples.UNBOUND) {
-
-      // do nothing
-      return this;
-    }
-
-    if (lastMap.containsKey(variable)) {
-
-      throw new IllegalArgumentException(variable + " already assigned!");
-    }
-
-    // Add the variables to the list if it doesn't already.
-    if (!variableList.contains(variable)) {
-
-      variableList.add(variable);
-      setVariables(variableList);
-    }
-
-    assert value != Tuples.UNBOUND;
-    lastMap.put(variable, new Long(value));
-
-    return this;
-  }
-
-  /**
-   * METHOD TO DO
-   *
-   * @param variable PARAMETER TO DO
-   * @param value PARAMETER TO DO
-   * @return RETURNED VALUE TO DO
-   */
-  public TestTuples or(Variable variable, long value) {
-
-    return or().and(variable, value);
-  }
-
-  //
-  // Methods implementing Tuples interface
-  //
-
-  /**
-   * METHOD TO DO
-   *
-   * @param prefix PARAMETER TO DO
-   * @param suffixTruncation PARAMETER TO DO
-   * @throws TuplesException EXCEPTION TO DO
-   */
-  public void beforeFirst(long[] prefix,
-      int suffixTruncation) throws TuplesException {
-
-    if (suffixTruncation != 0) {
-
-      throw new TuplesException("Suffix truncation not supported");
-    }
-
-    row = 0;
-    rowMap = null;
-    this.prefix = prefix;
-  }
-
-  /**
-   * METHOD TO DO
-   *
-   * @return RETURNED VALUE TO DO
-   * @throws TuplesException EXCEPTION TO DO
-   */
-  public boolean next() throws TuplesException {
-
-    A:while (advance()) {
-
-      for (int i = 0; i < prefix.length; i++) {
-
-        assert prefix[i] != Tuples.UNBOUND;
-
-        if (prefix[i] != getColumnValue(getColumnIndex(getVariables()[i]))) {
-
-          continue A;
-        }
-      }
-
-      return true;
-    }
-
-    return false;
-  }
-
-  public boolean hasNoDuplicates() {
-    return false;
-  }
-
-  //
-  // Methods overriding the Object class
-  //
-
-  /**
-   * METHOD TO DO
-   *
-   * @return RETURNED VALUE TO DO
-   */
-  public Object clone() {
-
-    return new TestTuples(this);
-  }
-
-  /**
-   * METHOD TO DO
-   *
-   */
-  public void close() {
-
-    // NO-OP
-  }
-
-  /**
-   * METHOD TO DO
-   *
-   * @return RETURNED VALUE TO DO
-   */
-  public int hashCode() {
-
-    return termList.hashCode();
-  }
-
-  /**
-   * Generate a new assignment and disjoin it as the new final term.
-   *
-   * @return RETURNED VALUE TO DO
-   */
-  private TestTuples or() {
-
-    lastMap = new HashMap<Variable,Long>();
-    termList.add(lastMap);
-
-    return this;
-  }
-
-  /**
-   * METHOD TO DO
-   *
-   * @return RETURNED VALUE TO DO
-   */
-  private boolean advance() {
-
-    assert row >= 0;
-    assert row <= termList.size();
-
-    if (row == termList.size()) {
-      rowMap = null;
-      return false;
-    } else {
-      assert row < termList.size();
-      rowMap = (Map<Variable,Long>) termList.get(row);
-      row++;
-
-      return true;
-    }
-  }
-}

Deleted: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesFactory.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesFactory.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesFactory.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,81 +0,0 @@
-/*
- * 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;
-
-// Locally written packages
-import org.mulgara.query.TuplesException;
-
-/**
- * Centralizes the generation of {@link TestTuples} instances.
- *
- * @created 2003-02-03
- *
- * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
- *
- * @version $Revision: 1.9 $
- *
- * @modified $Date: 2005/01/05 04:59:10 $
- *
- * @maintenanceAuthor $Author: newmana $
- *
- * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
- *
- * @copyright © 2003 <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 TestTuplesFactory extends TuplesFactory {
-
-  /**
-   * Copy constructor.
-   *
-   * @param tuples an existing instance, whose contents will be copied into the
-   *      new instance
-   * @return a new {@link TestTuples} instance
-   * @throws TuplesException EXCEPTION TO DO
-   */
-  public Tuples newTuples(Tuples tuples) throws TuplesException {
-
-    return new TestTuples(tuples);
-  }
-
-  /**
-   * METHOD TO DO
-   *
-   * @param tuples PARAMETER TO DO
-   * @param rowComparator PARAMETER TO DO
-   * @return RETURNED VALUE TO DO
-   * @throws TuplesException EXCEPTION TO DO
-   */
-  public Tuples newTuples(Tuples tuples, RowComparator rowComparator)
-    throws TuplesException {
-
-    throw new TuplesException("TestTuples doesn't support sorting");
-  }
-}

Deleted: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TestTuplesUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,255 +0,0 @@
-/*
- * 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.net.*;
-import java.util.*;
-
-// Third party packages
-import org.apache.log4j.Logger;  // Apache Log4J
-import junit.framework.*;          // JUnit
-
-// Local packages
-import org.mulgara.query.TuplesException;
-import org.mulgara.query.Variable;
-
-/**
- * Test case for {@link TestTuples}.
- *
- * @created 2003-01-10
- *
- * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
- *
- * @version $Revision: 1.9 $
- *
- * @modified $Date: 2005/01/05 04:59:10 $
- *
- * @maintenanceAuthor $Author: newmana $
- *
- * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
- *
- * @copyright © 2003 <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 TestTuplesUnitTest extends TestCase {
-
-  /**
-   * Logger.
-   */
-  private static final Logger logger = Logger.getLogger(TestTuplesUnitTest.class);
-
-  /**
-   * Constructs a new test with the given name.
-   *
-   * @param name the name of the test
-   */
-  public TestTuplesUnitTest(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 TestTuplesUnitTest("test1equals"));
-    suite.addTest(new TestTuplesUnitTest("test2equals"));
-    suite.addTest(new TestTuplesUnitTest("test1unequals"));
-    suite.addTest(new TestTuplesUnitTest("test2unequals"));
-    suite.addTest(new TestTuplesUnitTest("testCtor"));
-
-    return suite;
-  }
-
-  /**
-   * Default text runner.
-   *
-   * @param args The command line arguments
-   */
-  public static void main(String[] args) {
-
-    junit.textui.TestRunner.run(suite());
-  }
-
-  /**
-   * Create test instance.
-   *
-   * @throws Exception EXCEPTION TO DO
-   */
-  public void setUp() throws Exception {
-
-    // null implementation
-  }
-
-  //
-  // Test cases
-  //
-
-  /**
-   * Test {@link TestTuples}. When passed a list of zero arguments, the result
-   * of a join should be unconstrained.
-   *
-   * @throws Exception if query fails when it should have succeeded
-   */
-  public void testCtor() throws Exception {
-
-    Variable x = new Variable("x");
-    Variable y = new Variable("y");
-
-    Tuples operand = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
-
-    assertEquals(new HashSet(Arrays.asList(new Variable[] {
-        x, y})),
-        new HashSet(Arrays.asList(operand.getVariables())));
-
-    try {
-
-      operand.getColumnValue(0);
-      fail("Shouldn't be able to get a value before first row");
-    }
-    catch (TuplesException e) {
-
-      // correct behavior
-    }
-
-    operand.beforeFirst();
-    assertTrue(operand.next());
-    assertEquals(1, operand.getColumnValue(0));
-    assertEquals(2, operand.getColumnValue(1));
-
-    try {
-
-      operand.getColumnValue( -1);
-      fail("Shouldn't be able to get a value before first column");
-    }
-    catch (TuplesException e) {
-
-      // correct behavior
-    }
-
-    try {
-
-      operand.getColumnValue(2);
-      fail("Shouldn't be able to get a value after last column");
-    }
-    catch (TuplesException e) {
-
-      // correct behavior
-    }
-
-    assertTrue(operand.next());
-    assertEquals(3, operand.getColumnValue(0));
-    assertEquals(4, operand.getColumnValue(1));
-
-    assertTrue(!operand.next());
-
-    try {
-
-      operand.getColumnValue(0);
-      fail("Shouldn't be able to get a value after last row");
-    }
-    catch (TuplesException e) {
-
-      // correct behavior
-    }
-  }
-
-  /**
-   * A unit test for JUnit
-   *
-   * @throws Exception EXCEPTION TO DO
-   */
-  public void test1equals() throws Exception {
-
-    Variable x = new Variable("x");
-    Variable y = new Variable("y");
-
-    Tuples lhs = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
-    Tuples rhs = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
-
-    assertEquals(lhs, rhs);
-  }
-
-  /**
-   * A unit test for JUnit
-   *
-   * @throws Exception EXCEPTION TO DO
-   */
-  public void test2equals() throws Exception {
-
-    Variable x = new Variable("x");
-    Variable y = new Variable("y");
-
-    Tuples lhs = new TestTuples(x, 1).or(x, 3).and(y, 4);
-    Tuples rhs = new TestTuples(x, 1).or(x, 3).and(y, 4);
-
-    assertEquals(lhs, rhs);
-  }
-
-  /**
-   * A unit test for JUnit
-   *
-   * @throws Exception EXCEPTION TO DO
-   */
-  public void test1unequals() throws Exception {
-
-    Variable x = new Variable("x");
-    Variable y = new Variable("y");
-
-    Tuples lhs = new TestTuples(x, 1).and(y, 3).or(x, 2).and(y, 4);
-    Tuples rhs = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
-
-    assertTrue("Tuples: " + lhs + " and " + rhs + " should be unequal",
-        !lhs.equals(rhs));
-  }
-
-  /**
-   * A unit test for JUnit
-   *
-   * @throws Exception EXCEPTION TO DO
-   */
-  public void test2unequals() throws Exception {
-
-    Variable x = new Variable("x");
-    Variable y = new Variable("y");
-    Variable z = new Variable("z");
-
-    Tuples lhs = new TestTuples(x, 1).or(x, 3).and(y, 4).or(z, 5);
-    Tuples rhs = new TestTuples(x, 1).or(x, 3).and(y, 4).or(z, 4);
-
-    assertTrue("Tuples: " + lhs + " and " + rhs + " should be unequal",
-        !lhs.equals(rhs));
-  }
-}

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesFactory.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesFactory.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesFactory.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -79,7 +79,7 @@
           tuplesFactoryClass = "org.mulgara.store.xa.HybridTuplesFactory";
         }
 
-        //"org.mulgara.store.tuples.TestTuplesFactory";
+        //"org.mulgara.store.tuples.MemoryTuplesFactory";
         tuplesFactory =
           (TuplesFactory) Class.forName(tuplesFactoryClass).newInstance();
       }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoinUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoinUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnboundJoinUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -182,7 +182,7 @@
   public void testOneOperand() throws Exception {
 
     Tuples operand =
-        TuplesFactory.newInstance().newTuples(new TestTuples(x, 1).and(y, 2)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(x, 1).and(y, 2)
         .or(x, 3).and(y, 4));
     assert operand != null;
 
@@ -208,11 +208,11 @@
   public void testCartesianDyad() throws Exception {
 
     Tuples lhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(x, 1).and(y, 2)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(x, 1).and(y, 2)
         .or(x, 3).and(y, 4));
 
     Tuples rhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(z, 5).and(w, 6)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(z, 5).and(w, 6)
         .or(z, 7).and(w, 8));
 
     Tuples joined = new UnboundJoin(new Tuples[] {lhs, rhs});
@@ -245,15 +245,15 @@
   public void testCartesianTriad() throws Exception {
 
     Tuples lhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(x, 1).and(y, 2)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(x, 1).and(y, 2)
         .or(x, 3).and(y, 4));
 
     Tuples mhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(z, 5).and(w, 6)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(z, 5).and(w, 6)
         .or(z, 7).and(w, 8));
 
     Tuples rhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(u, 9).and(v, 10)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(u, 9).and(v, 10)
         .or(u, 11).and(v, 12));
 
     Tuples joined = new UnboundJoin(new Tuples[] {lhs, mhs, rhs});
@@ -310,7 +310,7 @@
     rhs.appendTuple(new long[] {2, 5});
     rhs.appendTuple(new long[] {4, 6});
 
-    TuplesFactory.newInstance().newTuples(new TestTuples(y, 2).and(z, 5)
+    TuplesFactory.newInstance().newTuples(new MemoryTuples(y, 2).and(z, 5)
         .or(y, 4).and(z, 6));
 
     UnboundJoin joined = new UnboundJoin(new Tuples[] {lhs, rhs});
@@ -367,7 +367,7 @@
   public void testSuffixJoin() throws Exception {
 
     Tuples lhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(x, 1).and(y, 4)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(x, 1).and(y, 4)
         .or(x, 1)
         .and(y, 5)
         .or(x, 2)
@@ -376,7 +376,7 @@
         7));
 
     Tuples rhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(y, 4).and(x, 1)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(y, 4).and(x, 1)
         .or(y, 6).and(x,
         2));
 
@@ -406,7 +406,7 @@
     Variable f = new Variable("_from");
 
     Tuples lhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(e, 62).and(v, 37)
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(e, 62).and(v, 37)
         .and(f, 36)
         .or(e, 89)
         .and(v, 78)
@@ -419,7 +419,7 @@
         .and(f, 36));
 
     Tuples rhs =
-        TuplesFactory.newInstance().newTuples(new TestTuples(e, 89).and(f, 36));
+        TuplesFactory.newInstance().newTuples(new MemoryTuples(e, 89).and(f, 36));
 
     Tuples actual = new UnboundJoin(new Tuples[] {
         lhs, rhs});

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnconstrainedTuples.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -111,7 +111,7 @@
   }
 
   /**
-   * Gets the ColumnValue attribute of the TestTuples object
+   * Gets the ColumnValue attribute of the MemoryTuples object
    *
    * @param column PARAMETER TO DO
    * @return The ColumnValue value

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppendUnitTest.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppendUnitTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedAppendUnitTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -108,7 +108,7 @@
   public void testZeroOperands() throws Exception {
 
     Tuples appendedTuples = new UnorderedAppend(new Tuples[] {});
-    assertEquals(new TestTuples(), new TestTuples(appendedTuples));
+    assertEquals(new MemoryTuples(), new MemoryTuples(appendedTuples));
   }
 
   /**
@@ -122,12 +122,12 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples operand = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
+    Tuples operand = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);
 
     Tuples appendedTuples = new UnorderedAppend(new Tuples[] {
         operand});
 
-    assertEquals(operand, new TestTuples(appendedTuples));
+    assertEquals(operand, new MemoryTuples(appendedTuples));
   }
 
   /**
@@ -141,13 +141,13 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
 
-    Tuples rhs = new TestTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
 
-    assertEquals(new TestTuples(x, 1).and(y, 8).or(x, 3).and(y, 7).or(x, 2)
+    assertEquals(new MemoryTuples(x, 1).and(y, 8).or(x, 3).and(y, 7).or(x, 2)
         .and(y, 6).or(x, 4).and(y, 5),
-        new TestTuples(new UnorderedAppend(new Tuples[] {
+        new MemoryTuples(new UnorderedAppend(new Tuples[] {
         lhs, rhs})));
   }
 
@@ -163,13 +163,13 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3);
 
-    Tuples rhs = new TestTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
 
-    assertEquals(new TestTuples(x, 1).and(y, 8).or(x, 3).or(x, 2).and(y, 6)
+    assertEquals(new MemoryTuples(x, 1).and(y, 8).or(x, 3).or(x, 2).and(y, 6)
         .or(x, 4).and(y, 5),
-        new TestTuples(new UnorderedAppend(new Tuples[] {
+        new MemoryTuples(new UnorderedAppend(new Tuples[] {
         lhs, rhs})));
   }
 
@@ -187,20 +187,20 @@
     Variable x = new Variable("x");
     Variable y = new Variable("y");
 
-    Tuples operand = new TestTuples(x, 1).and(y, 2);
+    Tuples operand = new MemoryTuples(x, 1).and(y, 2);
     appendedTuples = new UnorderedAppend(new Tuples[] { operand});
     assertEquals(Cursor.ONE, appendedTuples.getRowCardinality());
 
-    operand = new TestTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);;
+    operand = new MemoryTuples(x, 1).and(y, 2).or(x, 3).and(y, 4);;
     appendedTuples = new UnorderedAppend(new Tuples[] { operand});
     assertEquals(Cursor.MANY, appendedTuples.getRowCardinality());
 
-    Tuples lhs = new TestTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
-    Tuples rhs = new TestTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
+    Tuples lhs = new MemoryTuples(x, 1).and(y, 8).or(x, 3).and(y, 7);
+    Tuples rhs = new MemoryTuples(x, 2).and(y, 6).or(x, 4).and(y, 5);
     assertEquals(Cursor.MANY, new UnorderedAppend(new Tuples[] { lhs, rhs}).getRowCardinality());
 
-    lhs = new TestTuples(x, 1).and(y, 8);
-    rhs = new TestTuples(x, 2).and(y, 6);
+    lhs = new MemoryTuples(x, 1).and(y, 8);
+    rhs = new MemoryTuples(x, 2).and(y, 6);
     assertEquals(Cursor.MANY, new UnorderedAppend(new Tuples[] { lhs, rhs}).getRowCardinality());
   }
 

Copied: trunk/src/jar/util/java/org/mulgara/util/BooleanOp.java (from rev 2032, trunk/src/jar/util/java/org/mulgara/util/Tester.java)
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/BooleanOp.java	                        (rev 0)
+++ trunk/src/jar/util/java/org/mulgara/util/BooleanOp.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,29 @@
+/**
+ * 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.util;
+
+/**
+ * Functor interface for testing an object in some arbitrary way.
+ * @created Oct 18, 2007
+ * @author Paul Gearon
+ * @copyright © 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 interface BooleanOp {
+
+  /**
+   * Perform a test on an object, returning <code>true</code> if it passes.
+   * @param o The object to test
+   * @return <code>true</code> for a successful test.
+   */
+  public boolean test(Object o);
+}

Copied: trunk/src/jar/util/java/org/mulgara/util/BooleanOp2.java (from rev 2032, trunk/src/jar/util/java/org/mulgara/util/Tester2.java)
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/BooleanOp2.java	                        (rev 0)
+++ trunk/src/jar/util/java/org/mulgara/util/BooleanOp2.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,30 @@
+/**
+ * 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.util;
+
+/**
+ * Functor interface for testing a pair of objects in some arbitrary way.
+ * @created Oct 18, 2007
+ * @author Paul Gearon
+ * @copyright © 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 interface BooleanOp2 <T1,T2> {
+
+  /**
+   * Perform a test on an a pair of objects, returning <code>true</code> if it passes.
+   * @param o1 The first object to test.
+   * @param o2 The second object to test.
+   * @return <code>true</code> for a successful test.
+   */
+  public boolean test(T1 o1, T2 o2);
+}

Copied: trunk/src/jar/util/java/org/mulgara/util/MemoryResultSet.java (from rev 2032, trunk/src/jar/util/java/org/mulgara/util/TestResultSet.java)
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/MemoryResultSet.java	                        (rev 0)
+++ trunk/src/jar/util/java/org/mulgara/util/MemoryResultSet.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,788 @@
+/*
+ * 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.util;
+
+// Java 2 standard packages
+import java.io.InputStream;
+import java.io.Reader;
+import java.io.Serializable;
+import java.sql.*;
+import java.util.*;
+
+// third party packages
+import org.apache.log4j.Logger;
+
+// Log4J
+
+/**
+ * Implementation of {@link ResultSet} in memory. This is particularly suitable
+ * for generating test cases, though its use is more widespread. It's
+ * not a correct {@link ResultSet} in many respects, the foremost being an
+ * absence of column typing.
+ *
+ * @created 2001-07-12
+ *
+ * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
+ *
+ * @version $Revision: 1.9 $
+ *
+ * @modified $Date: 2005/01/05 04:59:29 $
+ *
+ * @maintenanceAuthor $Author: newmana $
+ *
+ * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
+ *
+ * @copyright © 2001-2003 <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 MemoryResultSet extends AbstractMulgaraResultSet
+  implements Serializable {
+
+ /**
+  * 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.
+  */
+  static final long serialVersionUID = 447953576074487320L;
+
+  /**
+   * Logger.
+   */
+  private static final Logger logger = Logger.getLogger(MemoryResultSet.class);
+
+  /**
+   * The metadata for this result set.
+   */
+  private ResultSetMetaData metaData;
+
+  /**
+   * The rows of the result set.
+   */
+  private List<ResultSetRow> rows = new RowList<ResultSetRow>();
+
+  /**
+   * The current row index.
+   */
+  private int currentRowIndex = 0;
+
+  /**
+   * The current row.
+   */
+  private ResultSetRow currentRow = null;
+
+  //
+  // Constructors
+  //
+
+  /**
+   * Create a result set with named columns and no rows.
+   *
+   * @param newColumnNames the new column names for this result set.
+   * @throws SQLException on failure
+   */
+  public MemoryResultSet(String[] newColumnNames) throws SQLException {
+
+    // FIXME: should validate columnNames, checking for duplicate names, etc
+    // initialize fields
+    columnNames = newColumnNames;
+    metaData = new ResultSetMetaDataImpl(columnNames);
+
+    // move the cursor before the first row
+    beforeFirst();
+  }
+
+  /**
+   * Create a result set with specified metadata and no rows.
+   *
+   * @param metaData PARAMETER TO DO
+   * @throws SQLException on failure
+   */
+  public MemoryResultSet(ResultSetMetaData metaData) throws SQLException {
+
+    initialiseMetaData(metaData);
+
+    // move the cursor before the first row
+    beforeFirst();
+  }
+
+  /**
+   * Create a result set with content copied from an existing result set.
+   *
+   * @param resultSet PARAMETER TO DO
+   * @throws SQLException on failure
+   */
+  public MemoryResultSet(ResultSet resultSet) throws SQLException {
+
+    // Validate "resultSet" parameter
+    if (resultSet == null) {
+      throw new IllegalArgumentException("Null \"resultSet\" parameter");
+    }
+
+    // Copy columns
+    initialiseMetaData(resultSet.getMetaData());
+
+    // Copy rows
+    if (resultSet.getClass() == MemoryResultSet.class) {
+      rows.addAll( ( (MemoryResultSet) resultSet).rows);
+    } else {
+
+      // Don't assume that it hasn't already been read.
+      resultSet.beforeFirst();
+
+      // Repeat until we get all of the items from the result sets.
+      while (resultSet.next()) {
+
+        ResultSetRow row = new ResultSetRow(resultSet);
+
+        for (int i = 0; i < columnNames.length; i++) {
+          row.setObject(columnNames[i], resultSet.getObject(columnNames[i]));
+        }
+
+        addRow(row);
+      }
+    }
+  }
+
+  /**
+   * Overwrites the existing set of rows available.
+   *
+   * @param newRows the new rows to set.
+   * @throws SQLException EXCEPTION TO DO
+   */
+  public void setAllRows(List<ResultSetRow> newRows) throws SQLException {
+    rows = newRows;
+  }
+
+  // next()
+
+  /**
+   * Return the object at the given index.
+   *
+   * @param columnIndex the index of the object to retrieve
+   * @return the value at the given index
+   * @throws SQLException on failure
+   */
+  public Object getObject(int columnIndex) throws SQLException {
+    // throw an error if the current row is invalid
+    if (this.currentRow == null) throw new SQLException("Not on a row.");
+
+    // get the value out of the current row
+    return this.currentRow.getObject(columnIndex);
+  }
+
+  // getObject()
+
+  /**
+   * Return the string at the given index.
+   *
+   * @param columnIndex the index of the string to retrieve
+   * @return the value at the given index (possibly <code>null</code>)
+   * @throws SQLException on failure
+   */
+  public String getString(int columnIndex) throws SQLException {
+
+    // throw an error if the current row is invalid
+    if (this.currentRow == null) throw new SQLException("Not on a row.");
+
+    // get the value out of the current row
+    Object object = this.currentRow.getObject(columnIndex);
+
+    return (object == null) ? null : object.toString();
+  }
+
+  // getString()
+
+  /**
+   * Returns the metadata for this result set.
+   *
+   * @return the metadata for this result set
+   * @throws SQLException on failure
+   */
+  public ResultSetMetaData getMetaData() throws SQLException {
+    return metaData;
+  }
+
+  /**
+   * Returns whether the cursor is before the first row.
+   *
+       * @return true if the cursor is before the first row in the result set, false
+   *      otherwise
+   * @throws SQLException on failure
+   */
+  public boolean isBeforeFirst() throws SQLException {
+    return this.currentRowIndex == 0;
+  }
+
+  /**
+   * Returns true if the cursor is after the last row.
+   *
+   * @return true if the cursor is after the first row in the result set, false
+   *      otherwise
+   * @throws SQLException on failure
+   */
+  public boolean isAfterLast() throws SQLException {
+    return this.currentRowIndex > this.rows.size();
+  }
+
+  /**
+   * Returns true if the cursor is on the first row.
+   *
+   * @return true if the cursor is on the first row, false otherwise
+   * @throws SQLException on failure
+   */
+  public boolean isFirst() throws SQLException {
+    return this.currentRowIndex == 1;
+  }
+
+  /**
+   * Returns true if the cursor is on the last row.
+   *
+   * @return true if the cursor is on the las row, false otherwise
+   * @throws SQLException on failure
+   */
+  public boolean isLast() throws SQLException {
+    return this.currentRowIndex == this.rows.size();
+  }
+
+  /**
+   * Returns the entire rows underlying the result set.
+   *
+   * @return the entire rows underlying the result set.
+   * @throws SQLException EXCEPTION TO DO
+   */
+  public List<ResultSetRow> getAllRows() throws SQLException {
+    return rows;
+  }
+
+  /**
+   * Returns the index of the row the cursor is on.
+   *
+   * @return the index of the row the cursor is on
+   * @throws SQLException on failure
+   */
+  public int getRow() throws SQLException {
+    return this.currentRowIndex;
+  }
+
+  /**
+   * Returns the total size of the number of rows.
+   *
+   * @return the total size of the number of rows available.
+   */
+  public int getTotalRowSize() {
+    return rows.size();
+  }
+
+  /**
+   * Gets the CurrentRow attribute of the MemoryResultSet object
+   *
+   * @return The CurrentRow value
+   */
+  public ResultSetRow getCurrentRow() {
+    return currentRow;
+  }
+
+  //
+  // Methods implementing the ResultSet interface
+  //
+
+  /**
+   * Moves the cursor down one row from its current position.
+   *
+   * @return true if the new current row is valid; false if there are no more
+   *      rows
+   * @throws SQLException on failure
+   */
+  public boolean next() throws SQLException {
+    boolean returnState = false;
+
+    // advance the cursor if we can
+    if (!this.isLast()) {
+
+      this.currentRowIndex++;
+      this.currentRow = (ResultSetRow)this.rows.get(this.currentRowIndex - 1);
+      returnState = true;
+    } else {
+
+      this.currentRow = null;
+      returnState = false;
+    }
+
+    // end if
+    // return
+    return returnState;
+  }
+
+  /**
+   * Moves the cursor to before the first row in the result set.
+   *
+   * @throws SQLException on failure
+   */
+  public void beforeFirst() throws SQLException {
+    // return members to their default state
+    this.currentRowIndex = 0;
+    this.currentRow = null;
+  }
+
+  /**
+   * Moves the cursor to after the last row in the result set.
+   *
+   * @throws SQLException on failure
+   */
+  public void afterLast() throws SQLException {
+    this.currentRowIndex = this.rows.size() + 1;
+    this.currentRow = null;
+  }
+
+  /**
+   * Moves the cursor to the first row in this ResultSet object.
+   *
+   * @return true if the cursor is on a valid row; false if there are no rows in
+   *      the result set
+   * @throws SQLException always
+   */
+  public boolean first() throws SQLException {
+
+    boolean returnState = false;
+
+    if (this.rows.size() > 0) {
+      this.beforeFirst();
+      this.next();
+      returnState = true;
+    }
+
+    return returnState;
+  }
+
+  /**
+   * Moves the cursor to the last row in the result set.
+   *
+   * @return RETURNED VALUE TO DO
+   * @throws SQLException always
+   */
+  public boolean last() throws SQLException {
+
+    boolean returnState = false;
+
+    if ( (this.rows != null) && (this.rows.size() > 0)) {
+      this.currentRowIndex = this.rows.size();
+      this.currentRow = (ResultSetRow)this.rows.get(this.currentRowIndex - 1);
+      returnState = true;
+    }
+
+    return returnState;
+  }
+
+  /**
+   * Adds a new row to the current set of rows.
+   *
+   * @param row new row to add to the end of the queue.
+   */
+  public void addRow(ResultSetRow row) {
+    rows.add(row);
+  }
+
+  /**
+   * Moves the cursor to the given row number (takes obsolute value) in this
+   * ResultSet object. An attempt to position the cursor beyond the first/last
+   * row in the result set leaves the cursor before the first row or after the
+   * last row.
+   *
+   * @param row the number of the row to which the cursor should move. A
+   *      positive number indicates the row number counting from the beginning
+   *      of the result set; a negative number indicates the row number counting
+   *      from the end of the result set
+   * @return RETURNED VALUE TO DO
+   * @throws SQLException on failure
+   */
+  public boolean absolute(int row) throws SQLException {
+
+    boolean returnState = false;
+
+    // Work forward from the start
+    if (row >= 0) {
+
+      if (row == 0) {
+        beforeFirst();
+      } else if (row <= this.rows.size()) {
+        this.currentRowIndex = row;
+        this.currentRow = this.rows.get(this.currentRowIndex - 1);
+        returnState = true;
+      } else {
+        afterLast();
+      }
+    } else {
+      // Work back from the end
+      if ( (this.rows.size() + row) >= 0) {
+        this.currentRowIndex = (this.rows.size() + 1) + row;
+        this.currentRow = this.rows.get(this.currentRowIndex - 1);
+        returnState = true;
+      } else {
+        beforeFirst();
+      }
+    }
+
+    return returnState;
+  }
+
+  /**
+   * Moves the cursor a relative number of rows, either positive or negative
+   * from its current position. Attempting to move beyond the first/last row in
+   * the result set positions the cursor before/after the the first/last row.
+   * Calling relative(0) is valid, but does not change the cursor position.
+   *
+   * @param numRows an int specifying the number of rows to move from the
+   *      current row; a positive number moves the cursor forward; a negative
+   *      number moves the cursor backward
+   * @return RETURNED VALUE TO DO
+   * @throws SQLException on failure
+   */
+  public boolean relative(int numRows) throws SQLException {
+
+    boolean returnState = false;
+
+    // Work forward from the start
+    if (numRows >= 0) {
+
+      if (numRows <= (this.rows.size() - this.currentRowIndex)) {
+
+        this.currentRowIndex += numRows;
+        this.currentRow =
+            (ResultSetRow)this.rows.get(this.currentRowIndex - 1);
+        returnState = true;
+      } else {
+        afterLast();
+      }
+    } else {
+      // Work back from the end
+
+      if ( (this.currentRowIndex + numRows) > 0) {
+
+        // Add 1 to size to go to end of list then add the negative row number
+        this.currentRowIndex += numRows;
+        this.currentRow = this.rows.get(this.currentRowIndex - 1);
+        returnState = true;
+      } else {
+        beforeFirst();
+      }
+    }
+
+    return returnState;
+  }
+
+  //
+  // Relational algebra methods
+  //
+
+  /**
+   * Result sets are equal if their rows are equal. Both row and column ordering
+   * is signicant.
+   *
+   * @param object PARAMETER TO DO
+   * @return RETURNED VALUE TO DO
+   */
+  public boolean equals(Object object) {
+
+    if (! (object instanceof ResultSet)) return false;
+
+    try {
+
+      // Convert the other result set into a comparable form
+      MemoryResultSet testResultSet =
+          (object instanceof MemoryResultSet) ? (MemoryResultSet) object
+          : new MemoryResultSet( (ResultSet) object);
+
+      // Compare the rows
+      return rows.equals(testResultSet.rows);
+    } catch (SQLException e) {
+      return false;
+    }
+  }
+
+  /**
+   * Produce a string version of the result set. Displaying the available
+   * columns and rows.
+   *
+   * @return the string version of the result set.
+   */
+  public String toString() {
+
+    try {
+
+      StringBuffer buffer = new StringBuffer(getColumnNames().length + " columns:");
+
+      // Save the current state of the result set.
+      int tmpCurrentRow = getRow();
+
+      // Get the names of the columns
+      for (int i = 0; i < columnNames.length; i++) {
+        buffer.append(" ").append(columnNames[i]);
+      }
+
+      buffer.append(" (").append(rows.size()).append(" rows)");
+
+      // Start at the start
+      beforeFirst();
+
+      while (next()) {
+        buffer.append("\n").append(getCurrentRow());
+      }
+
+      // Restore the state of the result set.
+      absolute(tmpCurrentRow);
+
+      return buffer.toString();
+    } catch (SQLException se) {
+      logger.error("Failed to convert object to string", se);
+      return "";
+    }
+  }
+
+  /**
+   * Initialises the column names and metadata from the given metadata object.
+   *
+   * @param newMetaData PARAMETER TO DO
+   * @throws SQLException if there was an error getting the metadata attributes.
+   */
+  private void initialiseMetaData(ResultSetMetaData newMetaData) throws SQLException {
+
+    int columnNameCount = newMetaData.getColumnCount();
+    columnNames = new String[columnNameCount];
+
+    for (int i = 0; i < columnNameCount; i++) {
+      columnNames[i] = newMetaData.getColumnName(i + 1);
+    }
+
+    // initialise the metadata field
+    metaData = new ResultSetMetaDataImpl(columnNames);
+  }
+
+  public int getHoldability() throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public Reader getNCharacterStream(int columnIndex) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public Reader getNCharacterStream(String columnLabel) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public NClob getNClob(int columnIndex) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public NClob getNClob(String columnLabel) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public String getNString(int columnIndex) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public String getNString(String columnLabel) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public RowId getRowId(int columnIndex) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public RowId getRowId(String columnLabel) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public SQLXML getSQLXML(int columnIndex) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public SQLXML getSQLXML(String columnLabel) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public boolean isClosed() throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateAsciiStream(int columnIndex, InputStream x, long length)  throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNClob(int columnIndex, NClob clob) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNClob(String columnLabel, NClob clob) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNString(int columnIndex, String string) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNString(String columnLabel, String string) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateRowId(int columnIndex, RowId x) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateRowId(String columnLabel, RowId x) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateClob(int columnIndex, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateClob(String columnLabel, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateNClob(int columnIndex, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public void updateNClob(String columnLabel, Reader reader) throws SQLException {
+    // Empty stub
+  }
+
+  public boolean isWrapperFor(Class<?> iface) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+  public <T> T unwrap(Class<T> iface) throws SQLException {
+    throw new SQLException(NOT_IMPLEMENTED);
+  }
+
+}

Copied: trunk/src/jar/util/java/org/mulgara/util/MemoryResultSetTest.java (from rev 2032, trunk/src/jar/util/java/org/mulgara/util/TestResultSetTest.java)
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/MemoryResultSetTest.java	                        (rev 0)
+++ trunk/src/jar/util/java/org/mulgara/util/MemoryResultSetTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,503 @@
+/*
+ * 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.util;
+
+// third party packages
+import junit.framework.*;
+
+// Java 2 standard packages
+import java.sql.SQLException;
+// import java.util.*;
+
+// JUnit
+import org.apache.log4j.Logger;
+
+// Log4J
+
+/**
+ * Test case for {@link MemoryResultSet}.
+ *
+ * @created 2001-07-12
+ * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
+ * @version $Revision: 1.9 $
+ * @modified $Date: 2005/01/05 04:59:29 $
+ * @maintenanceAuthor $Author: newmana $
+ * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
+ * @copyright © 2001-2003 <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 MemoryResultSetTest extends TestCase {
+
+  /** Logger. Named after the class. */
+  @SuppressWarnings("unused")
+  private static final Logger logger = Logger.getLogger(MemoryResultSetTest.class);
+
+  /** Test object. */
+//  private MemoryResultSet testResultSet;
+
+  /**
+   * CONSTRUCTOR MemoryResultSetTest TO DO
+   *
+   * @param name PARAMETER TO DO
+   */
+  public MemoryResultSetTest(String name) {
+    super(name);
+  }
+
+  /**
+   * Creates a test suite with various different output and compares the output.
+   *
+   * @return The test suite
+   */
+  public static TestSuite suite() {
+
+    TestSuite suite = new TestSuite();
+
+    //suite.addTest(new MemoryResultSetTest("test1Join"));
+    //suite.addTest(new MemoryResultSetTest("test1RemoveDuplicateRows"));
+    //suite.addTest(new MemoryResultSetTest("test2Join"));
+    //suite.addTest(new MemoryResultSetTest("test2RemoveDuplicateRows"));
+    //suite.addTest(new MemoryResultSetTest("testAppend"));
+    suite.addTest(new MemoryResultSetTest("testgetInt"));
+    //suite.addTest(new MemoryResultSetTest("testProject"));
+
+    return suite;
+  }
+
+  /**
+   * Default text runner.
+   *
+   * @param args The command line arguments
+   */
+  public static void main(String[] args) {
+
+    junit.textui.TestRunner.run(suite());
+  }
+
+  //
+  // Test cases
+  //
+
+  /**
+   * Test {@link MemoryResultSet#getInt}.
+   *
+   * @throws SQLException if a result set operation fails
+   */
+  public void testgetInt() throws SQLException {
+
+    // Create result set to test
+    String[] columnNames = new String[] {
+        "W", "X", "Y"};
+    MemoryResultSet rs = new MemoryResultSet(columnNames);
+
+    ResultSetRow row = new ResultSetRow(rs);
+    rs.addRow(row);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+
+    row = new ResultSetRow(rs);
+    rs.addRow(row);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    row.setInt(3, 4);
+
+    // Test for correct return values
+    assertTrue(rs.next());
+
+    assertEquals(rs.getInt(1), 1);
+    assertEquals(rs.getInt(2), 2);
+    assertEquals(rs.getInt(3), 3);
+
+    assertEquals(rs.getInt("W"), 1);
+    assertEquals(rs.getInt("X"), 2);
+    assertEquals(rs.getInt("Y"), 3);
+
+    assertTrue(rs.next());
+
+    assertEquals(rs.getInt(1), 2);
+    assertEquals(rs.getInt(2), 3);
+    assertEquals(rs.getInt(3), 4);
+
+    assertEquals(rs.getInt("W"), 2);
+    assertEquals(rs.getInt("X"), 3);
+    assertEquals(rs.getInt("Y"), 4);
+
+    assertTrue(!rs.next());
+  }
+
+  /**
+   * Test {@link MemoryResultSet#append}.
+   *
+   * @throws SQLException if the operation fails
+   */
+  /*
+  public void testAppend() throws SQLException {
+
+    // Create result set to test
+    MemoryResultSet rs = new MemoryResultSet(new String[] {
+        "X", "Y"});
+    ResultSetRow row = new ResultSetRow(rs);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    rs.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    rs.addRow(row);
+
+    // Compose the expected result set
+    MemoryResultSet expected = new MemoryResultSet(new String[] {
+        "X", "Y"});
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    expected.addRow(row);
+
+    // Call the method and verify the result
+    rs.append(rs);
+    assertEquals(expected, rs);
+  }
+  */
+
+  /**
+   * Test {@link MemoryResultSet#project}.
+   *
+   * @throws SQLException if the operation fails
+   */
+  /*
+  public void testProject() throws SQLException {
+
+    // Create result set to test
+    MemoryResultSet rs = new MemoryResultSet(new String[] {
+        "X", "Y", "Z"});
+
+    ResultSetRow row = new ResultSetRow(rs);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+    rs.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    row.setInt(3, 4);
+    rs.addRow(row);
+
+    // Compose the expected result set
+    MemoryResultSet expected = new MemoryResultSet(new String[] {
+        "X", "Z"});
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(2, 3);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 2);
+    row.setInt(2, 4);
+    expected.addRow(row);
+
+    // Call the method and verify the result
+    assertTrue(expected.equalsIgnoreOrder(rs.project(new String[] {
+        "X", "Z"})));
+  }
+  */
+
+  /**
+   * Test #1 for {@link MemoryResultSet#removeDuplicateRows}.
+   *
+   * @throws SQLException if the operation fails
+   */
+  /*
+  public void test1RemoveDuplicateRows() throws SQLException {
+
+    // Create result set to test
+    MemoryResultSet rs = new MemoryResultSet(new String[] {
+        "X", "Y"});
+    ResultSetRow row = new ResultSetRow(rs);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    rs.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    rs.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    rs.addRow(row);
+
+    // Compose the expected result set
+    MemoryResultSet expected = new MemoryResultSet(new String[] {
+        "X", "Y"});
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    expected.addRow(row);
+
+    // Call the method and verify the result
+    rs.removeDuplicateRows();
+    assertTrue(expected.equalsIgnoreOrder(rs));
+  }
+  */
+
+  /**
+   * Test #2 for {@link MemoryResultSet#removeDuplicateRows}. This tests
+   * duplicates that are {@link Object}s equal by value.
+   *
+   * @throws SQLException if the operation fails
+   */
+  /*
+  public void test2RemoveDuplicateRows() throws SQLException {
+
+    // Create result set to test
+    MemoryResultSet rs = new MemoryResultSet(new String[] {
+        "X", "Y"});
+    ResultSetRow row = new ResultSetRow(rs);
+    row.setObject(1, new Date(1));
+    row.setObject(2, new Date(2));
+    rs.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setObject(1, new Date(2));
+    row.setObject(2, new Date(3));
+    rs.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setObject(1, new Date(1));
+    row.setObject(2, new Date(2));
+    rs.addRow(row);
+
+    // Compose the expected result set
+    MemoryResultSet expected = new MemoryResultSet(new String[] {
+        "X", "Y"});
+
+    row = new ResultSetRow(rs);
+    row.setObject(1, new Date(1));
+    row.setObject(2, new Date(2));
+    expected.addRow(row);
+
+    row = new ResultSetRow(rs);
+    row.setObject(1, new Date(2));
+    row.setObject(2, new Date(3));
+    expected.addRow(row);
+
+    // Call the method and verify the result
+    rs.removeDuplicateRows();
+
+    if (!expected.equalsIgnoreOrder(rs)) {
+
+      System.out.println(expected + " expected, got " + rs);
+    }
+
+    assertTrue(expected.equalsIgnoreOrder(rs));
+  }
+  */
+
+  /**
+   * Test #1 for {@link MemoryResultSet#join}. Join <pre>
+   * W=1 X=2 Y=3
+   * W=2 X=3 Y=4
+   * W=4 X=2 Y=3
+   * </pre> with <pre>
+   * X=1 Y=2 Z=3
+   * X=2 Y=3 Z=4
+   * </pre> Expected result <pre>
+   * W=1 X=2 Y=3 Z=4
+   * W=4 X=2 Y=3 Z=4
+   * </pre>
+   *
+   * @throws SQLException if the join method call fails
+   */
+  /*
+  public void test1Join() throws SQLException {
+
+    // Create first result set
+    MemoryResultSet rs1 = new MemoryResultSet(new String[] {
+        "W", "X", "Y"});
+    ResultSetRow row = new ResultSetRow(rs1);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+    rs1.addRow(row);
+
+    row = new ResultSetRow(rs1);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    row.setInt(3, 4);
+    rs1.addRow(row);
+
+    row = new ResultSetRow(rs1);
+    row.setInt(1, 4);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+    rs1.addRow(row);
+
+    // Create second result set
+    MemoryResultSet rs2 = new MemoryResultSet(new String[] {
+        "X", "Y", "Z"});
+    row = new ResultSetRow(rs2);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+    rs2.addRow(row);
+
+    row = new ResultSetRow(rs2);
+    row.setInt(1, 2);
+    row.setInt(2, 3);
+    row.setInt(3, 4);
+    rs2.addRow(row);
+
+    // Create expected result of joining the two
+    String[] expectedColumnNames = new String[] {
+        "W", "X", "Y", "Z"};
+    MemoryResultSet expected = new MemoryResultSet(expectedColumnNames);
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+    row.setInt(4, 4);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 4);
+    row.setInt(2, 2);
+    row.setInt(3, 3);
+    row.setInt(4, 4);
+    expected.addRow(row);
+
+    // Perform the test
+    assertTrue(rs1.join(rs2).project(expectedColumnNames).equalsIgnoreOrder(
+        expected));
+    assertTrue(rs2.join(rs1).project(expectedColumnNames).equalsIgnoreOrder(
+        expected));
+  }
+  */
+
+  /**
+   * Test #2 for {@link MemoryResultSet#join}. This tests joins with nulls. Join
+   * <pre>
+   * X=1 Y=null
+   * </pre> with <pre>
+   * Y=null Z=2
+   * Y=3    Z=null
+   * </pre> Expected result <pre>
+   * X=1 Y=null Z=2
+   * X=1 Y=3    Z=null
+   * </pre>
+   *
+   * @throws SQLException if the join method call fails
+   */
+  /*
+  public void test2Join() throws SQLException {
+
+    // Create first result set
+    MemoryResultSet rs1 = new MemoryResultSet(new String[] {
+        "X", "Y"});
+    ResultSetRow row = new ResultSetRow(rs1);
+    row.setInt(1, 1);
+    rs1.addRow(row);
+
+    // Create second result set
+    MemoryResultSet rs2 = new MemoryResultSet(new String[] {
+        "Y", "Z"});
+
+    row = new ResultSetRow(rs2);
+    row.setInt(2, 2);
+    rs2.addRow(row);
+
+    row = new ResultSetRow(rs2);
+    row.setInt(1, 3);
+    rs2.addRow(row);
+
+    // Create expected result of joining the two
+    String[] expectedColumnNames = new String[] {
+        "X", "Y", "Z"};
+    MemoryResultSet expected = new MemoryResultSet(expectedColumnNames);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(3, 2);
+    expected.addRow(row);
+
+    row = new ResultSetRow(expected);
+    row.setInt(1, 1);
+    row.setInt(2, 3);
+    expected.addRow(row);
+
+    / *
+         System.err.println("RS1: "+rs1);
+         System.err.println("RS2: "+rs2);
+         System.err.println("EXPECTED: "+expected);
+         MemoryResultSet actual = rs1.join(rs2).project(expectedColumnNames);
+         System.err.println("ACTUAL: "+actual);
+         actual.removeDuplicateRows();
+         System.err.println("UNIQUE: "+actual);
+     * /
+    // Perform the test
+    assertTrue(rs1.join(rs2).project(expectedColumnNames).equalsIgnoreOrder(
+        expected));
+    assertTrue(rs2.join(rs1).project(expectedColumnNames).equalsIgnoreOrder(
+        expected));
+  }
+  */
+
+  /**
+   * Populate the test object.
+   *
+   */
+  protected void setUp() {
+
+    // not yet implemented
+  }
+}

Modified: trunk/src/jar/util/java/org/mulgara/util/Reflect.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/Reflect.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/Reflect.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -91,7 +91,7 @@
    * @return A constructor for clazz if one could be found, otherwise <code>null</code>.
    */
   @SuppressWarnings("unchecked")
-  private static <T> Constructor<T> openConstructorSearch(Class<T> clazz, Class<?>[] argTypes, Tester2<Class<?>,Class<?>> assignFrom) {
+  private static <T> Constructor<T> openConstructorSearch(Class<T> clazz, Class<?>[] argTypes, BooleanOp2<Class<?>,Class<?>> assignFrom) {
     for (Constructor<T> con: (Constructor<T>[])clazz.getConstructors()) {
       boolean match = true;
       Class<?>[] paramTypes = con.getParameterTypes();
@@ -146,11 +146,11 @@
    * Create a tester that can test for assignability of types, excluding the case when
    * the given type is null.  This differs from {@link Class#isAssignableFrom} in that
    * it will not throw a NullPointerException.
-   * @return A {@link Tester2} object that can test that the type defined in the second
+   * @return A {@link BooleanOp2} object that can test that the type defined in the second
    *  parameter can be assigned to the type in the first parameter.
    */
-  private static Tester2<Class<?>,Class<?>> getAssignableTester() {
-    return new Tester2<Class<?>,Class<?>>() {
+  private static BooleanOp2<Class<?>,Class<?>> getAssignableTester() {
+    return new BooleanOp2<Class<?>,Class<?>>() {
       public boolean test(Class<?> o1, Class<?> o2) {
         return o2 != null && o1.isAssignableFrom(o2);
        }
@@ -161,11 +161,11 @@
   /**
    * Create a tester that can test for assignability of types, including the case when
    * the given type is null.
-   * @return A {@link Tester2} object that can test that the type defined in the second
+   * @return A {@link BooleanOp2} object that can test that the type defined in the second
    *  parameter can be assigned to the type in the first parameter.
    */
-  private static Tester2<Class<?>,Class<?>> getNullAssignTester() {
-    return new Tester2<Class<?>,Class<?>>() {
+  private static BooleanOp2<Class<?>,Class<?>> getNullAssignTester() {
+    return new BooleanOp2<Class<?>,Class<?>>() {
       public boolean test(Class<?> o1, Class<?> o2) {
         return o2 == null || o1.isAssignableFrom(o2);
       }

Modified: trunk/src/jar/util/java/org/mulgara/util/ResultSetRow.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/ResultSetRow.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/ResultSetRow.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -160,7 +160,7 @@
 
   /**
    * Set a field to a Java {@link Object} value. In order to allow {@link
-   * TestResultSet} to be {@link Serializable}, we require that all object that
+   * MemoryResultSet} to be {@link Serializable}, we require that all object that
    * appear as field values are also {@link Serializable}.
    *
    * @param columnIndex the index into the column to get the object.

Deleted: trunk/src/jar/util/java/org/mulgara/util/TestResultSet.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/TestResultSet.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/TestResultSet.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,787 +0,0 @@
-/*
- * 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.util;
-
-// Java 2 standard packages
-import java.io.InputStream;
-import java.io.Reader;
-import java.io.Serializable;
-import java.sql.*;
-import java.util.*;
-
-// third party packages
-import org.apache.log4j.Logger;
-
-// Log4J
-
-/**
- * Implementation of {@link ResultSet} suitable for generating test cases. It's
- * not a correct {@link ResultSet} in many respects, the foremost being an
- * absence of column typing.
- *
- * @created 2001-07-12
- *
- * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
- *
- * @version $Revision: 1.9 $
- *
- * @modified $Date: 2005/01/05 04:59:29 $
- *
- * @maintenanceAuthor $Author: newmana $
- *
- * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
- *
- * @copyright © 2001-2003 <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 TestResultSet extends AbstractMulgaraResultSet
-  implements Serializable {
-
- /**
-  * 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.
-  */
-  static final long serialVersionUID = 447953576074487320L;
-
-  /**
-   * Logger.
-   */
-  private static final Logger logger = Logger.getLogger(TestResultSet.class);
-
-  /**
-   * The metadata for this result set.
-   */
-  private ResultSetMetaData metaData;
-
-  /**
-   * The rows of the result set.
-   */
-  private List<ResultSetRow> rows = new RowList<ResultSetRow>();
-
-  /**
-   * The current row index.
-   */
-  private int currentRowIndex = 0;
-
-  /**
-   * The current row.
-   */
-  private ResultSetRow currentRow = null;
-
-  //
-  // Constructors
-  //
-
-  /**
-   * Create a result set with named columns and no rows.
-   *
-   * @param newColumnNames the new column names for this result set.
-   * @throws SQLException on failure
-   */
-  public TestResultSet(String[] newColumnNames) throws SQLException {
-
-    // FIXME: should validate columnNames, checking for duplicate names, etc
-    // initialize fields
-    columnNames = newColumnNames;
-    metaData = new ResultSetMetaDataImpl(columnNames);
-
-    // move the cursor before the first row
-    beforeFirst();
-  }
-
-  /**
-   * Create a result set with specified metadata and no rows.
-   *
-   * @param metaData PARAMETER TO DO
-   * @throws SQLException on failure
-   */
-  public TestResultSet(ResultSetMetaData metaData) throws SQLException {
-
-    initialiseMetaData(metaData);
-
-    // move the cursor before the first row
-    beforeFirst();
-  }
-
-  /**
-   * Create a result set with content copied from an existing result set.
-   *
-   * @param resultSet PARAMETER TO DO
-   * @throws SQLException on failure
-   */
-  public TestResultSet(ResultSet resultSet) throws SQLException {
-
-    // Validate "resultSet" parameter
-    if (resultSet == null) {
-      throw new IllegalArgumentException("Null \"resultSet\" parameter");
-    }
-
-    // Copy columns
-    initialiseMetaData(resultSet.getMetaData());
-
-    // Copy rows
-    if (resultSet.getClass() == TestResultSet.class) {
-      rows.addAll( ( (TestResultSet) resultSet).rows);
-    } else {
-
-      // Don't assume that it hasn't already been read.
-      resultSet.beforeFirst();
-
-      // Repeat until we get all of the items from the result sets.
-      while (resultSet.next()) {
-
-        ResultSetRow row = new ResultSetRow(resultSet);
-
-        for (int i = 0; i < columnNames.length; i++) {
-          row.setObject(columnNames[i], resultSet.getObject(columnNames[i]));
-        }
-
-        addRow(row);
-      }
-    }
-  }
-
-  /**
-   * Overwrites the existing set of rows available.
-   *
-   * @param newRows the new rows to set.
-   * @throws SQLException EXCEPTION TO DO
-   */
-  public void setAllRows(List<ResultSetRow> newRows) throws SQLException {
-    rows = newRows;
-  }
-
-  // next()
-
-  /**
-   * Return the object at the given index.
-   *
-   * @param columnIndex the index of the object to retrieve
-   * @return the value at the given index
-   * @throws SQLException on failure
-   */
-  public Object getObject(int columnIndex) throws SQLException {
-    // throw an error if the current row is invalid
-    if (this.currentRow == null) throw new SQLException("Not on a row.");
-
-    // get the value out of the current row
-    return this.currentRow.getObject(columnIndex);
-  }
-
-  // getObject()
-
-  /**
-   * Return the string at the given index.
-   *
-   * @param columnIndex the index of the string to retrieve
-   * @return the value at the given index (possibly <code>null</code>)
-   * @throws SQLException on failure
-   */
-  public String getString(int columnIndex) throws SQLException {
-
-    // throw an error if the current row is invalid
-    if (this.currentRow == null) throw new SQLException("Not on a row.");
-
-    // get the value out of the current row
-    Object object = this.currentRow.getObject(columnIndex);
-
-    return (object == null) ? null : object.toString();
-  }
-
-  // getString()
-
-  /**
-   * Returns the metadata for this result set.
-   *
-   * @return the metadata for this result set
-   * @throws SQLException on failure
-   */
-  public ResultSetMetaData getMetaData() throws SQLException {
-    return metaData;
-  }
-
-  /**
-   * Returns whether the cursor is before the first row.
-   *
-       * @return true if the cursor is before the first row in the result set, false
-   *      otherwise
-   * @throws SQLException on failure
-   */
-  public boolean isBeforeFirst() throws SQLException {
-    return this.currentRowIndex == 0;
-  }
-
-  /**
-   * Returns true if the cursor is after the last row.
-   *
-   * @return true if the cursor is after the first row in the result set, false
-   *      otherwise
-   * @throws SQLException on failure
-   */
-  public boolean isAfterLast() throws SQLException {
-    return this.currentRowIndex > this.rows.size();
-  }
-
-  /**
-   * Returns true if the cursor is on the first row.
-   *
-   * @return true if the cursor is on the first row, false otherwise
-   * @throws SQLException on failure
-   */
-  public boolean isFirst() throws SQLException {
-    return this.currentRowIndex == 1;
-  }
-
-  /**
-   * Returns true if the cursor is on the last row.
-   *
-   * @return true if the cursor is on the las row, false otherwise
-   * @throws SQLException on failure
-   */
-  public boolean isLast() throws SQLException {
-    return this.currentRowIndex == this.rows.size();
-  }
-
-  /**
-   * Returns the entire rows underlying the result set.
-   *
-   * @return the entire rows underlying the result set.
-   * @throws SQLException EXCEPTION TO DO
-   */
-  public List<ResultSetRow> getAllRows() throws SQLException {
-    return rows;
-  }
-
-  /**
-   * Returns the index of the row the cursor is on.
-   *
-   * @return the index of the row the cursor is on
-   * @throws SQLException on failure
-   */
-  public int getRow() throws SQLException {
-    return this.currentRowIndex;
-  }
-
-  /**
-   * Returns the total size of the number of rows.
-   *
-   * @return the total size of the number of rows available.
-   */
-  public int getTotalRowSize() {
-    return rows.size();
-  }
-
-  /**
-   * Gets the CurrentRow attribute of the TestResultSet object
-   *
-   * @return The CurrentRow value
-   */
-  public ResultSetRow getCurrentRow() {
-    return currentRow;
-  }
-
-  //
-  // Methods implementing the ResultSet interface
-  //
-
-  /**
-   * Moves the cursor down one row from its current position.
-   *
-   * @return true if the new current row is valid; false if there are no more
-   *      rows
-   * @throws SQLException on failure
-   */
-  public boolean next() throws SQLException {
-    boolean returnState = false;
-
-    // advance the cursor if we can
-    if (!this.isLast()) {
-
-      this.currentRowIndex++;
-      this.currentRow = (ResultSetRow)this.rows.get(this.currentRowIndex - 1);
-      returnState = true;
-    } else {
-
-      this.currentRow = null;
-      returnState = false;
-    }
-
-    // end if
-    // return
-    return returnState;
-  }
-
-  /**
-   * Moves the cursor to before the first row in the result set.
-   *
-   * @throws SQLException on failure
-   */
-  public void beforeFirst() throws SQLException {
-    // return members to their default state
-    this.currentRowIndex = 0;
-    this.currentRow = null;
-  }
-
-  /**
-   * Moves the cursor to after the last row in the result set.
-   *
-   * @throws SQLException on failure
-   */
-  public void afterLast() throws SQLException {
-    this.currentRowIndex = this.rows.size() + 1;
-    this.currentRow = null;
-  }
-
-  /**
-   * Moves the cursor to the first row in this ResultSet object.
-   *
-   * @return true if the cursor is on a valid row; false if there are no rows in
-   *      the result set
-   * @throws SQLException always
-   */
-  public boolean first() throws SQLException {
-
-    boolean returnState = false;
-
-    if (this.rows.size() > 0) {
-      this.beforeFirst();
-      this.next();
-      returnState = true;
-    }
-
-    return returnState;
-  }
-
-  /**
-   * Moves the cursor to the last row in the result set.
-   *
-   * @return RETURNED VALUE TO DO
-   * @throws SQLException always
-   */
-  public boolean last() throws SQLException {
-
-    boolean returnState = false;
-
-    if ( (this.rows != null) && (this.rows.size() > 0)) {
-      this.currentRowIndex = this.rows.size();
-      this.currentRow = (ResultSetRow)this.rows.get(this.currentRowIndex - 1);
-      returnState = true;
-    }
-
-    return returnState;
-  }
-
-  /**
-   * Adds a new row to the current set of rows.
-   *
-   * @param row new row to add to the end of the queue.
-   */
-  public void addRow(ResultSetRow row) {
-    rows.add(row);
-  }
-
-  /**
-   * Moves the cursor to the given row number (takes obsolute value) in this
-   * ResultSet object. An attempt to position the cursor beyond the first/last
-   * row in the result set leaves the cursor before the first row or after the
-   * last row.
-   *
-   * @param row the number of the row to which the cursor should move. A
-   *      positive number indicates the row number counting from the beginning
-   *      of the result set; a negative number indicates the row number counting
-   *      from the end of the result set
-   * @return RETURNED VALUE TO DO
-   * @throws SQLException on failure
-   */
-  public boolean absolute(int row) throws SQLException {
-
-    boolean returnState = false;
-
-    // Work forward from the start
-    if (row >= 0) {
-
-      if (row == 0) {
-        beforeFirst();
-      } else if (row <= this.rows.size()) {
-        this.currentRowIndex = row;
-        this.currentRow = this.rows.get(this.currentRowIndex - 1);
-        returnState = true;
-      } else {
-        afterLast();
-      }
-    } else {
-      // Work back from the end
-      if ( (this.rows.size() + row) >= 0) {
-        this.currentRowIndex = (this.rows.size() + 1) + row;
-        this.currentRow = this.rows.get(this.currentRowIndex - 1);
-        returnState = true;
-      } else {
-        beforeFirst();
-      }
-    }
-
-    return returnState;
-  }
-
-  /**
-   * Moves the cursor a relative number of rows, either positive or negative
-   * from its current position. Attempting to move beyond the first/last row in
-   * the result set positions the cursor before/after the the first/last row.
-   * Calling relative(0) is valid, but does not change the cursor position.
-   *
-   * @param numRows an int specifying the number of rows to move from the
-   *      current row; a positive number moves the cursor forward; a negative
-   *      number moves the cursor backward
-   * @return RETURNED VALUE TO DO
-   * @throws SQLException on failure
-   */
-  public boolean relative(int numRows) throws SQLException {
-
-    boolean returnState = false;
-
-    // Work forward from the start
-    if (numRows >= 0) {
-
-      if (numRows <= (this.rows.size() - this.currentRowIndex)) {
-
-        this.currentRowIndex += numRows;
-        this.currentRow =
-            (ResultSetRow)this.rows.get(this.currentRowIndex - 1);
-        returnState = true;
-      } else {
-        afterLast();
-      }
-    } else {
-      // Work back from the end
-
-      if ( (this.currentRowIndex + numRows) > 0) {
-
-        // Add 1 to size to go to end of list then add the negative row number
-        this.currentRowIndex += numRows;
-        this.currentRow = this.rows.get(this.currentRowIndex - 1);
-        returnState = true;
-      } else {
-        beforeFirst();
-      }
-    }
-
-    return returnState;
-  }
-
-  //
-  // Relational algebra methods
-  //
-
-  /**
-   * Result sets are equal if their rows are equal. Both row and column ordering
-   * is signicant.
-   *
-   * @param object PARAMETER TO DO
-   * @return RETURNED VALUE TO DO
-   */
-  public boolean equals(Object object) {
-
-    if (! (object instanceof ResultSet)) return false;
-
-    try {
-
-      // Convert the other result set into a comparable form
-      TestResultSet testResultSet =
-          (object instanceof TestResultSet) ? (TestResultSet) object
-          : new TestResultSet( (ResultSet) object);
-
-      // Compare the rows
-      return rows.equals(testResultSet.rows);
-    } catch (SQLException e) {
-      return false;
-    }
-  }
-
-  /**
-   * Produce a string version of the result set. Displaying the available
-   * columns and rows.
-   *
-   * @return the string version of the result set.
-   */
-  public String toString() {
-
-    try {
-
-      StringBuffer buffer = new StringBuffer(getColumnNames().length + " columns:");
-
-      // Save the current state of the result set.
-      int tmpCurrentRow = getRow();
-
-      // Get the names of the columns
-      for (int i = 0; i < columnNames.length; i++) {
-        buffer.append(" ").append(columnNames[i]);
-      }
-
-      buffer.append(" (").append(rows.size()).append(" rows)");
-
-      // Start at the start
-      beforeFirst();
-
-      while (next()) {
-        buffer.append("\n").append(getCurrentRow());
-      }
-
-      // Restore the state of the result set.
-      absolute(tmpCurrentRow);
-
-      return buffer.toString();
-    } catch (SQLException se) {
-      logger.error("Failed to convert object to string", se);
-      return "";
-    }
-  }
-
-  /**
-   * Initialises the column names and metadata from the given metadata object.
-   *
-   * @param newMetaData PARAMETER TO DO
-   * @throws SQLException if there was an error getting the metadata attributes.
-   */
-  private void initialiseMetaData(ResultSetMetaData newMetaData) throws SQLException {
-
-    int columnNameCount = newMetaData.getColumnCount();
-    columnNames = new String[columnNameCount];
-
-    for (int i = 0; i < columnNameCount; i++) {
-      columnNames[i] = newMetaData.getColumnName(i + 1);
-    }
-
-    // initialise the metadata field
-    metaData = new ResultSetMetaDataImpl(columnNames);
-  }
-
-  public int getHoldability() throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public Reader getNCharacterStream(int columnIndex) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public Reader getNCharacterStream(String columnLabel) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public NClob getNClob(int columnIndex) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public NClob getNClob(String columnLabel) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public String getNString(int columnIndex) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public String getNString(String columnLabel) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public RowId getRowId(int columnIndex) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public RowId getRowId(String columnLabel) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public SQLXML getSQLXML(int columnIndex) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public SQLXML getSQLXML(String columnLabel) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public boolean isClosed() throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateAsciiStream(int columnIndex, InputStream x, long length)  throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateClob(int columnIndex, Reader reader, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateClob(String columnLabel, Reader reader, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNClob(int columnIndex, NClob clob) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNClob(String columnLabel, NClob clob) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNString(int columnIndex, String string) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNString(String columnLabel, String string) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateRowId(int columnIndex, RowId x) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateRowId(String columnLabel, RowId x) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public void updateNCharacterStream(int columnIndex, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateAsciiStream(int columnIndex, InputStream inputStream) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateBinaryStream(int columnIndex, InputStream inputStream) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateCharacterStream(int columnIndex, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateAsciiStream(String columnLabel, InputStream inputStream) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateBinaryStream(String columnLabel, InputStream inputStream) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateClob(int columnIndex, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateClob(String columnLabel, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateNClob(int columnIndex, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public void updateNClob(String columnLabel, Reader reader) throws SQLException {
-    // Empty stub
-  }
-
-  public boolean isWrapperFor(Class<?> iface) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-  public <T> T unwrap(Class<T> iface) throws SQLException {
-    throw new SQLException(NOT_IMPLEMENTED);
-  }
-
-}

Deleted: trunk/src/jar/util/java/org/mulgara/util/TestResultSetTest.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/TestResultSetTest.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/TestResultSetTest.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,503 +0,0 @@
-/*
- * 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.util;
-
-// third party packages
-import junit.framework.*;
-
-// Java 2 standard packages
-import java.sql.SQLException;
-// import java.util.*;
-
-// JUnit
-import org.apache.log4j.Logger;
-
-// Log4J
-
-/**
- * Test case for {@link TestResultSet}.
- *
- * @created 2001-07-12
- * @author <a href="http://staff.pisoftware.com/raboczi">Simon Raboczi</a>
- * @version $Revision: 1.9 $
- * @modified $Date: 2005/01/05 04:59:29 $
- * @maintenanceAuthor $Author: newmana $
- * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
- * @copyright © 2001-2003 <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 TestResultSetTest extends TestCase {
-
-  /** Logger. Named after the class. */
-  @SuppressWarnings("unused")
-  private static final Logger logger = Logger.getLogger(TestResultSetTest.class);
-
-  /** Test object. */
-//  private TestResultSet testResultSet;
-
-  /**
-   * CONSTRUCTOR TestResultSetTest TO DO
-   *
-   * @param name PARAMETER TO DO
-   */
-  public TestResultSetTest(String name) {
-    super(name);
-  }
-
-  /**
-   * Creates a test suite with various different output and compares the output.
-   *
-   * @return The test suite
-   */
-  public static TestSuite suite() {
-
-    TestSuite suite = new TestSuite();
-
-    //suite.addTest(new TestResultSetTest("test1Join"));
-    //suite.addTest(new TestResultSetTest("test1RemoveDuplicateRows"));
-    //suite.addTest(new TestResultSetTest("test2Join"));
-    //suite.addTest(new TestResultSetTest("test2RemoveDuplicateRows"));
-    //suite.addTest(new TestResultSetTest("testAppend"));
-    suite.addTest(new TestResultSetTest("testgetInt"));
-    //suite.addTest(new TestResultSetTest("testProject"));
-
-    return suite;
-  }
-
-  /**
-   * Default text runner.
-   *
-   * @param args The command line arguments
-   */
-  public static void main(String[] args) {
-
-    junit.textui.TestRunner.run(suite());
-  }
-
-  //
-  // Test cases
-  //
-
-  /**
-   * Test {@link TestResultSet#getInt}.
-   *
-   * @throws SQLException if a result set operation fails
-   */
-  public void testgetInt() throws SQLException {
-
-    // Create result set to test
-    String[] columnNames = new String[] {
-        "W", "X", "Y"};
-    TestResultSet rs = new TestResultSet(columnNames);
-
-    ResultSetRow row = new ResultSetRow(rs);
-    rs.addRow(row);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-
-    row = new ResultSetRow(rs);
-    rs.addRow(row);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    row.setInt(3, 4);
-
-    // Test for correct return values
-    assertTrue(rs.next());
-
-    assertEquals(rs.getInt(1), 1);
-    assertEquals(rs.getInt(2), 2);
-    assertEquals(rs.getInt(3), 3);
-
-    assertEquals(rs.getInt("W"), 1);
-    assertEquals(rs.getInt("X"), 2);
-    assertEquals(rs.getInt("Y"), 3);
-
-    assertTrue(rs.next());
-
-    assertEquals(rs.getInt(1), 2);
-    assertEquals(rs.getInt(2), 3);
-    assertEquals(rs.getInt(3), 4);
-
-    assertEquals(rs.getInt("W"), 2);
-    assertEquals(rs.getInt("X"), 3);
-    assertEquals(rs.getInt("Y"), 4);
-
-    assertTrue(!rs.next());
-  }
-
-  /**
-   * Test {@link TestResultSet#append}.
-   *
-   * @throws SQLException if the operation fails
-   */
-  /*
-  public void testAppend() throws SQLException {
-
-    // Create result set to test
-    TestResultSet rs = new TestResultSet(new String[] {
-        "X", "Y"});
-    ResultSetRow row = new ResultSetRow(rs);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    rs.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    rs.addRow(row);
-
-    // Compose the expected result set
-    TestResultSet expected = new TestResultSet(new String[] {
-        "X", "Y"});
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    expected.addRow(row);
-
-    // Call the method and verify the result
-    rs.append(rs);
-    assertEquals(expected, rs);
-  }
-  */
-
-  /**
-   * Test {@link TestResultSet#project}.
-   *
-   * @throws SQLException if the operation fails
-   */
-  /*
-  public void testProject() throws SQLException {
-
-    // Create result set to test
-    TestResultSet rs = new TestResultSet(new String[] {
-        "X", "Y", "Z"});
-
-    ResultSetRow row = new ResultSetRow(rs);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-    rs.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    row.setInt(3, 4);
-    rs.addRow(row);
-
-    // Compose the expected result set
-    TestResultSet expected = new TestResultSet(new String[] {
-        "X", "Z"});
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(2, 3);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 2);
-    row.setInt(2, 4);
-    expected.addRow(row);
-
-    // Call the method and verify the result
-    assertTrue(expected.equalsIgnoreOrder(rs.project(new String[] {
-        "X", "Z"})));
-  }
-  */
-
-  /**
-   * Test #1 for {@link TestResultSet#removeDuplicateRows}.
-   *
-   * @throws SQLException if the operation fails
-   */
-  /*
-  public void test1RemoveDuplicateRows() throws SQLException {
-
-    // Create result set to test
-    TestResultSet rs = new TestResultSet(new String[] {
-        "X", "Y"});
-    ResultSetRow row = new ResultSetRow(rs);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    rs.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    rs.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    rs.addRow(row);
-
-    // Compose the expected result set
-    TestResultSet expected = new TestResultSet(new String[] {
-        "X", "Y"});
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    expected.addRow(row);
-
-    // Call the method and verify the result
-    rs.removeDuplicateRows();
-    assertTrue(expected.equalsIgnoreOrder(rs));
-  }
-  */
-
-  /**
-   * Test #2 for {@link TestResultSet#removeDuplicateRows}. This tests
-   * duplicates that are {@link Object}s equal by value.
-   *
-   * @throws SQLException if the operation fails
-   */
-  /*
-  public void test2RemoveDuplicateRows() throws SQLException {
-
-    // Create result set to test
-    TestResultSet rs = new TestResultSet(new String[] {
-        "X", "Y"});
-    ResultSetRow row = new ResultSetRow(rs);
-    row.setObject(1, new Date(1));
-    row.setObject(2, new Date(2));
-    rs.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setObject(1, new Date(2));
-    row.setObject(2, new Date(3));
-    rs.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setObject(1, new Date(1));
-    row.setObject(2, new Date(2));
-    rs.addRow(row);
-
-    // Compose the expected result set
-    TestResultSet expected = new TestResultSet(new String[] {
-        "X", "Y"});
-
-    row = new ResultSetRow(rs);
-    row.setObject(1, new Date(1));
-    row.setObject(2, new Date(2));
-    expected.addRow(row);
-
-    row = new ResultSetRow(rs);
-    row.setObject(1, new Date(2));
-    row.setObject(2, new Date(3));
-    expected.addRow(row);
-
-    // Call the method and verify the result
-    rs.removeDuplicateRows();
-
-    if (!expected.equalsIgnoreOrder(rs)) {
-
-      System.out.println(expected + " expected, got " + rs);
-    }
-
-    assertTrue(expected.equalsIgnoreOrder(rs));
-  }
-  */
-
-  /**
-   * Test #1 for {@link TestResultSet#join}. Join <pre>
-   * W=1 X=2 Y=3
-   * W=2 X=3 Y=4
-   * W=4 X=2 Y=3
-   * </pre> with <pre>
-   * X=1 Y=2 Z=3
-   * X=2 Y=3 Z=4
-   * </pre> Expected result <pre>
-   * W=1 X=2 Y=3 Z=4
-   * W=4 X=2 Y=3 Z=4
-   * </pre>
-   *
-   * @throws SQLException if the join method call fails
-   */
-  /*
-  public void test1Join() throws SQLException {
-
-    // Create first result set
-    TestResultSet rs1 = new TestResultSet(new String[] {
-        "W", "X", "Y"});
-    ResultSetRow row = new ResultSetRow(rs1);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-    rs1.addRow(row);
-
-    row = new ResultSetRow(rs1);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    row.setInt(3, 4);
-    rs1.addRow(row);
-
-    row = new ResultSetRow(rs1);
-    row.setInt(1, 4);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-    rs1.addRow(row);
-
-    // Create second result set
-    TestResultSet rs2 = new TestResultSet(new String[] {
-        "X", "Y", "Z"});
-    row = new ResultSetRow(rs2);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-    rs2.addRow(row);
-
-    row = new ResultSetRow(rs2);
-    row.setInt(1, 2);
-    row.setInt(2, 3);
-    row.setInt(3, 4);
-    rs2.addRow(row);
-
-    // Create expected result of joining the two
-    String[] expectedColumnNames = new String[] {
-        "W", "X", "Y", "Z"};
-    TestResultSet expected = new TestResultSet(expectedColumnNames);
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-    row.setInt(4, 4);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 4);
-    row.setInt(2, 2);
-    row.setInt(3, 3);
-    row.setInt(4, 4);
-    expected.addRow(row);
-
-    // Perform the test
-    assertTrue(rs1.join(rs2).project(expectedColumnNames).equalsIgnoreOrder(
-        expected));
-    assertTrue(rs2.join(rs1).project(expectedColumnNames).equalsIgnoreOrder(
-        expected));
-  }
-  */
-
-  /**
-   * Test #2 for {@link TestResultSet#join}. This tests joins with nulls. Join
-   * <pre>
-   * X=1 Y=null
-   * </pre> with <pre>
-   * Y=null Z=2
-   * Y=3    Z=null
-   * </pre> Expected result <pre>
-   * X=1 Y=null Z=2
-   * X=1 Y=3    Z=null
-   * </pre>
-   *
-   * @throws SQLException if the join method call fails
-   */
-  /*
-  public void test2Join() throws SQLException {
-
-    // Create first result set
-    TestResultSet rs1 = new TestResultSet(new String[] {
-        "X", "Y"});
-    ResultSetRow row = new ResultSetRow(rs1);
-    row.setInt(1, 1);
-    rs1.addRow(row);
-
-    // Create second result set
-    TestResultSet rs2 = new TestResultSet(new String[] {
-        "Y", "Z"});
-
-    row = new ResultSetRow(rs2);
-    row.setInt(2, 2);
-    rs2.addRow(row);
-
-    row = new ResultSetRow(rs2);
-    row.setInt(1, 3);
-    rs2.addRow(row);
-
-    // Create expected result of joining the two
-    String[] expectedColumnNames = new String[] {
-        "X", "Y", "Z"};
-    TestResultSet expected = new TestResultSet(expectedColumnNames);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(3, 2);
-    expected.addRow(row);
-
-    row = new ResultSetRow(expected);
-    row.setInt(1, 1);
-    row.setInt(2, 3);
-    expected.addRow(row);
-
-    / *
-         System.err.println("RS1: "+rs1);
-         System.err.println("RS2: "+rs2);
-         System.err.println("EXPECTED: "+expected);
-         TestResultSet actual = rs1.join(rs2).project(expectedColumnNames);
-         System.err.println("ACTUAL: "+actual);
-         actual.removeDuplicateRows();
-         System.err.println("UNIQUE: "+actual);
-     * /
-    // Perform the test
-    assertTrue(rs1.join(rs2).project(expectedColumnNames).equalsIgnoreOrder(
-        expected));
-    assertTrue(rs2.join(rs1).project(expectedColumnNames).equalsIgnoreOrder(
-        expected));
-  }
-  */
-
-  /**
-   * Populate the test object.
-   *
-   */
-  protected void setUp() {
-
-    // not yet implemented
-  }
-}

Deleted: trunk/src/jar/util/java/org/mulgara/util/Tester.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/Tester.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/Tester.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,29 +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.util;
-
-/**
- * Functor interface for testing an object in some arbitrary way.
- * @created Oct 18, 2007
- * @author Paul Gearon
- * @copyright © 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 interface Tester {
-
-  /**
-   * Perform a test on an object, returning <code>true</code> if it passes.
-   * @param o The object to test
-   * @return <code>true</code> for a successful test.
-   */
-  public boolean test(Object o);
-}

Deleted: trunk/src/jar/util/java/org/mulgara/util/Tester2.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/Tester2.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/Tester2.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -1,30 +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.util;
-
-/**
- * Functor interface for testing a pair of objects in some arbitrary way.
- * @created Oct 18, 2007
- * @author Paul Gearon
- * @copyright © 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 interface Tester2 <T1,T2> {
-
-  /**
-   * Perform a test on an a pair of objects, returning <code>true</code> if it passes.
-   * @param o1 The first object to test.
-   * @param o2 The second object to test.
-   * @return <code>true</code> for a successful test.
-   */
-  public boolean test(T1 o1, T2 o2);
-}

Added: trunk/src/jar/util/java/org/mulgara/util/io/IOUtil.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/io/IOUtil.java	                        (rev 0)
+++ trunk/src/jar/util/java/org/mulgara/util/io/IOUtil.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2011 Paul Gearon.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.mulgara.util.io;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+
+/**
+ * Static utility methods for common actions on IO.
+ */
+public class IOUtil {
+
+  /**
+   * Reads the next non-empty line of text from a buffered reader, up to a given
+   * number of characters.
+   * 
+   * @param br The BufferedReader to get a line from.
+   * @param maxlen The maximum length of string to read from the line.
+   * @return A line of text, not including any line-termination characters,
+   *         or null if the end of stream has been reached. An empty string will
+   *         indicate that the maxlen number of characters was reached before any
+   *         text could be read. 
+   */
+  public static final String readLine(BufferedReader br, int maxlen) throws IOException {
+    StringBuilder s = new StringBuilder();
+
+    for (int i = 0; i < maxlen; i++) {
+      int c = br.read();
+      if (c == -1) {
+        if (s.length() == 0) return null;
+        break;
+      }
+      if (c == '\n' || c == '\r') {
+        if (s.length() == 0) continue;
+        break;
+      }
+      s.appendCodePoint(c);
+    }
+    return s.toString();
+  }
+}

Modified: trunk/src/jar/util/java/org/mulgara/util/io/LMappedBufferedFile.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/io/LMappedBufferedFile.java	2011-09-16 13:52:57 UTC (rev 2032)
+++ trunk/src/jar/util/java/org/mulgara/util/io/LMappedBufferedFile.java	2011-09-17 03:01:25 UTC (rev 2033)
@@ -26,7 +26,7 @@
   private static final int DEFAULT_PAGE_SIZE = 33554432; // 32 MB
 
   /** The page size to use. */
-  private static final int PAGE_SIZE;
+  public static final int PAGE_SIZE;
 
   /** The objects that want to know when the file gets remapped */
   private List<Runnable> listeners = new ArrayList<Runnable>();



More information about the Mulgara-svn mailing list