[Mulgara-svn] r1871 - in trunk: . KOWARI-MODIFICATIONS jxdata/iTQL jxdata/iTQL/distinct jxdata/iTQL/vargraph lib src/jar/content-n3/java/org/mulgara/content/n3 src/jar/content-rdfxml/java/org/mulgara/content/rdfxml src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer src/jar/krule/java/org/mulgara/krule src/jar/query/java/org/mulgara/connection src/jar/query/java/org/mulgara/jena src/jar/query/java/org/mulgara/query src/jar/query/java/org/mulgara/query/functions src/jar/query/java/org/mulgara/query/operation src/jar/query/java/org/mulgara/query/xpath src/jar/querylang/java/org/mulgara/itql src/jar/querylang/java/org/mulgara/protocol/http src/jar/querylang/java/org/mulgara/sparql src/jar/querylang/java/org/mulgara/sparql/parser/cst src/jar/querylang/java/org/mulgara/store/jxunit src/jar/querylang/javacc/org/mulgara/sparql/parser src/jar/querylang/sablecc src/jar/resolver/java/org/mulgara/resolver src/jar/resolver-distributed/java/org/mulgara/resolver/distributed src/jar/resolver-gis/java/org/mulgara/resolver/gis src/jar/resolver-lucene/java/org/mulgara/resolver/lucene src/jar/resolver-relational/java/org/mulgara/resolver/relational src/jar/resolver-spi/java/org/mulgara/resolver/spi src/jar/resolver-spi/java/org/mulgara/store/statement src/jar/resolver-store/java/org/mulgara/store/statement/xa11 src/jar/resolver-test/java/org/mulgara/resolver/test src/jar/resolver-view/java/org/mulgara/resolver/view src/jar/resolver-xsd/java/org/mulgara/resolver/xsd src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory src/jar/swrl/java/org/mulgara/swrl src/jar/tuples/java/org/mulgara/store/tuples src/jar/util/java/org/mulgara/util src/jar/web/java/org/mulgara/webquery

pag at mulgara.org pag at mulgara.org
Thu Dec 10 17:02:13 UTC 2009


Author: pag
Date: 2009-12-10 09:02:12 -0800 (Thu, 10 Dec 2009)
New Revision: 1871

Added:
   trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt
   trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt
   trunk/jxdata/iTQL/distinct/
   trunk/jxdata/iTQL/distinct/queryResult1.txt
   trunk/jxdata/iTQL/distinct/queryResult2.txt
   trunk/jxdata/iTQL/distinct/queryResult3.txt
   trunk/jxdata/iTQL/distinct/result1.txt
   trunk/jxdata/iTQL/distinct/test.jxu
   trunk/jxdata/iTQL/people.rdf
   trunk/jxdata/iTQL/unique.rdf
   trunk/jxdata/iTQL/unique2.rdf
   trunk/jxdata/iTQL/vargraph/
   trunk/jxdata/iTQL/vargraph/queryResult1.txt
   trunk/jxdata/iTQL/vargraph/queryResult2.txt
   trunk/jxdata/iTQL/vargraph/queryResult3.txt
   trunk/jxdata/iTQL/vargraph/result1.txt
   trunk/jxdata/iTQL/vargraph/result2.txt
   trunk/jxdata/iTQL/vargraph/result3.txt
   trunk/jxdata/iTQL/vargraph/test.jxu
   trunk/lib/apache-mime4j-0.5.jar
   trunk/lib/commons-logging-1.1.1.jar
   trunk/lib/httpclient-4.0-beta2.jar
   trunk/lib/httpcore-4.0-beta3.jar
   trunk/lib/httpmime-4.0-beta2.jar
   trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
   trunk/src/jar/query/java/org/mulgara/query/functions/
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/
   trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java
   trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java
Removed:
   trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt
   trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt
   trunk/jxdata/iTQL/distinct/queryResult1.txt
   trunk/jxdata/iTQL/distinct/queryResult2.txt
   trunk/jxdata/iTQL/distinct/queryResult3.txt
   trunk/jxdata/iTQL/distinct/result1.txt
   trunk/jxdata/iTQL/distinct/test.jxu
   trunk/jxdata/iTQL/vargraph/
   trunk/jxdata/iTQL/vargraph/queryResult1.txt
   trunk/jxdata/iTQL/vargraph/queryResult2.txt
   trunk/jxdata/iTQL/vargraph/queryResult3.txt
   trunk/jxdata/iTQL/vargraph/result1.txt
   trunk/jxdata/iTQL/vargraph/result2.txt
   trunk/jxdata/iTQL/vargraph/result3.txt
   trunk/jxdata/iTQL/vargraph/test.jxu
   trunk/lib/apache-mime4j-0.5.jar
   trunk/lib/commons-logging-1.1.1.jar
   trunk/lib/httpclient-4.0-beta2.jar
   trunk/lib/httpcore-4.0-beta3.jar
   trunk/lib/httpmime-4.0-beta2.jar
   trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
   trunk/src/jar/query/java/org/mulgara/query/functions/
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java
   trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/
   trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
   trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
   trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java
   trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java
Modified:
   trunk/.project
   trunk/src/jar/content-n3/java/org/mulgara/content/n3/Parser.java
   trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/Parser.java
   trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java
   trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java
   trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java
   trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
   trunk/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java
   trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java
   trunk/src/jar/query/java/org/mulgara/query/AbstractConstraintExpression.java
   trunk/src/jar/query/java/org/mulgara/query/AskQuery.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintAssignment.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintDifference.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintExpression.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintFalse.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintOperation.java
   trunk/src/jar/query/java/org/mulgara/query/ConstraintTrue.java
   trunk/src/jar/query/java/org/mulgara/query/ConstructQuery.java
   trunk/src/jar/query/java/org/mulgara/query/Query.java
   trunk/src/jar/query/java/org/mulgara/query/QueryUnitTest.java
   trunk/src/jar/query/java/org/mulgara/query/SingleTransitiveConstraint.java
   trunk/src/jar/query/java/org/mulgara/query/TransitiveConstraint.java
   trunk/src/jar/query/java/org/mulgara/query/WalkConstraint.java
   trunk/src/jar/querylang/java/org/mulgara/itql/ItqlInterpreterBeanUnitTest.java
   trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java
   trunk/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java
   trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/PatternMapper.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java
   trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java
   trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj
   trunk/src/jar/querylang/sablecc/itql.grammar
   trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java
   trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java
   trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
   trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalConstraint.java
   trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/ConjunctiveTransformerUnitTest.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java
   trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java
   trunk/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java
   trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java
   trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestConstraint.java
   trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java
   trunk/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java
   trunk/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/IntervalConstraint.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
   trunk/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java
   trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java
   trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java
   trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java
   trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
   trunk/src/jar/util/java/org/mulgara/util/Bootstrap.java
   trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java
Log:
This is a merge of 1774:1870 from branches/distinct_queries. This introduces DISTINCT to SPARQL and NONDISTINCT to TQL, along with numerous UNION optimizations.

Modified: trunk/.project
===================================================================
--- trunk/.project	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/.project	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <projectDescription>
-	<name>mulgara</name>
+	<name>nondistinct</name>
 	<comment></comment>
 	<projects>
 	</projects>

Deleted: trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt
===================================================================
--- trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,157 +0,0 @@
-------------------------------------------------------------------------
-r1776 | pag | 2009-08-13 18:27:31 -0500 (Thu, 13 Aug 2009) | 1 line
-
-Building the serverURI from a string as this is more forgiving for some hostnames, such as one PLoS test system that has a number for the TLD
-------------------------------------------------------------------------
-r1773 | pag | 2009-08-12 14:05:26 -0500 (Wed, 12 Aug 2009) | 1 line
-
-Added the base URI to fields in the form. This was required in a Tomcat environment
-------------------------------------------------------------------------
-r1772 | pag | 2009-08-12 14:04:17 -0500 (Wed, 12 Aug 2009) | 1 line
-
-added generics to, and a new private class to reduce the reuse of the same generics code over and over
-------------------------------------------------------------------------
-r1771 | pag | 2009-08-12 14:01:41 -0500 (Wed, 12 Aug 2009) | 1 line
-
-A query transformation that moves OR expressions up to the root of the expression tree
-------------------------------------------------------------------------
-r1770 | pag | 2009-08-12 13:54:16 -0500 (Wed, 12 Aug 2009) | 1 line
-
-implemented getRowCardinality locally to be more efficient
-------------------------------------------------------------------------
-r1769 | pag | 2009-08-12 11:49:11 -0500 (Wed, 12 Aug 2009) | 1 line
-
-Added an unorderedAppend method. This uses unsorted tuples in an UnorderedAppend, as opposed to sorting tuples in an OrderedAppend
-------------------------------------------------------------------------
-r1768 | pag | 2009-08-12 11:47:47 -0500 (Wed, 12 Aug 2009) | 1 line
-
-Adding a modifyThread permission to compliment the modifyThreadGroup permission
-------------------------------------------------------------------------
-r1767 | pag | 2009-08-12 11:47:08 -0500 (Wed, 12 Aug 2009) | 1 line
-
-Moving up to 2.1.3 to avoid conflicts with 2.1.2
-------------------------------------------------------------------------
-r1766 | pag | 2009-08-10 19:23:57 -0500 (Mon, 10 Aug 2009) | 1 line
-
-Isolated the Jena interfaces into an external object, so that Jena is not needed in the classpath unless explicitly required.
-------------------------------------------------------------------------
-r1765 | pag | 2009-07-10 11:42:21 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added quotes to build script to allow for paths with spaces
-------------------------------------------------------------------------
-r1764 | pag | 2009-07-10 11:41:34 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added the getRowExpectedCount method to supplant getRowUpperBound
-------------------------------------------------------------------------
-r1763 | pag | 2009-07-10 11:40:35 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added help text for EXPORT, and updated all references to 'model' to say'graph'
-------------------------------------------------------------------------
-r1762 | pag | 2009-07-10 11:39:20 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added in grammar optimizations through the PatternTransformer. This was always supposed to be attached, but had been missed.
-------------------------------------------------------------------------
-r1761 | pag | 2009-07-10 11:37:58 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added the getRowExpectedCount method to supplant getRowUpperBound
-------------------------------------------------------------------------
-r1760 | pag | 2009-07-10 11:37:20 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added the getRowExpectedCount method to supplant getRowUpperBound, and removed warnings by adding generics
-------------------------------------------------------------------------
-r1759 | pag | 2009-07-10 11:35:27 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added the getRowExpectedCount method to supplant getRowUpperBound
-------------------------------------------------------------------------
-r1758 | pag | 2009-07-10 11:31:20 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added support for typed and language coded literals
-------------------------------------------------------------------------
-r1757 | pag | 2009-07-10 11:29:09 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Fixed a bug where the wrong object was tested for null
-------------------------------------------------------------------------
-r1756 | pag | 2009-07-10 11:28:24 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Adding in the ability to use non-QName URIs, for future expressions
-------------------------------------------------------------------------
-r1755 | pag | 2009-07-10 11:26:53 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added the getRowExpectedCount method to supplant getRowUpperBound
-------------------------------------------------------------------------
-r1754 | pag | 2009-07-10 11:25:25 -0500 (Fri, 10 Jul 2009) | 1 line
-
-Added the getRowExpectedCount method to supplant getRowUpperBound, plus cleaned up warnings by removing unused imports and adding generics
-------------------------------------------------------------------------
-r1753 | pag | 2009-07-06 17:40:35 -0500 (Mon, 06 Jul 2009) | 1 line
-
-Added in JSON escapes for literal strings. Not having them was a bug
-------------------------------------------------------------------------
-r1752 | pag | 2009-07-03 12:35:47 -0500 (Fri, 03 Jul 2009) | 1 line
-
-Missed the new CST class for variable assignment in commit 1751
-------------------------------------------------------------------------
-r1751 | pag | 2009-07-03 12:34:49 -0500 (Fri, 03 Jul 2009) | 1 line
-
-Added variable assignment as a SPARQL extension. This touches the parser and CST, the mapper to the AST, the AST, and the query execution (including Tuples operations)
-------------------------------------------------------------------------
-r1750 | pag | 2009-07-03 12:33:12 -0500 (Fri, 03 Jul 2009) | 1 line
-
-Added a necessary library to the test path so that BlockFile is available. Don't know why this didn't fail before, but it's been failing now
-------------------------------------------------------------------------
-r1749 | pag | 2009-07-03 12:31:40 -0500 (Fri, 03 Jul 2009) | 1 line
-
-Fixed the license
-------------------------------------------------------------------------
-r1748 | pag | 2009-07-03 12:31:08 -0500 (Fri, 03 Jul 2009) | 1 line
-
-More reasonably assumption about the expected value for the size of a join. This needs a major overhaul
-------------------------------------------------------------------------
-r1747 | pag | 2009-07-03 12:26:51 -0500 (Fri, 03 Jul 2009) | 1 line
-
-Added setIO permission for Jetty
-------------------------------------------------------------------------
-r1746 | pag | 2009-06-29 17:06:41 -0500 (Mon, 29 Jun 2009) | 1 line
-
-Adjustment of fudge-factor used for probabilistic weighting of row counts
-------------------------------------------------------------------------
-r1745 | pag | 2009-06-29 17:04:10 -0500 (Mon, 29 Jun 2009) | 1 line
-
-Removed call to optimize indexes on every commit
-------------------------------------------------------------------------
-r1744 | pag | 2009-06-29 17:03:09 -0500 (Mon, 29 Jun 2009) | 1 line
-
-New option allows user configuration files to be partial
-------------------------------------------------------------------------
-r1743 | pag | 2009-06-29 17:01:31 -0500 (Mon, 29 Jun 2009) | 1 line
-
-Removed references to obsolete libraries
-------------------------------------------------------------------------
-r1742 | pag | 2009-06-29 17:00:44 -0500 (Mon, 29 Jun 2009) | 1 line
-
-Added comments to the system configuration
-------------------------------------------------------------------------
-r1741 | pag | 2009-06-29 16:47:19 -0500 (Mon, 29 Jun 2009) | 1 line
-
-Made fields non-compulsory so a user can write partial files. The system file must be complete though.
-------------------------------------------------------------------------
-r1740 | pag | 2009-06-26 15:19:39 -0500 (Fri, 26 Jun 2009) | 1 line
-
-Integrated Andy Seaborne's JenaMulgara bridge. Added the JenaTest jar to properly test this bridge. Lots of optimizations are still possible.
-------------------------------------------------------------------------
-r1739 | pag | 2009-06-26 15:16:26 -0500 (Fri, 26 Jun 2009) | 1 line
-
-Cleaned up some formatting, and removed warnings through added generics, annotating unused loggers, and removing unused imports
-------------------------------------------------------------------------
-r1738 | pag | 2009-06-26 13:49:07 -0500 (Fri, 26 Jun 2009) | 1 line
-
-Changed an info message down to debug. I expected this would be rare and notable, but it is common
-------------------------------------------------------------------------
-r1737 | pag | 2009-06-23 02:40:21 -0500 (Tue, 23 Jun 2009) | 1 line
-
-Escaping entities in SPARQL XML results
-------------------------------------------------------------------------
-r1736 | alexhall | 2009-06-11 19:35:28 -0500 (Thu, 11 Jun 2009) | 1 line
-
-Modify the rule engine to support any multiple of 3 columns in the selection variables of a rule's query.  This allows rules to have multiple atoms in their heads, and is a more efficient implementation than splitting such rules into multiple rules with the same body and one head atom each.
-------------------------------------------------------------------------

Copied: trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt (from rev 1870, branches/distinct_queries/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt)
===================================================================
--- trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt	                        (rev 0)
+++ trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,157 @@
+------------------------------------------------------------------------
+r1776 | pag | 2009-08-13 18:27:31 -0500 (Thu, 13 Aug 2009) | 1 line
+
+Building the serverURI from a string as this is more forgiving for some hostnames, such as one PLoS test system that has a number for the TLD
+------------------------------------------------------------------------
+r1773 | pag | 2009-08-12 14:05:26 -0500 (Wed, 12 Aug 2009) | 1 line
+
+Added the base URI to fields in the form. This was required in a Tomcat environment
+------------------------------------------------------------------------
+r1772 | pag | 2009-08-12 14:04:17 -0500 (Wed, 12 Aug 2009) | 1 line
+
+added generics to, and a new private class to reduce the reuse of the same generics code over and over
+------------------------------------------------------------------------
+r1771 | pag | 2009-08-12 14:01:41 -0500 (Wed, 12 Aug 2009) | 1 line
+
+A query transformation that moves OR expressions up to the root of the expression tree
+------------------------------------------------------------------------
+r1770 | pag | 2009-08-12 13:54:16 -0500 (Wed, 12 Aug 2009) | 1 line
+
+implemented getRowCardinality locally to be more efficient
+------------------------------------------------------------------------
+r1769 | pag | 2009-08-12 11:49:11 -0500 (Wed, 12 Aug 2009) | 1 line
+
+Added an unorderedAppend method. This uses unsorted tuples in an UnorderedAppend, as opposed to sorting tuples in an OrderedAppend
+------------------------------------------------------------------------
+r1768 | pag | 2009-08-12 11:47:47 -0500 (Wed, 12 Aug 2009) | 1 line
+
+Adding a modifyThread permission to compliment the modifyThreadGroup permission
+------------------------------------------------------------------------
+r1767 | pag | 2009-08-12 11:47:08 -0500 (Wed, 12 Aug 2009) | 1 line
+
+Moving up to 2.1.3 to avoid conflicts with 2.1.2
+------------------------------------------------------------------------
+r1766 | pag | 2009-08-10 19:23:57 -0500 (Mon, 10 Aug 2009) | 1 line
+
+Isolated the Jena interfaces into an external object, so that Jena is not needed in the classpath unless explicitly required.
+------------------------------------------------------------------------
+r1765 | pag | 2009-07-10 11:42:21 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added quotes to build script to allow for paths with spaces
+------------------------------------------------------------------------
+r1764 | pag | 2009-07-10 11:41:34 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added the getRowExpectedCount method to supplant getRowUpperBound
+------------------------------------------------------------------------
+r1763 | pag | 2009-07-10 11:40:35 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added help text for EXPORT, and updated all references to 'model' to say'graph'
+------------------------------------------------------------------------
+r1762 | pag | 2009-07-10 11:39:20 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added in grammar optimizations through the PatternTransformer. This was always supposed to be attached, but had been missed.
+------------------------------------------------------------------------
+r1761 | pag | 2009-07-10 11:37:58 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added the getRowExpectedCount method to supplant getRowUpperBound
+------------------------------------------------------------------------
+r1760 | pag | 2009-07-10 11:37:20 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added the getRowExpectedCount method to supplant getRowUpperBound, and removed warnings by adding generics
+------------------------------------------------------------------------
+r1759 | pag | 2009-07-10 11:35:27 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added the getRowExpectedCount method to supplant getRowUpperBound
+------------------------------------------------------------------------
+r1758 | pag | 2009-07-10 11:31:20 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added support for typed and language coded literals
+------------------------------------------------------------------------
+r1757 | pag | 2009-07-10 11:29:09 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Fixed a bug where the wrong object was tested for null
+------------------------------------------------------------------------
+r1756 | pag | 2009-07-10 11:28:24 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Adding in the ability to use non-QName URIs, for future expressions
+------------------------------------------------------------------------
+r1755 | pag | 2009-07-10 11:26:53 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added the getRowExpectedCount method to supplant getRowUpperBound
+------------------------------------------------------------------------
+r1754 | pag | 2009-07-10 11:25:25 -0500 (Fri, 10 Jul 2009) | 1 line
+
+Added the getRowExpectedCount method to supplant getRowUpperBound, plus cleaned up warnings by removing unused imports and adding generics
+------------------------------------------------------------------------
+r1753 | pag | 2009-07-06 17:40:35 -0500 (Mon, 06 Jul 2009) | 1 line
+
+Added in JSON escapes for literal strings. Not having them was a bug
+------------------------------------------------------------------------
+r1752 | pag | 2009-07-03 12:35:47 -0500 (Fri, 03 Jul 2009) | 1 line
+
+Missed the new CST class for variable assignment in commit 1751
+------------------------------------------------------------------------
+r1751 | pag | 2009-07-03 12:34:49 -0500 (Fri, 03 Jul 2009) | 1 line
+
+Added variable assignment as a SPARQL extension. This touches the parser and CST, the mapper to the AST, the AST, and the query execution (including Tuples operations)
+------------------------------------------------------------------------
+r1750 | pag | 2009-07-03 12:33:12 -0500 (Fri, 03 Jul 2009) | 1 line
+
+Added a necessary library to the test path so that BlockFile is available. Don't know why this didn't fail before, but it's been failing now
+------------------------------------------------------------------------
+r1749 | pag | 2009-07-03 12:31:40 -0500 (Fri, 03 Jul 2009) | 1 line
+
+Fixed the license
+------------------------------------------------------------------------
+r1748 | pag | 2009-07-03 12:31:08 -0500 (Fri, 03 Jul 2009) | 1 line
+
+More reasonably assumption about the expected value for the size of a join. This needs a major overhaul
+------------------------------------------------------------------------
+r1747 | pag | 2009-07-03 12:26:51 -0500 (Fri, 03 Jul 2009) | 1 line
+
+Added setIO permission for Jetty
+------------------------------------------------------------------------
+r1746 | pag | 2009-06-29 17:06:41 -0500 (Mon, 29 Jun 2009) | 1 line
+
+Adjustment of fudge-factor used for probabilistic weighting of row counts
+------------------------------------------------------------------------
+r1745 | pag | 2009-06-29 17:04:10 -0500 (Mon, 29 Jun 2009) | 1 line
+
+Removed call to optimize indexes on every commit
+------------------------------------------------------------------------
+r1744 | pag | 2009-06-29 17:03:09 -0500 (Mon, 29 Jun 2009) | 1 line
+
+New option allows user configuration files to be partial
+------------------------------------------------------------------------
+r1743 | pag | 2009-06-29 17:01:31 -0500 (Mon, 29 Jun 2009) | 1 line
+
+Removed references to obsolete libraries
+------------------------------------------------------------------------
+r1742 | pag | 2009-06-29 17:00:44 -0500 (Mon, 29 Jun 2009) | 1 line
+
+Added comments to the system configuration
+------------------------------------------------------------------------
+r1741 | pag | 2009-06-29 16:47:19 -0500 (Mon, 29 Jun 2009) | 1 line
+
+Made fields non-compulsory so a user can write partial files. The system file must be complete though.
+------------------------------------------------------------------------
+r1740 | pag | 2009-06-26 15:19:39 -0500 (Fri, 26 Jun 2009) | 1 line
+
+Integrated Andy Seaborne's JenaMulgara bridge. Added the JenaTest jar to properly test this bridge. Lots of optimizations are still possible.
+------------------------------------------------------------------------
+r1739 | pag | 2009-06-26 15:16:26 -0500 (Fri, 26 Jun 2009) | 1 line
+
+Cleaned up some formatting, and removed warnings through added generics, annotating unused loggers, and removing unused imports
+------------------------------------------------------------------------
+r1738 | pag | 2009-06-26 13:49:07 -0500 (Fri, 26 Jun 2009) | 1 line
+
+Changed an info message down to debug. I expected this would be rare and notable, but it is common
+------------------------------------------------------------------------
+r1737 | pag | 2009-06-23 02:40:21 -0500 (Tue, 23 Jun 2009) | 1 line
+
+Escaping entities in SPARQL XML results
+------------------------------------------------------------------------
+r1736 | alexhall | 2009-06-11 19:35:28 -0500 (Thu, 11 Jun 2009) | 1 line
+
+Modify the rule engine to support any multiple of 3 columns in the selection variables of a rule's query.  This allows rules to have multiple atoms in their heads, and is a more efficient implementation than splitting such rules into multiple rules with the same body and one head atom each.
+------------------------------------------------------------------------

Deleted: trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt
===================================================================
--- trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,272 +0,0 @@
-------------------------------------------------------------------------
-r1818 | pag | 2009-10-07 14:34:54 -0400 (Wed, 07 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedProjection.java
-
-Changed info message to debug
-------------------------------------------------------------------------
-r1817 | pag | 2009-10-06 23:04:28 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java
-   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java
-   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java
-
-The new 'unsafe' set of functions that missed the checking in r1816. Documentation on the use of these functions is at http://mulgara.org/trac/wiki/UnsafeFunctions
-------------------------------------------------------------------------
-r1816 | pag | 2009-10-06 23:02:38 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   A /trunk/src/jar/query/java/org/mulgara/query/functions
-   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java (from /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunction.java:1797)
-   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java (from /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunctionGroup.java:1797)
-   M /trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
-   D /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunction.java
-   D /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunctionGroup.java
-   M /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
-   M /trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
-   M /trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
-
-Refactored out common function loading code into MulgaraFunctionResolver. This meant changing static methods to instance methods (but that's OK, since they are only instantiated once). Also, took the completely abstract class of MulgaraFunctionGroup and converted to an interface. Common code was then moved to a new functions package. Finally, a new 'unsafe' set of functions was created. Documentation on the use of these functions is at http://mulgara.org/trac/wiki/UnsafeFunctions
-------------------------------------------------------------------------
-r1815 | pag | 2009-10-06 22:57:04 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
-
-Changed the registry to use a list instead of a set, so that preference can be provided to the functions that are loaded first
-------------------------------------------------------------------------
-r1814 | pag | 2009-10-06 02:45:58 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver/java/org/mulgara/resolver/StringPoolSession.java
-
-No longer canonicalizing URIs if they don't appear in the rmi scheme. The only exception is the system graph, which is always stored as relative.
-------------------------------------------------------------------------
-r1813 | pag | 2009-10-06 02:44:48 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/conf/mulgara-config.xml
-
-Added Xalan and Mulgara function libraries
-------------------------------------------------------------------------
-r1812 | pag | 2009-10-06 02:44:13 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/build.xml
-
-No longer allowing extra XML files to be loaded into JAR files that are created in the build
-------------------------------------------------------------------------
-r1811 | pag | 2009-10-06 02:43:18 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraServer.java
-
-Loading up XPathFunctionResolvers, as specified in the config files
-------------------------------------------------------------------------
-r1810 | pag | 2009-10-06 02:42:20 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
-
-Added support for IRIs to carry QNames with them
-------------------------------------------------------------------------
-r1809 | pag | 2009-10-06 02:41:42 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
-
-Added support for calling external functions, provided through XPathFunctionResolvers and identified by QName
-------------------------------------------------------------------------
-r1808 | pag | 2009-10-06 02:40:35 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/conf/mulgara-embedded.xsd
-   M /trunk/src/jar/server/java/org/mulgara/server/MulgaraUserConfig.java
-
-Added field for XpathFunctionResolvers
-------------------------------------------------------------------------
-r1807 | pag | 2009-10-06 02:39:27 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFileUnitTest.java
-
-removed warnings
-------------------------------------------------------------------------
-r1806 | pag | 2009-10-06 02:38:39 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java
-
-added generics and refactored a fixed IF statement to remove warnings
-------------------------------------------------------------------------
-r1805 | pag | 2009-10-06 02:37:07 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleWriteThread.java
-
-Added generics to avoid warnings
-------------------------------------------------------------------------
-r1804 | pag | 2009-10-06 02:36:36 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFile.java
-
-removed stack traces from phases to save on memory
-------------------------------------------------------------------------
-r1803 | pag | 2009-10-06 02:35:20 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/util/java/org/mulgara/util/AbstractMulgaraResultSet.java
-
-removed unnecessary annotations
-------------------------------------------------------------------------
-r1802 | pag | 2009-10-06 02:34:38 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/querylang/java/org/mulgara/sparql/FilterMapper.java
-
-Providing external functions with QNames and not just a URI
-------------------------------------------------------------------------
-r1801 | pag | 2009-10-06 02:33:44 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructureImpl.java
-
-Provides hints to IRIs to find QNames
-------------------------------------------------------------------------
-r1800 | pag | 2009-10-06 02:32:47 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
-
-Now includes QNames. Also scanning known namespaces to attempt to build up QNames
-------------------------------------------------------------------------
-r1799 | pag | 2009-10-06 02:31:49 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
-
-allowing unknown types to be converted to strings instead of throwing an error
-------------------------------------------------------------------------
-r1798 | pag | 2009-10-06 02:30:35 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/query/java/org/mulgara/query/rdf/Mulgara.java
-
-Added namespace data
-------------------------------------------------------------------------
-r1797 | pag | 2009-10-06 02:29:59 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunction.java
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunctionGroup.java
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
-   A /trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
-
-Initial implementation of a set of functions for Mulgara, and the XPathFunctionResolver
-------------------------------------------------------------------------
-r1796 | pag | 2009-10-06 02:28:57 -0400 (Tue, 06 Oct 2009) | 1 line
-Changed paths:
-   A /trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
-
-Added a central registry for loading XPathFunctionResolvers
-------------------------------------------------------------------------
-r1795 | pag | 2009-09-26 11:23:34 -0400 (Sat, 26 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/util/java/org/mulgara/util/ServerInfoRef.java
-
-Extended findSetter method to look for supertypes on provided parameters
-------------------------------------------------------------------------
-r1794 | pag | 2009-09-24 19:39:23 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/common.properties
-
-Moving to new version early
-------------------------------------------------------------------------
-r1793 | pag | 2009-09-24 19:38:37 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/conf/mulgara-rmi.policy
-   M /trunk/conf/mulgara-test.policy
-
-Added permission for Apple systems to access the keychain for HTTPS requests
-------------------------------------------------------------------------
-r1792 | pag | 2009-09-24 19:13:24 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/util-xa/java/org/mulgara/store/xa/FreeList.java
-
-Moved stack traces out of the Phase constructor and into the Phase.use method. Stack traces are not debug only
-------------------------------------------------------------------------
-r1791 | pag | 2009-09-24 19:12:38 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
-
-Moved stack traces out of the Phase constructor and into the Phase.use method. Stack traces are not debug only
-------------------------------------------------------------------------
-r1790 | pag | 2009-09-24 19:10:48 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/util/java/org/mulgara/util/functional/C.java
-
-Added string join() methods for lists
-------------------------------------------------------------------------
-r1789 | pag | 2009-09-24 17:33:53 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/http/LocalTriple.java
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/http/MulgaraServlet.java
-
-Fixed license
-------------------------------------------------------------------------
-r1788 | pag | 2009-09-24 10:56:54 -0400 (Thu, 24 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
-
-Tweaking weighted terms for operand ordering. This definitely helps Topaz queries.
-------------------------------------------------------------------------
-r1787 | pag | 2009-09-12 01:41:24 -0400 (Sat, 12 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/content-n3/java/org/mulgara/content/n3/N3WriterUnitTest.java
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedN3Answer.java
-
-Added the option to set the charset encoding, with a default of UTF-8
-------------------------------------------------------------------------
-r1786 | pag | 2009-09-12 01:39:37 -0400 (Sat, 12 Sep 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedAnswer.java
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedXMLAnswer.java
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswer.java
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswer.java
-   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswerUnitTest.java
-
-Changed default encoding to UTF-8, added encoding to the XML header, and added constructor variants to set the encoding
-------------------------------------------------------------------------
-r1785 | alexhall | 2009-08-26 12:53:58 -0400 (Wed, 26 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/conf/mulgara.policy
-
-Accidentally committed with the wrong permissions.
-------------------------------------------------------------------------
-r1784 | alexhall | 2009-08-26 12:49:41 -0400 (Wed, 26 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/conf/mulgara-rmi.policy
-   M /trunk/conf/mulgara.policy
-   M /trunk/src/jar/resolver/java/org/mulgara/resolver/ContentFactory.java
-
-Fix handling of content with an https: URL
-------------------------------------------------------------------------
-r1783 | alexhall | 2009-08-26 11:16:52 -0400 (Wed, 26 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver/java/org/mulgara/resolver/ContentFactory.java
-
-Add generics and fix warnings.
-------------------------------------------------------------------------
-r1782 | pag | 2009-08-20 09:48:04 -0400 (Thu, 20 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
-
-removed unused variables
-------------------------------------------------------------------------
-r1781 | pag | 2009-08-20 09:47:45 -0400 (Thu, 20 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
-
-Added stack trace to exceptions that are not being chained to their cause
-------------------------------------------------------------------------
-r1780 | pag | 2009-08-20 01:11:03 -0400 (Thu, 20 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexException.java
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexUnitTest.java
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneIndexerCache.java
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java
-   M /trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/ResolverException.java
-
-Removed warnings by adding serialization IDs and removing unused variables. Also fixed some TODO Javadocs and cleaned up some of the formatting
-------------------------------------------------------------------------
-r1779 | pag | 2009-08-20 01:09:53 -0400 (Thu, 20 Aug 2009) | 1 line
-Changed paths:
-   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
-
-Removed exception chains for FullTextStringIndexExceptions as these may not be instantiated at the client side.
-------------------------------------------------------------------------

Copied: trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt (from rev 1870, branches/distinct_queries/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt)
===================================================================
--- trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt	                        (rev 0)
+++ trunk/KOWARI-MODIFICATIONS/mods-mulgara-2.1.4.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,272 @@
+------------------------------------------------------------------------
+r1818 | pag | 2009-10-07 14:34:54 -0400 (Wed, 07 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/tuples/java/org/mulgara/store/tuples/UnorderedProjection.java
+
+Changed info message to debug
+------------------------------------------------------------------------
+r1817 | pag | 2009-10-06 23:04:28 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java
+   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java
+   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java
+
+The new 'unsafe' set of functions that missed the checking in r1816. Documentation on the use of these functions is at http://mulgara.org/trac/wiki/UnsafeFunctions
+------------------------------------------------------------------------
+r1816 | pag | 2009-10-06 23:02:38 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   A /trunk/src/jar/query/java/org/mulgara/query/functions
+   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java (from /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunction.java:1797)
+   A /trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java (from /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunctionGroup.java:1797)
+   M /trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
+   D /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunction.java
+   D /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunctionGroup.java
+   M /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
+   M /trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
+   M /trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
+
+Refactored out common function loading code into MulgaraFunctionResolver. This meant changing static methods to instance methods (but that's OK, since they are only instantiated once). Also, took the completely abstract class of MulgaraFunctionGroup and converted to an interface. Common code was then moved to a new functions package. Finally, a new 'unsafe' set of functions was created. Documentation on the use of these functions is at http://mulgara.org/trac/wiki/UnsafeFunctions
+------------------------------------------------------------------------
+r1815 | pag | 2009-10-06 22:57:04 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
+
+Changed the registry to use a list instead of a set, so that preference can be provided to the functions that are loaded first
+------------------------------------------------------------------------
+r1814 | pag | 2009-10-06 02:45:58 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver/java/org/mulgara/resolver/StringPoolSession.java
+
+No longer canonicalizing URIs if they don't appear in the rmi scheme. The only exception is the system graph, which is always stored as relative.
+------------------------------------------------------------------------
+r1813 | pag | 2009-10-06 02:44:48 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/conf/mulgara-config.xml
+
+Added Xalan and Mulgara function libraries
+------------------------------------------------------------------------
+r1812 | pag | 2009-10-06 02:44:13 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/build.xml
+
+No longer allowing extra XML files to be loaded into JAR files that are created in the build
+------------------------------------------------------------------------
+r1811 | pag | 2009-10-06 02:43:18 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/server/java/org/mulgara/server/EmbeddedMulgaraServer.java
+
+Loading up XPathFunctionResolvers, as specified in the config files
+------------------------------------------------------------------------
+r1810 | pag | 2009-10-06 02:42:20 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/query/java/org/mulgara/query/filter/value/IRI.java
+
+Added support for IRIs to carry QNames with them
+------------------------------------------------------------------------
+r1809 | pag | 2009-10-06 02:41:42 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/query/java/org/mulgara/query/filter/value/ExternalFn.java
+
+Added support for calling external functions, provided through XPathFunctionResolvers and identified by QName
+------------------------------------------------------------------------
+r1808 | pag | 2009-10-06 02:40:35 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/conf/mulgara-embedded.xsd
+   M /trunk/src/jar/server/java/org/mulgara/server/MulgaraUserConfig.java
+
+Added field for XpathFunctionResolvers
+------------------------------------------------------------------------
+r1807 | pag | 2009-10-06 02:39:27 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFileUnitTest.java
+
+removed warnings
+------------------------------------------------------------------------
+r1806 | pag | 2009-10-06 02:38:39 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/XAStatementStoreImplUnitTest.java
+
+added generics and refactored a fixed IF statement to remove warnings
+------------------------------------------------------------------------
+r1805 | pag | 2009-10-06 02:37:07 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleWriteThread.java
+
+Added generics to avoid warnings
+------------------------------------------------------------------------
+r1804 | pag | 2009-10-06 02:36:36 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa/TripleAVLFile.java
+
+removed stack traces from phases to save on memory
+------------------------------------------------------------------------
+r1803 | pag | 2009-10-06 02:35:20 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/util/java/org/mulgara/util/AbstractMulgaraResultSet.java
+
+removed unnecessary annotations
+------------------------------------------------------------------------
+r1802 | pag | 2009-10-06 02:34:38 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/querylang/java/org/mulgara/sparql/FilterMapper.java
+
+Providing external functions with QNames and not just a URI
+------------------------------------------------------------------------
+r1801 | pag | 2009-10-06 02:33:44 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/querylang/java/org/mulgara/sparql/parser/QueryStructureImpl.java
+
+Provides hints to IRIs to find QNames
+------------------------------------------------------------------------
+r1800 | pag | 2009-10-06 02:32:47 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
+
+Now includes QNames. Also scanning known namespaces to attempt to build up QNames
+------------------------------------------------------------------------
+r1799 | pag | 2009-10-06 02:31:49 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/query/java/org/mulgara/query/filter/value/TypedLiteral.java
+
+allowing unknown types to be converted to strings instead of throwing an error
+------------------------------------------------------------------------
+r1798 | pag | 2009-10-06 02:30:35 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/query/java/org/mulgara/query/rdf/Mulgara.java
+
+Added namespace data
+------------------------------------------------------------------------
+r1797 | pag | 2009-10-06 02:29:59 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunction.java
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraFunctionGroup.java
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
+   A /trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
+
+Initial implementation of a set of functions for Mulgara, and the XPathFunctionResolver
+------------------------------------------------------------------------
+r1796 | pag | 2009-10-06 02:28:57 -0400 (Tue, 06 Oct 2009) | 1 line
+Changed paths:
+   A /trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
+
+Added a central registry for loading XPathFunctionResolvers
+------------------------------------------------------------------------
+r1795 | pag | 2009-09-26 11:23:34 -0400 (Sat, 26 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/util/java/org/mulgara/util/ServerInfoRef.java
+
+Extended findSetter method to look for supertypes on provided parameters
+------------------------------------------------------------------------
+r1794 | pag | 2009-09-24 19:39:23 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/common.properties
+
+Moving to new version early
+------------------------------------------------------------------------
+r1793 | pag | 2009-09-24 19:38:37 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/conf/mulgara-rmi.policy
+   M /trunk/conf/mulgara-test.policy
+
+Added permission for Apple systems to access the keychain for HTTPS requests
+------------------------------------------------------------------------
+r1792 | pag | 2009-09-24 19:13:24 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/util-xa/java/org/mulgara/store/xa/FreeList.java
+
+Moved stack traces out of the Phase constructor and into the Phase.use method. Stack traces are not debug only
+------------------------------------------------------------------------
+r1791 | pag | 2009-09-24 19:12:38 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
+
+Moved stack traces out of the Phase constructor and into the Phase.use method. Stack traces are not debug only
+------------------------------------------------------------------------
+r1790 | pag | 2009-09-24 19:10:48 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/util/java/org/mulgara/util/functional/C.java
+
+Added string join() methods for lists
+------------------------------------------------------------------------
+r1789 | pag | 2009-09-24 17:33:53 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/http/LocalTriple.java
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/http/MulgaraServlet.java
+
+Fixed license
+------------------------------------------------------------------------
+r1788 | pag | 2009-09-24 10:56:54 -0400 (Thu, 24 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
+
+Tweaking weighted terms for operand ordering. This definitely helps Topaz queries.
+------------------------------------------------------------------------
+r1787 | pag | 2009-09-12 01:41:24 -0400 (Sat, 12 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/content-n3/java/org/mulgara/content/n3/N3WriterUnitTest.java
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedN3Answer.java
+
+Added the option to set the charset encoding, with a default of UTF-8
+------------------------------------------------------------------------
+r1786 | pag | 2009-09-12 01:39:37 -0400 (Sat, 12 Sep 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedAnswer.java
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/AbstractStreamedXMLAnswer.java
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlJSONAnswer.java
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswer.java
+   M /trunk/src/jar/querylang/java/org/mulgara/protocol/StreamedSparqlXMLAnswerUnitTest.java
+
+Changed default encoding to UTF-8, added encoding to the XML header, and added constructor variants to set the encoding
+------------------------------------------------------------------------
+r1785 | alexhall | 2009-08-26 12:53:58 -0400 (Wed, 26 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/conf/mulgara.policy
+
+Accidentally committed with the wrong permissions.
+------------------------------------------------------------------------
+r1784 | alexhall | 2009-08-26 12:49:41 -0400 (Wed, 26 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/conf/mulgara-rmi.policy
+   M /trunk/conf/mulgara.policy
+   M /trunk/src/jar/resolver/java/org/mulgara/resolver/ContentFactory.java
+
+Fix handling of content with an https: URL
+------------------------------------------------------------------------
+r1783 | alexhall | 2009-08-26 11:16:52 -0400 (Wed, 26 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver/java/org/mulgara/resolver/ContentFactory.java
+
+Add generics and fix warnings.
+------------------------------------------------------------------------
+r1782 | pag | 2009-08-20 09:48:04 -0400 (Thu, 20 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
+
+removed unused variables
+------------------------------------------------------------------------
+r1781 | pag | 2009-08-20 09:47:45 -0400 (Thu, 20 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
+
+Added stack trace to exceptions that are not being chained to their cause
+------------------------------------------------------------------------
+r1780 | pag | 2009-08-20 01:11:03 -0400 (Thu, 20 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexException.java
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/FullTextStringIndexUnitTest.java
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneIndexerCache.java
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolverUnitTest.java
+   M /trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/ResolverException.java
+
+Removed warnings by adding serialization IDs and removing unused variables. Also fixed some TODO Javadocs and cleaned up some of the formatting
+------------------------------------------------------------------------
+r1779 | pag | 2009-08-20 01:09:53 -0400 (Thu, 20 Aug 2009) | 1 line
+Changed paths:
+   M /trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneResolver.java
+
+Removed exception chains for FullTextStringIndexExceptions as these may not be instantiated at the client side.
+------------------------------------------------------------------------

Copied: trunk/jxdata/iTQL/distinct (from rev 1870, branches/distinct_queries/jxdata/iTQL/distinct)

Deleted: trunk/jxdata/iTQL/distinct/queryResult1.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/distinct/queryResult1.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/distinct/queryResult1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<sparql xmlns="http://www.w3.org/2005/sparql-results#">
-  <head>
-    <variable name="person"/>
-    <variable name="email"/>
-  </head>
-  <results>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Barney</uri>
-      </binding>
-      <binding name="email">
-        <literal>barney at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Brian</uri>
-      </binding>
-      <binding name="email">
-        <literal>brian at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#David</uri>
-      </binding>
-      <binding name="email">
-        <literal>david at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Fred</uri>
-      </binding>
-      <binding name="email">
-        <literal>fred at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Janelle</uri>
-      </binding>
-      <binding name="email">
-        <literal>janelle at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Peter</uri>
-      </binding>
-      <binding name="email">
-        <literal>peter at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Theresa</uri>
-      </binding>
-      <binding name="email">
-        <literal>theresa at test.com</literal>
-      </binding>
-    </result>
-  </results>
-</sparql>

Copied: trunk/jxdata/iTQL/distinct/queryResult1.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/distinct/queryResult1.txt)
===================================================================
--- trunk/jxdata/iTQL/distinct/queryResult1.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/distinct/queryResult1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sparql xmlns="http://www.w3.org/2005/sparql-results#">
+  <head>
+    <variable name="person"/>
+    <variable name="email"/>
+  </head>
+  <results>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Barney</uri>
+      </binding>
+      <binding name="email">
+        <literal>barney at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Brian</uri>
+      </binding>
+      <binding name="email">
+        <literal>brian at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#David</uri>
+      </binding>
+      <binding name="email">
+        <literal>david at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Fred</uri>
+      </binding>
+      <binding name="email">
+        <literal>fred at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Janelle</uri>
+      </binding>
+      <binding name="email">
+        <literal>janelle at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Peter</uri>
+      </binding>
+      <binding name="email">
+        <literal>peter at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Theresa</uri>
+      </binding>
+      <binding name="email">
+        <literal>theresa at test.com</literal>
+      </binding>
+    </result>
+  </results>
+</sparql>

Deleted: trunk/jxdata/iTQL/distinct/queryResult2.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/distinct/queryResult2.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/distinct/queryResult2.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,65 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<sparql xmlns="http://www.w3.org/2005/sparql-results#">
-  <head>
-    <variable name="person"/>
-    <variable name="email"/>
-  </head>
-  <results>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Barney</uri>
-      </binding>
-      <binding name="email">
-        <literal>barney at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Brian</uri>
-      </binding>
-      <binding name="email">
-        <literal>brian at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#David</uri>
-      </binding>
-      <binding name="email">
-        <literal>david at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Fred</uri>
-      </binding>
-      <binding name="email">
-        <literal>fred at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Janelle</uri>
-      </binding>
-      <binding name="email">
-        <literal>janelle at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Peter</uri>
-      </binding>
-      <binding name="email">
-        <literal>peter at test.com</literal>
-      </binding>
-    </result>
-    <result>
-      <binding name="person">
-        <uri>http://test.com/test#Theresa</uri>
-      </binding>
-      <binding name="email">
-        <literal>theresa at test.com</literal>
-      </binding>
-    </result>
-  </results>
-</sparql>

Copied: trunk/jxdata/iTQL/distinct/queryResult2.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/distinct/queryResult2.txt)
===================================================================
--- trunk/jxdata/iTQL/distinct/queryResult2.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/distinct/queryResult2.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<sparql xmlns="http://www.w3.org/2005/sparql-results#">
+  <head>
+    <variable name="person"/>
+    <variable name="email"/>
+  </head>
+  <results>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Barney</uri>
+      </binding>
+      <binding name="email">
+        <literal>barney at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Brian</uri>
+      </binding>
+      <binding name="email">
+        <literal>brian at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#David</uri>
+      </binding>
+      <binding name="email">
+        <literal>david at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Fred</uri>
+      </binding>
+      <binding name="email">
+        <literal>fred at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Janelle</uri>
+      </binding>
+      <binding name="email">
+        <literal>janelle at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Peter</uri>
+      </binding>
+      <binding name="email">
+        <literal>peter at test.com</literal>
+      </binding>
+    </result>
+    <result>
+      <binding name="person">
+        <uri>http://test.com/test#Theresa</uri>
+      </binding>
+      <binding name="email">
+        <literal>theresa at test.com</literal>
+      </binding>
+    </result>
+  </results>
+</sparql>

Deleted: trunk/jxdata/iTQL/distinct/queryResult3.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/distinct/queryResult3.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/distinct/queryResult3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><variables><person/><email/></variables><solution><person resource="http://test.com/test#Barney"/><email>barney at test.com</email></solution><solution><person resource="http://test.com/test#Fred"/><email>fred at test.com</email></solution><solution><person resource="http://test.com/test#Fred"/><email>fred at test.com</email></solution></query></answer>

Copied: trunk/jxdata/iTQL/distinct/queryResult3.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/distinct/queryResult3.txt)
===================================================================
--- trunk/jxdata/iTQL/distinct/queryResult3.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/distinct/queryResult3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><person/><email/></variables><solution><person resource="http://test.com/test#Barney"/><email>barney at test.com</email></solution><solution><person resource="http://test.com/test#Fred"/><email>fred at test.com</email></solution><solution><person resource="http://test.com/test#Fred"/><email>fred at test.com</email></solution></query></answer>

Deleted: trunk/jxdata/iTQL/distinct/result1.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/distinct/result1.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/distinct/result1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 96 statements from @baseuri@/jxdata/iTQL/people.rdf into test:people</message></query></answer>

Copied: trunk/jxdata/iTQL/distinct/result1.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/distinct/result1.txt)
===================================================================
--- trunk/jxdata/iTQL/distinct/result1.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/distinct/result1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 96 statements from @baseuri@/jxdata/iTQL/people.rdf into test:people</message></query></answer>

Deleted: trunk/jxdata/iTQL/distinct/test.jxu
===================================================================
--- branches/distinct_queries/jxdata/iTQL/distinct/test.jxu	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/distinct/test.jxu	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,137 +0,0 @@
-<jxu>
-  <set name="debug" value="false" />
-
-  <set name="modelName" value="test:people" />
-  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/people.rdf&gt; into &lt;test:people&gt; ;" />
-  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
-
-  <ifEqual converse="true" file="result1.txt" name="loadResult">
-    <save name="loadResult" file="badLoadResult.xml"/>
-    <fail>Output failed.  Check badLoadResult.xml for output.</fail>
-  </ifEqual>
-
-  <!-- now query the graphs -->
-
-  <set name="query" value="prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt;
-      prefix mulgara: &lt;http://mulgara.org/mulgara#&gt;
-      prefix foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
-      prefix contact: &lt;http://www.w3.org/2000/10/swap/pim/contact#&gt;
-  
-      select ?person ?email
-      from &lt;test:people&gt;
-      where {
-        ?person a foaf:Person .
-        ?person foaf:mbox ?email .
-        {
-          { ?person foaf:firstName 'Fred' }
-          UNION
-          { ?person foaf:firstName 'Barney' }
-          UNION
-          {
-            { ?person contact:home [ contact:address [ contact:city 'London' ] ] }
-            UNION
-            { ?person contact:home [ contact:address [ contact:city 'NY' ] ] } 
-            UNION
-            {
-              ?person foaf:birthday ?bd .
-              GRAPH &lt;sys:xsd&gt; {
-                ?bd mulgara:after '1970-07-01'^^xsd:date .
-                ?bd mulgara:before '1971-06-30'^^xsd:date
-              }
-            }
-            UNION
-            {
-              ?person foaf:birthday ?bd .
-              GRAPH &lt;sys:xsd&gt; { ?bd mulgara:after '1975-01-01'^^xsd:date .  ?bd mulgara:before '1975-12-31'^^xsd:date } .
-              {
-                { ?person contact:home [ contact:address [ contact:city 'Chicago' ] ] }
-                UNION
-                { ?person contact:home [ contact:address [ contact:city 'Fredericksburg' ] ] }
-              }
-            }
-          }
-        }
-      }
-      order by ?person"/>
-
-  <eval stepClass="org.mulgara.store.jxunit.SparqlQueryJX" />
-  <ifEqual converse="true" file="queryResult1.txt" name="queryResult">
-    <save name="queryResult" file="badQuery1Result.xml"/>
-    <fail>Output failed.  Check badQuery1Result.xml for output.</fail>
-  </ifEqual>
-
-
-  <set name="query" value="prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt;
-      prefix mulgara: &lt;http://mulgara.org/mulgara#&gt;
-      prefix foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
-      prefix contact: &lt;http://www.w3.org/2000/10/swap/pim/contact#&gt;
-  
-      select distinct ?person ?email
-      from &lt;test:people&gt;
-      where {
-        ?person a foaf:Person .
-        ?person foaf:mbox ?email .
-        {
-          { ?person foaf:firstName 'Fred' }
-          UNION
-          { ?person foaf:firstName 'Barney' }
-          UNION
-          {
-            { ?person contact:home [ contact:address [ contact:city 'London' ] ] }
-            UNION
-            { ?person contact:home [ contact:address [ contact:city 'NY' ] ] } 
-            UNION
-            {
-              ?person foaf:birthday ?bd .
-              GRAPH &lt;sys:xsd&gt; {
-                ?bd mulgara:after '1970-07-01'^^xsd:date .
-                ?bd mulgara:before '1971-06-30'^^xsd:date
-              }
-            }
-            UNION
-            {
-              ?person foaf:birthday ?bd .
-              GRAPH &lt;sys:xsd&gt; { ?bd mulgara:after '1975-01-01'^^xsd:date .  ?bd mulgara:before '1975-12-31'^^xsd:date } .
-              {
-                { ?person contact:home [ contact:address [ contact:city 'Chicago' ] ] }
-                UNION
-                { ?person contact:home [ contact:address [ contact:city 'Fredericksburg' ] ] }
-              }
-            }
-          }
-        }
-      }
-      order by ?person"/>
-
-  <eval stepClass="org.mulgara.store.jxunit.SparqlQueryJX" />
-  <ifEqual converse="true" file="queryResult2.txt" name="queryResult">
-    <save name="queryResult" file="badQuery2Result.xml"/>
-    <fail>Output failed.  Check badQuery2Result.xml for output.</fail>
-  </ifEqual>
-
-
-  <set name="query" value="
-      select nondistinct ?person ?email
-      from &lt;test:people&gt;
-      where 
-        ?person &lt;rdf:type&gt; &lt;foaf:Person&gt; and
-        ?person &lt;foaf:mbox&gt; ?email and
-        (
-          ?person &lt;foaf:firstName&gt; 'Fred'
-          or
-          ( ?person &lt;http://www.w3.org/2000/10/swap/pim/contact#home&gt; ?h and ?h &lt;http://www.w3.org/2000/10/swap/pim/contact#address&gt; ?a and ?a &lt;http://www.w3.org/2000/10/swap/pim/contact#city&gt; 'Bedrock' )
-        )
-      order by ?person ; "/>
-
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-  <ifEqual converse="true" file="queryResult3.txt" name="queryResult">
-    <save name="queryResult" file="badQuery3Result.xml"/>
-    <fail>Output failed.  Check badQuery3Result.xml for output.</fail>
-  </ifEqual>
-
-  <!-- now drop the graphs -->
-  <set name="query" value="drop &lt;test:people&gt;;"/>
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-
-</jxu>
-

Copied: trunk/jxdata/iTQL/distinct/test.jxu (from rev 1870, branches/distinct_queries/jxdata/iTQL/distinct/test.jxu)
===================================================================
--- trunk/jxdata/iTQL/distinct/test.jxu	                        (rev 0)
+++ trunk/jxdata/iTQL/distinct/test.jxu	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,137 @@
+<jxu>
+  <set name="debug" value="false" />
+
+  <set name="modelName" value="test:people" />
+  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/people.rdf&gt; into &lt;test:people&gt; ;" />
+  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
+
+  <ifEqual converse="true" file="result1.txt" name="loadResult">
+    <save name="loadResult" file="badLoadResult.xml"/>
+    <fail>Output failed.  Check badLoadResult.xml for output.</fail>
+  </ifEqual>
+
+  <!-- now query the graphs -->
+
+  <set name="query" value="prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt;
+      prefix mulgara: &lt;http://mulgara.org/mulgara#&gt;
+      prefix foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
+      prefix contact: &lt;http://www.w3.org/2000/10/swap/pim/contact#&gt;
+  
+      select ?person ?email
+      from &lt;test:people&gt;
+      where {
+        ?person a foaf:Person .
+        ?person foaf:mbox ?email .
+        {
+          { ?person foaf:firstName 'Fred' }
+          UNION
+          { ?person foaf:firstName 'Barney' }
+          UNION
+          {
+            { ?person contact:home [ contact:address [ contact:city 'London' ] ] }
+            UNION
+            { ?person contact:home [ contact:address [ contact:city 'NY' ] ] } 
+            UNION
+            {
+              ?person foaf:birthday ?bd .
+              GRAPH &lt;sys:xsd&gt; {
+                ?bd mulgara:after '1970-07-01'^^xsd:date .
+                ?bd mulgara:before '1971-06-30'^^xsd:date
+              }
+            }
+            UNION
+            {
+              ?person foaf:birthday ?bd .
+              GRAPH &lt;sys:xsd&gt; { ?bd mulgara:after '1975-01-01'^^xsd:date .  ?bd mulgara:before '1975-12-31'^^xsd:date } .
+              {
+                { ?person contact:home [ contact:address [ contact:city 'Chicago' ] ] }
+                UNION
+                { ?person contact:home [ contact:address [ contact:city 'Fredericksburg' ] ] }
+              }
+            }
+          }
+        }
+      }
+      order by ?person"/>
+
+  <eval stepClass="org.mulgara.store.jxunit.SparqlQueryJX" />
+  <ifEqual converse="true" file="queryResult1.txt" name="queryResult">
+    <save name="queryResult" file="badQuery1Result.xml"/>
+    <fail>Output failed.  Check badQuery1Result.xml for output.</fail>
+  </ifEqual>
+
+
+  <set name="query" value="prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt;
+      prefix mulgara: &lt;http://mulgara.org/mulgara#&gt;
+      prefix foaf: &lt;http://xmlns.com/foaf/0.1/&gt;
+      prefix contact: &lt;http://www.w3.org/2000/10/swap/pim/contact#&gt;
+  
+      select distinct ?person ?email
+      from &lt;test:people&gt;
+      where {
+        ?person a foaf:Person .
+        ?person foaf:mbox ?email .
+        {
+          { ?person foaf:firstName 'Fred' }
+          UNION
+          { ?person foaf:firstName 'Barney' }
+          UNION
+          {
+            { ?person contact:home [ contact:address [ contact:city 'London' ] ] }
+            UNION
+            { ?person contact:home [ contact:address [ contact:city 'NY' ] ] } 
+            UNION
+            {
+              ?person foaf:birthday ?bd .
+              GRAPH &lt;sys:xsd&gt; {
+                ?bd mulgara:after '1970-07-01'^^xsd:date .
+                ?bd mulgara:before '1971-06-30'^^xsd:date
+              }
+            }
+            UNION
+            {
+              ?person foaf:birthday ?bd .
+              GRAPH &lt;sys:xsd&gt; { ?bd mulgara:after '1975-01-01'^^xsd:date .  ?bd mulgara:before '1975-12-31'^^xsd:date } .
+              {
+                { ?person contact:home [ contact:address [ contact:city 'Chicago' ] ] }
+                UNION
+                { ?person contact:home [ contact:address [ contact:city 'Fredericksburg' ] ] }
+              }
+            }
+          }
+        }
+      }
+      order by ?person"/>
+
+  <eval stepClass="org.mulgara.store.jxunit.SparqlQueryJX" />
+  <ifEqual converse="true" file="queryResult2.txt" name="queryResult">
+    <save name="queryResult" file="badQuery2Result.xml"/>
+    <fail>Output failed.  Check badQuery2Result.xml for output.</fail>
+  </ifEqual>
+
+
+  <set name="query" value="
+      select nondistinct ?person ?email
+      from &lt;test:people&gt;
+      where 
+        ?person &lt;rdf:type&gt; &lt;foaf:Person&gt; and
+        ?person &lt;foaf:mbox&gt; ?email and
+        (
+          ?person &lt;foaf:firstName&gt; 'Fred'
+          or
+          ( ?person &lt;http://www.w3.org/2000/10/swap/pim/contact#home&gt; ?h and ?h &lt;http://www.w3.org/2000/10/swap/pim/contact#address&gt; ?a and ?a &lt;http://www.w3.org/2000/10/swap/pim/contact#city&gt; 'Bedrock' )
+        )
+      order by ?person ; "/>
+
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+  <ifEqual converse="true" file="queryResult3.txt" name="queryResult">
+    <save name="queryResult" file="badQuery3Result.xml"/>
+    <fail>Output failed.  Check badQuery3Result.xml for output.</fail>
+  </ifEqual>
+
+  <!-- now drop the graphs -->
+  <set name="query" value="drop &lt;test:people&gt;;"/>
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+
+</jxu>
+

Copied: trunk/jxdata/iTQL/people.rdf (from rev 1870, branches/distinct_queries/jxdata/iTQL/people.rdf)
===================================================================
--- trunk/jxdata/iTQL/people.rdf	                        (rev 0)
+++ trunk/jxdata/iTQL/people.rdf	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,164 @@
+<?xml version="1.0"?>
+<rdf:RDF
+      xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+      xmlns:foaf="http://xmlns.com/foaf/0.1/"
+      xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#"
+      xmlns:test="http://test.com/">
+
+  <!-- included: First name is Fred -->
+  <foaf:Person rdf:about="http://test.com/test#Fred">
+    <foaf:firstName>Fred</foaf:firstName>
+    <foaf:mbox>fred at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1980-02-11</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Bedrock</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- excluded: not a person -->
+  <test:Dog rdf:about="http://test.com/test#FredTheDog">
+    <foaf:firstName>Fred</foaf:firstName>
+    <foaf:mbox>fredthedog at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1980-02-11</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Bedrock</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </test:Dog>
+
+  <!-- included: First name is Barney -->
+  <foaf:Person rdf:about="http://test.com/test#Barney">
+    <foaf:firstName>Barney</foaf:firstName>
+    <foaf:mbox>barney at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1978-11-11</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Bedrock</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- excluded: not a first name we want, not the right place, not the right date -->
+  <foaf:Person rdf:about="http://test.com/test#Bruce">
+    <foaf:firstName>Bruce</foaf:firstName>
+    <foaf:mbox>bruce at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1939-05-01</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Gotham</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- included: in London -->
+  <foaf:Person rdf:about="http://test.com/test#Brian">
+    <foaf:firstName>Brian</foaf:firstName>
+    <foaf:mbox>brian at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1976-10-13</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>London</contact:city>
+        <contact:country>UK</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- included: in NY -->
+  <foaf:Person rdf:about="http://test.com/test#Peter">
+    <foaf:firstName>Peter</foaf:firstName>
+    <foaf:mbox>peter at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1962-08-01</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>NY</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- included: birthday in 70-71 -->
+  <foaf:Person rdf:about="http://test.com/test#Janelle">
+    <foaf:firstName>Janelle</foaf:firstName>
+    <foaf:mbox>janelle at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1971-02-21</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Brisbane</contact:city>
+        <contact:country>Australia</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- excluded: birthday in 75, but not in required city -->
+  <foaf:Person rdf:about="http://test.com/test#Rowan">
+    <foaf:firstName>Rowan</foaf:firstName>
+    <foaf:mbox>rowan at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1975-07-10</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Houston</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- included: birthday in 75 and in Chicago -->
+  <foaf:Person rdf:about="http://test.com/test#Theresa">
+    <foaf:firstName>Theresa</foaf:firstName>
+    <foaf:mbox>theresa at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1975-03-10</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Chicago</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- included: birthday in 75 and in Fredericksburg -->
+  <foaf:Person rdf:about="http://test.com/test#David">
+    <foaf:firstName>David</foaf:firstName>
+    <foaf:mbox>david at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1975-08-18</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Fredericksburg</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- excluded: in Chicago, but birthday not in 75 -->
+  <foaf:Person rdf:about="http://test.com/test#Alan">
+    <foaf:firstName>Alan</foaf:firstName>
+    <foaf:mbox>alan at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1974-04-04</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Chicago</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </foaf:Person>
+
+  <!-- excluded: required birthday, in Chicago, but not a person -->
+  <test:Dog rdf:about="http://test.com/test#Fido">
+    <foaf:firstName>Fido</foaf:firstName>
+    <foaf:mbox>fido at test.com</foaf:mbox>
+    <foaf:birthday rdf:datatype="http://www.w3.org/2001/XMLSchema#date">1975-09-13</foaf:birthday>
+    <contact:home rdf:parseType="Resource">
+      <contact:address rdf:parseType="Resource">
+        <contact:city>Chicago</contact:city>
+        <contact:country>USA</contact:country>
+      </contact:address>
+    </contact:home>
+  </test:Dog>
+
+</rdf:RDF>

Copied: trunk/jxdata/iTQL/unique.rdf (from rev 1870, branches/distinct_queries/jxdata/iTQL/unique.rdf)
===================================================================
--- trunk/jxdata/iTQL/unique.rdf	                        (rev 0)
+++ trunk/jxdata/iTQL/unique.rdf	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,46 @@
+<?xml version="1.0"?>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:cndb="cn:">
+
+<rdf:Description rdf:about = "cn:SP" >
+  <cndb:metal rdf:resource="cn:silver"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:Wazoo" >
+  <cndb:shape rdf:resource="cn:round"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:GP" >
+  <cndb:metal rdf:resource="cn:gold"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:Boing" >
+  <cndb:shape rdf:resource="cn:square"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:Wazoo/Silver" >
+  <cndb:metal rdf:resource="cn:silver"/>
+  <cndb:shape rdf:resource="cn:round"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:Boing/Silver" >
+  <cndb:metal rdf:resource="cn:silver"/>
+  <cndb:shape rdf:resource="cn:square"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:Wazoo/Gold" >
+  <cndb:metal rdf:resource="cn:gold"/>
+  <cndb:shape rdf:resource="cn:round"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:Boing/Gold" >
+  <cndb:metal rdf:resource="cn:gold"/>
+  <cndb:shape rdf:resource="cn:square"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:gold" >
+  <cndb:value rdf:resource="cn:high"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:silver" >
+  <cndb:value rdf:resource="cn:medium"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:round" >
+  <cndb:surface rdf:resource="cn:smooth"/>
+</rdf:Description>
+<rdf:Description rdf:about = "cn:square" >
+  <cndb:surface rdf:resource="cn:rough"/>
+</rdf:Description>
+
+</rdf:RDF>

Copied: trunk/jxdata/iTQL/unique2.rdf (from rev 1870, branches/distinct_queries/jxdata/iTQL/unique2.rdf)
===================================================================
--- trunk/jxdata/iTQL/unique2.rdf	                        (rev 0)
+++ trunk/jxdata/iTQL/unique2.rdf	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:vCard = "http://www.w3.org/2001/vcard-rdf/3.0#">
+
+<rdf:Description rdf:about = "http://qqq.com/staff/groo" >
+  <vCard:FN>Groo The Wanderer</vCard:FN>
+  <vCard:N rdf:parseType="Resource">
+   <vCard:Family>Wanderer</vCard:Family>
+   <vCard:Given>Groo</vCard:Given>
+  </vCard:N>
+  <vCard:ROLE>Wanderer</vCard:ROLE>
+  <vCard:TEL rdf:parseType="Resource">
+   <rdf:value>+1 773 5281639</rdf:value>
+   <rdf:type rdf:resource ="http://imc.org/vCard/3.0#mobile" />
+  </vCard:TEL>
+  <vCard:EMAIL>
+   <vCard:internet rdf:value="groo at qqq.com"/>
+  </vCard:EMAIL>
+</rdf:Description>
+
+</rdf:RDF>

Copied: trunk/jxdata/iTQL/vargraph (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph)

Deleted: trunk/jxdata/iTQL/vargraph/queryResult1.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/queryResult1.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/queryResult1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><variables><graph/></variables><solution><graph resource="@server@#unique3"/></solution></query></answer>

Copied: trunk/jxdata/iTQL/vargraph/queryResult1.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/queryResult1.txt)
===================================================================
--- trunk/jxdata/iTQL/vargraph/queryResult1.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/queryResult1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><graph/></variables><solution><graph resource="@server@#unique3"/></solution></query></answer>

Deleted: trunk/jxdata/iTQL/vargraph/queryResult2.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/queryResult2.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/queryResult2.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><variables><graph/></variables><solution><graph resource="@server@#unique1"/></solution><solution><graph resource="@server@#unique2"/></solution></query></answer>

Copied: trunk/jxdata/iTQL/vargraph/queryResult2.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/queryResult2.txt)
===================================================================
--- trunk/jxdata/iTQL/vargraph/queryResult2.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/queryResult2.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><graph/></variables><solution><graph resource="@server@#unique1"/></solution><solution><graph resource="@server@#unique2"/></solution></query></answer>

Deleted: trunk/jxdata/iTQL/vargraph/queryResult3.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/queryResult3.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/queryResult3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><variables><graph/></variables></query></answer>

Copied: trunk/jxdata/iTQL/vargraph/queryResult3.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/queryResult3.txt)
===================================================================
--- trunk/jxdata/iTQL/vargraph/queryResult3.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/queryResult3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><variables><graph/></variables></query></answer>

Deleted: trunk/jxdata/iTQL/vargraph/result1.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/result1.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/result1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 16 statements from @baseuri@/jxdata/iTQL/unique.rdf into @server@#unique1</message></query></answer>

Copied: trunk/jxdata/iTQL/vargraph/result1.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/result1.txt)
===================================================================
--- trunk/jxdata/iTQL/vargraph/result1.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/result1.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 16 statements from @baseuri@/jxdata/iTQL/unique.rdf into @server@#unique1</message></query></answer>

Deleted: trunk/jxdata/iTQL/vargraph/result2.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/result2.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/result2.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 16 statements from @baseuri@/jxdata/iTQL/unique.rdf into @server@#unique2</message></query></answer>

Copied: trunk/jxdata/iTQL/vargraph/result2.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/result2.txt)
===================================================================
--- trunk/jxdata/iTQL/vargraph/result2.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/result2.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 16 statements from @baseuri@/jxdata/iTQL/unique.rdf into @server@#unique2</message></query></answer>

Deleted: trunk/jxdata/iTQL/vargraph/result3.txt
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/result3.txt	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/result3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 11 statements from @baseuri@/jxdata/iTQL/unique2.rdf into @server@#unique3</message></query></answer>

Copied: trunk/jxdata/iTQL/vargraph/result3.txt (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/result3.txt)
===================================================================
--- trunk/jxdata/iTQL/vargraph/result3.txt	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/result3.txt	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<answer xmlns="http://mulgara.org/tql#"><query><message>Successfully loaded 11 statements from @baseuri@/jxdata/iTQL/unique2.rdf into @server@#unique3</message></query></answer>

Deleted: trunk/jxdata/iTQL/vargraph/test.jxu
===================================================================
--- branches/distinct_queries/jxdata/iTQL/vargraph/test.jxu	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/jxdata/iTQL/vargraph/test.jxu	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,69 +0,0 @@
-<jxu>
-  <set name="debug" value="false" />
-
-  <set name="modelName" value="@server@#unique1" />
-  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/unique.rdf&gt; into &lt;@server@#unique1&gt; ;" />
-  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
-
-  <ifEqual converse="true" file="result1.txt" name="loadResult">
-    <save name="loadResult" file="badLoadResult.xml"/>
-    <fail>Output failed.  Check badLoadResult.xml for output.</fail>
-  </ifEqual>
-
-  <set name="modelName" value="@server@#unique2" />
-  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/unique.rdf&gt; into &lt;@server@#unique2&gt; ;" />
-  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
-
-  <ifEqual converse="true" file="result2.txt" name="loadResult">
-    <save name="loadResult" file="badLoadResult2.xml"/>
-    <fail>Output failed.  Check badLoadResult2.xml for output.</fail>
-  </ifEqual>
-
-  <set name="modelName" value="@server@#unique3" />
-  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/unique2.rdf&gt; into &lt;@server@#unique3&gt; ;" />
-  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
-
-  <ifEqual converse="true" file="result3.txt" name="loadResult">
-    <save name="loadResult" file="badLoadResult3.xml"/>
-    <fail>Output failed.  Check badLoadResult3.xml for output.</fail>
-  </ifEqual>
-
-  <!-- now query the graphs -->
-
-  <set name="query" value="select $graph from &lt;@server@#unique1&gt; where &lt;http://qqq.com/staff/groo&gt; &lt;http://www.w3.org/2001/vcard-rdf/3.0#FN&gt; 'Groo The Wanderer' in $graph order by $graph;"/>
-
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-  <ifEqual converse="true" file="queryResult1.txt" name="queryResult">
-    <save name="queryResult" file="badQuery1Result.xml"/>
-    <fail>Output failed.  Check badQuery1Result.xml for output.</fail>
-  </ifEqual>
-
-
-  <set name="query" value="select $graph from &lt;@server@#unique1&gt; where &lt;cn:SP&gt; &lt;cn:metal&gt; &lt;cn:silver&gt; in $graph order by $graph;"/>
-
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-  <ifEqual converse="true" file="queryResult2.txt" name="queryResult">
-    <save name="queryResult" file="badQuery2Result.xml"/>
-    <fail>Output failed.  Check badQuery2Result.xml for output.</fail>
-  </ifEqual>
-
-  <set name="query" value="select $graph from &lt;unique1&gt; where &lt;foo:bar&gt; &lt;foo:baz&gt; &lt;foo:bop&gt; in $graph order by $graph;"/>
-
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-  <ifEqual converse="true" file="queryResult3.txt" name="queryResult">
-    <save name="queryResult" file="badQuery3Result.xml"/>
-    <fail>Output failed.  Check badQuery3Result.xml for output.</fail>
-  </ifEqual>
-
-  <!-- now drop the graphs -->
-  <set name="query" value="drop &lt;@server@#unique1&gt;;"/>
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-
-  <set name="query" value="drop &lt;@server@#unique2&gt;;"/>
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-
-  <set name="query" value="drop &lt;@server@#unique3&gt;;"/>
-  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
-
-</jxu>
-

Copied: trunk/jxdata/iTQL/vargraph/test.jxu (from rev 1870, branches/distinct_queries/jxdata/iTQL/vargraph/test.jxu)
===================================================================
--- trunk/jxdata/iTQL/vargraph/test.jxu	                        (rev 0)
+++ trunk/jxdata/iTQL/vargraph/test.jxu	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,69 @@
+<jxu>
+  <set name="debug" value="false" />
+
+  <set name="modelName" value="@server@#unique1" />
+  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/unique.rdf&gt; into &lt;@server@#unique1&gt; ;" />
+  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
+
+  <ifEqual converse="true" file="result1.txt" name="loadResult">
+    <save name="loadResult" file="badLoadResult.xml"/>
+    <fail>Output failed.  Check badLoadResult.xml for output.</fail>
+  </ifEqual>
+
+  <set name="modelName" value="@server@#unique2" />
+  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/unique.rdf&gt; into &lt;@server@#unique2&gt; ;" />
+  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
+
+  <ifEqual converse="true" file="result2.txt" name="loadResult">
+    <save name="loadResult" file="badLoadResult2.xml"/>
+    <fail>Output failed.  Check badLoadResult2.xml for output.</fail>
+  </ifEqual>
+
+  <set name="modelName" value="@server@#unique3" />
+  <set name="loadCommand" value="load &lt;@baseuri@/jxdata/iTQL/unique2.rdf&gt; into &lt;@server@#unique3&gt; ;" />
+  <eval stepClass="org.mulgara.store.jxunit.LoadDataJX" />
+
+  <ifEqual converse="true" file="result3.txt" name="loadResult">
+    <save name="loadResult" file="badLoadResult3.xml"/>
+    <fail>Output failed.  Check badLoadResult3.xml for output.</fail>
+  </ifEqual>
+
+  <!-- now query the graphs -->
+
+  <set name="query" value="select $graph from &lt;@server@#unique1&gt; where &lt;http://qqq.com/staff/groo&gt; &lt;http://www.w3.org/2001/vcard-rdf/3.0#FN&gt; 'Groo The Wanderer' in $graph order by $graph;"/>
+
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+  <ifEqual converse="true" file="queryResult1.txt" name="queryResult">
+    <save name="queryResult" file="badQuery1Result.xml"/>
+    <fail>Output failed.  Check badQuery1Result.xml for output.</fail>
+  </ifEqual>
+
+
+  <set name="query" value="select $graph from &lt;@server@#unique1&gt; where &lt;cn:SP&gt; &lt;cn:metal&gt; &lt;cn:silver&gt; in $graph order by $graph;"/>
+
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+  <ifEqual converse="true" file="queryResult2.txt" name="queryResult">
+    <save name="queryResult" file="badQuery2Result.xml"/>
+    <fail>Output failed.  Check badQuery2Result.xml for output.</fail>
+  </ifEqual>
+
+  <set name="query" value="select $graph from &lt;unique1&gt; where &lt;foo:bar&gt; &lt;foo:baz&gt; &lt;foo:bop&gt; in $graph order by $graph;"/>
+
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+  <ifEqual converse="true" file="queryResult3.txt" name="queryResult">
+    <save name="queryResult" file="badQuery3Result.xml"/>
+    <fail>Output failed.  Check badQuery3Result.xml for output.</fail>
+  </ifEqual>
+
+  <!-- now drop the graphs -->
+  <set name="query" value="drop &lt;@server@#unique1&gt;;"/>
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+
+  <set name="query" value="drop &lt;@server@#unique2&gt;;"/>
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+
+  <set name="query" value="drop &lt;@server@#unique3&gt;;"/>
+  <eval stepClass="org.mulgara.store.jxunit.QueryJX" />
+
+</jxu>
+

Deleted: trunk/lib/apache-mime4j-0.5.jar
===================================================================
(Binary files differ)

Copied: trunk/lib/apache-mime4j-0.5.jar (from rev 1870, branches/distinct_queries/lib/apache-mime4j-0.5.jar)
===================================================================
(Binary files differ)

Deleted: trunk/lib/commons-logging-1.1.1.jar
===================================================================
(Binary files differ)

Copied: trunk/lib/commons-logging-1.1.1.jar (from rev 1870, branches/distinct_queries/lib/commons-logging-1.1.1.jar)
===================================================================
(Binary files differ)

Deleted: trunk/lib/httpclient-4.0-beta2.jar
===================================================================
(Binary files differ)

Copied: trunk/lib/httpclient-4.0-beta2.jar (from rev 1870, branches/distinct_queries/lib/httpclient-4.0-beta2.jar)
===================================================================
(Binary files differ)

Deleted: trunk/lib/httpcore-4.0-beta3.jar
===================================================================
(Binary files differ)

Copied: trunk/lib/httpcore-4.0-beta3.jar (from rev 1870, branches/distinct_queries/lib/httpcore-4.0-beta3.jar)
===================================================================
(Binary files differ)

Deleted: trunk/lib/httpmime-4.0-beta2.jar
===================================================================
(Binary files differ)

Copied: trunk/lib/httpmime-4.0-beta2.jar (from rev 1870, branches/distinct_queries/lib/httpmime-4.0-beta2.jar)
===================================================================
(Binary files differ)

Modified: trunk/src/jar/content-n3/java/org/mulgara/content/n3/Parser.java
===================================================================
--- trunk/src/jar/content-n3/java/org/mulgara/content/n3/Parser.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/content-n3/java/org/mulgara/content/n3/Parser.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -70,6 +70,7 @@
 import org.mulgara.util.TempDir;
 
 /**
+ * nd
  * <p>This class parses N3 data. It is implemented as a {@link Runnable} to allow it to be running in
  * the background filling a queue, while a consumer thread drains the queue.</p>
  *
@@ -545,7 +546,18 @@
     // get the datatype details
     AST dt = a.getFirstChild();
     try {
-      return dt == null ? null : new URI(dt.toString());
+      if (dt == null) return null;
+      String uri = dt.toString();
+      // check for QName
+      int colonIndex = uri.indexOf(':');
+      // relative URI, so just return
+      if (colonIndex == -1) return new URI(uri);
+
+      // look for possible prefix
+      String qnamePrefix = uri.substring(0, colonIndex + 1);
+      String uriPrefix = prefixMap.get(qnamePrefix);
+      // if known prefix, then use it, otherwise just return the string as a URI
+      return uriPrefix == null ? new URI(uri) : new URI(uriPrefix + uri.substring(colonIndex + 1));
     } catch (URISyntaxException e) {
       logger.warn("Error parsing N3 datatype: " + dt.toString(), e);
       return null;

Modified: trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/Parser.java
===================================================================
--- trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/Parser.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/Parser.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -62,7 +62,7 @@
 import org.xml.sax.ErrorHandler;
 import org.xml.sax.SAXParseException;
 
-//Jea
+// Jena
 import com.hp.hpl.jena.rdf.arp.ALiteral;
 import com.hp.hpl.jena.rdf.arp.ARP;
 import com.hp.hpl.jena.rdf.arp.AResource;
@@ -375,7 +375,9 @@
    */
   public synchronized void error(SAXParseException e) {
     logger.warn("Recoverable error, line " + e.getLineNumber() + ", column " +
-                e.getColumnNumber() + ": " + e.getMessage(), e);
+                e.getColumnNumber() + ": " + e.getMessage());
+    logger.debug("Recoverable error, line " + e.getLineNumber() + ", column " +
+        e.getColumnNumber() + ": " + e.getMessage(), e);
   }
 
   /**
@@ -386,7 +388,9 @@
   {
     exception = e;
     logger.error("Fatal error, line " + e.getLineNumber() + ", column " +
-                 e.getColumnNumber() + ": " + e.getMessage(), e);
+                 e.getColumnNumber() + ": " + e.getMessage());
+    logger.debug("Fatal error, line " + e.getLineNumber() + ", column " +
+        e.getColumnNumber() + ": " + e.getMessage(), e);
   }
 
   /**
@@ -395,7 +399,9 @@
    */
   public void warning(SAXParseException e) {
     logger.warn("Warning, line " + e.getLineNumber() + ", column " +
-                e.getColumnNumber() + ": " + e.getMessage(), e);
+                e.getColumnNumber() + ": " + e.getMessage());
+    logger.debug("Warning, line " + e.getLineNumber() + ", column " +
+        e.getColumnNumber() + ": " + e.getMessage(), e);
   }
 
   //

Modified: trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java
===================================================================
--- trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/RDFXMLWriter.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -198,7 +198,7 @@
 
     // ensure variables are in the right order
     Tuples projectedTuples = TuplesOperations.project(materializedTuples,
-        Arrays.asList(vars));
+        Arrays.asList(vars), true);
     materializedTuples.close();
 
     // tuples must be sorted by subject for writing

Modified: trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java
===================================================================
--- trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/content-rdfxml/java/org/mulgara/content/rdfxml/writer/TestStatementsComparator.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -252,7 +252,7 @@
     Tuples projectedTuples = TuplesOperations.project(sortedTuples,
         Arrays.asList(new Variable[] {
         StatementStore.VARIABLES[0], StatementStore.VARIABLES[1],
-        StatementStore.VARIABLES[2]}));
+        StatementStore.VARIABLES[2]}), true);
     sortedTuples.close();
 
     return new TuplesWrapperStatements(projectedTuples,

Modified: trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/krule/java/org/mulgara/krule/KruleLoader.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1054,6 +1054,7 @@
         (List<Order>)Collections.EMPTY_LIST,        // ORDER BY
         null,                                       // LIMIT
         0,                                          // OFFSET
+        true,                                       // DISTINCT
         UNCONSTRAINED                               // GIVEN
     );
   }

Modified: trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java
===================================================================
--- trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/krule/java/org/mulgara/krule/QueryStruct.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -237,7 +237,7 @@
   @SuppressWarnings("unchecked")
   public Query extractQuery() {
     logger.debug("Extracting query");
-    return new Query(variables, graphs, where, having, (List<Order>)Collections.EMPTY_LIST, null, 0, new UnconstrainedAnswer());
+    return new Query(variables, graphs, where, having, (List<Order>)Collections.EMPTY_LIST, null, 0, true, new UnconstrainedAnswer());
   }
 
 }

Modified: trunk/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/connection/ConnectionFactoryUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -99,6 +99,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/jena/PatternMulgara.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -96,6 +96,7 @@
          x,                        // ORDER
          null,                     // LIMIT
          0,                        // OFFSET
+         true,                     // DISTINCT
          new UnconstrainedAnswer() // Initial Answer
     );
 

Modified: trunk/src/jar/query/java/org/mulgara/query/AbstractConstraintExpression.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/AbstractConstraintExpression.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/AbstractConstraintExpression.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -79,4 +79,13 @@
       return false;
     }
   }
+
+  /**
+   * Indicates if this operation is associative.
+   * @return <code>true</code> iff this operation is associative.
+   */
+  public boolean isAssociative() {
+    return true;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/AskQuery.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/AskQuery.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/AskQuery.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -49,6 +49,7 @@
         (List<Order>)Collections.EMPTY_LIST, // no ordering
         null, // no limit
         0, // zero offset
+        true, // distinct TODO: change to false when non-distinct is tested
         new UnconstrainedAnswer());
   }
 

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintAssignment.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintAssignment.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintAssignment.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -180,4 +180,13 @@
     buffer.append(var).append(" := ").append(expr).append(")");
     return buffer.toString();
   }
+
+  /**
+   * This expression is non associative.
+   * @return <code>false</code> since this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintDifference.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintDifference.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintDifference.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -77,4 +77,12 @@
     return " minus ";
   }
 
+  /**
+   * Minus is not an associative operation.
+   * @return <code>false</code> since this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintExpression.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintExpression.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintExpression.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -66,4 +66,11 @@
    * @return A set containing all variable constraints.
    */
   public Set<Variable> getVariables();
+
+  /**
+   * Indicates if this operation is associative.
+   * @return <code>true</code> iff this operation is associative.
+   */
+  boolean isAssociative();
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintFalse.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintFalse.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintFalse.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -142,4 +142,13 @@
   public String toString() {
     return "no";
   }
+
+  /**
+   * This expression is unary, so associativity is irrelevant.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintFilter.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -104,4 +104,13 @@
     // can't do an equals() on filter, as this evaluates the filter in context
     return constraintExpr.equals(other.constraintExpr) && filter == other.filter;
   }
+
+  /**
+   * This expression is unary, so associativity is irrelevant.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintIn.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -128,4 +128,12 @@
     return constraint.equals(other.constraint) && graph.equals(other.graph);
   }
 
+  /**
+   * This expression is unary, so associativity is irrelevant.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintOperation.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintOperation.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintOperation.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -90,14 +90,14 @@
     elements = new ArrayList<ConstraintExpression>(2);
 
     // Add the LHS
-    if (lhs.getClass().equals(getClass())) {
+    if (isAssociative() && lhs.getClass().equals(getClass())) {
       elements.addAll(((ConstraintOperation)lhs).getElements());
     } else {
       elements.add(lhs);
     }
 
     // Add the RHS
-    if (rhs.getClass().equals(getClass())) {
+    if (isAssociative() && rhs.getClass().equals(getClass())) {
       elements.addAll( ( (ConstraintOperation) rhs).getElements());
     } else {
       elements.add(rhs);
@@ -115,7 +115,16 @@
     // assert elements.size() > 1;
 
     // Initialize fields
-    this.elements = new ArrayList<ConstraintExpression>(elements);
+    this.elements = new ArrayList<ConstraintExpression>();
+
+    // add all the elements, flattening if needed
+    for (ConstraintExpression op: elements) {
+      if (op.isAssociative() && op.getClass().equals(getClass())) {
+        this.elements.addAll(((ConstraintOperation)op).getElements());
+      } else {
+        this.elements.add(op);
+      }
+    }
   }
 
 
@@ -211,6 +220,14 @@
   }
 
   /**
+   * Indicates if this operation is associative.
+   * @return <code>true</code> iff this operation is associative.
+   */
+  public boolean isAssociative() {
+    return true;
+  }
+
+  /**
    * Gets the Name attribute of the ConstraintOperation object
    *
    * @return The Name value

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstraintTrue.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstraintTrue.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstraintTrue.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -140,4 +140,13 @@
   public String toString() {
     return "yes";
   }
+
+  /**
+   * This expression is unary, so associativity is irrelevant.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/ConstructQuery.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/ConstructQuery.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/ConstructQuery.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -45,6 +45,7 @@
         orderList,
         limit,
         offset,
+        true,
         new UnconstrainedAnswer());
   }
 

Deleted: trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,86 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query;
-
-import org.mulgara.util.Reflect;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import javax.xml.xpath.XPathFunctionResolver;
-
-/**
- * A singleton registry for XPathFunctionResolvers.
- *
- * @created Sep 27, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
-public class FunctionResolverRegistry implements Iterable<XPathFunctionResolver> {
-
-  /** The singleton of this object */
-  static private FunctionResolverRegistry registry = new FunctionResolverRegistry();
-
-  /** The list of registered resolvers */
-  private List<XPathFunctionResolver> registered;
-
-  /**
-   * Constructs the singleton resolver.
-   */
-  private FunctionResolverRegistry() {
-    registered = new ArrayList<XPathFunctionResolver>();
-  }
-
-  /**
-   * Gets the singleton registry.
-   * @return The registry for resolvers.
-   */
-  public static FunctionResolverRegistry getFunctionResolverRegistry() {
-    return registry;
-  }
-
-  /**
-   * Registered a resolver instance.
-   * @param resolver The resolver instance to register.
-   */
-  public void register(XPathFunctionResolver resolver) {
-    registered.add(resolver);
-  }
-
-  /**
-   * Registered a resolver by name.
-   * @param resolver The name of a resolver type to register.
-   * @throws ClassNotFoundException Unable to find the specified class.
-   * @throws RuntimeException If the class could not be instantiated for any reason.
-   */
-  @SuppressWarnings("unchecked")
-  public void register(String resolverName) throws ClassNotFoundException {
-    Class<XPathFunctionResolver> resolverType = (Class<XPathFunctionResolver>)Class.forName(resolverName);
-    registered.add(Reflect.newInstance(resolverType));
-  }
-
-  /**
-   * Get an iterator for all the registered resolvers.
-   * @see java.lang.Iterable#iterator()
-   * @return an Iterator for the registry.
-   */
-  public Iterator<XPathFunctionResolver> iterator() {
-    return Collections.unmodifiableList(registered).iterator();
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/FunctionResolverRegistry.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query;
+
+import org.mulgara.util.Reflect;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.xml.xpath.XPathFunctionResolver;
+
+/**
+ * A singleton registry for XPathFunctionResolvers.
+ *
+ * @created Sep 27, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public class FunctionResolverRegistry implements Iterable<XPathFunctionResolver> {
+
+  /** The singleton of this object */
+  static private FunctionResolverRegistry registry = new FunctionResolverRegistry();
+
+  /** The list of registered resolvers */
+  private List<XPathFunctionResolver> registered;
+
+  /**
+   * Constructs the singleton resolver.
+   */
+  private FunctionResolverRegistry() {
+    registered = new ArrayList<XPathFunctionResolver>();
+  }
+
+  /**
+   * Gets the singleton registry.
+   * @return The registry for resolvers.
+   */
+  public static FunctionResolverRegistry getFunctionResolverRegistry() {
+    return registry;
+  }
+
+  /**
+   * Registered a resolver instance.
+   * @param resolver The resolver instance to register.
+   */
+  public void register(XPathFunctionResolver resolver) {
+    registered.add(resolver);
+  }
+
+  /**
+   * Registered a resolver by name.
+   * @param resolver The name of a resolver type to register.
+   * @throws ClassNotFoundException Unable to find the specified class.
+   * @throws RuntimeException If the class could not be instantiated for any reason.
+   */
+  @SuppressWarnings("unchecked")
+  public void register(String resolverName) throws ClassNotFoundException {
+    Class<XPathFunctionResolver> resolverType = (Class<XPathFunctionResolver>)Class.forName(resolverName);
+    registered.add(Reflect.newInstance(resolverType));
+  }
+
+  /**
+   * Get an iterator for all the registered resolvers.
+   * @see java.lang.Iterable#iterator()
+   * @return an Iterator for the registry.
+   */
+  public Iterator<XPathFunctionResolver> iterator() {
+    return Collections.unmodifiableList(registered).iterator();
+  }
+}

Modified: trunk/src/jar/query/java/org/mulgara/query/Query.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/Query.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/Query.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -106,6 +106,9 @@
   /** The offset on rows in the result. This value is never negative. */
   private int offset;
 
+  /** Indicates that the results must be without duplicates. */
+  private boolean distinct = true;
+
   /** The accumulated solutions. This can be <code>null</code>, indicating no solutions. */
   private Answer answer;
 
@@ -149,7 +152,7 @@
   public Query(List<? extends SelectElement> variableList, GraphExpression graphExpression,
       ConstraintExpression constraintExpression,
       ConstraintHaving havingExpression, List<Order> orderList, Integer limit,
-      int offset, Answer answer) {
+      int offset, boolean distinct, Answer answer) {
 
     // Validate parameters
     if (graphExpression == null) {
@@ -189,6 +192,7 @@
     this.orderList = Collections.unmodifiableList(new ArrayList<Order>(orderList));
     this.limit = limit;
     this.offset = offset;
+    this.distinct = distinct;
     this.answer = answer;
   }
 
@@ -206,6 +210,7 @@
     this.orderList = query.orderList;
     this.limit = query.limit;
     this.offset = query.offset;
+    this.distinct = query.distinct;
     this.answer = (query.answer != null) ?(Answer)query.answer.clone() : new UnconstrainedAnswer();
     /*
       this(query.getVariableList(),
@@ -343,6 +348,13 @@
     return answer;
   }
 
+  /**
+   * Accessor for the DISTINCT property on this query.
+   * @return <code>true</code> if results of the query should not contain duplicates.
+   */
+  public boolean isDistinct() {
+    return distinct;
+  }
 
   //
   // Methods overriding Object

Modified: trunk/src/jar/query/java/org/mulgara/query/QueryUnitTest.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/QueryUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/QueryUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -109,6 +109,7 @@
         (List<Order>)Collections.EMPTY_LIST,    // no ordering
         null,                                   // no limit
         0,                                      // zero offset
+        true,                                   // no duplicates
         new UnconstrainedAnswer());
   }
 
@@ -155,6 +156,7 @@
         (List<Order>)Collections.EMPTY_LIST,   // no ordering
         null,                                  // no limit
         0,                                     // zero offset
+        true,                                  // no duplicates
         new UnconstrainedAnswer());
 
     // These truths we hold to be self-evident:

Modified: trunk/src/jar/query/java/org/mulgara/query/SingleTransitiveConstraint.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/SingleTransitiveConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/SingleTransitiveConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -209,4 +209,14 @@
     }
     return buffer.toString();
   }
+
+
+  /**
+   * Not sure what associativity would mean here, but it shouldn't be possible.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/TransitiveConstraint.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/TransitiveConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/TransitiveConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -208,4 +208,13 @@
     buffer.append("]");
     return buffer.toString();
   }
+
+  /**
+   * Not sure what associativity would mean here, but it shouldn't be possible.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Modified: trunk/src/jar/query/java/org/mulgara/query/WalkConstraint.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/WalkConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/WalkConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -221,4 +221,13 @@
     buffer.append("]");
     return buffer.toString();
   }
+
+  /**
+   * Not sure what associativity would mean here, but it shouldn't be possible.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
 }

Copied: trunk/src/jar/query/java/org/mulgara/query/functions (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions)

Deleted: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,120 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.functions;
-
-import java.util.List;
-
-import javax.xml.xpath.XPathFunction;
-import javax.xml.xpath.XPathFunctionException;
-
-import org.jrdf.graph.Literal;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.SimpleLiteral;
-
-/**
- * General class for providing management information for XPath function implementations.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
- at SuppressWarnings("unchecked")
-public abstract class MulgaraFunction implements XPathFunction {
-
-  /**
-   * Evaluate the method represented by this class, using the supplied arguments.
-   * @see javax.xml.xpath.XPathFunction#evaluate(java.util.List)
-   */
-  public Object evaluate(List args) throws XPathFunctionException {
-    checkArgs(getArity(), args);
-    try {
-      return eval(args);
-    } catch (ClassCastException e) {
-      throw new XPathFunctionException("Incorrect parameter types passed to function: " + e.getMessage());
-    }
-  }
-
-  /**
-   * Test that the correct number of arguments were provided to the function call.
-   * @param expected The expected number of arguments.
-   * @param args The list of arguments.
-   * @throws XPathFunctionException Thrown if the argument list is the wrong length.
-   */
-  protected void checkArgs(int expected, List args) throws XPathFunctionException {
-    if (expected >= 0 && args.size() != expected) {
-      throw new XPathFunctionException("Incorrect number of parameters. Should be " + expected + ", but was: " + args.size());
-    }
-  }
-
-  /**
-   * Returns the number of arguments required to use this function. Default is 1. 
-   * @return The number of arguments for this function.
-   */
-  protected int getArity() { return 1; }
-
-  /**
-   * The name of this function, followed by its arity.
-   * If not overridden then this will be the function class's name, starting with a lower-case letter.
-   * @return The name/arity of this function.
-   */
-  public String getName() {
-    StringBuilder name = new StringBuilder(getClass().getSimpleName());
-    char c = name.charAt(0);
-    if (Character.isUpperCase(c)) {
-      name.setCharAt(0, Character.toLowerCase(c));
-    }
-    for (int i = 1; i < name.length(); i++) {
-      c = name.charAt(0);
-      if (Character.isUpperCase(c)) name.replace(i, i + 1, "-" + Character.toLowerCase(c));
-    }
-    name.append("/");
-    int arity = getArity();
-    if (arity >= 0) name.append(getArity());
-    else name.append("*");
-    return name.toString();
-  }
-
-  /**
-   * Evaluates the operation of the function. The argument list will be the correct length.
-   * @param args The arguments for the function.
-   * @return The return value of the function.
-   * @throws XPathFunctionException If there was an error executing the function.
-   */
-  protected abstract Object eval(List<?> args) throws XPathFunctionException;
-
-  /**
-   * Convert a singleton value into its effective boolean value (EBV).
-   * @param o The singleton to test.
-   * @return The EBV of the value.
-   * @throws XPathFunctionException If a complex evaluation throws an exception.
-   */
-  protected static final boolean toBool(Object o) throws XPathFunctionException {
-    if (o == null) return false;
-    if (o instanceof String) return ((String)o).length() != 0;
-    if (o instanceof Number) return ((Number)o).doubleValue() != 0 && ((Number)o).doubleValue() != Double.NaN;
-    if (o instanceof Boolean) return ((Boolean)o).booleanValue();
-    try {
-      if (o instanceof Literal) return new SimpleLiteral(((Literal)o).getLexicalForm(), ((Literal)o).getLanguage()).test(null);
-    } catch (NullPointerException e) {
-      throw new XPathFunctionException("Conversion of data to a simple literal requires a context: " + e.getMessage());
-    } catch (QueryException e) {
-      throw new XPathFunctionException("Unable to convert data to a simple literal: " + e.getMessage());
-    }
-    throw new XPathFunctionException("Type error: " + o + " [" + o.getClass() + "]");
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunction.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.functions;
+
+import java.util.List;
+
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionException;
+
+import org.jrdf.graph.Literal;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.SimpleLiteral;
+
+/**
+ * General class for providing management information for XPath function implementations.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+ at SuppressWarnings("unchecked")
+public abstract class MulgaraFunction implements XPathFunction {
+
+  /**
+   * Evaluate the method represented by this class, using the supplied arguments.
+   * @see javax.xml.xpath.XPathFunction#evaluate(java.util.List)
+   */
+  public Object evaluate(List args) throws XPathFunctionException {
+    checkArgs(getArity(), args);
+    try {
+      return eval(args);
+    } catch (ClassCastException e) {
+      throw new XPathFunctionException("Incorrect parameter types passed to function: " + e.getMessage());
+    }
+  }
+
+  /**
+   * Test that the correct number of arguments were provided to the function call.
+   * @param expected The expected number of arguments.
+   * @param args The list of arguments.
+   * @throws XPathFunctionException Thrown if the argument list is the wrong length.
+   */
+  protected void checkArgs(int expected, List args) throws XPathFunctionException {
+    if (expected >= 0 && args.size() != expected) {
+      throw new XPathFunctionException("Incorrect number of parameters. Should be " + expected + ", but was: " + args.size());
+    }
+  }
+
+  /**
+   * Returns the number of arguments required to use this function. Default is 1. 
+   * @return The number of arguments for this function.
+   */
+  protected int getArity() { return 1; }
+
+  /**
+   * The name of this function, followed by its arity.
+   * If not overridden then this will be the function class's name, starting with a lower-case letter.
+   * @return The name/arity of this function.
+   */
+  public String getName() {
+    StringBuilder name = new StringBuilder(getClass().getSimpleName());
+    char c = name.charAt(0);
+    if (Character.isUpperCase(c)) {
+      name.setCharAt(0, Character.toLowerCase(c));
+    }
+    for (int i = 1; i < name.length(); i++) {
+      c = name.charAt(0);
+      if (Character.isUpperCase(c)) name.replace(i, i + 1, "-" + Character.toLowerCase(c));
+    }
+    name.append("/");
+    int arity = getArity();
+    if (arity >= 0) name.append(getArity());
+    else name.append("*");
+    return name.toString();
+  }
+
+  /**
+   * Evaluates the operation of the function. The argument list will be the correct length.
+   * @param args The arguments for the function.
+   * @return The return value of the function.
+   * @throws XPathFunctionException If there was an error executing the function.
+   */
+  protected abstract Object eval(List<?> args) throws XPathFunctionException;
+
+  /**
+   * Convert a singleton value into its effective boolean value (EBV).
+   * @param o The singleton to test.
+   * @return The EBV of the value.
+   * @throws XPathFunctionException If a complex evaluation throws an exception.
+   */
+  protected static final boolean toBool(Object o) throws XPathFunctionException {
+    if (o == null) return false;
+    if (o instanceof String) return ((String)o).length() != 0;
+    if (o instanceof Number) return ((Number)o).doubleValue() != 0 && ((Number)o).doubleValue() != Double.NaN;
+    if (o instanceof Boolean) return ((Boolean)o).booleanValue();
+    try {
+      if (o instanceof Literal) return new SimpleLiteral(((Literal)o).getLexicalForm(), ((Literal)o).getLanguage()).test(null);
+    } catch (NullPointerException e) {
+      throw new XPathFunctionException("Conversion of data to a simple literal requires a context: " + e.getMessage());
+    } catch (QueryException e) {
+      throw new XPathFunctionException("Unable to convert data to a simple literal: " + e.getMessage());
+    }
+    throw new XPathFunctionException("Type error: " + o + " [" + o.getClass() + "]");
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,49 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.functions;
-
-import java.util.Set;
-
-
-/**
- * Represents a group of functions exposed as XPathFunctions in a single namespace.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
-public interface MulgaraFunctionGroup {
-
-  /**
-   * Get the prefix used for the namespace of these operations.
-   * @return The short string used for a prefix in a QName.
-   */
-  public String getPrefix();
-
-  /**
-   * Get the namespace of these operations.
-   * @return The string of the namespace URI.
-   */
-  public String getNamespace();
-
-  /**
-   * Get the set of function in this group.
-   * @return A set of MulgaraFunction for this entire group.
-   */
-  public Set<MulgaraFunction> getAllFunctions();
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.functions;
+
+import java.util.Set;
+
+
+/**
+ * Represents a group of functions exposed as XPathFunctions in a single namespace.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public interface MulgaraFunctionGroup {
+
+  /**
+   * Get the prefix used for the namespace of these operations.
+   * @return The short string used for a prefix in a QName.
+   */
+  public String getPrefix();
+
+  /**
+   * Get the namespace of these operations.
+   * @return The string of the namespace URI.
+   */
+  public String getNamespace();
+
+  /**
+   * Get the set of function in this group.
+   * @return A set of MulgaraFunction for this entire group.
+   */
+  public Set<MulgaraFunction> getAllFunctions();
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,75 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.functions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.xml.namespace.QName;
-import javax.xml.xpath.XPathFunction;
-import javax.xml.xpath.XPathFunctionResolver;
-
-
-/**
- * Retrieves Mulgara functions.
- *
- * @created Oct 6, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
-public abstract class MulgaraFunctionResolver implements XPathFunctionResolver {
-
-  /**
-   * A mapping of namespace URIs to the map of (name->functions) in that namespace.
-   * This is used to look up the requested function object.
-   */
-  private final Map<String,Map<String,XPathFunction>> functionGroups = new HashMap<String,Map<String,XPathFunction>>();
-
-
-  /**
-   * @see javax.xml.xpath.XPathFunctionResolver#resolveFunction(javax.xml.namespace.QName, int)
-   */
-  public XPathFunction resolveFunction(QName functionName, int arity) {
-    XPathFunction result = null;
-    String namespace = functionName.getNamespaceURI();
-    if (namespace != null) {
-      Map<String,XPathFunction> fnGroupMap = functionGroups.get(namespace);
-      if (fnGroupMap != null) {
-        result = fnGroupMap.get(functionName.getLocalPart() + "/" + arity);
-        // fall back to multiple arity
-        if (result == null) result = fnGroupMap.get(functionName.getLocalPart() + "/*");
-      }
-    }
-    return result;
-  }
-
-
-  /**
-   * A helper method to create a mapping of function names to their implementing classes,
-   * and of namespaces to these mappings.
-   * @param fnGroup A group of functions to be added into a single namespace.
-   *        This group also provides that namespace.
-   */
-  protected final void addFunctionGroup(MulgaraFunctionGroup fnGroup) {
-    // map the function names to the functions
-    Map<String,XPathFunction> functionMap = new HashMap<String,XPathFunction>();
-    for (MulgaraFunction fn: fnGroup.getAllFunctions()) functionMap.put(fn.getName(), fn);
-    // map the namespace to the name->function map
-    functionGroups.put(fnGroup.getNamespace(), functionMap);
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraFunctionResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.functions;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.xpath.XPathFunction;
+import javax.xml.xpath.XPathFunctionResolver;
+
+
+/**
+ * Retrieves Mulgara functions.
+ *
+ * @created Oct 6, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public abstract class MulgaraFunctionResolver implements XPathFunctionResolver {
+
+  /**
+   * A mapping of namespace URIs to the map of (name->functions) in that namespace.
+   * This is used to look up the requested function object.
+   */
+  private final Map<String,Map<String,XPathFunction>> functionGroups = new HashMap<String,Map<String,XPathFunction>>();
+
+
+  /**
+   * @see javax.xml.xpath.XPathFunctionResolver#resolveFunction(javax.xml.namespace.QName, int)
+   */
+  public XPathFunction resolveFunction(QName functionName, int arity) {
+    XPathFunction result = null;
+    String namespace = functionName.getNamespaceURI();
+    if (namespace != null) {
+      Map<String,XPathFunction> fnGroupMap = functionGroups.get(namespace);
+      if (fnGroupMap != null) {
+        result = fnGroupMap.get(functionName.getLocalPart() + "/" + arity);
+        // fall back to multiple arity
+        if (result == null) result = fnGroupMap.get(functionName.getLocalPart() + "/*");
+      }
+    }
+    return result;
+  }
+
+
+  /**
+   * A helper method to create a mapping of function names to their implementing classes,
+   * and of namespaces to these mappings.
+   * @param fnGroup A group of functions to be added into a single namespace.
+   *        This group also provides that namespace.
+   */
+  protected final void addFunctionGroup(MulgaraFunctionGroup fnGroup) {
+    // map the function names to the functions
+    Map<String,XPathFunction> functionMap = new HashMap<String,XPathFunction>();
+    for (MulgaraFunction fn: fnGroup.getAllFunctions()) functionMap.put(fn.getName(), fn);
+    // map the namespace to the name->function map
+    functionGroups.put(fnGroup.getNamespace(), functionMap);
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,34 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.functions;
-
-
-/**
- * Retrieves Mulgara functions.
- *
- * @created Oct 6, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
-public class MulgaraUnsafeFunctionResolver extends MulgaraFunctionResolver {
-
-  // initialize the maps of requested parameters to the function object being asked for
-  public MulgaraUnsafeFunctionResolver() {
-    addFunctionGroup(new MulgaraXFunctionGroup());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraUnsafeFunctionResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.functions;
+
+
+/**
+ * Retrieves Mulgara functions.
+ *
+ * @created Oct 6, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public class MulgaraUnsafeFunctionResolver extends MulgaraFunctionResolver {
+
+  // initialize the maps of requested parameters to the function object being asked for
+  public MulgaraUnsafeFunctionResolver() {
+    addFunctionGroup(new MulgaraXFunctionGroup());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,139 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.functions;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.xml.xpath.XPathFunctionException;
-
-import org.mulgara.query.functions.MulgaraFunction;
-import org.mulgara.query.functions.MulgaraFunctionGroup;
-
-/**
- * Container for functions in the mulgarax domain.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
- at SuppressWarnings("unchecked")
-public class MulgaraXFunctionGroup implements MulgaraFunctionGroup {
-
-  /** The prefix for the mulgarax: namespace */
-  static final String PREFIX = "mulgarax";
-
-  /** The mulgarax: namespace */
-  static final String NAMESPACE = "http://mulgara.org/mulgarax#";
-
-  /** Internal buffer size for reading from external processes */
-  private static final int BUFFER_SIZE = 1024;
-
-  /**
-   * Get the prefix used for the namespace of these operations.
-   * @return The short string used for a prefix in a QName.
-   */
-  public String getPrefix() {
-    return PREFIX;
-  }
-
-  /**
-   * Get the namespace of these operations.
-   * @return The string of the namespace URI.
-   */
-  public String getNamespace() {
-    return NAMESPACE;
-  }
-
-  /**
-   * Get the set of MulgaraX functions.
-   * @return A set of MulgaraFunction for this entire group.
-   */
-  public Set<MulgaraFunction> getAllFunctions() {
-    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
-    functions.add(new System());
-    functions.add(new System2());
-    return functions;
-  }
-
-  /**
-   * Function to execute a command in a shell. Stdout is captured and returned as a string.
-   * @see http://www.w3.org/TR/xpath-functions/#func-matches
-   */
-  static private class System extends MulgaraFunction {
-    public Object eval(List args) throws XPathFunctionException {
-      String str = (String)args.get(0);
-      StringBuilder outputString = new StringBuilder();
-      try {
-        Process proc = Runtime.getRuntime().exec(str);
-        proc.getOutputStream().close();
-        BufferedReader procStdOut = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-        char[] buffer = new char[BUFFER_SIZE];
-        int len;
-        while ((len = procStdOut.read(buffer)) >= 0) outputString.append(buffer, 0, len);
-        procStdOut.close();
-        proc.getErrorStream().close();
-      } catch (IOException e) {
-        throw new XPathFunctionException("I/O error communicating with external process.");
-      }
-      return outputString.toString();
-    }
-  }
-
-  /**
-   * Function to execute a command in a shell. A second parameter provides stdin for the process.
-   * Stdout is captured and returned as a string.
-   */
-  static private class System2 extends MulgaraFunction {
-    public String getName() { return "system/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) throws XPathFunctionException {
-      // get the command and arguments
-      String str = (String)args.get(0);
-      // get the data to feed to stdin
-      String inputString = args.get(1).toString();
-
-      StringBuilder outputString = new StringBuilder();
-      try {
-        Process proc = Runtime.getRuntime().exec(str);
-        // get stdin for the process
-        Writer procStdIn = new OutputStreamWriter(proc.getOutputStream());
-        // get stdout for the process
-        BufferedReader procStdOut = new BufferedReader(new InputStreamReader(proc.getInputStream()));
-
-        // write to stdin
-        procStdIn.append(inputString);
-        procStdIn.close();
-        // read from stdout
-        char[] buffer = new char[BUFFER_SIZE];
-        int len;
-        while ((len = procStdOut.read(buffer)) >= 0) outputString.append(buffer, 0, len);
-        procStdOut.close();
-        proc.getErrorStream().close();
-      } catch (IOException e) {
-        throw new XPathFunctionException("I/O error communicating with external process.");
-      }
-      return outputString.toString();
-    }
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/functions/MulgaraXFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.functions;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.xpath.XPathFunctionException;
+
+import org.mulgara.query.functions.MulgaraFunction;
+import org.mulgara.query.functions.MulgaraFunctionGroup;
+
+/**
+ * Container for functions in the mulgarax domain.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+ at SuppressWarnings("unchecked")
+public class MulgaraXFunctionGroup implements MulgaraFunctionGroup {
+
+  /** The prefix for the mulgarax: namespace */
+  static final String PREFIX = "mulgarax";
+
+  /** The mulgarax: namespace */
+  static final String NAMESPACE = "http://mulgara.org/mulgarax#";
+
+  /** Internal buffer size for reading from external processes */
+  private static final int BUFFER_SIZE = 1024;
+
+  /**
+   * Get the prefix used for the namespace of these operations.
+   * @return The short string used for a prefix in a QName.
+   */
+  public String getPrefix() {
+    return PREFIX;
+  }
+
+  /**
+   * Get the namespace of these operations.
+   * @return The string of the namespace URI.
+   */
+  public String getNamespace() {
+    return NAMESPACE;
+  }
+
+  /**
+   * Get the set of MulgaraX functions.
+   * @return A set of MulgaraFunction for this entire group.
+   */
+  public Set<MulgaraFunction> getAllFunctions() {
+    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
+    functions.add(new System());
+    functions.add(new System2());
+    return functions;
+  }
+
+  /**
+   * Function to execute a command in a shell. Stdout is captured and returned as a string.
+   * @see http://www.w3.org/TR/xpath-functions/#func-matches
+   */
+  static private class System extends MulgaraFunction {
+    public Object eval(List args) throws XPathFunctionException {
+      String str = (String)args.get(0);
+      StringBuilder outputString = new StringBuilder();
+      try {
+        Process proc = Runtime.getRuntime().exec(str);
+        proc.getOutputStream().close();
+        BufferedReader procStdOut = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+        char[] buffer = new char[BUFFER_SIZE];
+        int len;
+        while ((len = procStdOut.read(buffer)) >= 0) outputString.append(buffer, 0, len);
+        procStdOut.close();
+        proc.getErrorStream().close();
+      } catch (IOException e) {
+        throw new XPathFunctionException("I/O error communicating with external process.");
+      }
+      return outputString.toString();
+    }
+  }
+
+  /**
+   * Function to execute a command in a shell. A second parameter provides stdin for the process.
+   * Stdout is captured and returned as a string.
+   */
+  static private class System2 extends MulgaraFunction {
+    public String getName() { return "system/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) throws XPathFunctionException {
+      // get the command and arguments
+      String str = (String)args.get(0);
+      // get the data to feed to stdin
+      String inputString = args.get(1).toString();
+
+      StringBuilder outputString = new StringBuilder();
+      try {
+        Process proc = Runtime.getRuntime().exec(str);
+        // get stdin for the process
+        Writer procStdIn = new OutputStreamWriter(proc.getOutputStream());
+        // get stdout for the process
+        BufferedReader procStdOut = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+
+        // write to stdin
+        procStdIn.append(inputString);
+        procStdIn.close();
+        // read from stdout
+        char[] buffer = new char[BUFFER_SIZE];
+        int len;
+        while ((len = procStdOut.read(buffer)) >= 0) outputString.append(buffer, 0, len);
+        procStdOut.close();
+        proc.getErrorStream().close();
+      } catch (IOException e) {
+        throw new XPathFunctionException("I/O error communicating with external process.");
+      }
+      return outputString.toString();
+    }
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,72 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.operation;
-
-import java.net.URI;
-import java.util.Map;
-
-import org.mulgara.connection.Connection;
-
-
-/**
- * An AST element for the ALIAS command.
- *
- * @created 2009-10-19
- * @author Paul Gearon
- */
-public class ListAlias extends LocalCommand {
-
-  private final Map<String,URI> aliases;
-
-  /**
-   * Creates a new list alias command.
-   */
-  public ListAlias(Map<String,URI> aliases) {
-    this.aliases = aliases;
-    setResultMessage(buildAliasList(aliases));
-  }
-  
-  /**
-   * Indicates that this operation is for a UI.
-   * @return <code>true</code> as operation is for UI output only.
-   */
-  public boolean isUICommand() {
-    return true;
-  }
-
-  /**
-   * Asks for the dictionary of aliases.
-   * @param conn ignored.
-   * @return A Map object that maps namespace prefixes to the namespace URI.
-   */
-  public Object execute(Connection conn) {
-    return aliases;
-  }
-
-  /**
-   * Writes the alias map as a set of URI/namespace pairs to a string for printing.
-   * @return A String containing all the alias mappings.
-   */
-  private static String buildAliasList(Map<String,URI> aliases) {
-    StringBuilder buffer = new StringBuilder();
-    for (Map.Entry<String,URI> alias: aliases.entrySet()) {
-      buffer.append(alias.getKey()).append(":  <").append(alias.getValue()).append(">\n");
-    }
-    return buffer.toString();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/operation/ListAlias.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/operation/ListAlias.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.operation;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.mulgara.connection.Connection;
+
+
+/**
+ * An AST element for the ALIAS command.
+ *
+ * @created 2009-10-19
+ * @author Paul Gearon
+ */
+public class ListAlias extends LocalCommand {
+
+  private final Map<String,URI> aliases;
+
+  /**
+   * Creates a new list alias command.
+   */
+  public ListAlias(Map<String,URI> aliases) {
+    this.aliases = aliases;
+    setResultMessage(buildAliasList(aliases));
+  }
+  
+  /**
+   * Indicates that this operation is for a UI.
+   * @return <code>true</code> as operation is for UI output only.
+   */
+  public boolean isUICommand() {
+    return true;
+  }
+
+  /**
+   * Asks for the dictionary of aliases.
+   * @param conn ignored.
+   * @return A Map object that maps namespace prefixes to the namespace URI.
+   */
+  public Object execute(Connection conn) {
+    return aliases;
+  }
+
+  /**
+   * Writes the alias map as a set of URI/namespace pairs to a string for printing.
+   * @return A String containing all the alias mappings.
+   */
+  private static String buildAliasList(Map<String,URI> aliases) {
+    StringBuilder buffer = new StringBuilder();
+    for (Map.Entry<String,URI> alias: aliases.entrySet()) {
+      buffer.append(alias.getKey()).append(":  <").append(alias.getValue()).append(">\n");
+    }
+    return buffer.toString();
+  }
+
+}

Copied: trunk/src/jar/query/java/org/mulgara/query/xpath (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath)

Deleted: trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,369 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.xpath;
-
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.xml.xpath.XPathFunctionException;
-
-import org.apache.xerces.impl.xpath.regex.RegularExpression;
-import org.mulgara.query.functions.MulgaraFunction;
-import org.mulgara.query.functions.MulgaraFunctionGroup;
-
-/**
- * Container for functions in the fn domain.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
- at SuppressWarnings("unchecked")
-public class FnFunctionGroup implements MulgaraFunctionGroup {
-
-  /** The prefix for the fn: namespace */
-  static final String PREFIX = "fn";
-
-  /** The fn: namespace */
-  static final String NAMESPACE = "http://www.w3.org/2005/xpath-functions/#";
-
-  /** The name of the UTF-8 encoding scheme */
-  static private final String UTF8 = "UTF-8";
-
-  /**
-   * Get the prefix used for the namespace of these operations.
-   * @return The short string used for a prefix in a QName.
-   */
-  public String getPrefix() {
-    return PREFIX;
-  }
-
-  /**
-   * Get the namespace of these operations.
-   * @return The string of the namespace URI.
-   */
-  public String getNamespace() {
-    return NAMESPACE;
-  }
-
-  /**
-   * Get the set of SPARQL functions.
-   * @return A set of MulgaraFunction for this entire group.
-   */
-  public Set<MulgaraFunction> getAllFunctions() {
-    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
-    functions.add(new Matches2());
-    functions.add(new Matches3());
-    functions.add(new FnBoolean());
-    functions.add(new Not());
-    functions.add(new Concat());
-    functions.add(new Substring2());
-    functions.add(new Substring3());
-    functions.add(new StringLength());
-    functions.add(new NormalizeSpace());
-    functions.add(new UpperCase());
-    functions.add(new LowerCase());
-    functions.add(new Translate());
-    functions.add(new EncodeForUri());
-    functions.add(new IriToUri());
-    functions.add(new EscapeHtmlUri());
-    return functions;
-  }
-
-  /**
-   * Function to evaluate if a string matches a pattern.
-   * @see http://www.w3.org/TR/xpath-functions/#func-matches
-   */
-  static private class Matches2 extends MulgaraFunction {
-    public String getName() { return "matches/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) {
-      String str = (String)args.get(0);
-      String pattern = (String)args.get(1);
-      return new RegularExpression(pattern).matches(str);
-    }
-  }
-
-  /**
-   * Function to evaluate if a string matches a pattern, with a set of modifying flags.
-   * @see http://www.w3.org/TR/xpath-functions/#func-matches
-   */
-  static private class Matches3 extends MulgaraFunction {
-    public String getName() { return "matches/3"; }
-    public int getArity() { return 3; }
-    public Object eval(List args) {
-      String str = (String)args.get(0);
-      String pattern = (String)args.get(1);
-      String flags = (String)args.get(2);
-      return new RegularExpression(pattern, flags).matches(str);
-    }
-  }
-
-  /**
-   * Function to compute the EBV of a sequence. Unfortunately, no sequence info is available at this level.
-   * @see http://www.w3.org/TR/xpath-functions/#func-boolean
-   */
-  static private class FnBoolean extends MulgaraFunction {
-    public String getName() { return "boolean"; }
-    public int getArity() { return 1; }
-    public Object eval(List args) throws XPathFunctionException {
-      // no sequence info available here. Look at singleton only for the moment
-      return toBool(args.get(0));
-    }
-  }
-
-  // No implementation of fn:compare
-
-  /**
-   * Function to compute the inverse EBV of a sequence. See FnBoolean for restrictions.
-   * @see http://www.w3.org/TR/xpath-functions/#func-not
-   */
-  static private class Not extends MulgaraFunction {
-    public int getArity() { return 1; }
-    public Object eval(List args) throws XPathFunctionException {
-      return !toBool(args.get(0));
-    }
-  }
-
-  /**
-   * Concatenates two or more arguments cast to string.
-   * @see http://www.w3.org/TR/xpath-functions/#func-concat
-   */
-  static private class Concat extends MulgaraFunction {
-    public int getArity() { return -1; }
-    public String getName() { return "concat/*"; }
-    public Object eval(List args) throws XPathFunctionException {
-      StringBuilder s = new StringBuilder();
-      for (Object o: args) s.append(o);
-      return s.toString();
-    }
-  }
-
-  /**
-   * Returns the string located at a specified place within an argument string.
-   * @see http://www.w3.org/TR/xpath-functions/#func-substring
-   */
-  static private class Substring2 extends MulgaraFunction {
-    public int getArity() { return 2; }
-    public String getName() { return "substring/2"; }
-    public Object eval(List args) throws XPathFunctionException {
-      String source = args.get(0).toString();
-      int start = ((Number)args.get(1)).intValue();
-      // perform boundary checking
-      int len = source.length();
-      if (start < 0) start = 0;
-      if (start > len) start = len;
-      return source.substring(start);
-    }
-  }
-
-  /**
-   * Returns the string located at a specified place within an argument string.
-   * @see http://www.w3.org/TR/xpath-functions/#func-substring
-   */
-  static private class Substring3 extends MulgaraFunction {
-    public int getArity() { return 3; }
-    public String getName() { return "substring/3"; }
-    public Object eval(List args) throws XPathFunctionException {
-      String source = args.get(0).toString();
-      int start = ((Number)args.get(1)).intValue() - 1;
-      int end = ((Number)args.get(2)).intValue() + start;
-      // perform boundary checking
-      int len = source.length();
-      if (start < 0) start = 0;
-      if (start > len) {
-        start = len;
-        end = len;
-      }
-      if (end > len) end = len;
-      if (end < start) end = start;
-      
-      return source.substring(start, end);
-    }
-  }
-
-  /**
-   * Returns the length of the argument.
-   * @see http://www.w3.org/TR/xpath-functions/#func-string-length
-   */
-  static private class StringLength extends MulgaraFunction {
-    public String getName() { return "string-length/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      return args.get(0).toString().length();
-    }
-  }
-
-  /**
-   * Returns the whitespace-normalized value of the argument.
-   * @see http://www.w3.org/TR/xpath-functions/#func-normalize-space
-   */
-  static private class NormalizeSpace extends MulgaraFunction {
-    public String getName() { return "normalize-space/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      String str = args.get(0).toString().trim();
-      return str.replaceAll(" +", " ");
-    }
-  }
-
-  /**
-   * Returns the upper-cased value of the argument.
-   * @see http://www.w3.org/TR/xpath-functions/#func-upper-case
-   */
-  static private class UpperCase extends MulgaraFunction {
-    public String getName() { return "upper-case/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      return args.get(0).toString().toUpperCase();
-    }
-  }
-
-  /**
-   * Returns the lower-cased value of the argument.
-   * @see http://www.w3.org/TR/xpath-functions/#func-lower-case
-   */
-  static private class LowerCase extends MulgaraFunction {
-    public String getName() { return "lower-case/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      return args.get(0).toString().toLowerCase();
-    }
-  }
-
-  /**
-   * Returns the first xs:string argument with occurrences of characters contained
-   * in the second argument replaced by the character at the corresponding position
-   * in the third argument.
-   */
-  static private class Translate extends MulgaraFunction {
-    public int getArity() { return 3; }
-    public Object eval(List args) throws XPathFunctionException {
-      String str = args.get(0).toString();
-      String mapStr = args.get(1).toString();
-      String transStr = args.get(2).toString();
-      // iterate through the map chars
-      for (int i = 0; i < mapStr.length(); i++) {
-        char c = mapStr.charAt(i);
-        if (i < transStr.length()) str = replaceChars(str, c, transStr.charAt(i));
-        else str = removeChars(str, c);
-      }
-      return str;
-    }
-
-    private static String replaceChars(String str, char c, char r) {
-      StringBuilder s = new StringBuilder(str);
-      for (int i = 0; i < s.length(); i++) {
-        if (s.charAt(i) == c) s.setCharAt(i, r);
-      }
-      return s.toString();
-    }
-
-    private static String removeChars(String str, char c) {
-      StringBuilder s = new StringBuilder(str);
-      for (int i = 0; i < s.length(); i++) {
-        if (s.charAt(i) == c) {
-          s.replace(i, i + 1, "");
-          i--;
-        }
-      }
-      return s.toString();
-    }
-  }
-
-  /**
-   * Returns the xs:string argument with certain characters escaped to enable the
-   * resulting string to be used as a path segment in a URI.
-   * @see http://www.w3.org/TR/xpath-functions/#func-encode-for-uri
-   */
-  static private class EncodeForUri extends MulgaraFunction {
-    public String getName() { return "encode-for-uri/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      try {
-        return URLEncoder.encode(args.get(0).toString(), UTF8);
-      } catch (UnsupportedEncodingException e) {
-        throw new XPathFunctionException("Unable to encode string for URL: " + e.getMessage());
-      }
-    }
-  }
-
-  /**
-   * Returns the xs:string argument with certain characters escaped to enable the
-   * resulting string to be used as (part of) a URI.
-   * @see http://www.w3.org/TR/xpath-functions/#func-iri-to-uri
-   */
-  static private class IriToUri extends MulgaraFunction {
-    public String getName() { return "iri-to-uri/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      StringBuilder str = new StringBuilder(args.get(0).toString());
-      for (int i = 0; i < str.length(); i++) {
-        char c = str.charAt(i);
-        if (outOfRange(c)) str.replace(i, i + 1, escape(str.substring(i, i + 1)));
-      }
-      return str.toString();
-    }
-    /**
-     * Test for URI compatibility. See Errata note:
-     * @see http://www.w3.org/XML/2007/qt-errata/xpath-functions-errata.html#E8
-     * @param c The character to test.
-     * @return <code>true</code> if the character is out of range for a URI and must be encoded.
-     */
-    static private final boolean outOfRange(char c) {
-      return c < 0x20 || c > 0x7E || c == '<' || c == '>' || c == '"' ||
-             c == '{' || c == '}' || c == '|' || c == '\\' || c == '^' || c == '`';
-    }
-  }
-
-  /**
-   * Returns the string argument with certain characters escaped in the manner that html user agents
-   * handle attribute values that expect URIs.
-   * @see http://www.w3.org/TR/xpath-functions/#func-escape-html-uri
-   */
-  static private class EscapeHtmlUri extends MulgaraFunction {
-    public String getName() { return "escape-html-uri/1"; }
-    public Object eval(List args) throws XPathFunctionException {
-      StringBuilder str = new StringBuilder(args.get(0).toString());
-      for (int i = 0; i < str.length(); i++) {
-        char c = str.charAt(i);
-        if (outOfRange(c)) str.replace(i, i + 1, escape(str.substring(i, i + 1)));
-      }
-      return str.toString();
-    }
-    static private final boolean outOfRange(char c) {
-      return c < 0x20 || c > 0x7E;
-    }
-  }
-
-  /**
-   * Converts a single character to a string containing escaped UTF-8 encoding.
-   * A utility used by both EscapeHtmlUri and IriToUri.
-   * @param c The character to escape.
-   * @return A string containing a sequence of %HH representing the UTF-8 encoding of <var>c</var>
-   * @throws XPathFunctionException If UTF-8 encoding fails.
-   */
-  static private final String escape(String c) throws XPathFunctionException {
-    byte[] bytes = null;
-    try {
-      bytes = c.getBytes(UTF8);
-    } catch (UnsupportedEncodingException e) {
-      throw new XPathFunctionException("Unable to encode string for URL: " + e.getMessage());
-    }
-    StringBuilder result = new StringBuilder();
-    for (int i = 0; i < bytes.length; i++) result.append(String.format("%%%02X", bytes[i]));
-    return result.toString();
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/FnFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,369 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.xpath;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.xpath.XPathFunctionException;
+
+import org.apache.xerces.impl.xpath.regex.RegularExpression;
+import org.mulgara.query.functions.MulgaraFunction;
+import org.mulgara.query.functions.MulgaraFunctionGroup;
+
+/**
+ * Container for functions in the fn domain.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+ at SuppressWarnings("unchecked")
+public class FnFunctionGroup implements MulgaraFunctionGroup {
+
+  /** The prefix for the fn: namespace */
+  static final String PREFIX = "fn";
+
+  /** The fn: namespace */
+  static final String NAMESPACE = "http://www.w3.org/2005/xpath-functions/#";
+
+  /** The name of the UTF-8 encoding scheme */
+  static private final String UTF8 = "UTF-8";
+
+  /**
+   * Get the prefix used for the namespace of these operations.
+   * @return The short string used for a prefix in a QName.
+   */
+  public String getPrefix() {
+    return PREFIX;
+  }
+
+  /**
+   * Get the namespace of these operations.
+   * @return The string of the namespace URI.
+   */
+  public String getNamespace() {
+    return NAMESPACE;
+  }
+
+  /**
+   * Get the set of SPARQL functions.
+   * @return A set of MulgaraFunction for this entire group.
+   */
+  public Set<MulgaraFunction> getAllFunctions() {
+    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
+    functions.add(new Matches2());
+    functions.add(new Matches3());
+    functions.add(new FnBoolean());
+    functions.add(new Not());
+    functions.add(new Concat());
+    functions.add(new Substring2());
+    functions.add(new Substring3());
+    functions.add(new StringLength());
+    functions.add(new NormalizeSpace());
+    functions.add(new UpperCase());
+    functions.add(new LowerCase());
+    functions.add(new Translate());
+    functions.add(new EncodeForUri());
+    functions.add(new IriToUri());
+    functions.add(new EscapeHtmlUri());
+    return functions;
+  }
+
+  /**
+   * Function to evaluate if a string matches a pattern.
+   * @see http://www.w3.org/TR/xpath-functions/#func-matches
+   */
+  static private class Matches2 extends MulgaraFunction {
+    public String getName() { return "matches/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) {
+      String str = (String)args.get(0);
+      String pattern = (String)args.get(1);
+      return new RegularExpression(pattern).matches(str);
+    }
+  }
+
+  /**
+   * Function to evaluate if a string matches a pattern, with a set of modifying flags.
+   * @see http://www.w3.org/TR/xpath-functions/#func-matches
+   */
+  static private class Matches3 extends MulgaraFunction {
+    public String getName() { return "matches/3"; }
+    public int getArity() { return 3; }
+    public Object eval(List args) {
+      String str = (String)args.get(0);
+      String pattern = (String)args.get(1);
+      String flags = (String)args.get(2);
+      return new RegularExpression(pattern, flags).matches(str);
+    }
+  }
+
+  /**
+   * Function to compute the EBV of a sequence. Unfortunately, no sequence info is available at this level.
+   * @see http://www.w3.org/TR/xpath-functions/#func-boolean
+   */
+  static private class FnBoolean extends MulgaraFunction {
+    public String getName() { return "boolean"; }
+    public int getArity() { return 1; }
+    public Object eval(List args) throws XPathFunctionException {
+      // no sequence info available here. Look at singleton only for the moment
+      return toBool(args.get(0));
+    }
+  }
+
+  // No implementation of fn:compare
+
+  /**
+   * Function to compute the inverse EBV of a sequence. See FnBoolean for restrictions.
+   * @see http://www.w3.org/TR/xpath-functions/#func-not
+   */
+  static private class Not extends MulgaraFunction {
+    public int getArity() { return 1; }
+    public Object eval(List args) throws XPathFunctionException {
+      return !toBool(args.get(0));
+    }
+  }
+
+  /**
+   * Concatenates two or more arguments cast to string.
+   * @see http://www.w3.org/TR/xpath-functions/#func-concat
+   */
+  static private class Concat extends MulgaraFunction {
+    public int getArity() { return -1; }
+    public String getName() { return "concat/*"; }
+    public Object eval(List args) throws XPathFunctionException {
+      StringBuilder s = new StringBuilder();
+      for (Object o: args) s.append(o);
+      return s.toString();
+    }
+  }
+
+  /**
+   * Returns the string located at a specified place within an argument string.
+   * @see http://www.w3.org/TR/xpath-functions/#func-substring
+   */
+  static private class Substring2 extends MulgaraFunction {
+    public int getArity() { return 2; }
+    public String getName() { return "substring/2"; }
+    public Object eval(List args) throws XPathFunctionException {
+      String source = args.get(0).toString();
+      int start = ((Number)args.get(1)).intValue();
+      // perform boundary checking
+      int len = source.length();
+      if (start < 0) start = 0;
+      if (start > len) start = len;
+      return source.substring(start);
+    }
+  }
+
+  /**
+   * Returns the string located at a specified place within an argument string.
+   * @see http://www.w3.org/TR/xpath-functions/#func-substring
+   */
+  static private class Substring3 extends MulgaraFunction {
+    public int getArity() { return 3; }
+    public String getName() { return "substring/3"; }
+    public Object eval(List args) throws XPathFunctionException {
+      String source = args.get(0).toString();
+      int start = ((Number)args.get(1)).intValue() - 1;
+      int end = ((Number)args.get(2)).intValue() + start;
+      // perform boundary checking
+      int len = source.length();
+      if (start < 0) start = 0;
+      if (start > len) {
+        start = len;
+        end = len;
+      }
+      if (end > len) end = len;
+      if (end < start) end = start;
+      
+      return source.substring(start, end);
+    }
+  }
+
+  /**
+   * Returns the length of the argument.
+   * @see http://www.w3.org/TR/xpath-functions/#func-string-length
+   */
+  static private class StringLength extends MulgaraFunction {
+    public String getName() { return "string-length/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      return args.get(0).toString().length();
+    }
+  }
+
+  /**
+   * Returns the whitespace-normalized value of the argument.
+   * @see http://www.w3.org/TR/xpath-functions/#func-normalize-space
+   */
+  static private class NormalizeSpace extends MulgaraFunction {
+    public String getName() { return "normalize-space/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      String str = args.get(0).toString().trim();
+      return str.replaceAll(" +", " ");
+    }
+  }
+
+  /**
+   * Returns the upper-cased value of the argument.
+   * @see http://www.w3.org/TR/xpath-functions/#func-upper-case
+   */
+  static private class UpperCase extends MulgaraFunction {
+    public String getName() { return "upper-case/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      return args.get(0).toString().toUpperCase();
+    }
+  }
+
+  /**
+   * Returns the lower-cased value of the argument.
+   * @see http://www.w3.org/TR/xpath-functions/#func-lower-case
+   */
+  static private class LowerCase extends MulgaraFunction {
+    public String getName() { return "lower-case/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      return args.get(0).toString().toLowerCase();
+    }
+  }
+
+  /**
+   * Returns the first xs:string argument with occurrences of characters contained
+   * in the second argument replaced by the character at the corresponding position
+   * in the third argument.
+   */
+  static private class Translate extends MulgaraFunction {
+    public int getArity() { return 3; }
+    public Object eval(List args) throws XPathFunctionException {
+      String str = args.get(0).toString();
+      String mapStr = args.get(1).toString();
+      String transStr = args.get(2).toString();
+      // iterate through the map chars
+      for (int i = 0; i < mapStr.length(); i++) {
+        char c = mapStr.charAt(i);
+        if (i < transStr.length()) str = replaceChars(str, c, transStr.charAt(i));
+        else str = removeChars(str, c);
+      }
+      return str;
+    }
+
+    private static String replaceChars(String str, char c, char r) {
+      StringBuilder s = new StringBuilder(str);
+      for (int i = 0; i < s.length(); i++) {
+        if (s.charAt(i) == c) s.setCharAt(i, r);
+      }
+      return s.toString();
+    }
+
+    private static String removeChars(String str, char c) {
+      StringBuilder s = new StringBuilder(str);
+      for (int i = 0; i < s.length(); i++) {
+        if (s.charAt(i) == c) {
+          s.replace(i, i + 1, "");
+          i--;
+        }
+      }
+      return s.toString();
+    }
+  }
+
+  /**
+   * Returns the xs:string argument with certain characters escaped to enable the
+   * resulting string to be used as a path segment in a URI.
+   * @see http://www.w3.org/TR/xpath-functions/#func-encode-for-uri
+   */
+  static private class EncodeForUri extends MulgaraFunction {
+    public String getName() { return "encode-for-uri/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      try {
+        return URLEncoder.encode(args.get(0).toString(), UTF8);
+      } catch (UnsupportedEncodingException e) {
+        throw new XPathFunctionException("Unable to encode string for URL: " + e.getMessage());
+      }
+    }
+  }
+
+  /**
+   * Returns the xs:string argument with certain characters escaped to enable the
+   * resulting string to be used as (part of) a URI.
+   * @see http://www.w3.org/TR/xpath-functions/#func-iri-to-uri
+   */
+  static private class IriToUri extends MulgaraFunction {
+    public String getName() { return "iri-to-uri/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      StringBuilder str = new StringBuilder(args.get(0).toString());
+      for (int i = 0; i < str.length(); i++) {
+        char c = str.charAt(i);
+        if (outOfRange(c)) str.replace(i, i + 1, escape(str.substring(i, i + 1)));
+      }
+      return str.toString();
+    }
+    /**
+     * Test for URI compatibility. See Errata note:
+     * @see http://www.w3.org/XML/2007/qt-errata/xpath-functions-errata.html#E8
+     * @param c The character to test.
+     * @return <code>true</code> if the character is out of range for a URI and must be encoded.
+     */
+    static private final boolean outOfRange(char c) {
+      return c < 0x20 || c > 0x7E || c == '<' || c == '>' || c == '"' ||
+             c == '{' || c == '}' || c == '|' || c == '\\' || c == '^' || c == '`';
+    }
+  }
+
+  /**
+   * Returns the string argument with certain characters escaped in the manner that html user agents
+   * handle attribute values that expect URIs.
+   * @see http://www.w3.org/TR/xpath-functions/#func-escape-html-uri
+   */
+  static private class EscapeHtmlUri extends MulgaraFunction {
+    public String getName() { return "escape-html-uri/1"; }
+    public Object eval(List args) throws XPathFunctionException {
+      StringBuilder str = new StringBuilder(args.get(0).toString());
+      for (int i = 0; i < str.length(); i++) {
+        char c = str.charAt(i);
+        if (outOfRange(c)) str.replace(i, i + 1, escape(str.substring(i, i + 1)));
+      }
+      return str.toString();
+    }
+    static private final boolean outOfRange(char c) {
+      return c < 0x20 || c > 0x7E;
+    }
+  }
+
+  /**
+   * Converts a single character to a string containing escaped UTF-8 encoding.
+   * A utility used by both EscapeHtmlUri and IriToUri.
+   * @param c The character to escape.
+   * @return A string containing a sequence of %HH representing the UTF-8 encoding of <var>c</var>
+   * @throws XPathFunctionException If UTF-8 encoding fails.
+   */
+  static private final String escape(String c) throws XPathFunctionException {
+    byte[] bytes = null;
+    try {
+      bytes = c.getBytes(UTF8);
+    } catch (UnsupportedEncodingException e) {
+      throw new XPathFunctionException("Unable to encode string for URL: " + e.getMessage());
+    }
+    StringBuilder result = new StringBuilder();
+    for (int i = 0; i < bytes.length; i++) result.append(String.format("%%%02X", bytes[i]));
+    return result.toString();
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,39 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.xpath;
-
-import org.mulgara.query.functions.MulgaraFunctionResolver;
-
-/**
- * Retrieves functions for SPARQL expressions.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
-public class MulgaraXPathFunctionResolver extends MulgaraFunctionResolver {
-
-  /**
-   * Initialize the maps of requested parameters to the function object being asked for
-   */
-  public MulgaraXPathFunctionResolver() {
-    addFunctionGroup(new SparqlFunctionGroup());
-    addFunctionGroup(new FnFunctionGroup());
-    addFunctionGroup(new OpFunctionGroup());
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/MulgaraXPathFunctionResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.xpath;
+
+import org.mulgara.query.functions.MulgaraFunctionResolver;
+
+/**
+ * Retrieves functions for SPARQL expressions.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+public class MulgaraXPathFunctionResolver extends MulgaraFunctionResolver {
+
+  /**
+   * Initialize the maps of requested parameters to the function object being asked for
+   */
+  public MulgaraXPathFunctionResolver() {
+    addFunctionGroup(new SparqlFunctionGroup());
+    addFunctionGroup(new FnFunctionGroup());
+    addFunctionGroup(new OpFunctionGroup());
+  }
+
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,171 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.xpath;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import org.mulgara.query.functions.MulgaraFunction;
-import org.mulgara.query.functions.MulgaraFunctionGroup;
-
-/**
- * Container for functions in the op pseudo-domain.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
- at SuppressWarnings("unchecked")
-public class OpFunctionGroup implements MulgaraFunctionGroup {
-
-  /** The prefix for the fn: namespace */
-  static final String PREFIX = "op";
-
-  /** The op: namespace */
-  static final String NAMESPACE = PREFIX;
-
-  /**
-   * Get the prefix used for the namespace of these operations.
-   * @return The short string used for a prefix in a QName.
-   */
-  public String getPrefix() {
-    return PREFIX;
-  }
-
-  /**
-   * Get the namespace of these operations.
-   * @return The string of the namespace URI.
-   */
-  public String getNamespace() {
-    return NAMESPACE;
-  }
-
-  /**
-   * Get the set of SPARQL functions.
-   * @return A set of MulgaraFunction for this entire group.
-   */
-  public Set<MulgaraFunction> getAllFunctions() {
-    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
-    functions.add(new NumericEqual());
-    functions.add(new NumericLessThan());
-    functions.add(new NumericGreaterThan());
-    functions.add(new NumericIntegerDivision());
-    functions.add(new NumericMod());
-    return functions;
-  }
-
-  /**
-   * Function to evaluate if two numbers are equal.
-   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-equal
-   */
-  static private class NumericEqual extends MulgaraFunction {
-    public String getName() { return "numeric-equal/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) {
-      Number left = (Number)args.get(0);
-      Number right = (Number)args.get(1);
-      return left.doubleValue() == right.doubleValue();
-    }
-  }
-
-  /**
-   * Function to evaluate if one number is less than another.
-   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-less-than
-   */
-  static private class NumericLessThan extends MulgaraFunction {
-    public String getName() { return "numeric-less-than/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) {
-      Number left = (Number)args.get(0);
-      Number right = (Number)args.get(1);
-      return left.doubleValue() < right.doubleValue();
-    }
-  }
-
-  /**
-   * Function to evaluate if one number is greater than another.
-   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-greater-than
-   */
-  static private class NumericGreaterThan extends MulgaraFunction {
-    public String getName() { return "numeric-greater-than/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) {
-      Number left = (Number)args.get(0);
-      Number right = (Number)args.get(1);
-      return left.doubleValue() > right.doubleValue();
-    }
-  }
-
-  /**
-   * Function to evaluate integer division between numbers. This does not meet the XPath semantics
-   * perfectly, but will work for many situations.
-   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-integer-divide
-   */
-  static private class NumericIntegerDivision extends MulgaraFunction {
-    public String getName() { return "numeric-integer-divide/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) {
-      Number left = (Number)args.get(0);
-      Number right = (Number)args.get(1);
-      if (left instanceof BigDecimal) {
-        return ((BigDecimal)left).divide(
-            (right instanceof BigDecimal) ? (BigDecimal)right : new BigDecimal(right.toString())
-        );
-      }
-      if (left instanceof BigInteger) {
-        return ((BigInteger)left).divide(
-            (right instanceof BigInteger) ? (BigInteger)right : new BigInteger(right.toString())
-        );
-      }
-      return Double.valueOf(left.doubleValue() / right.doubleValue()).longValue();
-    }
-  }
-
-  /**
-   * Function to evaluate the numeric mod operation. This does not meet the XPath semantics
-   * perfectly, but will work for most situations.
-   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-mod
-   */
-  static private class NumericMod extends MulgaraFunction {
-    public String getName() { return "numeric-mod/2"; }
-    public int getArity() { return 2; }
-    public Object eval(List args) {
-      Number left = (Number)args.get(0);
-      Number right = (Number)args.get(1);
-      if (left instanceof Byte || left instanceof Short || left instanceof Integer || left instanceof Long) {
-        return left.longValue() % right.longValue();
-      }
-      if (left instanceof Float || left instanceof Double) {
-        return left.doubleValue() % right.doubleValue();
-      }
-      if (left instanceof BigDecimal) {
-        return ((BigDecimal)left).remainder(
-            (right instanceof BigDecimal) ? (BigDecimal)right : new BigDecimal(right.toString())
-        );
-      }
-      if (left instanceof BigInteger) {
-        return ((BigInteger)left).remainder(
-            (right instanceof BigInteger) ? (BigInteger)right : new BigInteger(right.toString())
-        );
-      }
-      return Double.valueOf(left.doubleValue() % right.doubleValue()).longValue();
-    }
-  }
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/OpFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.xpath;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.mulgara.query.functions.MulgaraFunction;
+import org.mulgara.query.functions.MulgaraFunctionGroup;
+
+/**
+ * Container for functions in the op pseudo-domain.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+ at SuppressWarnings("unchecked")
+public class OpFunctionGroup implements MulgaraFunctionGroup {
+
+  /** The prefix for the fn: namespace */
+  static final String PREFIX = "op";
+
+  /** The op: namespace */
+  static final String NAMESPACE = PREFIX;
+
+  /**
+   * Get the prefix used for the namespace of these operations.
+   * @return The short string used for a prefix in a QName.
+   */
+  public String getPrefix() {
+    return PREFIX;
+  }
+
+  /**
+   * Get the namespace of these operations.
+   * @return The string of the namespace URI.
+   */
+  public String getNamespace() {
+    return NAMESPACE;
+  }
+
+  /**
+   * Get the set of SPARQL functions.
+   * @return A set of MulgaraFunction for this entire group.
+   */
+  public Set<MulgaraFunction> getAllFunctions() {
+    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
+    functions.add(new NumericEqual());
+    functions.add(new NumericLessThan());
+    functions.add(new NumericGreaterThan());
+    functions.add(new NumericIntegerDivision());
+    functions.add(new NumericMod());
+    return functions;
+  }
+
+  /**
+   * Function to evaluate if two numbers are equal.
+   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-equal
+   */
+  static private class NumericEqual extends MulgaraFunction {
+    public String getName() { return "numeric-equal/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) {
+      Number left = (Number)args.get(0);
+      Number right = (Number)args.get(1);
+      return left.doubleValue() == right.doubleValue();
+    }
+  }
+
+  /**
+   * Function to evaluate if one number is less than another.
+   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-less-than
+   */
+  static private class NumericLessThan extends MulgaraFunction {
+    public String getName() { return "numeric-less-than/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) {
+      Number left = (Number)args.get(0);
+      Number right = (Number)args.get(1);
+      return left.doubleValue() < right.doubleValue();
+    }
+  }
+
+  /**
+   * Function to evaluate if one number is greater than another.
+   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-greater-than
+   */
+  static private class NumericGreaterThan extends MulgaraFunction {
+    public String getName() { return "numeric-greater-than/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) {
+      Number left = (Number)args.get(0);
+      Number right = (Number)args.get(1);
+      return left.doubleValue() > right.doubleValue();
+    }
+  }
+
+  /**
+   * Function to evaluate integer division between numbers. This does not meet the XPath semantics
+   * perfectly, but will work for many situations.
+   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-integer-divide
+   */
+  static private class NumericIntegerDivision extends MulgaraFunction {
+    public String getName() { return "numeric-integer-divide/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) {
+      Number left = (Number)args.get(0);
+      Number right = (Number)args.get(1);
+      if (left instanceof BigDecimal) {
+        return ((BigDecimal)left).divide(
+            (right instanceof BigDecimal) ? (BigDecimal)right : new BigDecimal(right.toString())
+        );
+      }
+      if (left instanceof BigInteger) {
+        return ((BigInteger)left).divide(
+            (right instanceof BigInteger) ? (BigInteger)right : new BigInteger(right.toString())
+        );
+      }
+      return Double.valueOf(left.doubleValue() / right.doubleValue()).longValue();
+    }
+  }
+
+  /**
+   * Function to evaluate the numeric mod operation. This does not meet the XPath semantics
+   * perfectly, but will work for most situations.
+   * @see http://www.w3.org/TR/xpath-functions/#func-numeric-mod
+   */
+  static private class NumericMod extends MulgaraFunction {
+    public String getName() { return "numeric-mod/2"; }
+    public int getArity() { return 2; }
+    public Object eval(List args) {
+      Number left = (Number)args.get(0);
+      Number right = (Number)args.get(1);
+      if (left instanceof Byte || left instanceof Short || left instanceof Integer || left instanceof Long) {
+        return left.longValue() % right.longValue();
+      }
+      if (left instanceof Float || left instanceof Double) {
+        return left.doubleValue() % right.doubleValue();
+      }
+      if (left instanceof BigDecimal) {
+        return ((BigDecimal)left).remainder(
+            (right instanceof BigDecimal) ? (BigDecimal)right : new BigDecimal(right.toString())
+        );
+      }
+      if (left instanceof BigInteger) {
+        return ((BigInteger)left).remainder(
+            (right instanceof BigInteger) ? (BigInteger)right : new BigInteger(right.toString())
+        );
+      }
+      return Double.valueOf(left.doubleValue() % right.doubleValue()).longValue();
+    }
+  }
+}

Deleted: trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java
===================================================================
--- branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,181 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.query.xpath;
-
-import java.net.URI;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-import javax.xml.xpath.XPathFunctionException;
-
-import org.jrdf.graph.BlankNode;
-import org.jrdf.graph.Literal;
-import org.mulgara.query.QueryException;
-import org.mulgara.query.filter.value.SimpleLiteral;
-import org.mulgara.query.functions.MulgaraFunction;
-import org.mulgara.query.functions.MulgaraFunctionGroup;
-
-/**
- * Container for functions in the SPARQL domain.
- *
- * @created Oct 5, 2009
- * @author Paul Gearon
- * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
- */
- at SuppressWarnings("unchecked")
-public class SparqlFunctionGroup implements MulgaraFunctionGroup {
-
-  /** The prefix for the sparql: namespace */
-  static final String PREFIX = "sparql";
-
-  /** The sparql: namespace */
-  static final String NAMESPACE = "http://www.w3.org/2006/sparql-functions#";
-
-  /**
-   * Get the prefix used for the namespace of these operations.
-   * @return The short string used for a prefix in a QName.
-   */
-  public String getPrefix() {
-    return PREFIX;
-  }
-
-  /**
-   * Get the namespace of these operations.
-   * @return The string of the namespace URI.
-   */
-  public String getNamespace() {
-    return NAMESPACE;
-  }
-
-  /**
-   * Get the set of SPARQL functions.
-   * @return A set of MulgaraFunction for this entire group.
-   */
-  public Set<MulgaraFunction> getAllFunctions() {
-    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
-    functions.add(new Bound());
-    functions.add(new IsIRI());
-    functions.add(new IsURI());
-    functions.add(new IsBlank());
-    functions.add(new IsLiteral());
-    functions.add(new Str());
-    functions.add(new Lang());
-    functions.add(new Datatype());
-    functions.add(new LangMatches());
-    functions.add(new LogicalOr());
-    functions.add(new LogicalAnd());
-    return functions;
-  }
-
-  /** Function to evaluate if a parameter is bound. */
-  static private class Bound extends MulgaraFunction {
-    public Object eval(List args) { return args.get(0) != null; }
-  }
-
-  /** Function to evaluate if a parameter is an IRI. */
-  static private class IsIRI extends MulgaraFunction {
-    public Object eval(List args) { return args.get(0) instanceof URI; }
-  }
-
-  /** Function to evaluate if a parameter is a URI. */
-  static private class IsURI extends MulgaraFunction {
-    public Object eval(List args) { return args.get(0) instanceof URI; }
-  }
-
-  /** Function to evaluate if a parameter is a blank node. */
-  static private class IsBlank extends MulgaraFunction {
-    public Object eval(List args) { return args.get(0) instanceof BlankNode; }
-  }
-
-  /** Function to evaluate if a parameter is a literal. */
-  static private class IsLiteral extends MulgaraFunction {
-    public Object eval(List args) {
-      Object o = args.get(0);
-      return o instanceof Literal || o instanceof String || o instanceof Number;
-    }
-  }
-
-  /** Function to convert a value to a string. */
-  static private class Str extends MulgaraFunction {
-    public Object eval(List args) { return args.get(0).toString(); }
-  }
-
-  /** Function to get the language of a literal. This information is probably not available for this implementation. */
-  static private class Lang extends MulgaraFunction {
-    public Object eval(List args) {
-      Object o = args.get(0);
-      return o instanceof Literal ? ((Literal)o).getLanguage() : "";
-    }
-  }
-    
-  /** Function to get the datatype of a literal. This information is probably not available for this implementation. */
-  static private class Datatype extends MulgaraFunction {
-    public Object eval(List args) {
-      Object o = args.get(0);
-      return o instanceof Literal ? ((Literal)o).getDatatype() : null;
-    }
-  }
-  
-  /**
-   * Function to test if a language code matches a pattern.
-   * This information is probably not available for this implementation.
-   */
-  static private class LangMatches extends MulgaraFunction {
-    protected int getArity() { return 2; }
-    public Object eval(List args) throws XPathFunctionException {
-      Object o = args.get(0);
-      if (o instanceof Literal) {
-        Literal l = (Literal)o;
-        if (l.getLanguage() == null || l.getLanguage().length() == 0) return false;
-        org.mulgara.query.filter.LangMatches match = new org.mulgara.query.filter.LangMatches(new SimpleLiteral(l.getLexicalForm(), l.getLanguage()), new SimpleLiteral((String)args.get(1)));
-        try {
-          return match.getValue();
-        } catch (QueryException e) {
-          throw new XPathFunctionException("Unable to get data from lang matching test: " + e.getMessage());
-        }
-      }
-      return false;
-    }
-  }
-
-  /** Common operations required for a logical operation. */
-  static private abstract class LogicOp extends MulgaraFunction {
-    protected int getArity() { return 2; }
-    protected abstract boolean op(Object left, Object right) throws XPathFunctionException;
-    public Object eval(List args) throws XPathFunctionException {
-      return op(args.get(0), args.get(1));
-    }
-  }
-
-  /** Function to perform a logical OR between 2 operands. */
-  static private class LogicalOr extends LogicOp {
-    public String getName() { return "logical-or"; }
-    public boolean op(Object left, Object right) throws XPathFunctionException {
-      return toBool(left) || toBool(right);
-    }
-  }
-
-  /** Function to perform a logical AND between 2 operands. */
-  static private class LogicalAnd extends LogicOp {
-    public String getName() { return "logical-and"; }
-    public boolean op(Object left, Object right) throws XPathFunctionException {
-      return toBool(left) && toBool(right);
-    }
-  }
-
-}

Copied: trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java (from rev 1870, branches/distinct_queries/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java)
===================================================================
--- trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java	                        (rev 0)
+++ trunk/src/jar/query/java/org/mulgara/query/xpath/SparqlFunctionGroup.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.query.xpath;
+
+import java.net.URI;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.xpath.XPathFunctionException;
+
+import org.jrdf.graph.BlankNode;
+import org.jrdf.graph.Literal;
+import org.mulgara.query.QueryException;
+import org.mulgara.query.filter.value.SimpleLiteral;
+import org.mulgara.query.functions.MulgaraFunction;
+import org.mulgara.query.functions.MulgaraFunctionGroup;
+
+/**
+ * Container for functions in the SPARQL domain.
+ *
+ * @created Oct 5, 2009
+ * @author Paul Gearon
+ * @copyright &copy; 2009 <a href="http://www.duraspace.org/">DuraSpace</a>
+ */
+ at SuppressWarnings("unchecked")
+public class SparqlFunctionGroup implements MulgaraFunctionGroup {
+
+  /** The prefix for the sparql: namespace */
+  static final String PREFIX = "sparql";
+
+  /** The sparql: namespace */
+  static final String NAMESPACE = "http://www.w3.org/2006/sparql-functions#";
+
+  /**
+   * Get the prefix used for the namespace of these operations.
+   * @return The short string used for a prefix in a QName.
+   */
+  public String getPrefix() {
+    return PREFIX;
+  }
+
+  /**
+   * Get the namespace of these operations.
+   * @return The string of the namespace URI.
+   */
+  public String getNamespace() {
+    return NAMESPACE;
+  }
+
+  /**
+   * Get the set of SPARQL functions.
+   * @return A set of MulgaraFunction for this entire group.
+   */
+  public Set<MulgaraFunction> getAllFunctions() {
+    Set<MulgaraFunction> functions = new HashSet<MulgaraFunction>();
+    functions.add(new Bound());
+    functions.add(new IsIRI());
+    functions.add(new IsURI());
+    functions.add(new IsBlank());
+    functions.add(new IsLiteral());
+    functions.add(new Str());
+    functions.add(new Lang());
+    functions.add(new Datatype());
+    functions.add(new LangMatches());
+    functions.add(new LogicalOr());
+    functions.add(new LogicalAnd());
+    return functions;
+  }
+
+  /** Function to evaluate if a parameter is bound. */
+  static private class Bound extends MulgaraFunction {
+    public Object eval(List args) { return args.get(0) != null; }
+  }
+
+  /** Function to evaluate if a parameter is an IRI. */
+  static private class IsIRI extends MulgaraFunction {
+    public Object eval(List args) { return args.get(0) instanceof URI; }
+  }
+
+  /** Function to evaluate if a parameter is a URI. */
+  static private class IsURI extends MulgaraFunction {
+    public Object eval(List args) { return args.get(0) instanceof URI; }
+  }
+
+  /** Function to evaluate if a parameter is a blank node. */
+  static private class IsBlank extends MulgaraFunction {
+    public Object eval(List args) { return args.get(0) instanceof BlankNode; }
+  }
+
+  /** Function to evaluate if a parameter is a literal. */
+  static private class IsLiteral extends MulgaraFunction {
+    public Object eval(List args) {
+      Object o = args.get(0);
+      return o instanceof Literal || o instanceof String || o instanceof Number;
+    }
+  }
+
+  /** Function to convert a value to a string. */
+  static private class Str extends MulgaraFunction {
+    public Object eval(List args) { return args.get(0).toString(); }
+  }
+
+  /** Function to get the language of a literal. This information is probably not available for this implementation. */
+  static private class Lang extends MulgaraFunction {
+    public Object eval(List args) {
+      Object o = args.get(0);
+      return o instanceof Literal ? ((Literal)o).getLanguage() : "";
+    }
+  }
+    
+  /** Function to get the datatype of a literal. This information is probably not available for this implementation. */
+  static private class Datatype extends MulgaraFunction {
+    public Object eval(List args) {
+      Object o = args.get(0);
+      return o instanceof Literal ? ((Literal)o).getDatatype() : null;
+    }
+  }
+  
+  /**
+   * Function to test if a language code matches a pattern.
+   * This information is probably not available for this implementation.
+   */
+  static private class LangMatches extends MulgaraFunction {
+    protected int getArity() { return 2; }
+    public Object eval(List args) throws XPathFunctionException {
+      Object o = args.get(0);
+      if (o instanceof Literal) {
+        Literal l = (Literal)o;
+        if (l.getLanguage() == null || l.getLanguage().length() == 0) return false;
+        org.mulgara.query.filter.LangMatches match = new org.mulgara.query.filter.LangMatches(new SimpleLiteral(l.getLexicalForm(), l.getLanguage()), new SimpleLiteral((String)args.get(1)));
+        try {
+          return match.getValue();
+        } catch (QueryException e) {
+          throw new XPathFunctionException("Unable to get data from lang matching test: " + e.getMessage());
+        }
+      }
+      return false;
+    }
+  }
+
+  /** Common operations required for a logical operation. */
+  static private abstract class LogicOp extends MulgaraFunction {
+    protected int getArity() { return 2; }
+    protected abstract boolean op(Object left, Object right) throws XPathFunctionException;
+    public Object eval(List args) throws XPathFunctionException {
+      return op(args.get(0), args.get(1));
+    }
+  }
+
+  /** Function to perform a logical OR between 2 operands. */
+  static private class LogicalOr extends LogicOp {
+    public String getName() { return "logical-or"; }
+    public boolean op(Object left, Object right) throws XPathFunctionException {
+      return toBool(left) || toBool(right);
+    }
+  }
+
+  /** Function to perform a logical AND between 2 operands. */
+  static private class LogicalAnd extends LogicOp {
+    public String getName() { return "logical-and"; }
+    public boolean op(Object left, Object right) throws XPathFunctionException {
+      return toBool(left) && toBool(right);
+    }
+  }
+
+}

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/ItqlInterpreterBeanUnitTest.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/ItqlInterpreterBeanUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/ItqlInterpreterBeanUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -752,7 +752,7 @@
   
       URI serverURI = new URI("rmi://localhost/server1");
   
-      bean.restore(file.toURL().openStream(), serverURI);
+      bean.restore(file.toURI().toURL().openStream(), serverURI);
     } catch (QueryException e) {
       System.err.println("Error processing query" + e);
       Throwable t = e.getCause();
@@ -816,7 +816,7 @@
       assertTrue("Excepting a backup file", file.exists());
   
       // restore the server
-      bean.restore(file.toURL().openStream(), serverURI);
+      bean.restore(file.toURI().toURL().openStream(), serverURI);
   
       // select the statement
       answer = bean.executeQuery(select);

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/ItqlSession.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -546,7 +546,7 @@
       // return the URL!!!
       try {
 
-        scriptURL = loadingScript.toURL();
+        scriptURL = loadingScript.toURI().toURL();
       } catch (MalformedURLException mue) {
 
         // log the error

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/TqlInterpreter.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -868,7 +868,8 @@
     AHavingClause havingClause;
     ALimitClause limitClause;
     AOffsetClause offsetClause;
-  
+    boolean distinct = true;
+
     // cast the correct way (we don't have a common superclass, event though we
     // have methods with the same names)
     if (rawQuery instanceof AQuery) {
@@ -876,6 +877,7 @@
       AQuery query = (AQuery) rawQuery;
       PSelectClause selectClause = query.getSelectClause();
       if (selectClause instanceof ANormalSelectSelectClause) {
+        distinct = ((ANormalSelectSelectClause)selectClause).getNondistinct() == null;
         variables = (LinkedList<PElement>)((ANormalSelectSelectClause)selectClause).getElement();
       }
       fromClause = ((AFromClause)query.getFromClause());
@@ -945,7 +947,7 @@
   
     // build a query using the information we've obtained from the parser
     return new Query(variableList, graphExpression, constraintExpression,
-        havingExpression, orderList, limit, offset, new UnconstrainedAnswer());
+        havingExpression, orderList, limit, offset, distinct, new UnconstrainedAnswer());
   }
 
 

Modified: trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/itql/TqlSession.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -594,7 +594,7 @@
       // found the URL. Return it.
       log.debug("Found loading script - " + loadingScript);
       try {
-        scriptUrl = loadingScript.toURL();
+        scriptUrl = loadingScript.toURI().toURL();
       } catch (MalformedURLException mue) {
         log.warn("Unable to convert loading script filename to URL - " + mue.getMessage());
         System.err.println("Unable to convert loading script filename " + "to URL - " + loadingScript);

Deleted: trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,45 +0,0 @@
-/*
- * Copyright 2009 Duraspace.
- *
- * 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.protocol.http;
-
-import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
-
-/**
- * Encodes the condition of a bad HTTP servlet request.
- *
- * @created Sep 8, 2008
- * @author Paul Gearon
- * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
- */
-public class PartialFailureException extends ServletException {
-
-  /** The serialization ID */
-  private static final long serialVersionUID = 3953416493075214645L;
-
-  /** An default constructor to indicate a problem. */
-  public PartialFailureException() {
-    super(SC_NO_CONTENT);
-  }
-
-  /**
-   * @param message The message to send with a bad request code.
-   */
-  public PartialFailureException(String message) {
-    super(SC_NO_CONTENT, message);
-  }
-
-}

Copied: trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java (from rev 1870, branches/distinct_queries/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java)
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/protocol/http/PartialFailureException.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2009 Duraspace.
+ *
+ * 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.protocol.http;
+
+import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
+
+/**
+ * Encodes the condition of a bad HTTP servlet request.
+ *
+ * @created Sep 8, 2008
+ * @author Paul Gearon
+ * @copyright &copy; 2008 <a href="http://www.fedora-commons.org/">Fedora Commons</a>
+ */
+public class PartialFailureException extends ServletException {
+
+  /** The serialization ID */
+  private static final long serialVersionUID = 3953416493075214645L;
+
+  /** An default constructor to indicate a problem. */
+  public PartialFailureException() {
+    super(SC_NO_CONTENT);
+  }
+
+  /**
+   * @param message The message to send with a bad request code.
+   */
+  public PartialFailureException(String message) {
+    super(SC_NO_CONTENT, message);
+  }
+
+}

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/PatternMapper.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/PatternMapper.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/PatternMapper.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -169,8 +169,7 @@
       if (lit.isLanguageCoded()) return new LiteralImpl(lit.getValue(), lit.getLanguage());
       return new LiteralImpl(lit.getValue());
     }
-    // integer, decimal, double, boolean
-    if (n instanceof IntegerLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.INT_URI);
+    // decimal, double, boolean
     if (n instanceof DecimalLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.DECIMAL_URI);
     if (n instanceof DoubleLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.DOUBLE_URI);
     if (n instanceof BooleanLiteral) return new LiteralImpl(((IntegerLiteral)n).getValue().toString(), XSD.BOOLEAN_URI);
@@ -183,13 +182,73 @@
    * @param t The triple to convert.
    * @return The new constraint.
    */
-  private static ConstraintImpl newConstraintImpl(Triple t) {
+  private static ConstraintExpression newConstraintImpl(Triple t) {
     ConstraintElement s = convertElement(t.getSubject());
     ConstraintElement p = convertElement(t.getPredicate());
-    ConstraintElement o = convertElement(t.getObject());
+    // if the object it a literal, then it may need to be expanded into various equivalent types
+    Node n = t.getObject();
+    if (n instanceof IntegerLiteral) {
+      ConstraintElement[] numbers = createIntLiterals((IntegerLiteral)n);
+      List<ConstraintExpression> options = new ArrayList<ConstraintExpression>();
+      for (ConstraintElement obj: numbers) {
+        options.add(new ConstraintImpl(s, p, obj));
+      }
+      return new ConstraintDisjunction(options);
+    }
+
+    ConstraintElement o = convertElement(n);
     return new ConstraintImpl(s, p, o);
   }
 
+  /**
+   * Create an array of the literals represented by a number.
+   * @param nrText The text of a number.
+   * @return All the literals that this number can represent.
+   */
+  private static ConstraintElement[] createIntLiterals(IntegerLiteral n) {
+    List<ConstraintElement> elts = new ArrayList<ConstraintElement>();
+    String nrText = n.getValue().toString();
+    long nr = n.getValue().longValue();
+
+    elts.add(new LiteralImpl(nrText, XSD.DECIMAL_URI));
+    elts.add(new LiteralImpl(nrText, XSD.INTEGER_URI));
+    elts.add(new LiteralImpl(nrText, XSD.LONG_URI));
+    if (nr <= Integer.MAX_VALUE && nr >= Integer.MIN_VALUE) {
+      elts.add(new LiteralImpl(nrText, XSD.INT_URI));
+      if (nr <= Short.MAX_VALUE && nr >= Short.MIN_VALUE) {
+        elts.add(new LiteralImpl(nrText, XSD.SHORT_URI));
+        if (nr <= Byte.MAX_VALUE && nr >= Byte.MIN_VALUE) {
+          elts.add(new LiteralImpl(nrText, XSD.BYTE_URI));
+        }
+      }
+    }
+    if (nr < 0) {
+      elts.add(new LiteralImpl(nrText, XSD.NON_POSITIVE_INTEGER_URI));
+      elts.add(new LiteralImpl(nrText, XSD.NEGATIVE_INTEGER_URI));
+    } else if (nr > 0) {
+      elts.add(new LiteralImpl(nrText, XSD.NON_NEGATIVE_INTEGER_URI));
+      elts.add(new LiteralImpl(nrText, XSD.POSITIVE_INTEGER_URI));
+      elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_LONG_URI));
+      if (nr <= UInt.MAX_VALUE) {
+        elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_INT_URI));
+        if (nr <= UShort.MAX_VALUE) {
+          elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_SHORT_URI));
+          if (nr <= UByte.MAX_VALUE) {
+            elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_BYTE_URI));
+          }
+        }
+      }
+    } else { // nr == 0
+      elts.add(new LiteralImpl(nrText, XSD.NON_POSITIVE_INTEGER_URI));
+      elts.add(new LiteralImpl(nrText, XSD.NON_NEGATIVE_INTEGER_URI));
+      elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_LONG_URI));
+      elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_INT_URI));
+      elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_SHORT_URI));
+      elts.add(new LiteralImpl(nrText, XSD.UNSIGNED_BYTE_URI));
+    }
+    return elts.toArray(new ConstraintElement[elts.size()]);
+  }
+
   /** A mapping of pattern types to constructors for the objects they map to. */
   private static Map<Class<? extends GroupGraphPattern>,PatternToConstraintMapper<? extends GroupGraphPattern>> constructors = new HashMap<Class<? extends GroupGraphPattern>,PatternToConstraintMapper<? extends GroupGraphPattern>>();
 
@@ -315,4 +374,12 @@
     }
   }
 
+  /** Describes the range of unsigned ints */
+  private static class UInt { public static final long MAX_VALUE = 0xFFFFFFFFL; }
+
+  /** Describes the range of unsigned shorts */
+  private static class UShort { public static final long MAX_VALUE = 0xFFFFL; }
+
+  /** Describes the range of unsigned bytes */
+  private static class UByte { public static final long MAX_VALUE = 0xFFL; }
 }

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/SparqlInterpreter.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -254,8 +254,9 @@
     List<Order> orderBy = getOrdering(queryStruct);
     Integer limit = getLimit(queryStruct);
     int offset = queryStruct.getOffset();
+    boolean distinct = queryStruct.isDistinct();
     // null having, unconstrained answer
-    return new Query(selection, defaultGraphs, whereClause, null, orderBy, limit, offset, new UnconstrainedAnswer());
+    return new Query(selection, defaultGraphs, whereClause, null, orderBy, limit, offset, distinct, new UnconstrainedAnswer());
   }
 
   /**

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/AbstractNaryOperator.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -61,4 +61,11 @@
    */
   protected abstract String getOperatorString();
 
+  /**
+   * @see java.lang.Object#toString()
+   * @return By default this will return the image, since that's often right.
+   */
+  public String toString() {
+    return getImage();
+  }
 }

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/IRIReference.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -165,6 +165,13 @@
   }
 
   /**
+   * @see java.lang.Object#toString()
+   */
+  public String toString() {
+    return "<" + uri.toString() + ">";
+  }
+
+  /**
    * Parse a URI, looking for a valid QName structure.
    * @param uri The URI to parse.
    * @return a new QName if one could be parsed, or <code>null</code> if one couldn't be found.

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Triple.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -40,16 +40,9 @@
   public Triple(Node s, Node p, Node o) {
     subject = s;
     predicate = p;
-    assert !(o instanceof AnnotatedNode): "Can't make a single triple with an annotated node";
     object = o;
   }
 
-  public Triple(Node s, Node p, AnnotatedNode o) {
-    subject = s;
-    predicate = p;
-    object = o.getSubject();
-  }
-
   /**
    * @return the subject
    */
@@ -98,4 +91,10 @@
     return addPatterns(result.toString());
   }
 
+  /**
+   * @see java.lang.Object#toString()
+   */
+  public String toString() {
+    return subject.toString() + " " + predicate.toString() + " " + object.toString();
+  }
 }

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/TripleList.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -173,4 +173,12 @@
     addAll(annotations);
   }
 
+  /**
+   * @see java.lang.Object#toString()
+   */
+  public String toString() {
+    StringBuilder b = new StringBuilder();
+    for (Triple t: triples) b.append(t).append(" . ");
+    return b.toString();
+  }
 }

Modified: trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/sparql/parser/cst/Variable.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -47,4 +47,10 @@
     return "?" + name;
   }
 
+  /**
+   * @see java.lang.Object#toString()
+   */
+  public String toString() {
+    return getImage();
+  }
 }

Deleted: trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1,196 +0,0 @@
-/*
- * Copyright 2009 DuraSpace.
- *
- * 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.store.jxunit;
-
-// 3rd party package
-import net.sourceforge.jxunit.JXTestCase;
-import net.sourceforge.jxunit.JXTestStep;
-import net.sourceforge.jxunit.JXProperties;
-
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.HttpStatus;
-import org.apache.http.StatusLine;
-import org.apache.http.client.HttpClient;
-import org.apache.http.client.methods.HttpGet;
-import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.params.CoreProtocolPNames;
-
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URI;
-import java.net.URLEncoder;
-
-
-/**
- * Test frame for SPARQL queries.
- *
- * @created 2009-09-17
- * @author Paul Gearon
- */
-public class SparqlQueryJX implements JXTestStep {
-
-  /** Line separator. */
-  private static final String EOL = System.getProperty("line.separator");
-
-  /** Name of the query command parameter */
-  public final static String QUERY = "query";
-
-  /** Parameter name of the results of the command */
-  public final static String RESULT = "queryResult";
-
-  /** Parameter name of the time flag */
-  public final static String TIME_NAME = "time";
-
-  /** Parameter name of the endpoint parameter */
-  public final static String ENDPOINT_NAME = "endpoint";
-
-  /** Parameter name of the default graph */
-  public final static String DEFAULT_GRAPH_NAME = "default-graph-uri";
-
-  /** The default endpoint to connect to */
-  private final static String DEFAULT_ENDPOINT = "http://localhost:8080/sparql/";
-
-  /** The character encoding to use for the request URL */
-  private static final String UTF8 = "UTF-8";
-
-  /** Internal record of the URL used */
-  private String requestUrl = "-";
-
-  /** Size for internal read buffer */
-  private final static int BUFFER_SIZE = 1024;
-
-  /**
-   * Execute this object. Retrieves a string from the testCase properties and
-   * executes it as a SPARQL query, returning the results in the testCase object.
-   *
-   * @param testCase The map object containing the properties.
-   * @throws Exception propagated exception from the query framework.
-   */
-  @SuppressWarnings("unchecked")  // JXProperties does not use Generics
-  public void eval(JXTestCase testCase) throws Exception {
-
-    JXProperties props = testCase.getProperties();
-
-    // get the query to execute
-    String query = (String)props.get(QUERY);
-
-    // get the default graph URI
-    String defGraphStr = props.getString(DEFAULT_GRAPH_NAME);
-    URI defGraph = (defGraphStr != null) ? new URI(defGraphStr) : null;
-
-    // retrieve the endpoint to use
-    String confEndpoint =  props.getString(ENDPOINT_NAME);
-    String endpoint = (confEndpoint != null && !confEndpoint.equals("")) ? confEndpoint : DEFAULT_ENDPOINT;
-
-    // retrieve flag asking if the query should be timed
-    String timeStr = props.getString(TIME_NAME);
-    boolean time = (timeStr != null) && Boolean.valueOf(timeStr).booleanValue();
-
-    long start = System.currentTimeMillis();
-    String queryResult = "";
-
-    try {
-      queryResult = executeQuery(endpoint, query, defGraph);
-    } catch (Exception ex) {
-      queryResult = "URL = <" + requestUrl + ">";
-      queryResult += "Exception: " + org.mulgara.util.StackTrace.throwableToString(ex);
-    } finally {
-    }
-
-    if (time) {
-      System.out.println(EOL + "query: \"" + query + "\" query has taken " +
-        (System.currentTimeMillis() - start) + " milliseconds to execute." + EOL);
-    }
-
-    props.put(RESULT, queryResult + EOL);
-  }
-
-
-  /**
-   * Execute a query against a SPARQL endpoint.
-   * @param endpoint The URL of the endpoint.
-   * @param query The query to execute.
-   * @param defGraph The default graph to execute the query against,
-   *        or <code>null</code> if not set.
-   * @return A string representation of the result from the server.
-   * @throws IOException If there was an error communicating with the server.
-   * @throws UnsupportedEncodingException The SPARQL endpoint used an encoding not understood by this system.
-   * @throws HttpClientException An unexpected response was returned from the SPARQL endpoint.
-   */
-  String executeQuery(String endpoint, String query, URI defGraph)
-        throws IOException, UnsupportedEncodingException, HttpClientException {
-    String request = endpoint + "?";
-    if (defGraph != null && (0 != defGraph.toString().length())) request += "default-graph-uri=" + defGraph.toString() + "&";
-    request += "query=" + URLEncoder.encode(query, UTF8);
-    requestUrl = request;
-
-    HttpClient client = new DefaultHttpClient();
-    client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
-
-    HttpGet get = new HttpGet(request);
-    get.setHeader("Accept", "application/rdf+xml");
-
-    StringBuilder result = new StringBuilder();
-    try {
-      HttpResponse response = client.execute(get);
-      StatusLine status = response.getStatusLine();
-      if (status.getStatusCode() != HttpStatus.SC_OK) {
-        String msg = "Bad result from SPARQL endpoint: " + status;
-        System.err.println(msg);
-        throw new HttpClientException(msg);
-      }
-
-      HttpEntity entity = response.getEntity();
-      if (entity != null) {
-        InputStreamReader resultStream = new InputStreamReader(entity.getContent());
-        char[] buffer = new char[BUFFER_SIZE];
-        int len;
-        while ((len = resultStream.read(buffer)) >= 0) result.append(buffer, 0, len);
-        resultStream.close();
-      } else {
-        String msg = "No data in response from SPARQL endpoint";
-        System.out.println(msg);
-        throw new HttpClientException(msg);
-      }
-    } catch (UnsupportedEncodingException e) {
-      System.err.println("Unsupported encoding returned from SPARQL endpoint: " + e.getMessage());
-      throw e;
-    } catch (IOException ioe) {
-      System.err.println("Error communicating with SPARQL endpoint: " + ioe.getMessage());
-      throw ioe;
-    }
-    return result.toString();
-  }
-
-
-  public static class HttpClientException extends Exception {
-    /** Serialization ID */
-    private static final long serialVersionUID = -7563267824587372995L;
-    public HttpClientException() {}
-    public HttpClientException(String msg) {
-      super(msg);
-    }
-    public HttpClientException(String msg, Throwable cause) {
-      super(msg, cause);
-    }
-    public HttpClientException(Throwable cause) {
-      super(cause);
-    }
-  }
-}

Copied: trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java (from rev 1870, branches/distinct_queries/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java)
===================================================================
--- trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java	                        (rev 0)
+++ trunk/src/jar/querylang/java/org/mulgara/store/jxunit/SparqlQueryJX.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2009 DuraSpace.
+ *
+ * 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.store.jxunit;
+
+// 3rd party package
+import net.sourceforge.jxunit.JXTestCase;
+import net.sourceforge.jxunit.JXTestStep;
+import net.sourceforge.jxunit.JXProperties;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
+import org.apache.http.StatusLine;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.params.CoreProtocolPNames;
+
+import java.io.InputStreamReader;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+
+
+/**
+ * Test frame for SPARQL queries.
+ *
+ * @created 2009-09-17
+ * @author Paul Gearon
+ */
+public class SparqlQueryJX implements JXTestStep {
+
+  /** Line separator. */
+  private static final String EOL = System.getProperty("line.separator");
+
+  /** Name of the query command parameter */
+  public final static String QUERY = "query";
+
+  /** Parameter name of the results of the command */
+  public final static String RESULT = "queryResult";
+
+  /** Parameter name of the time flag */
+  public final static String TIME_NAME = "time";
+
+  /** Parameter name of the endpoint parameter */
+  public final static String ENDPOINT_NAME = "endpoint";
+
+  /** Parameter name of the default graph */
+  public final static String DEFAULT_GRAPH_NAME = "default-graph-uri";
+
+  /** The default endpoint to connect to */
+  private final static String DEFAULT_ENDPOINT = "http://localhost:8080/sparql/";
+
+  /** The character encoding to use for the request URL */
+  private static final String UTF8 = "UTF-8";
+
+  /** Internal record of the URL used */
+  private String requestUrl = "-";
+
+  /** Size for internal read buffer */
+  private final static int BUFFER_SIZE = 1024;
+
+  /**
+   * Execute this object. Retrieves a string from the testCase properties and
+   * executes it as a SPARQL query, returning the results in the testCase object.
+   *
+   * @param testCase The map object containing the properties.
+   * @throws Exception propagated exception from the query framework.
+   */
+  @SuppressWarnings("unchecked")  // JXProperties does not use Generics
+  public void eval(JXTestCase testCase) throws Exception {
+
+    JXProperties props = testCase.getProperties();
+
+    // get the query to execute
+    String query = (String)props.get(QUERY);
+
+    // get the default graph URI
+    String defGraphStr = props.getString(DEFAULT_GRAPH_NAME);
+    URI defGraph = (defGraphStr != null) ? new URI(defGraphStr) : null;
+
+    // retrieve the endpoint to use
+    String confEndpoint =  props.getString(ENDPOINT_NAME);
+    String endpoint = (confEndpoint != null && !confEndpoint.equals("")) ? confEndpoint : DEFAULT_ENDPOINT;
+
+    // retrieve flag asking if the query should be timed
+    String timeStr = props.getString(TIME_NAME);
+    boolean time = (timeStr != null) && Boolean.valueOf(timeStr).booleanValue();
+
+    long start = System.currentTimeMillis();
+    String queryResult = "";
+
+    try {
+      queryResult = executeQuery(endpoint, query, defGraph);
+    } catch (Exception ex) {
+      queryResult = "URL = <" + requestUrl + ">";
+      queryResult += "Exception: " + org.mulgara.util.StackTrace.throwableToString(ex);
+    } finally {
+    }
+
+    if (time) {
+      System.out.println(EOL + "query: \"" + query + "\" query has taken " +
+        (System.currentTimeMillis() - start) + " milliseconds to execute." + EOL);
+    }
+
+    props.put(RESULT, queryResult + EOL);
+  }
+
+
+  /**
+   * Execute a query against a SPARQL endpoint.
+   * @param endpoint The URL of the endpoint.
+   * @param query The query to execute.
+   * @param defGraph The default graph to execute the query against,
+   *        or <code>null</code> if not set.
+   * @return A string representation of the result from the server.
+   * @throws IOException If there was an error communicating with the server.
+   * @throws UnsupportedEncodingException The SPARQL endpoint used an encoding not understood by this system.
+   * @throws HttpClientException An unexpected response was returned from the SPARQL endpoint.
+   */
+  String executeQuery(String endpoint, String query, URI defGraph)
+        throws IOException, UnsupportedEncodingException, HttpClientException {
+    String request = endpoint + "?";
+    if (defGraph != null && (0 != defGraph.toString().length())) request += "default-graph-uri=" + defGraph.toString() + "&";
+    request += "query=" + URLEncoder.encode(query, UTF8);
+    requestUrl = request;
+
+    HttpClient client = new DefaultHttpClient();
+    client.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
+
+    HttpGet get = new HttpGet(request);
+    get.setHeader("Accept", "application/rdf+xml");
+
+    StringBuilder result = new StringBuilder();
+    try {
+      HttpResponse response = client.execute(get);
+      StatusLine status = response.getStatusLine();
+      if (status.getStatusCode() != HttpStatus.SC_OK) {
+        String msg = "Bad result from SPARQL endpoint: " + status;
+        System.err.println(msg);
+        throw new HttpClientException(msg);
+      }
+
+      HttpEntity entity = response.getEntity();
+      if (entity != null) {
+        InputStreamReader resultStream = new InputStreamReader(entity.getContent());
+        char[] buffer = new char[BUFFER_SIZE];
+        int len;
+        while ((len = resultStream.read(buffer)) >= 0) result.append(buffer, 0, len);
+        resultStream.close();
+      } else {
+        String msg = "No data in response from SPARQL endpoint";
+        System.out.println(msg);
+        throw new HttpClientException(msg);
+      }
+    } catch (UnsupportedEncodingException e) {
+      System.err.println("Unsupported encoding returned from SPARQL endpoint: " + e.getMessage());
+      throw e;
+    } catch (IOException ioe) {
+      System.err.println("Error communicating with SPARQL endpoint: " + ioe.getMessage());
+      throw ioe;
+    }
+    return result.toString();
+  }
+
+
+  public static class HttpClientException extends Exception {
+    /** Serialization ID */
+    private static final long serialVersionUID = -7563267824587372995L;
+    public HttpClientException() {}
+    public HttpClientException(String msg) {
+      super(msg);
+    }
+    public HttpClientException(String msg, Throwable cause) {
+      super(msg, cause);
+    }
+    public HttpClientException(Throwable cause) {
+      super(cause);
+    }
+  }
+}

Modified: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -1940,15 +1940,15 @@
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
     case INTEGER_POSITIVE:
       t = jj_consume_token(INTEGER_POSITIVE);
-                           {if (true) return new IntegerLiteral(t.image);}
+                           {if (true) return new IntegerLiteral(t.image.substring(1));}
       break;
     case DECIMAL_POSITIVE:
       t = jj_consume_token(DECIMAL_POSITIVE);
-                             {if (true) return new DecimalLiteral(t.image);}
+                             {if (true) return new DecimalLiteral(t.image.substring(1));}
       break;
     case DOUBLE_POSITIVE:
       t = jj_consume_token(DOUBLE_POSITIVE);
-                            {if (true) return new DoubleLiteral(t.image);}
+                            {if (true) return new DoubleLiteral(t.image.substring(1));}
       break;
     default:
       jj_la1[70] = jj_gen;

Modified: trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj
===================================================================
--- trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/javacc/org/mulgara/sparql/parser/SparqlParser.jj	2009-12-10 17:02:12 UTC (rev 1871)
@@ -695,9 +695,9 @@
 /* [63]    NumericLiteralPositive    ::=    INTEGER_POSITIVE |  DECIMAL_POSITIVE |  DOUBLE_POSITIVE */
 NumericLiteral NumericLiteralPositive() : { Token t; }
 {
-    t=<INTEGER_POSITIVE> { return new IntegerLiteral(t.image); }
-    | t=<DECIMAL_POSITIVE> { return new DecimalLiteral(t.image); }
-    | t=<DOUBLE_POSITIVE> { return new DoubleLiteral(t.image); }
+    t=<INTEGER_POSITIVE> { return new IntegerLiteral(t.image.substring(1)); }
+    | t=<DECIMAL_POSITIVE> { return new DecimalLiteral(t.image.substring(1)); }
+    | t=<DOUBLE_POSITIVE> { return new DoubleLiteral(t.image.substring(1)); }
 }
 
 /* [64]    NumericLiteralNegative    ::=    INTEGER_NEGATIVE |  DECIMAL_NEGATIVE |  DOUBLE_NEGATIVE */

Modified: trunk/src/jar/querylang/sablecc/itql.grammar
===================================================================
--- trunk/src/jar/querylang/sablecc/itql.grammar	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/querylang/sablecc/itql.grammar	2009-12-10 17:02:12 UTC (rev 1871)
@@ -57,6 +57,7 @@
   {def}                limit       = 'limit';
   {def}                load        = 'load';
   {def}                minus       = 'minus';
+  {def}                nondistinct = 'nondistinct';
   {def}                off         = 'off';
   {def}                offset      = 'offset';
   {def}                or          = 'or';
@@ -208,8 +209,8 @@
     {on} on   ;
 
   select_clause =
-    {empty_select} select |
-    {normal_select} select element+;
+    {empty_select} select nondistinct? |
+    {normal_select} select nondistinct? element+;
 
   from_clause =
     from model_expression;

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/AdvDatabaseSessionUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -310,6 +310,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -327,6 +328,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -385,6 +387,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -402,6 +405,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -1073,7 +1077,7 @@
         session1.createModel(delayTwoSecs, new URI(Mulgara.NAMESPACE + "MockModel"));
 
         try {
-          Answer answer = session1.query(createQuery(delayTwoSecs));
+          session1.query(createQuery(delayTwoSecs));
           fail("query should've gotten interrupted");
         } catch (QueryException qe) {
           logger.debug("query was interrupted", qe);
@@ -1100,7 +1104,7 @@
         logger.debug("Slept for 2sec");
 
         try {
-          Answer answer = session1.query(createQuery(model3URI));
+          session1.query(createQuery(model3URI));
           fail("query should've gotten interrupted");
         } catch (QueryException qe) {
           logger.debug("query was interrupted", qe);
@@ -1256,6 +1260,7 @@
           }),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -1684,6 +1689,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/BasicDatabaseSessionUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -210,6 +210,7 @@
             ),
             null,                               // LIMIT
             0,                                  // OFFSET
+            true,                               // DISTINCT
             new UnconstrainedAnswer()           // GIVEN
           )));
 
@@ -304,6 +305,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
       } finally {

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseOperationContext.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -34,6 +34,7 @@
 import java.net.URISyntaxException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
@@ -59,6 +60,7 @@
 import org.mulgara.resolver.spi.ResolverFactoryException;
 import org.mulgara.resolver.spi.SecurityAdapter;
 import org.mulgara.resolver.spi.Statements;
+import org.mulgara.resolver.spi.SumOfProductExpansionTransformer;
 import org.mulgara.resolver.spi.SymbolicTransformation;
 import org.mulgara.resolver.spi.SymbolicTransformationContext;
 import org.mulgara.resolver.spi.SystemResolver;
@@ -822,7 +824,16 @@
     }
 
     MutableLocalQueryImpl mutable = new MutableLocalQueryImpl(query);
-    Iterator<SymbolicTransformation> i = symbolicTransformationList.iterator();
+    List<SymbolicTransformation> symTxList;
+    symTxList = symbolicTransformationList;
+
+    // non-DISTINCT queries need to be expanded so the disjunction is at the root
+    if (!query.isDistinct()) {
+      symTxList = new ArrayList<SymbolicTransformation>(symbolicTransformationList);
+      symTxList.add(new SumOfProductExpansionTransformer());
+    }
+
+    Iterator<SymbolicTransformation> i = symTxList.iterator();
     while (i.hasNext()) {
       SymbolicTransformation symbolicTransformation = i.next();
       assert symbolicTransformation != null;
@@ -843,7 +854,7 @@
         mutable = new MutableLocalQueryImpl(query);
 
         // start again
-        i = symbolicTransformationList.iterator();
+        i = symTxList.iterator();
       }
     }
 

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionListQueryUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -302,6 +302,7 @@
         (List<Order>)Collections.EMPTY_LIST, // no ordering
         null, // no limit
         0, // zero offset
+        true, // distinct results
         new UnconstrainedAnswer() // nothing given
         );
   }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/DatabaseSessionUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -547,7 +547,6 @@
   // Test cases
   //
 
-  @SuppressWarnings("unchecked")
   public void testModel() {
     try {
       logger.debug("Testing: " + test.errorString);
@@ -565,6 +564,7 @@
           orderList,                // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         )));
 

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/DefaultConstraintHandlers.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -176,7 +176,8 @@
             List l =
                 context.resolveConstraintOperation(modelExpr, (ConstraintOperation)constraintExpr);
             try {
-              return TuplesOperations.append(l);
+              if (context.isDistinctQuery()) return TuplesOperations.append(l);
+              else return TuplesOperations.unorderedAppend(l);
             } finally {
               Iterator i = l.iterator();
               while (i.hasNext()) {
@@ -187,13 +188,19 @@
         }),
         new NVPair(ConstraintDifference.class, new ConstraintResolutionHandler() {
           public Tuples resolve(QueryEvaluationContext context, GraphExpression modelExpr, ConstraintExpression constraintExpr) throws Exception {
-            List args = context.resolveConstraintOperation(modelExpr, (ConstraintOperation)constraintExpr);
-            assert args.size() == 2;
+            List<ConstraintExpression> constraints = ((ConstraintOperation)constraintExpr).getElements();
+            assert constraints.size() == 2;
+            Tuples lhs = ConstraintOperations.resolveConstraintExpression(context, modelExpr, constraints.get(0));
+            // The RHS must be searchable, so it must return a distinct result
+            // since DISTINCT forces sorting
+            boolean distinct = context.setDistinctQuery(true);
+            Tuples rhs = ConstraintOperations.resolveConstraintExpression(context, modelExpr, constraints.get(1));
+            context.setDistinctQuery(distinct);
             try {
-              return TuplesOperations.subtract((Tuples)args.get(0), (Tuples)args.get(1));
+              return TuplesOperations.subtract(lhs, rhs);
             } finally {
-              ((Tuples)args.get(0)).close();
-              ((Tuples)args.get(1)).close();
+              lhs.close();
+              rhs.close();
             }
           }
         }),

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/ExternalTransactionUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -602,6 +602,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -619,6 +620,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -683,6 +685,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -700,6 +703,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -2578,6 +2582,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/JotmTransactionStandaloneTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -503,6 +503,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         )));
 
@@ -520,6 +521,7 @@
           ),
           null,                                             // LIMIT
           0,                                                // OFFSET
+          true,                                             // DISTINCT
           new UnconstrainedAnswer()                         // GIVEN
         ));
 
@@ -1523,6 +1525,7 @@
       }),
       null,                                             // LIMIT
       0,                                                // OFFSET
+      true,                                             // DISTINCT
       new UnconstrainedAnswer()                         // GIVEN
     );
   }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/LocalJRDFDatabaseSession.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -196,6 +196,7 @@
           (List<Order>)Collections.EMPTY_LIST,          // no ordering
           null,                            // no limit
           0,                               // zero offset
+          true,                            // distinct results
           new UnconstrainedAnswer()        // nothing given
       );
 

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/LocalQueryResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -91,6 +91,8 @@
 
   private ResolverSession resolverSession;
 
+  private boolean distinctQuery = false;
+
   // Constructor
   LocalQueryResolver(DatabaseOperationContext operationContext, ResolverSession resolverSession) {
     if (operationContext == null) {
@@ -207,8 +209,26 @@
     return resolverSession;
   }
 
-  Tuples resolveMap(Query query, Map outerBindings) throws QueryException
-  {
+  /**
+   * Indicates that the query being run in this context should return distinct results.
+   * @return If <code>true</code>, then return distinct results. Otherwise allow for duplicates.
+   */
+  public boolean isDistinctQuery() {
+    return distinctQuery;
+  }
+
+  /**
+   * Sets the "distinct" status of a query context, returning the previous value.
+   * @param newValue The new value to set the distinct status to. 
+   * @return The previous value of the distinct status.
+   */
+  public boolean setDistinctQuery(boolean newValue) {
+    boolean oldValue = distinctQuery;
+    distinctQuery = newValue;
+    return oldValue;
+  }
+
+  Tuples resolveMap(Query query, Map outerBindings) throws QueryException {
     try {
       Query newQuery = new Query(
           query.getVariableList(),
@@ -220,6 +240,7 @@
           query.getOrderList(),
           query.getLimit(),
           query.getOffset(),
+          query.isDistinct(),
           (Answer)query.getGiven().clone());
           
       return operationContext.innerCount(newQuery);
@@ -266,6 +287,7 @@
         logger.debug(new StackTrace().toString());
       }
 
+      distinctQuery = query.isDistinct();
       Tuples result = ConstraintOperations.resolveConstraintExpression(this,
           query.getModelExpression(), query.getConstraintExpression());
 
@@ -307,7 +329,7 @@
           }
         }
 
-        result = TuplesOperations.project(result, variables);
+        result = TuplesOperations.project(result, variables, query.isDistinct());
       } finally {
         tmp.close();
       }

Modified: trunk/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java
===================================================================
--- trunk/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver/java/org/mulgara/resolver/XADatabaseSessionUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -618,6 +618,7 @@
           orderList,                // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         )));
 

Modified: trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java
===================================================================
--- trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-distributed/java/org/mulgara/resolver/distributed/NetworkDelegator.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -216,7 +216,7 @@
     // convert the variable set to a variable list - add types via unchecked casts
     List<Variable> variables = new ArrayList<Variable>((Set<Variable>)globalConstraint.getVariables());
     // build the new query
-    return new Query(variables, new GraphResource(model.getURI()), globalConstraint, null, Collections.EMPTY_LIST, null, 0, new UnconstrainedAnswer());
+    return new Query(variables, new GraphResource(model.getURI()), globalConstraint, null, Collections.EMPTY_LIST, null, 0, true, new UnconstrainedAnswer());
   }
 
 
@@ -357,3 +357,4 @@
     }
   }
 }
+

Modified: trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java
===================================================================
--- trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-gis/java/org/mulgara/resolver/gis/WritableGISResolver.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -247,7 +247,7 @@
           StatementStore.VARIABLES[1],
           StatementStore.VARIABLES[2]
       };
-      projectedDistTypes = TuplesOperations.project(distanceTypes, Arrays.asList(vars));
+      projectedDistTypes = TuplesOperations.project(distanceTypes, Arrays.asList(vars), true);
       if (!isEmpty(distanceTypes)) {
         distTypeStatements = new TuplesWrapperStatements((Tuples)distanceTypes.clone(), d, vars[1], vars[2]);
       }

Modified: trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java
===================================================================
--- trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-lucene/java/org/mulgara/resolver/lucene/LuceneConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -259,4 +259,12 @@
     return "LC{subj=" + subject + ", pred=" + predicate + ", obj=" + object + ", score=" + score +
            ", binder=" + binder + "}";
   }
+
+  /**
+   * Not a binary operation, so not associative
+   * @return <code>false</code>
+   */
+  public boolean isAssociative() {
+    return false;
+  }
 }

Modified: trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalConstraint.java
===================================================================
--- trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -195,6 +195,14 @@
     return variables;
   }
 
+  /**
+   * Not a binary operation, so not a binary constraint.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
+
   static RelationalConstraint localize(QueryEvaluationContext context, RelationalConstraint constraint) throws Exception {
     RelationalConstraint localized = new RelationalConstraint();
 

Modified: trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java
===================================================================
--- trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-relational/java/org/mulgara/resolver/relational/RelationalResolverUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -387,6 +387,7 @@
           Collections.singletonList(new Order(new Variable("s"), true)),     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -429,6 +430,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -474,6 +476,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -515,6 +518,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -561,6 +565,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -597,6 +602,7 @@
           Collections.singletonList(new Order(new Variable("s"), true)),     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -639,6 +645,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -683,6 +690,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -725,6 +733,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -810,6 +819,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -855,6 +865,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -904,6 +915,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -962,6 +974,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1010,6 +1023,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1051,6 +1065,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1105,6 +1120,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1174,6 +1190,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1232,6 +1249,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1292,6 +1310,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1347,6 +1366,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1402,6 +1422,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 
@@ -1474,6 +1495,7 @@
           orderList,     // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         ));
 

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/ConjunctiveTransformerUnitTest.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/ConjunctiveTransformerUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/ConjunctiveTransformerUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -643,5 +643,9 @@
     public String toString() {
       return "[TC:" + id + "]";
     }
+
+    public boolean isAssociative() {
+      return false;
+    }
   }
 }

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/QueryEvaluationContext.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -87,4 +87,18 @@
 
   public List<Tuples> resolveConstraintOperation(GraphExpression modelExpr,
                                         ConstraintOperation constraintOper) throws QueryException;
+
+  /**
+   * Indicates that the query being run in this context should return distinct results.
+   * @return If <code>true</code>, then return distinct results. Otherwise allow for duplicates.
+   */
+  public boolean isDistinctQuery();
+
+  /**
+   * Sets the "distinct" status of a query context, returning the previous value.
+   * @param newValue The new value to set the distinct status to. 
+   * @return The previous value of the distinct status.
+   */
+  public boolean setDistinctQuery(boolean newValue);
+
 }

Modified: trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java
===================================================================
--- trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/resolver/spi/SumOfProductExpansionTransformer.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -29,6 +29,12 @@
 /**
  * A transformer that works on the basis of expanding a product of sums into a sum of products.
  * This is needed because our disjunctions (sums) are very inefficient, particularly for searching.
+ * Performs the following transforms:
+ * A and (B or C) -> (A and B) or (A and C)
+ * FILTER(A or B, F) -> FILTER(A, F) or FILTER(B, F)
+ * TODO:
+ * A and ((B or C) - D) -> (A and (B - D)) or (A and (C - D))
+ * A - (B or C) -> (A - B) - C, iff B and C share all variables
  *
  * @created August 7, 2009
  * @author Paul Gearon

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	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-spi/java/org/mulgara/store/statement/StatementStoreAbstractUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -185,7 +185,7 @@
     TestTuples expected = getDump();
 
     Tuples t = store.findTuples(NodePool.NONE, NodePool.NONE, NodePool.NONE, NodePool.NONE);
-    Tuples r = TuplesOperations.project(t, Arrays.asList(StatementStore.VARIABLES));
+    Tuples r = TuplesOperations.project(t, Arrays.asList(StatementStore.VARIABLES), true);
     assertEquals(expected, r);
     t.close();
     r.close();

Modified: trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java
===================================================================
--- trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-store/java/org/mulgara/store/statement/xa11/XA11StatementStoreImpl.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -197,9 +197,6 @@
   /** A reference token for keeping the recording phase available until we no longer need it */
   private Phase.Token recordingPhaseToken = null;
 
-  /** The list of graphs known to this statement store. */
-  private LinkedHashSet<Long> committedGraphNodes = null;
-
   /**
    * This flag indicates that the current object has been fully written, and may be considered
    * as committed when the rest of the system is ready.
@@ -327,7 +324,7 @@
 
     if (!dirty && currentPhase.isInUse()) {
       try {
-        new Phase();
+        new Phase(true);
       } catch (IOException ex) {
         throw new StatementStoreException("I/O error", ex);
       }
@@ -350,7 +347,7 @@
     if (node0 != NONE && node1 != NONE && node2 != NONE && node3 != NONE) {
       if (!dirty && currentPhase.isInUse()) {
         try {
-          new Phase();
+          new Phase(true);
         } catch (IOException ex) {
           throw new StatementStoreException("I/O error", ex);
         }
@@ -367,7 +364,7 @@
             // There is at least one triple to remove so protect the
             // Tuples as we make changes to the triplestore.
             try {
-              new Phase();
+              new Phase(true);
             } catch (IOException ex) {
               throw new StatementStoreException("I/O error", ex);
             }
@@ -625,13 +622,13 @@
     openMetarootFile(true);
 
     synchronized (committedPhaseLock) {
-      committedPhaseToken = new Phase().use();
+      committedPhaseToken = new Phase(true).use();
     }
     this.phaseNumber = phaseNumber;
     phaseIndex = 1;
     for (int i = 0; i < NR_INDEXES; ++i) tripleAVLFiles[i].clear();
 
-    new Phase();
+    new Phase(true);
   }
 
 
@@ -661,11 +658,15 @@
     // check that prepare() was not caleld twice
     if (prepared) throw new SimpleXAResourceException("prepare() called twice.");
 
+    Phase newCurrent = null;
     try {
       // Perform a prepare.
       recordingPhaseToken = currentPhase.use();
       Phase recordingPhase = currentPhase;
-      new Phase();
+      // new Phase() has a side effect of setting the current phase, but we'll keep a local copy anyway
+      newCurrent = new Phase(false);
+      // could not set up the committed graphs yet, so send them in after the fact
+      newCurrent.graphNodes = new LinkedHashSet<Long>(recordingPhase.graphNodes);
 
       // Ensure that all data associated with the phase is on disk.
       for (int i = 0; i < NR_INDEXES; ++i) tripleAVLFiles[i].force();
@@ -699,6 +700,11 @@
           recordingPhaseToken.release();
           recordingPhaseToken = null;
         }
+        try {
+          newCurrent.graphNodes = newCurrent.scanForGraphs();
+        } catch (Exception e) {
+          logger.error("Error reading graphs while handling exception from phase.prepare", e);
+        }
       }
     }
   }
@@ -726,7 +732,6 @@
       synchronized (committedPhaseLock) {
         if (committedPhaseToken != null) committedPhaseToken.release();
         committedPhaseToken = recordingPhaseToken;
-        committedGraphNodes = currentPhase.graphNodes;
       }
       recordingPhaseToken = null;
     } catch (IOException ex) {
@@ -821,7 +826,7 @@
     } catch (IllegalStateException ex) {
       throw new SimpleXAResourceException("Cannot construct initial phase.", ex);
     }
-    new Phase();
+    new Phase(true);
 
     // Invalidate the on-disk metaroot that the new phase will be saved to.
     Block block = metarootBlocks[1 - phaseIndex];
@@ -1197,16 +1202,19 @@
     /**
      * Creates a new phase based on the current state of the database.
      * This sets the latest phase on the outer statement store.
+     * @param initializeGraphs scan for graphs to initialize the graphs list.
      * @throws IOException Error on the filesystem.
      */
-    Phase() throws IOException {
+    Phase(boolean initializeGraphs) throws IOException {
       for (int i = 0; i < NR_INDEXES; ++i) tripleAVLFilePhases[i] = tripleAVLFiles[i].new Phase();
       currentPhase = this;
       dirty = true;
-      try {
-        graphNodes = committedGraphNodes == null ? scanForGraphs() : new LinkedHashSet<Long>(committedGraphNodes);
-      } catch (StatementStoreException e) {
-        throw new IOException("Unable to get metadata for phase: " + e.getMessage());
+      if (initializeGraphs) {
+        try {
+          graphNodes = scanForGraphs();
+        } catch (StatementStoreException e) {
+          throw new IOException("Unable to get metadata for phase: " + e.getMessage());
+        }
       }
     }
 

Modified: trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestConstraint.java
===================================================================
--- trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -159,4 +159,8 @@
         testSelection.equals(rhs.testSelection) &&
         testParam.equals(rhs.testParam);
   }
+
+  public boolean isAssociative() {
+    return false;
+  }
 }

Modified: trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java
===================================================================
--- trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-test/java/org/mulgara/resolver/test/TestResolverUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -142,9 +142,10 @@
           { new Order(varArray[0], true), new Order(varArray[1], true), }),     // ORDER BY
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
-    
+
     String[][] result = new String[][] {
       new String[] { "A", "A" },
       new String[] { "A", "B" },
@@ -189,6 +190,7 @@
           { new Order(varArray[0], true), new Order(varArray[1], true), }),     // ORDER BY
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
     
@@ -238,6 +240,7 @@
 				new Order(varArray[2], true) }),
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
     
@@ -289,6 +292,7 @@
 				new Order(varArray[2], true) }),
       null,                                                                     // LIMIT
       0,                                                                        // OFFSET
+      true,                                                                     // DISTINCT
       new UnconstrainedAnswer()                                                 // GIVEN
     ));
     
@@ -341,6 +345,7 @@
 					new Order(varArray[2], true) }),
 				null,                                                                     // LIMIT
 				0,                                                                        // OFFSET
+        true,                                                                     // DISTINCT
 				new UnconstrainedAnswer()                                                 // GIVEN
 			));
 
@@ -358,6 +363,7 @@
    *
    * @throws Exception EXCEPTION TO DO
    */
+  @SuppressWarnings("deprecation")
   protected void setUp() throws Exception {
 		if (database == null) {
 			// Create the persistence directory

Modified: trunk/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java
===================================================================
--- trunk/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-view/java/org/mulgara/resolver/view/ViewResolverUnitTest.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -615,6 +615,7 @@
           orderList,                // ORDER BY
           null,                     // LIMIT
           0,                        // OFFSET
+          true,                     // DISTINCT
           new UnconstrainedAnswer() // GIVEN
         )));
 

Modified: trunk/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/IntervalConstraint.java
===================================================================
--- trunk/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/IntervalConstraint.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/resolver-xsd/java/org/mulgara/resolver/xsd/IntervalConstraint.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -337,4 +337,12 @@
     buffer.append("]");
     return buffer.toString();
   }
+
+  /**
+   * Not a binary operation, so not a binary constraint.
+   * @return <code>false</code> to indicate that this operation is not associative.
+   */
+  public boolean isAssociative() {
+    return false;
+  }
 }

Modified: trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java
===================================================================
--- trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/store-stringpool/java/org/mulgara/store/stringpool/xa/SPDecimalImpl.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -359,6 +359,7 @@
    */
   SPDecimalExtImpl(int subtypeId, URI typeURI, String lexicalForm) {
     super(subtypeId, typeURI);
+    if (lexicalForm.startsWith("+")) lexicalForm = lexicalForm.substring(1);
     l = Long.valueOf(lexicalForm);
   }
 
@@ -395,6 +396,9 @@
     if (o instanceof SPDecimalBaseImpl) {
       return BigDecimal.valueOf(l).compareTo(((SPDecimalBaseImpl)o).val);
     }
+    // if this is an unparseable value, then hard code it to the bottom of the type ordering
+    if (o instanceof UnknownSPTypedLiteralImpl) return -1;
+
     // Compare the longs.
     SPDecimalExtImpl di = (SPDecimalExtImpl)o;
     return compare(l, di.l);

Modified: trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java
===================================================================
--- trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/store-stringpool-memory/java/org/mulgara/store/stringpool/memory/MemoryStringPoolImpl.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -198,7 +198,11 @@
       // Add to both ways of indexing objects and nodes.
       nodeToStringPool.put(gNode, spObject);
       stringToNodePool.put(spObject, gNode);
-      stringIndex.add(spObject);
+      try {
+        stringIndex.add(spObject);
+      } catch (RuntimeException e) {
+        throw new StringPoolException("Unable to add object: " + spObject + " for " + gNode, e);
+      }
     }
   }
 

Modified: trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java
===================================================================
--- trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/swrl/java/org/mulgara/swrl/SWRLLoader.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -817,6 +817,7 @@
         (List<Order>)Collections.EMPTY_LIST,        // ORDER BY
         null,                                       // LIMIT
         0,                                          // OFFSET
+        true,                                       // DISTINCT
         UNCONSTRAINED                               // GIVEN
     );
   }

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/LeftJoin.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -113,7 +113,8 @@
     // get the variables to merge on
     commonVars = Collections.unmodifiableSet((Set<Variable>)TuplesOperations.getMatchingVars(lhs, rhs));
 
-    if (commonVars.isEmpty()) logger.warn("Tuples should have variables in common for optional join to occur");
+    // This is more common than we expected, so just log a debug message
+    if (commonVars.isEmpty()) logger.debug("Tuples should have variables in common for optional join to occur");
 
     // initialise the mapping of lhs columns to rhs columns
     varMap = new int[commonVars.size()];

Modified: trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java
===================================================================
--- trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/tuples/java/org/mulgara/store/tuples/TuplesOperations.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -178,7 +178,7 @@
     } else {
       List<Tuples> projected = new ArrayList<Tuples>();
       for (Tuples operand: operands) {
-        Tuples proj = project(operand, variables);
+        Tuples proj = project(operand, variables, true);
         Tuples sorted = sort(proj);
         projected.add(sorted);
         proj.close();
@@ -257,7 +257,7 @@
     } else {
       List<Tuples> projected = new ArrayList<Tuples>();
       for (Tuples operand: operands) {
-        Tuples proj = project(operand, variables);
+        Tuples proj = project(operand, variables, false);
         projected.add(proj);
         operand.close();
       }
@@ -399,7 +399,7 @@
       }
       // double check that the variables are not equal
       if (subtrahend.getRowCardinality() == Cursor.ZERO || minuend.getRowCardinality() == Cursor.ZERO) {
-        logger.warn("Found an empty Tuples with bound variables");
+        logger.debug("Found an empty Tuples with bound variables");
         return (Tuples)minuend.clone();
       }
       // reorder the subtrahend as necessary
@@ -409,7 +409,7 @@
         // yes, there are extra variables
         logger.debug("removing extra variables not needed in subtraction");
         // project out the extra variables (sorting happens in projection)
-        sortedSubtrahend = project(subtrahend, new ArrayList<Variable>(matchingVars));
+        sortedSubtrahend = project(subtrahend, new ArrayList<Variable>(matchingVars), true);
       } else {
         // there were no extra variables in the subtrahend
         logger.debug("All variables needed");
@@ -794,12 +794,13 @@
    * Relational projection. This eliminates any columns not in the specified
    * list, and eliminates any duplicate rows that result.
    *
-   * @param tuples PARAMETER TO DO
+   * @param tuples The original tuples to project
    * @param variableList the list of {@link Variable}s to project on
-   * @return RETURNED VALUE TO DO
+   * @param distinct indicates that duplicate rows should be removed
+   * @return The tuples, with only the required columns, and possibly with duplicates removed
    * @throws TuplesException if the projection operation fails
    */
-  public static Tuples project(Tuples tuples, List<Variable> variableList) throws TuplesException {
+  public static Tuples project(Tuples tuples, List<Variable> variableList, boolean distinct) throws TuplesException {
     try {
 
       boolean noVariables = (variableList == null) || (variableList.size() == 0);
@@ -812,9 +813,9 @@
       if (logger.isDebugEnabled()) logger.debug("Projecting to " + variableList);
 
       // Perform the actual projection
-      Tuples oldTuples = tuples;
+      Tuples originalTuples = tuples;
       tuples = new UnorderedProjection(tuples, variableList);
-      assert tuples != oldTuples;
+      assert tuples != originalTuples;
 
       // Test whether creating an unordered projects has removed variables.
       if (tuples.isUnconstrained()) {
@@ -823,18 +824,19 @@
       }
 
       // Eliminate any duplicates
-      oldTuples = tuples;
-      tuples = removeDuplicates(tuples);
-      assert tuples != oldTuples;
+      if (distinct) {
+        Tuples oldTuples = tuples;
+        tuples = removeDuplicates(tuples);
+        assert tuples != oldTuples;
 
-      if (tuples == oldTuples) {
-        logger.warn("removeDuplicates does not change the underlying tuples");
-      } else {
-        oldTuples.close();
+        if (tuples == oldTuples) {
+          logger.warn("removeDuplicates does not change the underlying tuples");
+        } else {
+          oldTuples.close();
+        }
+        assert tuples.hasNoDuplicates();
       }
 
-      assert tuples.hasNoDuplicates();
-
       return tuples;
     } catch (TuplesException e) {
       throw new TuplesException("Couldn't perform projection", e);

Modified: trunk/src/jar/util/java/org/mulgara/util/Bootstrap.java
===================================================================
--- trunk/src/jar/util/java/org/mulgara/util/Bootstrap.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/util/java/org/mulgara/util/Bootstrap.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -16,7 +16,7 @@
  * created by Plugged In Software Pty Ltd are Copyright (C) 2001,2002
  * Plugged In Software Pty Ltd. All Rights Reserved.
  *
- * Contributor(s): N/A.
+ * Contributor(s): Duraspace.
  *
  * [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
@@ -70,13 +70,8 @@
  *
  * @modified $Date: 2005/01/05 04:59:29 $
  *
- * @maintenanceAuthor $Author: newmana $
- *
  * @company <A href="mailto:info at PIsoftware.com">Plugged In Software</A>
  *
- * @copyright &copy;2001 <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 Bootstrap extends URLClassLoader {
@@ -100,7 +95,7 @@
   /**
    * Used by the addToSystemClasspath hack
    */
-  private static final Class[] parameters = new Class[]{URL.class};
+  private static final Class<?>[] parameters = new Class[]{URL.class};
 
   /**
    * create a 100K temp buffer to store the JAR bytes in
@@ -114,10 +109,8 @@
   // Members
   //
 
-  /**
-   * the array of JAR files to load
-   *
-   */
+  /** the array of JAR files to load */
+  @SuppressWarnings("unused")
   private URL[] jarURLs = null;
 
   //
@@ -146,7 +139,6 @@
     this.jarURLs = jarURLs;
   }
 
-  // Bootstrap
 
   /**
    * Loads a comma separated list of embedded JAR files specified by an <CODE>Embedded-Jar</CODE>
@@ -173,26 +165,18 @@
       Attributes manifestAttr = retrieveManifestAttributes();
 
       // throw and error if we couldn't get any manifest attributes
-      if (manifestAttr == null) {
+      if (manifestAttr == null) throw new Exception("No manifest attributes found for JAR");
 
-        throw new Exception("No manifest attributes found for JAR");
-      }
-
-      // end if
       // get the name of the embedded main class
       String embeddedMainClass = manifestAttr.getValue(EMBEDDED_MAIN_CLASS_KEY);
 
       // it's pointless to continue without a main class
       if (embeddedMainClass == null) {
-
         throw new Exception("No Embedded-Main-Class attribute in manifest");
       }
 
-      // end if
       // Set the path of the jar as a System property - mulgara.jar.path
-      URL bootURL =
-          Bootstrap.class.getClassLoader().getSystemResource(
-          "org/mulgara/util/Bootstrap.class");
+      URL bootURL = ClassLoader.getSystemResource("org/mulgara/util/Bootstrap.class");
 
       String bootURLString = bootURL.toString();
       String preString = "jar:file:";
@@ -207,31 +191,26 @@
       //       dodgy error message problem.
       // set the xerces system property if we're executing the Mulgara server
       if (embeddedMainClass.equals("org.mulgara.server.EmbeddedMulgaraServer")) {
-
         System.setProperty("org.mulgara.xml.ResourceDocumentBuilderFactory",
             "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl");
       }
 
-      // end if
       // ************************************************************************
       // get a list of URLs to the embedded JARs
-      LinkedList jarURLs = getEmbeddedJarURLs(manifestAttr);
+      LinkedList<URL> jarURLs = getEmbeddedJarURLs(manifestAttr);
 
       // create a new bootstrap classloader
-      Bootstrap loader =
-            new Bootstrap( (URL[]) jarURLs.toArray(new URL[jarURLs.size()]));
+      Bootstrap loader = new Bootstrap((URL[])jarURLs.toArray(new URL[jarURLs.size()]));
 
       // set the context class loader to the bootstrap
       Thread.currentThread().setContextClassLoader(loader);
 
       // invokes the 'real' main class
       loader.invokeClass(embeddedMainClass, args);
-    }
-    catch (Exception e) {
+    } catch (Exception e) {
 
       // print the contents of the exception
-      System.err.println("Unable to bootstrap embedded main class: " +
-          e.toString());
+      System.err.println("Unable to bootstrap embedded main class: " + e.toString());
       System.err.println(">> Stack trace:");
       e.printStackTrace();
 
@@ -240,36 +219,28 @@
       Throwable cause = e.getCause();
 
       while (cause != null) {
-
         rootCause = cause;
         cause = cause.getCause();
       }
 
-      // end while
       // print a stack trace on it
       if (rootCause != null) {
-
         System.err.println(">> Root cause stack trace:");
         System.err.flush();
         rootCause.printStackTrace();
       }
 
-      // end if
     }
 
-    // try-catch
   }
 
-  // main()
 
   /**
-   * Shutdown the current application by forcing the runtime shutdown hooks to
-   * be executed.
+   * Shutdown the current application by forcing the runtime shutdown hooks to be executed.
    *
-   * @param args PARAMETER TO DO
+   * @param args command line arguments
    */
   public static void shutdown(String[] args) {
-
     System.exit(0);
   }
 
@@ -277,13 +248,11 @@
    * Hack used to add the Embedded Jars to the system classpath.
    *
    * @param urls URLs of JARs to embed
-   * @throws IOException
+   * @throws IOException Caused by any problem updating the system class path
    */
   public static void addToSystemClasspath(URL[] urls) throws IOException {
 
-    if (urls == null) {
-      throw new IllegalArgumentException("null 'urls' parameter.");
-    }
+    if (urls == null) throw new IllegalArgumentException("null 'urls' parameter.");
 
     //add each
     for (int i = 0; i < urls.length; i++) {
@@ -294,47 +263,39 @@
   /**
    * Adds the jar (url) to the system classpath.
    *
-   * @param url URL
-   * @throws IOException
+   * @param url URL to add to the system classpath.
+   * @throws IOException Caused by any problem updating the system class path
    */
   public static void addToSystemClasspath(URL url) throws IOException {
 
-    URLClassLoader sysloader = (URLClassLoader) ClassLoader.
-        getSystemClassLoader();
-    Class sysclass = URLClassLoader.class;
+    URLClassLoader sysloader = (URLClassLoader)ClassLoader.getSystemClassLoader();
+    Class<URLClassLoader> sysclass = URLClassLoader.class;
 
     try {
       Method method = sysclass.getDeclaredMethod("addURL", parameters);
       method.setAccessible(true);
       method.invoke(sysloader, new Object[] {url});
-    }
-    catch (Throwable t) {
+    } catch (Throwable t) {
       t.printStackTrace();
       throw new IOException("Error, could not add URL to system classloader");
     }
   }
 
 
-  // retrieveManifestAttributes()
-
   /**
    * Returns a list of URLs to the embedded jar files.
    *
    * @param manifestAttr the manifest attributes of the jar to retrieve the
    *      embedded jar names from
-   * @return a list of URLs to the embedded jar files, null if no embedded jars
-   *      found
+   * @return a list of URLs to the embedded jar files, null if no embedded jars found
    */
-  private static LinkedList getEmbeddedJarURLs(Attributes manifestAttr) {
+  private static LinkedList<URL> getEmbeddedJarURLs(Attributes manifestAttr) {
 
     // check the parameters
-    if (manifestAttr == null) {
+    if (manifestAttr == null) throw new IllegalArgumentException("Null manifest attribute");
 
-      throw new IllegalArgumentException("Null manifest attribute");
-    }
-
     // create a list to hold the JAR resources
-    LinkedList jarURLs = new LinkedList();
+    LinkedList<URL> jarURLs = new LinkedList<URL>();
 
     // get the list of embedded jars
     String embeddedJarList = manifestAttr.getValue(EMBEDDED_JAR_KEY);
@@ -342,25 +303,16 @@
     if (embeddedJarList != null ) {
     
       // tokense the list of jar files
-      StringTokenizer jarTokenizer =
-          new StringTokenizer(embeddedJarList, " ,\t\f");
+      StringTokenizer jarTokenizer = new StringTokenizer(embeddedJarList, " ,\t\f");
 
       // add a URL for each embedded jar to the array
       while (jarTokenizer.hasMoreTokens()) {
-
         // write this JAR to a temp file and get its URL
         URL jarURL = writeTempJARFile(jarTokenizer.nextToken());
-
-        if (jarURL != null) {
-
-          jarURLs.add(jarURL);
-        }
-
-        // end if
+        if (jarURL != null) jarURLs.add(jarURL);
       }
     }
 
-    // end while
     // we don't want the buffer hanging around
     buf = null;
 
@@ -369,10 +321,9 @@
   }
 
   /**
-   * Retrieves the manifest attributes of the JAR from which this file is
-   * running.
+   * Retrieves the manifest attributes of the JAR from which this file is running.
    *
-       * @return the manifest attributes of the JAR from which this class is running
+   * @return the manifest attributes of the JAR from which this class is running
    * @throws Exception if unable to retrieve the JAR resource for a class
    */
   private static Attributes retrieveManifestAttributes() throws Exception {
@@ -384,27 +335,21 @@
     URL classURL = ClassLoader.getSystemResource(className + ".class");
 
     // throw an error if we could not get it
-    if (classURL == null) {
+    if (classURL == null) throw new Exception("Unable to retrieve JAR resource for " + className);
 
-      throw new Exception("Unable to retrieve JAR resource for " + className);
-    }
-
     // end if
     // open a connection to the class resource
     URLConnection urlConn = classURL.openConnection();
 
     // make sure that we're executing from within a JAR
     if ( (urlConn == null) || ! (urlConn instanceof JarURLConnection)) {
-
       throw new Exception("Bootstrap class must be executed from within a JAR");
     }
 
-    // end if
     // return its manifest attributes
-    return ( (JarURLConnection) urlConn).getMainAttributes();
+    return ((JarURLConnection)urlConn).getMainAttributes();
   }
 
-  // getEmbeddedJarURLs()
 
   /**
    * Writes an embedded JAR file to a temporary file, and returns a URL to the
@@ -412,8 +357,7 @@
    *
    * @param embeddedJARFilename the name of the embedded JAR file to retrieve
    * @return the URL of the temporary JAR file, null if we were unable to
-   *      retrieve a the embedded JAR or something went wrong writing a temp
-   *      file
+   *      retrieve a the embedded JAR or something went wrong writing a temp file
    */
   private static URL writeTempJARFile(String embeddedJARFilename) {
 
@@ -422,17 +366,13 @@
     try {
 
       // get the embedded jar as a stream
-      InputStream jarIn =
-          ClassLoader.getSystemResourceAsStream(embeddedJARFilename);
+      InputStream jarIn =ClassLoader.getSystemResourceAsStream(embeddedJARFilename);
 
       // check that the embedded filename is valid
       if (jarIn == null) {
-
-        throw new IOException("Embedded JAR: " + embeddedJARFilename +
-            " does not exist in enclosing JAR.");
+        throw new IOException("Embedded JAR: " + embeddedJARFilename + " does not exist in enclosing JAR.");
       }
 
-      // end if
       // create a temporary file to write the jar to (we may need to keep the
       // class on disk for windows weenies...)
       File tmpJarFile = File.createTempFile("mulgara", ".jar");
@@ -444,29 +384,24 @@
       // write the embedded jar to disk
       int n;
 
-      while ( (n = jarIn.read(buf)) != -1) {
-
+      while ((n = jarIn.read(buf)) != -1) {
         out.write(buf, 0, n);
       }
 
-      // end if
       // set the embedded JAR's URL
-      embeddedJarURL = tmpJarFile.toURL();
-    }
-    catch (IOException ioe) {
+      embeddedJarURL = tmpJarFile.toURI().toURL();
 
+    } catch (IOException ioe) {
       System.err.println(ioe);
     }
 
-    // try-catch
     // return the temp file's URL
     return embeddedJarURL;
   }
 
-  // writeTempJARFile()
 
   /**
-       * Invokes the <CODE>main()</CODE> or or <CODE>shutdown()</CODE> method of the
+   * Invokes the <CODE>main()</CODE> or or <CODE>shutdown()</CODE> method of the
    * class <CODE>className</CODE> with the given array of arguments. The class
    * must define a <CODE>public static void xxx()</CODE> that takes an array of
    * String.
@@ -492,38 +427,29 @@
     // check for a shutdown request
     for (int i = 0; i < args.length; i++) {
 
-      if (args[i].equalsIgnoreCase("--shutdown") ||
-          args[i].equalsIgnoreCase("-x")) {
-
+      if (args[i].equalsIgnoreCase("--shutdown") || args[i].equalsIgnoreCase("-x")) {
         // change the method to a shutdown
         methodRequest = "shutdown";
       }
     }
 
     // load the class
-    Class c = this.loadClass(className);
+    Class<?> c = this.loadClass(className);
 
     // get its main method
-    Method m = c.getMethod(methodRequest, new Class[] {
-        args.getClass()});
+    Method m = c.getMethod(methodRequest, new Class[] {args.getClass()});
     m.setAccessible(true);
 
     // retrieve its modifiers
     int mods = m.getModifiers();
 
     // make sure that it is a public static void method
-    if ( (m.getReturnType() != void.class) ||
-        !Modifier.isStatic(mods) ||
-        !Modifier.isPublic(mods)) {
-
+    if ((m.getReturnType() != void.class) || !Modifier.isStatic(mods) || !Modifier.isPublic(mods)) {
       throw new NoSuchMethodException(methodRequest);
     }
 
-    // end if
     // invoke it!
-    m.invoke(null, new Object[] {
-        args});
+    m.invoke(null, new Object[] {args});
   }
 
-  // invokeClass()
 }

Modified: trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java
===================================================================
--- trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java	2009-12-10 14:14:43 UTC (rev 1870)
+++ trunk/src/jar/web/java/org/mulgara/webquery/QueryServlet.java	2009-12-10 17:02:12 UTC (rev 1871)
@@ -291,7 +291,8 @@
       resp.sendError(SC_SERVICE_UNAVAILABLE, ise.getMessage());
       return;
     } catch (Exception e) {
-      resp.sendError(SC_BAD_REQUEST, "Error executing command. Reason: " + StackTrace.getReasonMessage(e));
+      // resp.sendError(SC_BAD_REQUEST, "Error executing command. Reason: " + StackTrace.getReasonMessage(e));
+      resp.sendError(SC_BAD_REQUEST, "Error executing command. Reason: " + StackTrace.throwableToString(e));
       return;
     }
 




More information about the Mulgara-svn mailing list