JENA-1899: TDB1 and TDB2 SPARQL* tests
diff --git a/jena-arq/Vocabularies/test-manifest-x.ttl b/jena-arq/Vocabularies/test-manifest-x.ttl
index b2162ae..26c577f 100644
--- a/jena-arq/Vocabularies/test-manifest-x.ttl
+++ b/jena-arq/Vocabularies/test-manifest-x.ttl
@@ -29,6 +29,13 @@
     rdfs:subClassOf :TestSyntax ;
     rdfs:comment "Syntax tests which expect a parse failure" .
 
+:PositiveUpdateSyntaxTestARQ rdf:type rdfs:Class ;
+    rdfs:comment "Syntax tests (query)" .
+
+:NegativeUpdateSyntaxTestARQ rdf:type rdfs:Class ;
+    rdfs:subClassOf :TestSyntax ;
+    rdfs:comment "Syntax tests which expect a parse failure" .
+
 :TestSerialization rdf:type rdfs:Class ;
     rdfs:comment "Query serialization tests" .
 
diff --git a/jena-arq/src/main/java/org/apache/jena/query/Query.java b/jena-arq/src/main/java/org/apache/jena/query/Query.java
index bfe51b6..933b85b 100644
--- a/jena-arq/src/main/java/org/apache/jena/query/Query.java
+++ b/jena-arq/src/main/java/org/apache/jena/query/Query.java
@@ -131,12 +131,9 @@
     }
 
     // Allocate variables that are unique to this query.
-    private VarAlloc varAlloc = new VarAlloc(ARQConstants.allocVarMarker) ;
+    private VarAlloc varAlloc = new VarAlloc(ARQConstants.allocQueryVariables) ;
     private Var allocInternVar() { return varAlloc.allocVar() ; }
 
-    //private VarAlloc varAnonAlloc = new VarAlloc(ARQConstants.allocVarAnonMarker) ;
-    //public Var allocVarAnon() { return varAnonAlloc.allocVar() ; }
-
     public void setQuerySelectType()            { queryType = QueryType.SELECT ; }
     public void setQueryConstructType()         { queryType = QueryType.CONSTRUCT ; queryResultStar = true ; }
     public void setQueryDescribeType()          { queryType = QueryType.DESCRIBE; }
diff --git a/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFmtLib.java b/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFmtLib.java
index 579501d..ecc1393 100644
--- a/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFmtLib.java
+++ b/jena-arq/src/main/java/org/apache/jena/riot/out/NodeFmtLib.java
@@ -18,22 +18,23 @@
 
 package org.apache.jena.riot.out;
 
-import java.net.MalformedURLException ;
-import java.util.Map ;
+import java.net.MalformedURLException;
+import java.util.Map;
+import java.util.StringJoiner;
 
-import org.apache.jena.atlas.io.IndentedLineBuffer ;
-import org.apache.jena.atlas.io.IndentedWriter ;
-import org.apache.jena.atlas.lib.Bytes ;
-import org.apache.jena.atlas.lib.Chars ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.graph.Triple ;
-import org.apache.jena.iri.IRI ;
-import org.apache.jena.iri.IRIRelativize ;
-import org.apache.jena.rdf.model.RDFNode ;
-import org.apache.jena.riot.system.* ;
-import org.apache.jena.shared.PrefixMapping ;
-import org.apache.jena.sparql.ARQConstants ;
-import org.apache.jena.sparql.core.Quad ;
+import org.apache.jena.atlas.io.IndentedLineBuffer;
+import org.apache.jena.atlas.io.IndentedWriter;
+import org.apache.jena.atlas.lib.Bytes;
+import org.apache.jena.atlas.lib.Chars;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.iri.IRI;
+import org.apache.jena.iri.IRIRelativize;
+import org.apache.jena.rdf.model.RDFNode;
+import org.apache.jena.riot.system.*;
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.sparql.ARQConstants;
+import org.apache.jena.sparql.core.Quad;
 
 /** Presentation utilities for Nodes, Triples, Quads and more.
  * <p>
@@ -48,98 +49,98 @@
     // See OutputLangUtils.
     // See and use EscapeStr
     
-    private static final NodeFormatter plainFormatter = new NodeFormatterNT() ;
+    private static final NodeFormatter plainFormatter = new NodeFormatterNT();
     
-    private static PrefixMap dftPrefixMap = PrefixMapFactory.create() ;
+    private static PrefixMap dftPrefixMap = PrefixMapFactory.create();
     static {
-        PrefixMapping pm = ARQConstants.getGlobalPrefixMap() ;
-        Map<String, String> map = pm.getNsPrefixMap() ;
+        PrefixMapping pm = ARQConstants.getGlobalPrefixMap();
+        Map<String, String> map = pm.getNsPrefixMap();
         for ( Map.Entry<String, String> e : map.entrySet() )
-            dftPrefixMap.add(e.getKey(), e.getValue() ) ;
+            dftPrefixMap.add(e.getKey(), e.getValue() );
     }
 
-    public static String str(Triple t)
-    {
-        return strNodes(t.getSubject(), t.getPredicate(),t.getObject()) ;
+    public static String str(Triple t) {
+        return strNodes(t.getSubject(), t.getPredicate(), t.getObject());
     }
 
-    public static String str(Quad q)
-    {
-        return strNodes(q.getGraph(), q.getSubject(), q.getPredicate(), q.getObject()) ;
+    public static String str(Quad q) {
+        return strNodes(q.getGraph(), q.getSubject(), q.getPredicate(), q.getObject());
     }
 
-    public static String str(Node n)
-    {
-        IndentedLineBuffer sw = new IndentedLineBuffer() ;
-        str(sw, n) ;
-        return sw.toString() ; 
+    public static String str(Node n) {
+        IndentedLineBuffer sw = new IndentedLineBuffer();
+        str(sw, n);
+        return sw.toString();
+    }
+
+    // Worker
+    public static String strNodes(Node...nodes) {
+        IndentedLineBuffer sw = new IndentedLineBuffer();
+        boolean first = true;
+        for ( Node n : nodes ) {
+            if ( !first )
+                sw.append(" ");
+            first = false;
+            if ( n == null ) {
+                sw.append("null");
+                continue;
+            }
+            str(sw, n);
+        }
+        return sw.toString();
     }
 
     /** A displayable string for an RDFNode. Includes common abbreviations */
-    public static String displayStr(RDFNode obj)
-    {
-        return displayStr(obj.asNode()) ;
-    }
-    
-    public static String displayStr(Node n)
-    { 
-        return str(n, null, dftPrefixMap) ;
+    public static String displayStr(RDFNode obj) {
+        return displayStr(obj.asNode());
     }
 
-    
-    // Worker
-    public static String strNodes(Node ... nodes)
-    {
-        IndentedLineBuffer sw = new IndentedLineBuffer() ;
-        boolean first = true ;
+    public static String displayStr(Triple t) {
+        return displayStrNodes(t.getSubject(), t.getPredicate(), t.getObject());
+    }
+
+    public static String displayStr(Node n) {
+        return str(n, null, dftPrefixMap);
+    }
+
+    private static String displayStrNodes(Node...nodes) {
+        StringJoiner sj = new StringJoiner(" ");
         for ( Node n : nodes ) 
-        {
-            if ( ! first )
-                sw.append(" ") ;
-            first = false ;
-            if ( n == null ) {
-                sw.append("null") ;
-                continue;
-            }
-            str(sw, n) ;
-        }
-        return sw.toString() ; 
+            sj.add(displayStr(n));
+        return sj.toString(); 
     }
 
-    //public static String displayStr(Node n) { return serialize(n) ; }
-
-    public static void str(IndentedWriter w, Node n)
-    { serialize(w, n, null, null) ; }
-
-    public static String str(Node n, Prologue prologue)
-    {
-        return str(n, prologue.getBaseURI(), prologue.getPrefixMap()) ;
+    public static void str(IndentedWriter w, Node n) {
+        serialize(w, n, null, null);
     }
 
-    public static String str(Node n, String base, PrefixMap prefixMap)
-    {
-        IndentedLineBuffer sw = new IndentedLineBuffer() ;
-        serialize(sw, n, base, prefixMap) ;
-        return sw.toString() ;
+    public static String str(Node n, Prologue prologue) {
+        return str(n, prologue.getBaseURI(), prologue.getPrefixMap());
     }
 
-    public static void serialize(IndentedWriter w, Node n, Prologue prologue)
-    { serialize(w, n, prologue.getBaseURI(), prologue.getPrefixMap()) ; }
-    
-    public static void serialize(IndentedWriter w, Node n, String base, PrefixMap prefixMap)
-    {
-        NodeFormatter formatter ;
+    public static String str(Node n, String base, PrefixMap prefixMap) {
+        IndentedLineBuffer sw = new IndentedLineBuffer();
+        serialize(sw, n, base, prefixMap);
+        return sw.toString();
+    }
+
+    public static void serialize(IndentedWriter w, Node n, Prologue prologue) {
+        serialize(w, n, prologue.getBaseURI(), prologue.getPrefixMap());
+    }
+
+    public static void serialize(IndentedWriter w, Node n, String base, PrefixMap prefixMap) {
+        NodeFormatter formatter;
         if ( base == null && prefixMap == null )
-            formatter = plainFormatter ;
-        else 
-            formatter = new NodeFormatterTTL(base, prefixMap) ;
-        formatter.format(w, n) ;
+            formatter = plainFormatter;
+        else
+            formatter = new NodeFormatterTTL(base, prefixMap);
+        formatter.format(w, n);
     }
     
     // ---- Blank node labels.
     
     // Strict N-triples only allows [A-Za-z][A-Za-z0-9]
-    static char encodeMarkerChar = 'X' ;
+    static char encodeMarkerChar = 'X';
 
     // These two form a pair to convert bNode labels to a safe (i.e. legal N-triples form) and back agains. 
     
@@ -148,86 +149,78 @@
     // 2 - Hexify, as Xnn, anything outside ASCII A-Za-z0-9
     // 3 - X is encoded as XX
     
-    private static char LabelLeadingLetter = 'B' ; 
+    private static char LabelLeadingLetter = 'B'; 
     
-    public static String encodeBNodeLabel(String label)
-    {
-        StringBuilder buff = new StringBuilder() ;
+    public static String encodeBNodeLabel(String label) {
+        StringBuilder buff = new StringBuilder();
         // Must be at least one char and not a digit.
-        buff.append(LabelLeadingLetter) ;
-        
-        for ( int i = 0 ; i < label.length() ; i++ )
-        {
-            char ch = label.charAt(i) ;
-            if ( ch == encodeMarkerChar )
-            {
-                buff.append(ch) ;
-                buff.append(ch) ;
-            }
-            else if ( RiotChars.isA2ZN(ch) )
-                buff.append(ch) ;
+        buff.append(LabelLeadingLetter);
+
+        for ( int i = 0 ; i < label.length() ; i++ ) {
+            char ch = label.charAt(i);
+            if ( ch == encodeMarkerChar ) {
+                buff.append(ch);
+                buff.append(ch);
+            } else if ( RiotChars.isA2ZN(ch) )
+                buff.append(ch);
             else
-                Chars.encodeAsHex(buff, encodeMarkerChar, ch) ;
+                Chars.encodeAsHex(buff, encodeMarkerChar, ch);
         }
-        return buff.toString() ;
+        return buff.toString();
     }
 
     // Assumes that blank nodes only have characters in the range of 0-255
-    public static String decodeBNodeLabel(String label)
-    {
-        StringBuilder buffer = new StringBuilder() ;
+    public static String decodeBNodeLabel(String label) {
+        StringBuilder buffer = new StringBuilder();
 
         if ( label.charAt(0) != LabelLeadingLetter )
-            return label ;
-        
-        // Skip first.
-        for ( int i = 1; i < label.length(); i++ )
-        {
-            char ch = label.charAt(i) ;
-            
-            if ( ch != encodeMarkerChar )
-            {
-                buffer.append(ch) ;
-            }
-            else
-            {
-                // Maybe XX or Xnn.
-                char ch2 = label.charAt(i+1) ;
-                if ( ch2 == encodeMarkerChar )
-                {
-                    i++ ;
-                    buffer.append(ch) ;
-                    continue ;
-                }
-                
-                // Xnn
-                i++ ;
-                char hiC = label.charAt(i) ;
-                int hi = Bytes.hexCharToInt(hiC) ;
-                i++ ;
-                char loC = label.charAt(i) ;
-                int lo = Bytes.hexCharToInt(loC) ;
+            return label;
 
-                int combined = ((hi << 4) | lo) ;
-                buffer.append((char) combined) ;
+        // Skip first.
+        for ( int i = 1 ; i < label.length() ; i++ ) {
+            char ch = label.charAt(i);
+
+            if ( ch != encodeMarkerChar ) {
+                buffer.append(ch);
+            } else {
+                // Maybe XX or Xnn.
+                char ch2 = label.charAt(i + 1);
+                if ( ch2 == encodeMarkerChar ) {
+                    i++;
+                    buffer.append(ch);
+                    continue;
+                }
+
+                // Xnn
+                i++;
+                char hiC = label.charAt(i);
+                int hi = Bytes.hexCharToInt(hiC);
+                i++;
+                char loC = label.charAt(i);
+                int lo = Bytes.hexCharToInt(loC);
+
+                int combined = ((hi << 4) | lo);
+                buffer.append((char)combined);
             }
         }
 
-        return buffer.toString() ;
+        return buffer.toString();
     }
-    
+
     // ---- Relative URIs.
-    
-    static private int relFlags = IRIRelativize.SAMEDOCUMENT | IRIRelativize.CHILD ;
-    static public String abbrevByBase(String uri, String base)
-    {
+
+    static private int relFlags = IRIRelativize.SAMEDOCUMENT | IRIRelativize.CHILD;
+    static public String abbrevByBase(String uri, String base) {
         if ( base == null )
-            return null ;
-        IRI baseIRI = IRIResolver.iriFactory().construct(base) ;
-        IRI rel = baseIRI.relativize(uri, relFlags) ;
-        String r = null ;
-        try { r = rel.toASCIIString() ; }
-        catch (MalformedURLException  ex) { r = rel.toString() ; }
-        return r ;
+            return null;
+        IRI baseIRI = IRIResolver.iriFactory().construct(base);
+        IRI rel = baseIRI.relativize(uri, relFlags);
+        String r = null;
+        try {
+            r = rel.toASCIIString();
+        } catch (MalformedURLException ex) {
+            r = rel.toString();
+        }
+        return r;
     }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java b/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
index d29fe17..ade0820 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/ARQConstants.java
@@ -172,9 +172,6 @@
     // Secondary marker for globally allocated variables.
     private static final String globalVar =     "." ;
 
-    /** Marker for variables replacing blank nodes in SPARQL Update patterns */
-    public static final String allocVarBNodeToVar =  "~" ;
-
     /** Marker for variables renamed to make variables hidden by scope have globally unique names */
     public static final String allocVarScopeHiding =  "/" ;
 
@@ -187,13 +184,16 @@
     // These strings are without the leading "?"
 
     // Put each constant here and not in the place the variable allocator created.
-    // Alwats 0, 1, 2, 3 after these prefixes.
+    // Always 0, 1, 2, 3 after these prefixes.
 
-    public static final String allocGlobalVarMarker     = allocVarMarker+globalVar ;    // VarAlloc
+    //public static final String allocGlobalVarMarker     = allocVarMarker+globalVar ;    // VarAlloc
     public static final String allocPathVariables       = allocVarAnonMarker+"P" ;      // PathCompiler
     public static final String allocQueryVariables      = allocVarMarker ;              // Query
+    
+    /** Marker for RDF* variables */
+    public static final String allocVarTripleTerm      = "~";                           // RX, SolverRX
+    
     public static final String allocParserAnonVars      = allocVarAnonMarker ;          // LabelToModeMap
-
     // SSE
     public static final String allocSSEUnamedVars       = "_" ;                         // ParseHandlerPlain - SSE token "?" - legal SPARQL
     public static final String allocSSEAnonVars         = allocVarAnonMarker ;          // ParseHandlerPlain - SSE token "??"
@@ -219,6 +219,8 @@
     /** Context key for the dataset for the current query execution. */
     public static final Symbol sysCurrentDataset        = Symbol.create(systemVarNS+"dataset") ;
 
+    public static final Symbol sysVarAllocRDFStar       = Symbol.create(systemVarNS+"varAllocRDFStar") ;
+    
     /** Context key for the dataset description (if any).
      *  See the <a href="http://www.w3.org/TR/sparql11-protocol">SPARQL protocol</a>.
      *  <p>
@@ -264,7 +266,7 @@
     /** Context symbol for a supplied {@link Prologue} (used for text out of result sets). */
     public static final Symbol symPrologue                 = SystemARQ.allocSymbol("prologue");
 
-    /** Context key for making all SELECT queries have DISTINCT applied, whether stated ot not */
+    /** Context key for making all SELECT queries have DISTINCT applied, whether stated or not */
     public static final Symbol autoDistinct             = SystemARQ.allocSymbol("autoDistinct") ;
 
     // Context keys : some here, some in ARQ - sort out
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadBlockGraph.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadBlockGraph.java
index 5dea138..483cd11 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadBlockGraph.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadBlockGraph.java
@@ -20,106 +20,22 @@
 
 import java.util.Deque ;
 
-import org.apache.jena.graph.Node ;
 import org.apache.jena.sparql.algebra.AlgebraQuad.QuadSlot ;
-import org.apache.jena.sparql.algebra.op.* ;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.expr.ExprVar ;
+import org.apache.jena.sparql.algebra.op.OpBGP;
+import org.apache.jena.sparql.algebra.op.OpQuadBlock;
 
 /**
  * Transform that rewrites an algebra into quadblock form
  *
  */
-public class TransformQuadBlockGraph extends TransformCopy
+public class TransformQuadBlockGraph extends TransformQuadGraph
 {
-    private Deque<QuadSlot> tracker ;
-    private OpVisitor beforeVisitor ;
-    private OpVisitor afterVisitor ;
-
     public TransformQuadBlockGraph(Deque<QuadSlot> tracker, OpVisitor before, OpVisitor after) {
-        this.tracker = tracker ;
-        this.beforeVisitor = before ;
-        this.afterVisitor = after ;
-    }
-
-    private Node getNode() { return tracker.peek().rewriteGraphName ; }
-
-    @Override
-    public Op transform(OpGraph opGraph, Op op) {
-
-        // ?? Could just leave the (graph) in place always - just rewrite BGPs.
-        boolean noPattern = false ;
-
-        /* One case to consider is when the pattern for the GRAPH
-         * statement includes uses the variable inside the GRAPH clause.
-         * In this case, we must rename away the inner variable
-         * to allow stream execution via index joins,
-         * and then put back the value via an assign.
-         * (This is what QueryIterGraph does using a streaming join
-         * for triples)
-         */
-
-        // Note: op is already quads by this point.
-        // Must test scoping by the subOp of GRAPH
-
-        QuadSlot qSlot = tracker.peek() ;
-        Node actualName= qSlot.actualGraphName ;
-        Node rewriteName= qSlot.rewriteGraphName ;
-
-        if ( OpBGP.isBGP(op) )
-        {
-            // Empty BGP
-            if ( ((OpBGP)op).getPattern().isEmpty() )
-                noPattern = true ;
-        }
-        else if ( op instanceof OpTable )
-        {
-            // Empty BGP compiled to a unit table
-            if ( ((OpTable)op).isJoinIdentity() )
-                noPattern = true ;
-        }
-
-        if ( noPattern )
-        {
-            // The case of something like:
-            // GRAPH ?g {} or GRAPH <v> {}
-            // which are ways of accessing the names in the dataset.
-            return new OpDatasetNames(opGraph.getNode()) ;
-        }
-
-        if ( actualName != rewriteName )
-            op = OpAssign.assign(op, Var.alloc(actualName), new ExprVar(rewriteName)) ;
-
-        // Drop (graph...) because inside nodes
-        // have been converted to quads.
-        return op ;
-    }
-
-    @Override
-    public Op transform(OpPropFunc opPropFunc, Op subOp) {
-        if ( opPropFunc.getSubOp() != subOp )
-            opPropFunc = new OpPropFunc(opPropFunc.getProperty(), opPropFunc.getSubjectArgs(), opPropFunc.getObjectArgs(), subOp) ;
-        // Put the (graph) back round it so the property function works on the named graph.
-        return new OpGraph(getNode() , opPropFunc) ;
-    }
-
-    @Override
-    public Op transform(OpPath opPath) {
-        // Put the (graph) back round it
-        // ?? inc default graph node.
-        return new OpGraph(getNode() , opPath) ;
-        // Does not get removed by transform above because this is
-        // not the OpGraph that gets walked by the transform.
+        super(tracker, before, after);
     }
 
     @Override
     public Op transform(OpBGP opBGP) {
-        //System.out.print("transform(OpBGP) : "+getNode()+"\n"+opBGP) ;
         return OpQuadBlock.create(getNode(), opBGP.getPattern()) ;
     }
-
-    @Override
-    public Op transform(OpExt opExt) {
-        return opExt.apply(this, beforeVisitor, afterVisitor) ;
-    }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadGraph.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadGraph.java
index 07c2c0e..6616342 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadGraph.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/TransformQuadGraph.java
@@ -23,6 +23,7 @@
 import org.apache.jena.graph.Node ;
 import org.apache.jena.sparql.algebra.AlgebraQuad.QuadSlot ;
 import org.apache.jena.sparql.algebra.op.* ;
+import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.sparql.core.Var ;
 import org.apache.jena.sparql.expr.ExprVar ;
 
@@ -42,13 +43,10 @@
         this.afterVisitor = after ;
     }
 
-    private Node getNode() { return tracker.peek().rewriteGraphName ; }
+    protected Node getNode() { return tracker.peek().rewriteGraphName ; }
 
     @Override
     public Op transform(OpGraph opGraph, Op op) {
-
-        //System.err.println("transform(OpGraph)\n"+opGraph+op) ;
-
         // ?? Could just leave the (graph) in place always - just rewrite BGPs.
         boolean noPattern = false ;
 
@@ -106,9 +104,13 @@
     }
 
     @Override
+    public Op transform(OpFind opFind) {
+        // Put the (graph) back round it so FIND works on the named graph.
+        return new OpGraph(getNode() , opFind) ;
+    }
+
+    @Override
     public Op transform(OpPath opPath) {
-        // Put the (graph) back round it
-        // ?? inc default graph node.
         return new OpGraph(getNode() , opPath) ;
         // Does not get removed by transform above because this is
         // not the OpGraph that gets walked by the transform.
@@ -116,11 +118,15 @@
 
     @Override
     public Op transform(OpBGP opBGP) {
-        //System.out.print("transform(OpBGP) : "+getNode()+"\n"+opBGP) ;
         return new OpQuadPattern(getNode(), opBGP.getPattern()) ;
     }
 
     @Override
+    public Op transform(OpTriple opTriple) {
+        return new OpQuad(Quad.create(getNode(), opTriple.getTriple())); 
+    }
+
+    @Override
     public Op transform(OpExt opExt) {
         return opExt.apply(this, beforeVisitor, afterVisitor) ;
     }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBase.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBase.java
index 1dc5180..116456d 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBase.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/op/OpBase.java
@@ -58,8 +58,8 @@
             out.ensureStartOfLine() ;
     }
 
-    // Constants used in hashing to stop an element and it's subelement
-    // (if just one) having the same hash.  That isn't usualy any problem but
+    // Constants used in hashing to stop an element and it's sub-element
+    // (if just one) having the same hash.  That isn't usually any problem but
     // it's easy to avoid so we do.
     
     static final int HashBasicGraphPattern      = 0xB1 ;
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/optimize/TransformPattern2Join.java b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/optimize/TransformPattern2Join.java
index 5c4902f..fc48dc4 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/algebra/optimize/TransformPattern2Join.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/algebra/optimize/TransformPattern2Join.java
@@ -33,7 +33,7 @@
 {
     /*
      * Get standard shaped trees?
-     * Alternative is hard flatteniing to (sequence of all the quads, triples) 
+     * Alternative is hard flattening to (sequence of all the quads, triples) 
      */
     
     @Override
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/core/VarAlloc.java b/jena-arq/src/main/java/org/apache/jena/sparql/core/VarAlloc.java
index 2c3f4c8..09a8cc3 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/core/VarAlloc.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/core/VarAlloc.java
@@ -18,7 +18,6 @@
 
 package org.apache.jena.sparql.core;
 
-import org.apache.jena.sparql.ARQConstants ;
 import org.apache.jena.sparql.util.Context ;
 import org.apache.jena.sparql.util.Symbol ;
 
@@ -31,20 +30,16 @@
 
     // Globals
     // Try to avoid their use because of clashes/very large allocated names.
-    //private static VarAlloc varAnonAllocator  = new VarAlloc(ARQConstants.allocGlobalVarAnonMarker) ;
-    //public static VarAlloc getVarAnonAllocator() { return bNodeAllocator ; }
 
-    private static VarAlloc varAllocator    = new VarAlloc(ARQConstants.allocGlobalVarMarker) ;
-    public static VarAlloc getVarAllocator() { return varAllocator ; }
+//    private static VarAlloc varGlobalAllocator    = new VarAlloc(ARQConstants.allocGlobalVarMarker) ;
+//    public static VarAlloc getVarGlobalAllocator() { return varGlobalAllocator ; }
 
-    public static VarAlloc get(Context context, Symbol name)
-    {
-        return (VarAlloc)context.get(name) ;
+    public static VarAlloc get(Context context, Symbol name) {
+        return (VarAlloc)context.get(name);
     }
 
-    public VarAlloc(String baseMarker)
-    {
-        this.baseMarker = baseMarker ;
+    public VarAlloc(String baseMarker) {
+        this.baseMarker = baseMarker;
     }
 
     public Var allocVar()
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/QueryIterAddTripleTerm.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/QueryIterAddTripleTerm.java
index df3f490..114e73a 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/QueryIterAddTripleTerm.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/QueryIterAddTripleTerm.java
@@ -37,22 +37,35 @@
  * with terms from the current binding. It is an error not to have substitutions for
  * all variables and results in the original binding unchanged.
  */
-public class QueryIterAddTripleTerm extends QueryIterConvert {
+public class QueryIterAddTripleTerm extends QueryIterProcessBinding {
     private final Triple triple;
     private final Var    var;
 
     public QueryIterAddTripleTerm(QueryIterator chain, Var var, Triple triple, ExecutionContext execContext) {
-        super(chain, b->convert(var, triple, b), execContext);
+        super(chain, execContext);
         this.triple = triple;
         this.var = var;
     }
 
+    @Override
+    public Binding accept(Binding binding) {
+        return convert(var, triple, binding);
+    }
+
     private static Binding convert(Var var, Triple triple, Binding binding) {
         Triple matchedTriple = Substitute.substitute(triple, binding);
         if ( ! matchedTriple.isConcrete() )
             // Not all concrete terms.
-            return binding;
+            return null;
         Node nt = NodeFactory.createTripleNode(matchedTriple);
+        // This makes it a filter. Syntactically not allowed but execution support
+        // "AS ?t" for existing ?t where it must be the same RDF term.
+        if ( binding.contains(var) ) {
+            Node nt2 = binding.get(var);
+            if ( ! nt.equals(nt2) )
+                return null;
+            return binding;
+        }
         Binding b = BindingFactory.binding(binding, var, nt);
         return b;
     }
@@ -61,4 +74,5 @@
     protected void details(IndentedWriter out, SerializationContext sCxt) {
         out.print(this.getClass().getSimpleName()+": ["+var+"] " + triple);
     }
+
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/RX.java b/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/RX.java
index 9f1a661..9e6184f 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/RX.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/engine/iterator/RX.java
@@ -23,10 +23,12 @@
 import org.apache.jena.atlas.lib.Pair;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.ARQConstants;
 import org.apache.jena.sparql.core.Var;
 import org.apache.jena.sparql.core.VarAlloc;
 import org.apache.jena.sparql.engine.ExecutionContext;
 import org.apache.jena.sparql.engine.QueryIterator;
+import org.apache.jena.sparql.util.Context;
 
 /**
  * Solver library for RDF*.
@@ -42,9 +44,6 @@
  * {@code FIND(<<...>> AS ?t)}.
  */
 public class RX {
-    // From context?
-    static String allocTripleTerms = "*";
-    static VarAlloc varAlloc = new VarAlloc(allocTripleTerms) ;
 
     /**
      * Match a single triple pattern that may involve RDF* terms.
@@ -61,14 +60,23 @@
      * </pre>
      */
     public static QueryIterator rdfStarTriple(QueryIterator chain, Triple triple, ExecutionContext execCxt) {
-        // Should all work without this trap for plain RDF but for now,
-        // fast track the non-RDF* case.
+        // Should all work without this trap for plain RDF.
         if ( ! tripleHasNodeTriple(triple) )
             // No RDF* : direct to data.
             return matchData(chain, triple, execCxt);
         return rdfStarTripleSub(chain, triple, execCxt);
     }
 
+    private static VarAlloc varAlloc(ExecutionContext execCxt) {
+        Context context = execCxt.getContext();
+        VarAlloc varAlloc = VarAlloc.get(context, ARQConstants.sysVarAllocRDFStar);
+        if ( varAlloc == null ) {
+            varAlloc = new VarAlloc(ARQConstants.allocVarTripleTerm);
+            context.set(ARQConstants.sysVarAllocRDFStar, varAlloc);  
+        }
+        return varAlloc;
+    }
+
     /**
      * Insert the stages necessary for a triple with triple pattern term inside it.
      * If the triple pattern has a triple term, possibly with variables, introduce
@@ -112,14 +120,14 @@
         // Recurse.
         if ( s.isNodeTriple() && ! s.isConcrete() ) {
             Triple t2 = triple(s);
-            Var var = varAlloc.allocVar();
+            Var var = varAlloc(execCxt).allocVar();
             Triple tripleTerm = Triple.create(t2.getSubject(), t2.getPredicate(), t2.getObject());
             chain = matchTripleStar(chain, var, tripleTerm, execCxt);
             s1 = var;
         }
         if ( o.isNodeTriple() && ! o.isConcrete() ) {
             Triple t2 = triple(o);
-            Var var = varAlloc.allocVar();
+            Var var = varAlloc(execCxt).allocVar();
             Triple tripleTerm = Triple.create(t2.getSubject(), t2.getPredicate(), t2.getObject());
             chain = matchTripleStar(chain, var, tripleTerm, execCxt);
             o1 = var;
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java b/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java
index 0921892..c185365 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/function/FunctionRegistry.java
@@ -42,7 +42,7 @@
     }
 
     public static void init() {
-        // Intialize if there is no registry already set 
+        // Initialize if there is no registry already set 
         FunctionRegistry reg = new FunctionRegistry() ;
         ARQFunctions.load(reg);
         StandardFunctions.loadStdDefs(reg) ;
@@ -51,7 +51,7 @@
     
     public static FunctionRegistry get()
     {
-        // Intialize if there is no registry already set 
+        // Initialize if there is no registry already set 
         FunctionRegistry reg = get(ARQ.getContext()) ;
         if ( reg == null )
         {
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/lang/SyntaxVarScope.java b/jena-arq/src/main/java/org/apache/jena/sparql/lang/SyntaxVarScope.java
index 325419a..3c81961 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/lang/SyntaxVarScope.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/lang/SyntaxVarScope.java
@@ -18,295 +18,257 @@
 
 package org.apache.jena.sparql.lang;
 
-import java.util.* ;
+import java.util.*;
 
-import org.apache.jena.query.ARQ ;
-import org.apache.jena.query.Query ;
-import org.apache.jena.query.QueryParseException ;
-import org.apache.jena.query.Syntax ;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.core.VarExprList ;
-import org.apache.jena.sparql.expr.Expr ;
-import org.apache.jena.sparql.syntax.* ;
+import org.apache.jena.query.ARQ;
+import org.apache.jena.query.Query;
+import org.apache.jena.query.QueryParseException;
+import org.apache.jena.query.Syntax;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.core.VarExprList;
+import org.apache.jena.sparql.expr.Expr;
+import org.apache.jena.sparql.syntax.*;
 
-/** Calculate in-scope variables from the AST */ 
-public class SyntaxVarScope
-{
-    /* SPARQL 1.1 "in scope" rules
-       These define the variables from a pattern that are in-scope
-       These are not the usage rules.
-         
-    Syntax Form                                     In-scope variables
-    
-    Basic Graph Pattern (BGP)                       v occurs in the BGP
-    Path                                            v occurs in the path
-    Group { P1 P2 ... }                             v is in-scope if in-scope in one or more of P1, P2, ...
-    GRAPH term { P }                                v is term or v is in-scope in P
-    { P1 } UNION { P2 }                             v is in-scope in P1 or in-scope in P2
-    OPTIONAL {P}                                    v is in-scope in P
-    SERVICE term {P}                                v is term or v is in-scope in P
-    (expr AS v) for BIND, SELECT and GROUP BY       v is in-scope
-    SELECT ..v .. { P }                             v is in-scope if v is mentioned as a project variable
-    SELECT * { P }                                  v is in-scope in P
-    VALUES var     (values)                         v is in-scope if v is in varlist
-    VALUES varlist (values)                         v is in-scope if v is in varlist
-     */
-    
+/** Calculate in-scope variables from the AST */
+public class SyntaxVarScope {
+    /* SPARQL 1.1 "in scope" rules These define the variables from a pattern that are
+     * in-scope These are not the usage rules.
+     * 
+     * Syntax Form In-scope variables
+     * 
+     * Basic Graph Pattern (BGP) v occurs in the BGP Path v occurs in the path Group
+     * { P1 P2 ... } v is in-scope if in-scope in one or more of P1, P2, ... GRAPH
+     * term { P } v is term or v is in-scope in P { P1 } UNION { P2 } v is in-scope
+     * in P1 or in-scope in P2 OPTIONAL {P} v is in-scope in P SERVICE term {P} v is
+     * term or v is in-scope in P (expr AS v) for BIND, SELECT and GROUP BY v is
+     * in-scope SELECT ..v .. { P } v is in-scope if v is mentioned as a project
+     * variable SELECT * { P } v is in-scope in P VALUES var (values) v is in-scope
+     * if v is in varlist VALUES varlist (values) v is in-scope if v is in varlist */
+
     // Weakness : EXISTS inside FILTERs?
 
-    public static void check(Query query)
-    {
+    public static void check(Query query) {
         if ( query.getQueryPattern() == null )
             // DESCRIBE may not have a pattern
-            return ;
-        check(query.getQueryPattern()) ;
+            return;
+        check(query.getQueryPattern());
         // Check this level.
-        checkQueryScope(query) ;
+        checkQueryScope(query);
         // Other checks.
-        Collection<Var> vars = varsOfQuery(query) ;
-        check(query, vars) ;
+        Collection<Var> vars = varsOfQuery(query);
+        check(query, vars);
     }
 
     public static void check(Element queryPattern) {
-        checkSubQuery(queryPattern) ;
-        checkBind(queryPattern);
+        checkSubQuery(queryPattern);
+        checkPatternAssign(queryPattern);
     }
 
-    // Check BIND by accumulating variables and making sure BIND does not attempt to reuse one  
-    private static void checkBind(Element queryPattern)
-    {
-        BindScopeChecker v = new BindScopeChecker() ;
-        ElementWalker.walk(queryPattern, v) ;
+    // Check assignment forms that require a new variable.  
+    // BIND and FIND
+    private static void checkPatternAssign(Element queryPattern) {
+        VarScopeChecker v = new VarScopeChecker();
+        ElementWalker.walk(queryPattern, v);
     }
-    
-    // Check subquery by finding subquries and recurisively checking.
-    // Includes appling all checks to nested subqueries.
-    private static void checkSubQuery(Element el)
-    {
-        ElementVisitor v = new SubQueryScopeChecker() ;
-        ElementWalker.walk(el, v) ;
+
+    // Check sub-query by finding sub-queries and recursively checking.
+    // Includes applying all checks to nested sub-queries.
+    private static void checkSubQuery(Element el) {
+        ElementVisitor v = new SubQueryScopeChecker();
+        ElementWalker.walk(el, v);
     }
-    
+
     // Check one level of query - SELECT expressions
-    private static void checkQueryScope(Query query)
-    {
-        Collection<Var> vars = varsOfQuery(query) ;
-        checkExprListAssignment(vars, query.getProject()) ;
+    private static void checkQueryScope(Query query) {
+        Collection<Var> vars = varsOfQuery(query);
+        checkExprListAssignment(vars, query.getProject());
     }
-    
+
     // get all vars of a query
-    private static Collection<Var> varsOfQuery(Query query)
-    {
-        Collection<Var> vars = PatternVars.vars(query.getQueryPattern()) ;
+    private static Collection<Var> varsOfQuery(Query query) {
+        Collection<Var> vars = PatternVars.vars(query.getQueryPattern());
         if ( query.hasValues() )
-            vars.addAll(query.getValuesVariables()) ;
-        return vars ;
+            vars.addAll(query.getValuesVariables());
+        return vars;
     }
-    
+
     // Other check (not scoping at this level) of a query
-    private static void check(Query query, Collection<Var> vars)
-    {
+    private static void check(Query query, Collection<Var> vars) {
         // Check any expressions are assigned to fresh variables.
-        checkExprListAssignment(vars, query.getProject()) ;
-        
+        checkExprListAssignment(vars, query.getProject());
+
         // Check for SELECT * GROUP BY
         // Legal in ARQ, not in SPARQL 1.1
-        if ( ! Syntax.syntaxARQ.equals(query.getSyntax()) )
-        {
+        if ( !Syntax.syntaxARQ.equals(query.getSyntax()) ) {
             if ( query.isQueryResultStar() && query.hasGroupBy() )
-                throw new QueryParseException("SELECT * not legal with GROUP BY", -1 , -1) ;
+                throw new QueryParseException("SELECT * not legal with GROUP BY", -1, -1);
         }
-        
-        // Check any variable in an expression is in scope (if GROUP BY) 
-        checkExprVarUse(query) ;
-        
-        // Check GROUP BY AS 
+
+        // Check any variable in an expression is in scope (if GROUP BY)
+        checkExprVarUse(query);
+
+        // Check GROUP BY AS
         // ENABLE
-        if ( false && query.hasGroupBy() )
-        {
-            VarExprList exprList2 = query.getGroupBy() ;
-            checkExprListAssignment(vars, exprList2) ;
-        // CHECK 
+        if ( false && query.hasGroupBy() ) {
+            VarExprList exprList2 = query.getGroupBy();
+            checkExprListAssignment(vars, exprList2);
+            // CHECK
         }
-        
     }
-    
-    private static void checkExprListAssignment(Collection<Var> vars, VarExprList exprList)
-    {
-        Set<Var> vars2 = new LinkedHashSet<>(vars) ;
-        exprList.forEachExpr((v,e) -> {
-            Set<Var> varInExpr = e.getVarsMentioned() ;
+
+    private static void checkExprListAssignment(Collection<Var> vars, VarExprList exprList) {
+        Set<Var> vars2 = new LinkedHashSet<>(vars);
+        exprList.forEachExpr((v, e) -> {
+            Set<Var> varInExpr = e.getVarsMentioned();
             // Include mentioned variables
             // These may be unused in the query (in vars) but still contribute.
-            vars2.addAll(varInExpr) ;
-            checkAssignment( vars2, e, v );
-            vars2.add( v );
-        }) ;
+            vars2.addAll(varInExpr);
+            checkExpr(vars2, e, v);
+            vars2.add(v);
+        });
     }
-    
-    private static void checkExprVarUse(Query query)
-    {
-        if ( query.hasGroupBy() )
-        {
-            VarExprList groupKey = query.getGroupBy() ;
-            
-            // Copy - we need to add variables
-            // SELECT (count(*) AS ?C)  (?C+1 as ?D) 
-            List<Var> inScopeVars = new ArrayList<>(groupKey.getVars()) ;
-            VarExprList exprList = query.getProject() ;
 
-            for ( Var v : exprList.getVars() )
-            {
+    private static void checkExprVarUse(Query query) {
+        if ( query.hasGroupBy() ) {
+            VarExprList groupKey = query.getGroupBy();
+
+            // Copy - we need to add variables
+            // SELECT (count(*) AS ?C) (?C+1 as ?D)
+            List<Var> inScopeVars = new ArrayList<>(groupKey.getVars());
+            VarExprList exprList = query.getProject();
+
+            for ( Var v : exprList.getVars() ) {
                 // In scope?
-                Expr e = exprList.getExpr( v );
-                if ( e == null )
-                {
-                    if ( !inScopeVars.contains( v ) )
-                    {
-                        throw new QueryParseException( "Non-group key variable in SELECT: " + v, -1, -1 );
+                Expr e = exprList.getExpr(v);
+                if ( e == null ) {
+                    if ( !inScopeVars.contains(v) ) {
+                        throw new QueryParseException("Non-group key variable in SELECT: " + v, -1, -1);
                     }
-                }
-                else
-                {
+                } else {
                     Set<Var> eVars = e.getVarsMentioned();
-                    for ( Var v2 : eVars )
-                    {
-                        if ( !inScopeVars.contains( v2 ) )
-                        {
-                            throw new QueryParseException(
-                                "Non-group key variable in SELECT: " + v2 + " in expression " + e, -1, -1 );
+                    for ( Var v2 : eVars ) {
+                        if ( !inScopeVars.contains(v2) ) {
+                            throw new QueryParseException("Non-group key variable in SELECT: " + v2 + " in expression " + e, -1, -1);
                         }
                     }
                 }
-                inScopeVars.add( v );
+                inScopeVars.add(v);
             }
         }
     }
-    
-    private static void checkAssignment(Collection<Var> scope, Expr expr, Var var)
-    {
+
+    private static void checkExpr(Collection<Var> scope, Expr expr, Var var) {
         // Project SELECT ?x
         if ( expr == null )
-            return ;
-        
+            return;
         // expr not null
         if ( scope.contains(var) ) 
             throw new QueryParseException("Variable used when already in-scope: "+var+" in "+fmtAssignment(expr, var), -1 , -1) ;
 
         // test for impossible variables - bound() is a bit odd.
-        if ( false )
-        {
-            Set<Var> vars = expr.getVarsMentioned() ;
-            for ( Var v : vars )
-            {
+        if ( false ) {
+            Set<Var> vars = expr.getVarsMentioned();
+            for ( Var v : vars ) {
                 if ( !scope.contains(v) )
-                    throw new QueryParseException("Variable used in expression is not in-scope: "+v+" in "+expr, -1 , -1) ;
+                    throw new QueryParseException("Variable used in expression is not in-scope: " + v + " in " + expr, -1, -1);
             }
         }
     }
-    
-    private static String fmtExprList(VarExprList exprList)
-    {
-        StringBuilder sb = new StringBuilder() ;
-        boolean first = true ;
-        for ( Var v : exprList.getVars() )
-        {
-            Expr e = exprList.getExpr( v );
-            if ( !first )
-            {
-                sb.append( " " );
-            }
-            first = false;
-            sb.append( "(" ).append( e ).append( " AS " ).append( v ).append( ")" );
-        }
-        return sb.toString() ;
-    }
-    
-    private static String fmtAssignment(Expr expr, Var var)
-    {
-        return "("+expr+" AS "+var+")" ;
-    }
 
-    // Modifed walked for variables.
-    
+    private static String fmtExprList(VarExprList exprList) {
+        StringBuilder sb = new StringBuilder();
+        boolean first = true;
+        for ( Var v : exprList.getVars() ) {
+            Expr e = exprList.getExpr(v);
+            if ( !first ) {
+                sb.append(" ");
+            }
+            first = false;
+            sb.append("(").append(e).append(" AS ").append(v).append(")");
+        }
+        return sb.toString();
+    }
+
+    private static String fmtAssignment(Expr expr, Var var) {
+        return "(" + expr + " AS " + var + ")";
+    }
+
+    // Modified walked for variables.
+
     /** Visitor for subqueries scope rules . */
-    private static class SubQueryScopeChecker extends ElementVisitorBase
-    {
+    private static class SubQueryScopeChecker extends ElementVisitorBase {
         @Override
-        public void visit(ElementSubQuery el)
-        {
-            Query query = el.getQuery() ;
-            checkQueryScope(query) ;
+        public void visit(ElementSubQuery el) {
+            Query query = el.getQuery();
+            checkQueryScope(query);
             // Recursively check sub-queries in sub-queries.
-            check(el.getQuery()) ;
+            check(el.getQuery());
         }
     }
 
     // Applies scope rules at each point it matters.
     // Does some recalculation in nested structures.
-    
-    public static class BindScopeChecker extends ElementVisitorBase
-    {
-        public BindScopeChecker() {}
-        
+
+    public static class VarScopeChecker extends ElementVisitorBase {
+        VarScopeChecker() {}
+
         @Override
-        public void visit(ElementGroup el)
-        {
+        public void visit(ElementGroup el) {
             // BIND scope rules
             // (and service warning)
-            
-            for ( int i = 0 ; i < el.size() ; i++ )
-            {
-                Element e = el.get(i) ;
+
+            for ( int i = 0 ; i < el.size() ; i++ ) {
+                Element e = el.get(i);
                 // Tests.
-                if ( e instanceof ElementBind )
-                {
-                    Collection<Var> accScope = calcScopeAll(el.getElements(), i) ;
-                    check(accScope, (ElementBind)e) ;
+                if ( e instanceof ElementBind ) {
+                    Collection<Var> accScope = calcScopeAll(el.getElements(), i);
+                    check(accScope, (ElementBind)e);
                 }
-                
-                if ( e instanceof ElementService )
-                {
-                    Collection<Var> accScope = calcScopeAll(el.getElements(), i) ;
-                    check(accScope, (ElementService)e) ;
+
+                if ( e instanceof ElementFind ) {
+                    Collection<Var> accScope = calcScopeAll(el.getElements(), i);
+                    check(accScope, (ElementFind)e);
+                }
+
+                if ( e instanceof ElementService ) {
+                    Collection<Var> accScope = calcScopeAll(el.getElements(), i);
+                    check(accScope, (ElementService)e);
                 }
             }
         }
-        
-        private static Collection<Var> calcScopeAll(List<Element> elements, int idx)
-        {
-            return calcScope(elements, 0, idx) ;
+
+        private static Collection<Var> calcScopeAll(List<Element> elements, int idx) {
+            return calcScope(elements, 0, idx);
         }
 
         /** Calculate scope, working forwards */
-        private static Collection<Var> calcScope(List<Element> elements, int start, int finish)
-        {
-            Collection<Var> accScope = new HashSet<>() ;
-            for ( int i = start ; i < finish ; i++ )
-            {
-                Element e = elements.get(i) ;
-                PatternVars.vars(accScope, e) ;
+        private static Collection<Var> calcScope(List<Element> elements, int start, int finish) {
+            Collection<Var> accScope = new HashSet<>();
+            for ( int i = start ; i < finish ; i++ ) {
+                Element e = elements.get(i);
+                PatternVars.vars(accScope, e);
             }
-            return accScope ;
+            return accScope;
         }
 
-        // Inside filters.
-        
-        private static void check(Collection<Var> scope, ElementBind el)
-        {
-            Var var = el.getVar() ;
-            if ( scope.contains(var) ) 
-                throw new QueryParseException("BIND: Variable used when already in-scope: "+var+" in "+el, -1 , -1) ;
-            checkAssignment(scope, el.getExpr(), var) ;
+        private static void check(Collection<Var> scope, ElementBind el) {
+            Var var = el.getVar();
+            if ( scope.contains(var) )
+                throw new QueryParseException("BIND: Variable used when already in-scope: " + var + " in " + el, -1, -1);
+            checkExpr(scope, el.getExpr(), var);
         }
-        
-        private static void check(Collection<Var> scope, ElementService el)
-        {
-            if ( ARQ.isStrictMode() && el.getServiceNode().isVariable() )
-            {
-                Var var = Var.alloc(el.getServiceNode()) ;
-                if ( ! scope.contains(var) ) 
-                    throw new QueryParseException("SERVICE: Variable not already in-scope: "+var+" in "+el, -1 , -1) ;
+
+        private static void check(Collection<Var> scope, ElementFind el) {
+            Var var = el.getVar();
+            if ( scope.contains(var) )
+                throw new QueryParseException("FIND: Variable used when already in-scope: " + var + " in " + el, -1, -1);
+        }
+
+        private static void check(Collection<Var> scope, ElementService el) {
+            if ( ARQ.isStrictMode() && el.getServiceNode().isVariable() ) {
+                Var var = Var.alloc(el.getServiceNode());
+                if ( !scope.contains(var) )
+                    throw new QueryParseException("SERVICE: Variable not already in-scope: " + var + " in " + el, -1, -1);
             }
         }
     }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/NodeTransformBNodesToVariables.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/NodeTransformBNodesToVariables.java
deleted file mode 100644
index 0ae775f..0000000
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/NodeTransformBNodesToVariables.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.jena.sparql.modify;
-
-import java.util.HashMap ;
-import java.util.Map ;
-import org.apache.jena.graph.Node ;
-import org.apache.jena.sparql.ARQConstants ;
-import org.apache.jena.sparql.core.Var ;
-import org.apache.jena.sparql.core.VarAlloc ;
-import org.apache.jena.sparql.graph.NodeTransform;
-
-public class NodeTransformBNodesToVariables implements NodeTransform
-{
-    private VarAlloc varAlloc = new VarAlloc(ARQConstants.allocVarBNodeToVar) ;
-    private Map<Node, Var> mapping ;
-
-    public NodeTransformBNodesToVariables()
-    {
-        this.mapping = new HashMap<>();
-    }
-
-    @Override
-    public Node apply(Node node)
-    {
-        if ( ! node.isBlank() )
-            return node ;
-        Node node2 = mapping.get(node) ;
-        if ( node2 == null )
-        {
-            Var v = varAlloc.allocVar() ;
-            mapping.put(node, v) ;
-            node2 = v ;
-        }
-        return node2 ;
-    }
-}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateEngineWorker.java b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateEngineWorker.java
index fa8bccb..26385a0 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateEngineWorker.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/modify/UpdateEngineWorker.java
@@ -51,8 +51,6 @@
 import org.apache.jena.sparql.engine.binding.BindingRoot ;
 import org.apache.jena.sparql.graph.GraphFactory ;
 import org.apache.jena.sparql.graph.GraphOps ;
-import org.apache.jena.sparql.graph.NodeTransform;
-import org.apache.jena.sparql.graph.NodeTransformLib ;
 import org.apache.jena.sparql.modify.request.* ;
 import org.apache.jena.sparql.syntax.Element ;
 import org.apache.jena.sparql.syntax.ElementGroup ;
@@ -438,11 +436,6 @@
         return g;
     }
 
-    protected static List<Quad> unused_convertBNodesToVariables(List<Quad> quads) {
-        NodeTransform bnodesToVariables = new NodeTransformBNodesToVariables();
-        return NodeTransformLib.transformQuads(bnodesToVariables, quads);
-    }
-
     protected Element elementFromQuads(List<Quad> quads) {
         ElementGroup el = new ElementGroup();
         ElementTriplesBlock x = new ElementTriplesBlock();
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/path/PathCompiler.java b/jena-arq/src/main/java/org/apache/jena/sparql/path/PathCompiler.java
index 0d15352..ab84fd6 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/path/PathCompiler.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/path/PathCompiler.java
@@ -30,7 +30,7 @@
     // Convert to work on OpPath.
     // Need pre (and post) BGPs.
     
-    private static VarAlloc varAlloc = new VarAlloc(ARQConstants.allocVarAnonMarker+"P") ;
+    private static VarAlloc varAlloc = new VarAlloc(ARQConstants.allocPathVariables) ;
     
     // Move to AlgebraCompiler and have a per-transaction scoped var generator 
     
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java
index d0f6fae..185aa08 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/PropertyFunctionRegistry.java
@@ -117,17 +117,19 @@
     /** Lookup by URI */
     public PropertyFunctionFactory get(String uri)
     {
+        // Is it mapped?
         String mappedUri = MappedLoader.mapDynamicURI(uri) ;
         if ( mappedUri != null )
-            uri = mappedUri ; 
-        
-        PropertyFunctionFactory ext = registry.get(uri) ;
-        if ( ext != null )
-            return ext ;
-        
+            uri = mappedUri ;
+
+        // Plain registration, after mapping.
+        PropertyFunctionFactory factory = registry.get(uri) ;
+        if ( factory != null )
+            return factory;
+
         if ( attemptedLoads.contains(uri) )
             return null ;
-
+        
         Class<?> extClass = MappedLoader.loadClass(uri, PropertyFunction.class) ;
         if ( extClass == null )
             return null ;
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/StandardPropertyFunctions.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/StandardPropertyFunctions.java
index 92ee396..c06d89c 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/StandardPropertyFunctions.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/StandardPropertyFunctions.java
@@ -18,31 +18,38 @@
 
 package org.apache.jena.sparql.pfunction;
 
-import org.apache.jena.sparql.vocabulary.ListPFunction ;
+import org.apache.jena.sparql.ARQConstants;
+import org.apache.jena.sparql.pfunction.library.triple.TripleTermFind;
+import org.apache.jena.sparql.vocabulary.ListPFunction;
 import org.apache.jena.vocabulary.RDFS;
 
 public class StandardPropertyFunctions {
     @SuppressWarnings("deprecation")
     public static void loadStdDefs(PropertyFunctionRegistry registry) {
-        add(registry, ListPFunction.member.getURI() , org.apache.jena.sparql.pfunction.library.listMember.class) ;
-        add(registry, ListPFunction.index.getURI() , org.apache.jena.sparql.pfunction.library.listIndex.class) ;
-        add(registry, ListPFunction.length.getURI() , org.apache.jena.sparql.pfunction.library.listLength.class) ;
-        add(registry, ListPFunction.memberJ2.getURI() , org.apache.jena.sparql.pfunction.library.listMember.class) ;
-        add(registry, ListPFunction.indexJ2.getURI() , org.apache.jena.sparql.pfunction.library.listIndex.class) ;
-        add(registry, ListPFunction.lengthJ2.getURI() , org.apache.jena.sparql.pfunction.library.listLength.class) ;
+        add(registry, ListPFunction.member.getURI(),    org.apache.jena.sparql.pfunction.library.listMember.class);
+        add(registry, ListPFunction.index.getURI(),     org.apache.jena.sparql.pfunction.library.listIndex.class);
+        add(registry, ListPFunction.length.getURI(),    org.apache.jena.sparql.pfunction.library.listLength.class);
+        add(registry, ListPFunction.memberJ2.getURI(),  org.apache.jena.sparql.pfunction.library.listMember.class);
+        add(registry, ListPFunction.indexJ2.getURI(),   org.apache.jena.sparql.pfunction.library.listIndex.class);
+        add(registry, ListPFunction.lengthJ2.getURI(),  org.apache.jena.sparql.pfunction.library.listLength.class);
 
         // (Very) old forms
-        add(registry, ListPFunction.listMember.getURI() , org.apache.jena.sparql.pfunction.library.listMember.class) ;
-        add(registry, ListPFunction.listIndex.getURI() , org.apache.jena.sparql.pfunction.library.listIndex.class) ;
-        add(registry, ListPFunction.listLength.getURI() , org.apache.jena.sparql.pfunction.library.listLength.class) ;
-        
+        add(registry, ListPFunction.listMember.getURI(),    org.apache.jena.sparql.pfunction.library.listMember.class);
+        add(registry, ListPFunction.listIndex.getURI(),     org.apache.jena.sparql.pfunction.library.listIndex.class);
+        add(registry, ListPFunction.listLength.getURI(),    org.apache.jena.sparql.pfunction.library.listLength.class);
+
         // This is called during Jena-wide initialization.
         // Use function for constant (JENA-1294)
-        add(registry, RDFS.Init.member().getURI(), org.apache.jena.sparql.pfunction.library.container.class) ;
+        add(registry, RDFS.Init.member().getURI(), org.apache.jena.sparql.pfunction.library.container.class);
+
+        // Property function - RDF*
+//        PropertyFunctionFactory factory = (uri)->new TripleTermFind();
+//        registry.put(ARQConstants.ARQPropertyFunctionLibraryURI+"find", factory);
+        add(registry, ARQConstants.ARQPropertyFunctionLibraryURI+"find", TripleTermFind.class);
+        
     }
-    
-    private static void add(PropertyFunctionRegistry registry, String uri, Class<?> funcClass)
-    {
-        registry.put(uri, funcClass) ;
+
+    private static void add(PropertyFunctionRegistry registry, String uri, Class<? > funcClass) {
+        registry.put(uri, funcClass);
     }
 }
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/triple/TripleTermFind.java b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/triple/TripleTermFind.java
new file mode 100644
index 0000000..c033ff1
--- /dev/null
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/pfunction/library/triple/TripleTermFind.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.sparql.pfunction.library.triple;
+
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Node_Triple;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.sparql.core.Var;
+import org.apache.jena.sparql.engine.ExecutionContext;
+import org.apache.jena.sparql.engine.QueryIterator;
+import org.apache.jena.sparql.engine.binding.Binding;
+import org.apache.jena.sparql.engine.iterator.QueryIterNullIterator;
+import org.apache.jena.sparql.engine.iterator.QueryIterSingleton;
+import org.apache.jena.sparql.engine.iterator.RX;
+import org.apache.jena.sparql.expr.ExprEvalException;
+import org.apache.jena.sparql.pfunction.*;
+
+/** Property function for FIND() - allows already bound.
+ * <pre>
+ *    << ?s ?p ?o >> apf:find ?t .
+ * <pre>
+ * This binds all the variables, with <tt>?t</tt> bound to a triple term for the match of <tt>?s ?p ?o</tt>. 
+ */ 
+public class TripleTermFind extends PropertyFunctionEval {
+
+    static public void init() {
+        PropertyFunctionFactory factory = (uri)->new TripleTermFind();
+        Node uri = NodeFactory.createURI("http://arq/find");
+        PropertyFunctionRegistry.get().put(uri.getURI(), factory);
+    }
+
+    public TripleTermFind() {
+        super(PropFuncArgType.PF_ARG_SINGLE, PropFuncArgType.PF_ARG_SINGLE);
+    }
+
+    @Override
+    public QueryIterator execEvaluated(Binding binding, PropFuncArg argSubject, Node predicate, PropFuncArg argObject, ExecutionContext execCxt) {
+
+        Node sArg = argSubject.getArg();
+        if ( ! sArg.isNodeTriple() )
+            throw new ExprEvalException("Not a triple term: "+sArg);
+        Triple triple = Node_Triple.triple(sArg);
+
+        Node nAssign = argObject.getArg();
+        if ( ! Var.isVar(nAssign) ) {
+            if ( ! nAssign.isNodeTriple() )
+                return QueryIterNullIterator.create(execCxt); 
+            Triple t2 = Node_Triple.triple(nAssign);
+            if ( t2.equals(triple) )
+                return QueryIterSingleton.create(binding, execCxt);
+            return QueryIterNullIterator.create(execCxt);
+        }
+        
+        Var var = Var.alloc(nAssign);
+
+        QueryIterator input = QueryIterSingleton.create(binding, execCxt);
+
+        // This matches the triple inside the Node_Triple, recursively,
+        // and adds the binding for "(<< >> AS ?t)".
+
+        QueryIterator qIter = RX.matchTripleStar(input, var, triple, execCxt);
+        return qIter;
+    }
+}
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/sse/writers/WriterOp.java b/jena-arq/src/main/java/org/apache/jena/sparql/sse/writers/WriterOp.java
index 9c9f873..9779d85 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/sse/writers/WriterOp.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/sse/writers/WriterOp.java
@@ -240,7 +240,6 @@
             out.print(opFind.getVar());
             out.print(" ");
             formatTriple(opFind.getTriple()) ;
-            out.println() ;
             finish(opFind) ;
         }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/util/MappedLoader.java b/jena-arq/src/main/java/org/apache/jena/sparql/util/MappedLoader.java
index 9ff04aa..7be7db8 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/util/MappedLoader.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/util/MappedLoader.java
@@ -87,7 +87,6 @@
                 return e;
             }
         }
-
         return null;
     }
 
diff --git a/jena-arq/src/main/java/org/apache/jena/sparql/vocabulary/TestManifestX.java b/jena-arq/src/main/java/org/apache/jena/sparql/vocabulary/TestManifestX.java
index 677e227..1067356 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/vocabulary/TestManifestX.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/vocabulary/TestManifestX.java
@@ -67,6 +67,12 @@
     /** <p>Syntax tests (query)</p> */
     public static final Resource PositiveSyntaxTestARQ = m_model.createResource( "http://jena.hpl.hp.com/2005/05/test-manifest-extra#PositiveSyntaxTestARQ" );
     
+    /** <p>Syntax tests which expect a parse failure</p> */
+    public static final Resource NegativeUpdateSyntaxTestARQ = m_model.createResource( "http://jena.hpl.hp.com/2005/05/test-manifest-extra#NegativeUpdateSyntaxTestARQ" );
+    
+    /** <p>Syntax tests (query)</p> */
+    public static final Resource PositiveUpdateSyntaxTestARQ = m_model.createResource( "http://jena.hpl.hp.com/2005/05/test-manifest-extra#PositiveUpdateSyntaxTestARQ" );
+    
     /** <p>The class of test that are Query tests (query, data, results)</p> */
     public static final Resource TestQuery = m_model.createResource( "http://jena.hpl.hp.com/2005/05/test-manifest-extra#TestQuery" );
     
diff --git a/jena-arq/src/test/java/org/apache/jena/rdf_star/TS_RDF_Star.java b/jena-arq/src/test/java/org/apache/jena/rdf_star/TS_RDF_Star.java
index 3d68987..fdb6d84 100644
--- a/jena-arq/src/test/java/org/apache/jena/rdf_star/TS_RDF_Star.java
+++ b/jena-arq/src/test/java/org/apache/jena/rdf_star/TS_RDF_Star.java
@@ -30,7 +30,7 @@
     TestSPARQLStarParse.class,
     TestSPARQLStarExtra.class
 
-    //See also TC_Scripted SPARQL-star/manifest.ttl which run from JUnit3-centric ARQTestSuite 
+    //See also TC_Scripted SPARQL-Star/manifest.ttl which run from JUnit3-centric ARQTestSuite 
 })
 public class TS_RDF_Star {
 }
diff --git a/jena-arq/src/test/java/org/apache/jena/rdf_star/TestSPARQLStarExtra.java b/jena-arq/src/test/java/org/apache/jena/rdf_star/TestSPARQLStarExtra.java
index 5b30b42..7e39e22 100644
--- a/jena-arq/src/test/java/org/apache/jena/rdf_star/TestSPARQLStarExtra.java
+++ b/jena-arq/src/test/java/org/apache/jena/rdf_star/TestSPARQLStarExtra.java
@@ -38,4 +38,3 @@
         ResultSetFormatter.consume(rs);
     }
 }
-
diff --git a/jena-arq/src/test/java/org/apache/jena/riot/tokens/TestTokenizer.java b/jena-arq/src/test/java/org/apache/jena/riot/tokens/TestTokenizer.java
index 65ae632..019b3e1 100644
--- a/jena-arq/src/test/java/org/apache/jena/riot/tokens/TestTokenizer.java
+++ b/jena-arq/src/test/java/org/apache/jena/riot/tokens/TestTokenizer.java
@@ -666,7 +666,7 @@
 
     @Test
     public void tokenUnit_var9() {
-        tokenizeAndTestExact("?" + ARQConstants.allocVarBNodeToVar + "ABC", TokenType.VAR, ARQConstants.allocVarBNodeToVar + "ABC") ;
+        tokenizeAndTestExact("?" + ARQConstants.allocVarTripleTerm + "9", TokenType.VAR, ARQConstants.allocVarTripleTerm + "9") ;
     }
 
     @Test
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/TC_Scripted.java b/jena-arq/src/test/java/org/apache/jena/sparql/TC_Scripted.java
index 6b18f7b..c9a6351 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/TC_Scripted.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/TC_Scripted.java
@@ -34,9 +34,8 @@
         ts.addTest(ScriptTestSuiteFactory.make(ARQTestSuite.testDirARQ+"/Serialization/manifest.ttl")) ;
         
         String testDirRDFStar = "testing/ARQ/RDF-Star";
-        ts.addTest(FactoryTestRiot.make(testDirRDFStar+"/Turtle-star/manifest.ttl"));
-        ts.addTest(ScriptTestSuiteFactory.make(testDirRDFStar+"/SPARQL-star/manifest.ttl")) ;
-
+        ts.addTest(FactoryTestRiot.make(testDirRDFStar+"/Turtle-Star/manifest.ttl"));
+        ts.addTest(ScriptTestSuiteFactory.make(testDirRDFStar+"/SPARQL-Star/manifest.ttl")) ;
         
         return ts ;
     }
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/junit/ScriptTestSuiteFactory.java b/jena-arq/src/test/java/org/apache/jena/sparql/junit/ScriptTestSuiteFactory.java
index a054fb7..065f16c 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/junit/ScriptTestSuiteFactory.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/junit/ScriptTestSuiteFactory.java
@@ -106,8 +106,13 @@
             // ---- Update tests
             if ( testType.equals(TestManifest_11.PositiveUpdateSyntaxTest11) )
                 return new SyntaxUpdateTest(testName, results, item, true) ;
+            if ( testType.equals(TestManifestX.PositiveUpdateSyntaxTestARQ) )
+                return new SyntaxUpdateTest(testName, results, item, true) ;
+            
             if ( testType.equals(TestManifest_11.NegativeUpdateSyntaxTest11) )
                 return new SyntaxUpdateTest(testName, results, item, false) ;
+            if ( testType.equals(TestManifestX.NegativeUpdateSyntaxTestARQ) )
+                return new SyntaxUpdateTest(testName, results, item, false) ;
 
             // Two names for same thing.
             // Note item is not passed down.
diff --git a/jena-arq/src/test/java/org/apache/jena/sparql/junit/TestItem.java b/jena-arq/src/test/java/org/apache/jena/sparql/junit/TestItem.java
index eedd64e..3ff0632 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/junit/TestItem.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/junit/TestItem.java
@@ -108,7 +108,7 @@
         namedGraphURIs = new ArrayList<>() ;
         resultFile = _resultFile ;
         comment = "" ;
-        queryFileSyntax = Syntax.guessFileSyntax(_queryFile) ;
+        queryFileSyntax = guessFileSyntax(_queryFile) ;
     }
 
     public Resource getResource() {
@@ -190,6 +190,16 @@
         return buildLuceneIndex ;
     }
 
+    // *.rq is strictly SPARQL 1.1 tests.
+    protected Syntax guessFileSyntax(String filename) {
+        if ( filename.endsWith(".rq") )
+            return Syntax.syntaxSPARQL_11;
+        if ( filename.endsWith(".ru") )
+            return Syntax.syntaxSPARQL_11;
+        
+        return Syntax.guessFileSyntax(filename);
+    }
+
     private String _getName() {
         
         Statement s = testResource.getProperty(TestManifest.name) ;
@@ -299,7 +309,7 @@
         }
 
         if ( uri != null ) {
-            Syntax synFileName = Syntax.guessFileSyntax(uri) ;
+            Syntax synFileName = guessFileSyntax(uri) ;
             if ( synFileName != null )
                 return synFileName ;
         }
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data-quads.trig b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data-quads.trig
new file mode 100644
index 0000000..d03c51f
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data-quads.trig
@@ -0,0 +1,15 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+GRAPH :g1 {
+  :s :p1 :o .
+  <<:s :p1 :o>> :q1 :z1 .
+}
+
+GRAPH :g2 {
+  << <<:s :p1 :o>> :q1 :z1 >> :q1 :z1 . 
+  :s :p2 :o .
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/data1.ttl b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data1.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/data1.ttl
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data1.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/data2.ttl b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data2.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/data2.ttl
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data2.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data3.ttl b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data3.ttl
new file mode 100644
index 0000000..a3e864f
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/data3.ttl
@@ -0,0 +1,10 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+:s :p1 :o .
+<<:s :p1 :o>> :q1 :z1 .
+<< <<:s :p1 :o>> :q1 :z1 >> :q1 :z1 . 
+:s :p2 :o .
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/manifest.ttl b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/manifest.ttl
similarity index 64%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/manifest.ttl
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/manifest.ttl
index 55703b1..e9eb664 100644
--- a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/manifest.ttl
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/manifest.ttl
@@ -28,84 +28,106 @@
         :sparql-star-syntax-2
         :sparql-star-syntax-3
         :sparql-star-syntax-4
+        :sparql-star-syntax-5
 
         :sparql-star-bad-syntax-1
         :sparql-star-bad-syntax-2
         :sparql-star-bad-syntax-3
         :sparql-star-bad-syntax-4
+        :sparql-star-bad-syntax-5
 
         :sparql-star-basic-1
         :sparql-star-basic-2
         :sparql-star-basic-3
         :sparql-star-basic-4
 
-        :sparql-pattern-1
-        :sparql-pattern-2
-        :sparql-pattern-3
-        :sparql-pattern-4
-        :sparql-pattern-5
-        :sparql-pattern-6
-        :sparql-pattern-7
-        :sparql-pattern-8
+        :sparql-star-pattern-1
+        :sparql-star-pattern-2
+        :sparql-star-pattern-3
+        :sparql-star-pattern-4
+        :sparql-star-pattern-5
+        :sparql-star-pattern-6
+        :sparql-star-pattern-7
+        :sparql-star-pattern-8
 
-        :sparql-update-syntax-1
-        :sparql-update-syntax-2
-        :sparql-update-bad-syntax-1
-        :sparql-update-bad-syntax-2
+        :sparql-star-find-1
+
+        :sparql-star-update-syntax-1
+        :sparql-star-update-syntax-2
+        :sparql-star-update-bad-syntax-1
+        :sparql-star-update-bad-syntax-2
+
+        :sparql-star-union-1
+        :sparql-star-union-2
+
+        :sparql-star-named-graph-1
+        :sparql-star-named-graph-2
     ) .
 
 ## Good syntax
 
 :sparql-star-syntax-1
-    rdf:type   mf:PositiveSyntaxTest11 ;
+    rdf:type   mfx:PositiveSyntaxTestARQ ;
     mf:name    "sparql-star-syntax-01.arq" ;
     mf:action  <sparql-star-syntax-01.arq>
     .
 
 :sparql-star-syntax-2
-    rdf:type   mf:PositiveSyntaxTest11 ;
+    rdf:type   mfx:PositiveSyntaxTestARQ ;
     mf:name    "sparql-star-syntax-02.arq" ;
     mf:action  <sparql-star-syntax-02.arq>
     .
 
 :sparql-star-syntax-3
-    rdf:type   mf:PositiveSyntaxTest11 ;
+    rdf:type   mfx:PositiveSyntaxTestARQ ;
     mf:name    "sparql-star-syntax-03.arq" ;
     mf:action  <sparql-star-syntax-03.arq>
     .
 
 :sparql-star-syntax-4
-    rdf:type   mf:PositiveSyntaxTest11 ;
+    rdf:type   mfx:PositiveSyntaxTestARQ ;
     mf:name    "sparql-star-syntax-04.arq" ;
     mf:action  <sparql-star-syntax-04.arq>
     .
 
+:sparql-star-syntax-5
+    rdf:type   mfx:PositiveSyntaxTestARQ ;
+    mf:name    "sparql-star-syntax-05.arq" ;
+    mf:action  <sparql-star-syntax-05.arq>
+    .
+
 ## Bad syntax
 
 :sparql-star-bad-syntax-1
-    rdf:type   mf:NegativeSyntaxTest11 ;
+    rdf:type   mfx:NegativeSyntaxTestARQ ;
     mf:name    "sparql-star-bad-syntax-01" ;
     mf:action  <sparql-star-bad-syntax-01.arq>
     .
 
 :sparql-star-bad-syntax-2
-    rdf:type   mf:NegativeSyntaxTest11 ;
+    rdf:type   mfx:NegativeSyntaxTestARQ ;
     mf:name    "sparql-star-bad-syntax-02" ;
     mf:action  <sparql-star-bad-syntax-02.arq>
     .
 
 :sparql-star-bad-syntax-3
-    rdf:type   mf:NegativeSyntaxTest11 ;
+    rdf:type   mfx:NegativeSyntaxTestARQ ;
     mf:name    "sparql-star-bad-syntax-03" ;
     mf:action  <sparql-star-bad-syntax-03.arq>
     .
 
 :sparql-star-bad-syntax-4
-    rdf:type   mf:NegativeSyntaxTest11 ;
+    rdf:type   mfx:NegativeSyntaxTestARQ ;
     mf:name    "sparql-star-bad-syntax-04" ;
     mf:action  <sparql-star-bad-syntax-04.arq>
     .
 
+:sparql-star-bad-syntax-5
+    rdf:type   mfx:NegativeSyntaxTestARQ ;
+    mf:name    "sparql-star-bad-syntax-05" ;
+    mf:action  <sparql-star-bad-syntax-05.arq>
+    .
+
 ## Execution - one triple pattern, no nesting
 
 :sparql-star-basic-1
@@ -142,7 +164,7 @@
 
 ## Execution - patterns
 
-:sparql-pattern-1
+:sparql-star-pattern-1
     mf:name    "SPARQL* - Pattern - 1" ;
     mf:action
         [ qt:query  <sparql-star-pattern-01.arq> ;
@@ -150,7 +172,7 @@
     mf:result  <sparql-star-pattern-01.srj>
 .
 
-:sparql-pattern-2
+:sparql-star-pattern-2
     mf:name    "SPARQL* - Pattern - 2" ;
     mf:action
         [ qt:query  <sparql-star-pattern-02.arq> ;
@@ -158,7 +180,7 @@
     mf:result  <sparql-star-pattern-02.srj>
 .
 
-:sparql-pattern-3
+:sparql-star-pattern-3
     mf:name    "SPARQL* - Pattern - Variable for triple term" ;
     mf:action
         [ qt:query  <sparql-star-pattern-03.arq> ;
@@ -166,7 +188,7 @@
     mf:result  <sparql-star-pattern-03.srj>
 .
 
-:sparql-pattern-4
+:sparql-star-pattern-4
     mf:name    "SPARQL* - Pattern - No match" ;
     mf:action
         [ qt:query  <sparql-star-pattern-04.arq> ;
@@ -174,7 +196,7 @@
     mf:result  <sparql-star-pattern-04.srj>
 .
 
-:sparql-pattern-5
+:sparql-star-pattern-5
     mf:name    "SPARQL* - Pattern - match variables in triple terms" ;
     mf:action
         [ qt:query  <sparql-star-pattern-05.arq> ;
@@ -182,7 +204,7 @@
     mf:result  <sparql-star-pattern-05.srj>
 .
 
-:sparql-pattern-6
+:sparql-star-pattern-6
     mf:name    "SPARQL* - Pattern - Nesting 1" ;
     mf:action
         [ qt:query  <sparql-star-pattern-06.arq> ;
@@ -190,7 +212,7 @@
     mf:result  <sparql-star-pattern-06.srj>
 .
 
-:sparql-pattern-7
+:sparql-star-pattern-7
     mf:name    "SPARQL* - Pattern - Nesting - 2" ;
     mf:action
         [ qt:query  <sparql-star-pattern-07.arq> ;
@@ -198,7 +220,7 @@
     mf:result  <sparql-star-pattern-07.srj>
 .
 
-:sparql-pattern-8
+:sparql-star-pattern-8
     mf:name    "SPARQL* - Pattern - Match and nesting" ;
     mf:action
         [ qt:query  <sparql-star-pattern-08.arq> ;
@@ -206,28 +228,78 @@
     mf:result  <sparql-star-pattern-08.srj>
 .
 
+:sparql-star-pattern-9
+    mf:name    "SPARQL* - Pattern - No Match" ;
+    mf:action
+        [ qt:query  <sparql-star-pattern-09.arq> ;
+          qt:data   <data2.ttl> ] ;
+    mf:result  <sparql-star-pattern-09.srj>
+.
+
+## SPARQL FIND*
+
+:sparql-star-find-1
+    mf:name    "SPARQL* - FIND - 1" ;
+    mf:action
+        [ qt:query  <sparql-star-find-01.arq> ;
+          qt:data   <data3.ttl> ] ;
+    mf:result  <sparql-star-find-01.srj>
+.
+
 ## SPARQL* Update
 
-:sparql-update-syntax-1
-    rdf:type mf:PositiveUpdateSyntaxTest11;
+:sparql-star-update-syntax-1
+    rdf:type mfx:PositiveUpdateSyntaxTestARQ;
     mf:name    "sparql-star-update-syntax-01" ;
     mf:action  <sparql-star-update-syntax-01.aru>
     .
     
-:sparql-update-syntax-2
-    rdf:type mf:PositiveUpdateSyntaxTest11;
+:sparql-star-update-syntax-2
+    rdf:type mfx:PositiveUpdateSyntaxTestARQ;
     mf:name    "sparql-star-update-syntax-02" ;
     mf:action  <sparql-star-update-syntax-02.aru>
     .
     
-:sparql-update-bad-syntax-1
-    rdf:type mf:NegativeUpdateSyntaxTest11;
+:sparql-star-update-bad-syntax-1
+    rdf:type mfx:NegativeUpdateSyntaxTestARQ;
     mf:name    "sparql-star-update-bad-syntax-01" ;
     mf:action  <sparql-star-update-bad-syntax-01.aru>
     .
     
-:sparql-update-bad-syntax-2
-    rdf:type mf:NegativeUpdateSyntaxTest11;
+:sparql-star-update-bad-syntax-2
+    rdf:type mfx:NegativeUpdateSyntaxTestARQ;
     mf:name    "sparql-star-update-bad-syntax-02" ;
     mf:action  <sparql-star-update-bad-syntax-02.aru>
     .
+
+:sparql-star-union-1
+    mf:name    "SPARQL* - Pattern - union graph" ;
+    mf:action
+        [ qt:query  <sparql-star-union-1.arq> ;
+          qt:data   <data-quads.trig> ] ;
+    mf:result  <sparql-star-union-1.srj>
+.
+
+:sparql-star-union-2
+    mf:name    "SPARQL* - Pattern - union graph" ;
+    mf:action
+        [ qt:query  <sparql-star-union-2.arq> ;
+          qt:data   <data-quads.trig> ] ;
+    mf:result  <sparql-star-union-2.srj>
+.
+
+:sparql-star-named-graph-1
+    mf:name    "SPARQL* - Pattern - named graph" ;
+    mf:action
+        [ qt:query  <sparql-star-named-graph-1.arq> ;
+          qt:data   <data-quads.trig> ] ;
+    mf:result  <sparql-star-named-graph-1.srj>
+.
+
+:sparql-star-named-graph-2
+    mf:name    "SPARQL* - FIND - named graph" ;
+    mf:action
+        [ qt:query  <sparql-star-named-graph-2.arq> ;
+          qt:data   <data-quads.trig> ] ;
+    mf:result  <sparql-star-named-graph-2.srj>
+.
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-01.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-01.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-01.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-01.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-02.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-02.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-02.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-02.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-03.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-03.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-03.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-03.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-04.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-04.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-bad-syntax-04.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-04.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-05.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-05.arq
new file mode 100644
index 0000000..4190765
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-bad-syntax-05.arq
@@ -0,0 +1,10 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+    ?t ?p ?o .
+    FIND ( << :s :p1 :o >> as ?t )
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-1.rq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-1.rq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-1.rq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-1.rq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-1.srx b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-1.srx
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-1.srx
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-1.srx
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-2.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-2.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-2.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-2.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-2.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-2.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-2.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-2.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-3.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-3.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-3.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-3.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-3.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-3.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-3.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-3.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-4.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-4.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-4.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-4.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-4.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-4.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-basic-4.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-basic-4.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-01.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-01.arq
new file mode 100644
index 0000000..4bb8a65
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-01.arq
@@ -0,0 +1,10 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+    FIND ( << :s :p1 :o >> as ?t )
+    ?t ?p ?o .
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-01.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-01.srj
new file mode 100644
index 0000000..bf7c1eb
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-01.srj
@@ -0,0 +1,20 @@
+{ "head": {
+    "vars": [ "t" , "p" , "o" ]
+  } ,
+  "results": {
+    "bindings": [
+      { 
+        "t": {
+          "type": "triple" , 
+          "value": {
+            "subject":  { "type": "uri" , "value": "http://example/s" } ,
+            "property": { "type": "uri" , "value": "http://example/p1" } ,
+            "object":   { "type": "uri" , "value": "http://example/o" }
+          }
+        } ,
+        "p": { "type": "uri" , "value": "http://example/q1" } ,
+        "o": { "type": "uri" , "value": "http://example/z1" }
+      }
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-02.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-02.arq
new file mode 100644
index 0000000..61a5071
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-02.arq
@@ -0,0 +1,11 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+    ?s :p1 ?o .
+    BIND ( ?p1 AS ?p )
+    FIND ( << ?s ?p ?o >> as ?t )
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-02.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-02.srj
new file mode 100644
index 0000000..a5f1a3d
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-find-02.srj
@@ -0,0 +1,34 @@
+{ "head": {
+    "vars": [ "s" , "o" , "p" , "t" ]
+  } ,
+  "results": {
+    "bindings": [
+      { 
+        "s": { "type": "uri" , "value": "http://example/s" } ,
+        "o": { "type": "uri" , "value": "http://example/o" } ,
+        "p": { "type": "uri" , "value": "http://example/p2" } ,
+        "t": {
+          "type": "triple" , 
+          "value": {
+            "subject":  { "type": "uri" , "value": "http://example/s" } ,
+            "property": { "type": "uri" , "value": "http://example/p2" } ,
+            "object":   { "type": "uri" , "value": "http://example/o" }
+          }
+        }
+      } ,
+      { 
+        "s": { "type": "uri" , "value": "http://example/s" } ,
+        "o": { "type": "uri" , "value": "http://example/o" } ,
+        "p": { "type": "uri" , "value": "http://example/p1" } ,
+        "t": {
+          "type": "triple" , 
+          "value": {
+            "subject":  { "type": "uri" , "value": "http://example/s" } ,
+            "property": { "type": "uri" , "value": "http://example/p1" } ,
+            "object":   { "type": "uri" , "value": "http://example/o" }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-1.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-1.arq
new file mode 100644
index 0000000..cb6d81a
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-1.arq
@@ -0,0 +1,12 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+  GRAPH :g1 {
+    FIND(<<?s ?p ?o >> AS ?t )
+  }
+}
+
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-1.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-1.srj
new file mode 100644
index 0000000..96fbcca
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-1.srj
@@ -0,0 +1,48 @@
+{ "head": {
+    "vars": [ "t" , "s" , "p" , "o" ]
+  } ,
+  "results": {
+    "bindings": [
+      { 
+        "t": {
+          "type": "triple" , 
+          "value": {
+            "subject":  {
+              "type": "triple" , 
+              "value": {
+                "subject":  { "type": "uri" , "value": "http://example/s" } ,
+                "property": { "type": "uri" , "value": "http://example/p1" } ,
+                "object":   { "type": "uri" , "value": "http://example/o" }
+              }
+            } ,
+            "property": { "type": "uri" , "value": "http://example/q1" } ,
+            "object":   { "type": "uri" , "value": "http://example/z1" }
+          }
+        } ,
+        "s": {
+          "type": "triple" , 
+          "value": {
+            "subject":  { "type": "uri" , "value": "http://example/s" } ,
+            "property": { "type": "uri" , "value": "http://example/p1" } ,
+            "object":   { "type": "uri" , "value": "http://example/o" }
+          }
+        } ,
+        "p": { "type": "uri" , "value": "http://example/q1" } ,
+        "o": { "type": "uri" , "value": "http://example/z1" }
+      } ,
+      { 
+        "t": {
+          "type": "triple" , 
+          "value": {
+            "subject":  { "type": "uri" , "value": "http://example/s" } ,
+            "property": { "type": "uri" , "value": "http://example/p1" } ,
+            "object":   { "type": "uri" , "value": "http://example/o" }
+          }
+        } ,
+        "s": { "type": "uri" , "value": "http://example/s" } ,
+        "p": { "type": "uri" , "value": "http://example/p1" } ,
+        "o": { "type": "uri" , "value": "http://example/o" }
+      }
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-2.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-2.arq
new file mode 100644
index 0000000..059f460
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-2.arq
@@ -0,0 +1,12 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+  GRAPH :g1 {
+    <<?s ?p ?o >> ?q ?z .
+  }
+}
+
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-2.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-2.srj
new file mode 100644
index 0000000..5f7b82d
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-named-graph-2.srj
@@ -0,0 +1,15 @@
+{ "head": {
+    "vars": [ "s" , "p" , "o" , "q" , "z" ]
+  } ,
+  "results": {
+    "bindings": [
+      { 
+        "s": { "type": "uri" , "value": "http://example/s" } ,
+        "p": { "type": "uri" , "value": "http://example/p1" } ,
+        "o": { "type": "uri" , "value": "http://example/o" } ,
+        "q": { "type": "uri" , "value": "http://example/q1" } ,
+        "z": { "type": "uri" , "value": "http://example/z1" }
+      }
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-01.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-01.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-01.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-01.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-01.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-01.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-01.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-01.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-02.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-02.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-02.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-02.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-02.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-02.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-02.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-02.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-03.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-03.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-03.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-03.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-03.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-03.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-03.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-03.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-04.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-04.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-04.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-04.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-04.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-04.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-04.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-04.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-05.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-05.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-05.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-05.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-05.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-05.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-05.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-05.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-06.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-06.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-06.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-06.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-06.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-06.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-06.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-06.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-07.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-07.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-07.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-07.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-07.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-07.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-07.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-07.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-08.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-08.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-08.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-08.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-08.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-08.srj
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-pattern-08.srj
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-08.srj
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-09.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-09.arq
new file mode 100644
index 0000000..2532efb
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-09.arq
@@ -0,0 +1,10 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+# No match
+SELECT * {
+   <<?s ?p :nomatch>> ?q ?z .
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-09.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-09.srj
new file mode 100644
index 0000000..6525df9
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-pattern-09.srj
@@ -0,0 +1,9 @@
+{ "head": {
+    "vars": [ "s" , "p" , "q" , "z" ]
+  } ,
+  "results": {
+    "bindings": [
+      
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-01.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-01.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-01.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-01.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-02.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-02.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-02.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-02.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-03.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-03.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-03.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-03.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-04.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-04.arq
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-syntax-04.arq
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-04.arq
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-05.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-05.arq
new file mode 100644
index 0000000..4bb8a65
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-syntax-05.arq
@@ -0,0 +1,10 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+    FIND ( << :s :p1 :o >> as ?t )
+    ?t ?p ?o .
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-1.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-1.arq
new file mode 100644
index 0000000..c56e293
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-1.arq
@@ -0,0 +1,12 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+SELECT * {
+  GRAPH <urn:x-arq:UnionGraph> {
+     # Spans graphs
+     << <<:s :p1 ?o>> :q1 :z1 >> :q1 ?z .
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-1.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-1.srj
new file mode 100644
index 0000000..bea53f1
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-1.srj
@@ -0,0 +1,12 @@
+{ "head": {
+    "vars": [ "o" , "z" ]
+  } ,
+  "results": {
+    "bindings": [
+      { 
+        "o": { "type": "uri" , "value": "http://example/o" } ,
+        "z": { "type": "uri" , "value": "http://example/z1" }
+      }
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-2.arq b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-2.arq
new file mode 100644
index 0000000..4213363
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-2.arq
@@ -0,0 +1,13 @@
+## Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
+
+PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
+PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>
+PREFIX :       <http://example/>
+
+# Nesting via match
+SELECT * {
+  GRAPH <urn:x-arq:UnionGraph> {
+     FIND( <<:s :p1 ?o>> AS ?t )
+     << ?t :q1 :z1 >> :q1 ?z .
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-2.srj b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-2.srj
new file mode 100644
index 0000000..ff18e9e
--- /dev/null
+++ b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-union-2.srj
@@ -0,0 +1,20 @@
+{ "head": {
+    "vars": [ "t" , "o" , "z" ]
+  } ,
+  "results": {
+    "bindings": [
+      { 
+        "t": {
+          "type": "triple" , 
+          "value": {
+            "subject":  { "type": "uri" , "value": "http://example/s" } ,
+            "property": { "type": "uri" , "value": "http://example/p1" } ,
+            "object":   { "type": "uri" , "value": "http://example/o" }
+          }
+        } ,
+        "o": { "type": "uri" , "value": "http://example/o" } ,
+        "z": { "type": "uri" , "value": "http://example/z1" }
+      }
+    ]
+  }
+}
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-bad-syntax-01.aru b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-bad-syntax-01.aru
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-bad-syntax-01.aru
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-bad-syntax-01.aru
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-bad-syntax-02.aru b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-bad-syntax-02.aru
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-bad-syntax-02.aru
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-bad-syntax-02.aru
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-syntax-01.aru b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-syntax-01.aru
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-syntax-01.aru
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-syntax-01.aru
diff --git a/jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-syntax-02.aru b/jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-syntax-02.aru
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/SPARQL-star/sparql-star-update-syntax-02.aru
rename to jena-arq/testing/ARQ/RDF-Star/SPARQL-Star/sparql-star-update-syntax-02.aru
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/manifest.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/manifest.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/manifest.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/manifest.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-01.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-01.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-01.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-01.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-02.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-02.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-02.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-02.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-03.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-03.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-03.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-03.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-04.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-04.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-04.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-04.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-05.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-05.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-05.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-05.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-06.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-06.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-06.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-06.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-07.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-07.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-07.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-07.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-01.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-01.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-01.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-01.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-02.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-02.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-02.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-02.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-03.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-03.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-03.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-03.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-04.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-04.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-04.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-04.ttl
diff --git a/jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-05.ttl b/jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-05.ttl
similarity index 100%
rename from jena-arq/testing/ARQ/RDF-Star/Turtle-star/turtle-star-syntax-bad-05.ttl
rename to jena-arq/testing/ARQ/RDF-Star/Turtle-Star/turtle-star-syntax-bad-05.ttl
diff --git a/jena-cmds/src/main/java/arq/cmdline/ModQueryIn.java b/jena-cmds/src/main/java/arq/cmdline/ModQueryIn.java
index 290df7c..26e41e3 100644
--- a/jena-cmds/src/main/java/arq/cmdline/ModQueryIn.java
+++ b/jena-cmds/src/main/java/arq/cmdline/ModQueryIn.java
@@ -66,7 +66,7 @@
 
         if ( cmdline.contains(queryFileDecl) ) {
             queryFilename = cmdline.getValue(queryFileDecl) ;
-            querySyntax = Syntax.guessFileSyntax(queryFilename, defaultQuerySyntax) ;
+            querySyntax = Syntax.guessQueryFileSyntax(queryFilename, defaultQuerySyntax) ;
         }
 
         if ( cmdline.getNumPositional() == 0 && queryFilename == null )
@@ -82,7 +82,7 @@
             // One positional argument.
             String qs = cmdline.getPositionalArg(0) ;
             if ( cmdline.matchesIndirect(qs) )
-                querySyntax = Syntax.guessFileSyntax(qs, defaultQuerySyntax) ;
+                querySyntax = Syntax.guessQueryFileSyntax(qs, defaultQuerySyntax) ;
 
             queryString = cmdline.indirect(qs) ;
         }
diff --git a/jena-cmds/src/main/java/arq/qparse.java b/jena-cmds/src/main/java/arq/qparse.java
index 041ebeb..2cee976 100644
--- a/jena-cmds/src/main/java/arq/qparse.java
+++ b/jena-cmds/src/main/java/arq/qparse.java
@@ -20,6 +20,7 @@
 
 import java.io.PrintStream ;
 import java.util.Iterator ;
+import java.util.Locale;
 
 import arq.cmdline.CmdARQ ;
 import arq.cmdline.ModEngine ;
@@ -43,7 +44,7 @@
 
 public class qparse extends CmdARQ
 {
-    protected ModQueryIn    modQuery        = new ModQueryIn(Syntax.syntaxSPARQL_11) ;
+    protected ModQueryIn    modQuery        = new ModQueryIn(Syntax.syntaxARQ) ;
     protected ModQueryOut   modOutput       = new ModQueryOut() ; 
     protected ModEngine     modEngine       = new ModEngine() ;
     protected final ArgDecl argDeclPrint    = new ArgDecl(ArgDecl.HasValue, "print") ;
@@ -71,7 +72,7 @@
         super.addModule(modOutput) ;
         super.addModule(modEngine) ;
         super.getUsage().startCategory(null) ;
-        super.add(argDeclPrint, "--print", "Print in various forms [query, op, quad, plan]") ;
+        super.add(argDeclPrint, "--print", "Print in various forms [query, op, quad, optquad, plan]") ;
         super.add(argDeclExplain, "--explain", "Print with algebra-level optimization") ;
         super.add(argDeclOpt, "--opt", "[deprecated]") ;
         super.add(argDeclFixup, "--fixup", "Convert undeclared prefix names to URIs") ;
@@ -99,48 +100,30 @@
 
         for ( String arg : getValues( argDeclPrint ) )
         {
-            if ( arg.equalsIgnoreCase( "query" ) )
-            {
-                printQuery = true;
-            }
-            else if ( arg.equalsIgnoreCase( "op" ) ||
-                arg.equalsIgnoreCase( "alg" ) ||
-                arg.equalsIgnoreCase( "algebra" ) )
-            {
-                printOp = true;
-            }
-            else if ( arg.equalsIgnoreCase( "quad" ) )
-            {
-                printQuad = true;
-            }
-            else if ( arg.equalsIgnoreCase( "quads" ) )
-            {
-                printQuad = true;
-            }
-            else if ( arg.equalsIgnoreCase( "plan" ) )
-            {
-                printPlan = true;
-            }
-            else if ( arg.equalsIgnoreCase( "opt" ) )
-            {
-                printOpt = true;
-            }
-            else if ( arg.equalsIgnoreCase( "optquad" ) )
-            {
-                printQuadOpt = true;
-            }
-            else if ( arg.equalsIgnoreCase( "quadopt" ) )
-            {
-                printQuadOpt = true;
-            }
-            else if ( arg.equalsIgnoreCase( "none" ) )
-            {
-                printNone = true;
-            }
-            else
-            {
-                throw new CmdException(
-                    "Not a recognized print form: " + arg + " : Choices are: query, op, quad, opt, optquad" );
+            switch(arg.toLowerCase(Locale.ROOT)) {
+                case "query":
+                    printQuery = true;
+                    break;
+                case "op": case "alg": case "algebra":
+                    printOp = true;
+                    break;
+                case "quad": case "quads":
+                    printQuad = true;
+                    break;
+                case "plan":
+                    printPlan = true;
+                    break;
+                case "opt": 
+                    printOpt = true;
+                    break;
+                case "optquad": case "quadopt":
+                    printQuadOpt = true;
+                    break;
+                case "none": 
+                    printNone = true;
+                    break;
+                default:
+                    throw new CmdException("Not a recognized print form: " + arg + " : Choices are: query, op, quad, opt, optquad, plan" );
             }
         }
         
diff --git a/jena-cmds/src/main/java/arq/uparse.java b/jena-cmds/src/main/java/arq/uparse.java
index 22290b5..019b315 100644
--- a/jena-cmds/src/main/java/arq/uparse.java
+++ b/jena-cmds/src/main/java/arq/uparse.java
@@ -111,20 +111,17 @@
         {
             Syntax syntax = updateSyntax ;
             if ( syntax == null )
-                syntax = Syntax.guessUpdateFileSyntax(filename) ;
+                syntax = Syntax.guessFileSyntax(filename) ;
             String x = oneFile( filename );
             if ( x != null )
                 execOne( x, syntax );
         }
-
-        
-        
         
         for ( String x : super.positionals ) {
             Syntax syntax = updateSyntax ;    
             if ( matchesIndirect(x) ) {
                 if ( syntax == null )
-                    syntax = Syntax.guessUpdateFileSyntax(x) ;
+                    syntax = Syntax.guessFileSyntax(x) ;
                 x = indirect( x );
             }
             if ( syntax == null )
diff --git a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/SolverRX.java b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/SolverRX.java
index f5cf5b8..f43d2aa 100644
--- a/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/SolverRX.java
+++ b/jena-db/jena-tdb2/src/main/java/org/apache/jena/tdb2/solver/SolverRX.java
@@ -31,12 +31,12 @@
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.graph.Triple;
-import org.apache.jena.sparql.ARQException;
-import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.ARQConstants;
 import org.apache.jena.sparql.core.Var;
 import org.apache.jena.sparql.core.VarAlloc;
 import org.apache.jena.sparql.engine.ExecutionContext;
 import org.apache.jena.sparql.engine.iterator.RX;
+import org.apache.jena.sparql.util.Context;
 import org.apache.jena.tdb2.TDBException;
 import org.apache.jena.tdb2.store.NodeId;
 import org.apache.jena.tdb2.store.nodetable.NodeTable;
@@ -50,34 +50,66 @@
     // These argument get passed around a lot, making the argument lists long.
     private static class Args {
         final NodeTupleTable nodeTupleTable;
-        final boolean anyGraphs;
+        final boolean anyGraph;
         final Predicate<Tuple<NodeId>> filter;
         final ExecutionContext execCxt;
-        Args(NodeTupleTable nodeTupleTable, boolean anyGraphs, Predicate<Tuple<NodeId>> filter, ExecutionContext execCxt) {
+        final VarAlloc varAlloc;
+        Args(NodeTupleTable nodeTupleTable, boolean anyGraph, Predicate<Tuple<NodeId>> filter, ExecutionContext execCxt) {
             super();
             this.nodeTupleTable = nodeTupleTable;
-            this.anyGraphs = anyGraphs;
+            this.anyGraph = anyGraph;
             this.filter = filter;
             this.execCxt = execCxt;
+            this.varAlloc = varAlloc(execCxt);
         }
     }
 
-
-    // Call point for SolverLib.execute
-    public static Iterator<BindingNodeId> solveRX(NodeTupleTable nodeTupleTable, Tuple<Node> tuple, boolean anyGraph,
-                                                  Iterator<BindingNodeId> chain, Predicate<Tuple<NodeId>> filter,
-                                                  ExecutionContext execCxt) {
-        Args args = new Args(nodeTupleTable, anyGraph, filter, execCxt);
-        return rdfStarTriple(chain, tuple, args);
+    private static VarAlloc varAlloc(ExecutionContext execCxt) {
+        Context context = execCxt.getContext();
+        VarAlloc varAlloc = VarAlloc.get(context, ARQConstants.sysVarAllocRDFStar);
+        if ( varAlloc == null ) {
+            varAlloc = new VarAlloc(ARQConstants.allocVarTripleTerm);
+            context.set(ARQConstants.sysVarAllocRDFStar, varAlloc);  
+        }
+        return varAlloc;
     }
 
+    // Call point for SolverLib.execute
+    public static Iterator<BindingNodeId> solveRX(NodeTupleTable nodeTupleTable, Tuple<Node> pattern, boolean anyGraph,
+                                                  Iterator<BindingNodeId> chain, Predicate<Tuple<NodeId>> filter,
+                                                  ExecutionContext execCxt) {
+        if ( ! tripleHasNodeTriple(pattern) )
+            SolverLib.solve(nodeTupleTable, pattern, anyGraph, chain, filter, execCxt);
+        
+        Args args = new Args(nodeTupleTable, anyGraph, filter, execCxt);
+        return rdfStarTriple(chain, pattern, args);
+    }
 
+    /**
+     * Match a single triple pattern that may involve RDF* terms. This is the top
+     * level function for matching triples. The function {@link #matchTripleStar}
+     * matches a triple term and assigns the triple matched to a variable. It is used
+     * within {@link #rdfStarTriple} for nested triple term and a temporary allocated
+     * variable as well can for {@code FIND(<<...>> AS ?t)}.
+     *
+     * @implNote 
+     * Without RDF*, this would be a plain call of {@link #matchData} which
+     * is simply a call to {@link SolverLib#solve}.
+     */
     private static Iterator<BindingNodeId> rdfStarTriple(Iterator<BindingNodeId> input, Tuple<Node> pattern, Args args) {
+        // Should all work without this trap for plain RDF.
         if ( ! tripleHasNodeTriple(pattern) )
             return matchData( input, pattern, args);
         return rdfStarTripleSub(input, pattern, args);
     }
 
+    /**
+     * Insert the stages necessary for a triple with triple pattern term inside it.
+     * If the triple pattern has a triple term, possibly with variables, introduce
+     * an iterator to solve for that, assign the matching triple term to a hidden
+     * variable, and put allocated variable in to main triple pattern. Do for subject
+     * and object positions, and also any nested triple pattern terms.
+     */
     private static Iterator<BindingNodeId> rdfStarTripleSub(Iterator<BindingNodeId> input,
                                                             Tuple<Node> pattern, Args args) {
         Pair<Iterator<BindingNodeId>, Tuple<Node>> pair = preprocessForTripleTerms(input, pattern, args);
@@ -101,9 +133,11 @@
         return qIter;
     }
 
-    // XXX RX
-    private static VarAlloc varAlloc = new VarAlloc("*1*"/*allocTripleTerms*/) ;
-
+    /**
+     * Process a triple for triple terms.
+     * <p>
+     * This creates additional matchers for triple terms in the pattern triple recursively.
+     */
     private static Pair<Iterator<BindingNodeId>, Tuple<Node>>
             preprocessForTripleTerms(Iterator<BindingNodeId> chain, Tuple<Node> patternTuple, Args args) {
         int sIdx = subjectIdx(patternTuple);
@@ -111,24 +145,29 @@
 
         Node subject = patternTuple.get(sIdx);
         Node object = patternTuple.get(oIdx);
+        Node subject1 = null;
+        Node object1 = null;
 
         if ( subject.isNodeTriple() && ! subject.isConcrete() ) {
             Triple tripleTerm = triple(subject);
-            Var var = varAlloc.allocVar();
+            Var var = args.varAlloc.allocVar();
             patternTuple = createTuple(patternTuple, var, sIdx);
-            Tuple<Node> patternTuple2 = tuple(tripleTerm);
+            Tuple<Node> patternTuple2 = tuple(patternTuple, tripleTerm);
             chain = matchTripleStar(chain, var, patternTuple2, args);
+            subject1 = var;
         }
 
         if ( object.isNodeTriple() && ! object.isConcrete() ) {
             Triple tripleTerm = triple(object);
-            Var var = varAlloc.allocVar();
+            Var var = args.varAlloc.allocVar();
             patternTuple = createTuple(patternTuple, var, oIdx);
-            Tuple<Node> patternTuple2 = tuple(tripleTerm);
+            Tuple<Node> patternTuple2 = tuple(patternTuple, tripleTerm);
             chain = matchTripleStar(chain, var, patternTuple2, args);
+            object1 = var;
         }
 
-        // XXX Optimize for no change. But we caught that earlier?
+        if ( subject1 == null && object1 == null )
+            return Pair.create(chain, patternTuple);
         return Pair.create(chain, patternTuple);
     }
 
@@ -175,6 +214,14 @@
         // Should not happen.
         if ( NodeId.isDoesNotExist(tid) )
             return null;
+        // Already bound (FIND)?
+        if ( binding.containsKey(var) ) {
+            NodeId tid2 = binding.get(var);
+            if ( tid.equals(tid2) )
+                return binding;
+            return null;
+        }
+        
         BindingNodeId b2 = new BindingNodeId(binding);
         b2.put(var, tid);
         return b2;
@@ -202,8 +249,14 @@
         }
     }
 
+    /**
+     * Match the NodeTupleTable with a tuple pattern.
+     * This is the accessor to the data.
+     * It assumes any triple terms have been dealt with.
+     */
+
     private static Iterator<BindingNodeId> matchData(Iterator<BindingNodeId> chain, Tuple<Node> pattern, Args args) {
-        return SolverLib.solve(args.nodeTupleTable, pattern, args.anyGraphs, chain, args.filter, args.execCxt);
+        return SolverLib.solve(args.nodeTupleTable, pattern, args.anyGraph, chain, args.filter, args.execCxt);
     }
 
     private static Tuple<Node> createTuple(Tuple<Node> tuple, Var var, int idx) {
@@ -213,7 +266,7 @@
             case 2: return TupleFactory.create3(tuple.get(0), tuple.get(1), var);
             case 3: return TupleFactory.create4(tuple.get(0), tuple.get(1), tuple.get(2), var);
             default:
-                throw new ARQException("Index is not recognized: "+idx);
+                throw new TDBException("Index is not recognized: "+idx);
         }
     }
 
@@ -221,7 +274,7 @@
         switch(pattern.len()) {
             case 3: return 0;
             case 4: return 1;
-            default: throw new ARQException("Tuple not of length 3 or 4");
+            default: throw new TDBException("Tuple not of length 3 or 4");
         }
     }
 
@@ -229,7 +282,7 @@
         switch(pattern.len()) {
             case 3: return 2;
             case 4: return 3;
-            default: throw new ARQException("Tuple not of length 3 or 4");
+            default: throw new TDBException("Tuple not of length 3 or 4");
         }
     }
 
@@ -250,13 +303,13 @@
         return false;
     }
 
-    // XXX Somewhere
-    private static Tuple<Node> tuple(Triple triple) {
-        return TupleFactory.create3(triple.getSubject(), triple.getPredicate(), triple.getObject());
+    private static Tuple<Node> tuple(Tuple<Node> base, Triple triple) {
+        switch(base.len()){
+            case 3: 
+                return TupleFactory.create3(triple.getSubject(), triple.getPredicate(), triple.getObject());   
+            case 4:
+                return TupleFactory.create4(base.get(0), triple.getSubject(), triple.getPredicate(), triple.getObject());
+            default:
+        }       throw new TDBException("Tuple not of length 3 or 4"); 
     }
-
-    private static Tuple<Node> tuple(Quad quad) {
-        return TupleFactory.create4(quad.getGraph(), quad.getSubject(), quad.getPredicate(), quad.getObject());
-    }
-}
-
+}
\ No newline at end of file
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TC_TDB2.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TC_TDB2.java
index 4d9c459..c4a26ae 100644
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TC_TDB2.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TC_TDB2.java
@@ -55,6 +55,7 @@
     , TS_TDBAssembler.class
     , TS_Sys.class
     , TS_Loader.class
+    , TS_ScriptsTDB2.class
 } )
 
 public class TC_TDB2
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TS_ScriptsTDB2.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TS_ScriptsTDB2.java
new file mode 100644
index 0000000..73c2094
--- /dev/null
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TS_ScriptsTDB2.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.tdb2;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses( {
+    TestScriptsTDB2.class
+})
+
+public class TS_ScriptsTDB2 {}
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestSuiteGraphTDB.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TestScriptsTDB2.java
similarity index 62%
copy from jena-tdb/src/test/java/org/apache/jena/tdb/store/TestSuiteGraphTDB.java
copy to jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TestScriptsTDB2.java
index 22cc7e7..5e44bde 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestSuiteGraphTDB.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/TestScriptsTDB2.java
@@ -16,25 +16,29 @@
  * limitations under the License.
  */
 
-package org.apache.jena.tdb.store;
+package org.apache.jena.tdb2;
 
 import junit.framework.TestSuite ;
-import org.apache.jena.tdb.ConfigTest ;
-import org.apache.jena.tdb.junit.TestFactoryTDB ;
+import org.apache.jena.tdb2.junit.TestFactoryTDB2;
 import org.junit.runner.RunWith ;
 import org.junit.runners.AllTests ;
 
 /** Scripted test generation */
 
 @RunWith(AllTests.class)
-public class TestSuiteGraphTDB extends TestSuite
+public class TestScriptsTDB2 extends TestSuite
 {
-    static public TestSuite suite() { return new TestSuiteGraphTDB() ; }
+    static final String ARQ_DIR = "../../jena-arq/testing/ARQ";
+    static public TestSuite suite() { return new TestScriptsTDB2(); }
     
-    private TestSuiteGraphTDB()
+    private TestScriptsTDB2()
     {
         super("TDB-Scripts") ;
-        String manifestMain = ConfigTest.getTestingDataRoot()+"/manifest.ttl" ;
-        TestFactoryTDB.make(this, manifestMain, "TDB-") ;
+        String manifestMain1 = ConfigTest.getTestingDataRoot()+"/manifest.ttl";
+        TestFactoryTDB2.make(this, manifestMain1, "TDB2-");
+
+        // From ARQ
+        String manifestMain2 = ARQ_DIR + "/RDF-Star/SPARQL-Star/manifest.ttl";
+        TestFactoryTDB2.make(this, manifestMain2, "TDB2-");
     }
 }
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/QueryTestTDB.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/QueryTestTDB2.java
similarity index 85%
rename from jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/QueryTestTDB.java
rename to jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/QueryTestTDB2.java
index f0951ed..1b78db6 100644
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/QueryTestTDB.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/QueryTestTDB2.java
@@ -20,9 +20,8 @@
 
 import java.util.List;
 
-import org.apache.jena.system.Txn;
 import org.apache.jena.query.*;
-import org.apache.jena.rdf.model.Model;
+import org.apache.jena.riot.RDFDataMgr;
 import org.apache.jena.sparql.SystemARQ;
 import org.apache.jena.sparql.engine.QueryEngineFactory;
 import org.apache.jena.sparql.engine.QueryExecutionBase;
@@ -32,17 +31,17 @@
 import org.apache.jena.sparql.junit.TestItem;
 import org.apache.jena.sparql.resultset.ResultSetCompare;
 import org.apache.jena.sparql.resultset.SPARQLResult;
+import org.apache.jena.system.Txn;
 import org.apache.jena.tdb2.TDB2Factory;
-import org.apache.jena.util.FileManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public class QueryTestTDB extends EarlTestCase
+public class QueryTestTDB2 extends EarlTestCase
 {
     // Changed to using in-memory graphs/datasets because this is testing the query
     // processing.  Physical graph/datsets is in package "store".
 
-    private static Logger log = LoggerFactory.getLogger(QueryTestTDB.class);
+    private static Logger log = LoggerFactory.getLogger(QueryTestTDB2.class);
     private Dataset dataset = null;
 
     boolean skipThisTest = false;
@@ -57,7 +56,7 @@
     private static List<String> currentNamedGraphs = null;
 
     // Old style (Junit3)
-    public QueryTestTDB(String testName, EarlReport report, TestItem item)
+    public QueryTestTDB2(String testName, EarlReport report, TestItem item)
     {
         this(testName, report, item.getURI(),
              item.getDefaultGraphURIs(), item.getNamedGraphURIs(),
@@ -65,7 +64,7 @@
              );
     }
 
-    public QueryTestTDB(String testName, EarlReport report,
+    public QueryTestTDB2(String testName, EarlReport report,
                         String uri,
                         List<String> dftGraphs,
                         List<String> namedGraphs,
@@ -113,11 +112,12 @@
 
         //graphLocation.clear();
 
+        // Allow "qt:data" to be quads in defaultGraphURIs.
         for ( String fn : defaultGraphURIs )
-            load(dataset.getDefaultModel(), fn);
-
+            RDFDataMgr.read(dataset, fn);
+        
         for ( String fn : namedGraphURIs )
-            load(dataset.getNamedModel(fn), fn);
+            RDFDataMgr.read(dataset.getNamedModel(fn), fn) ;
     }
 
 
@@ -131,28 +131,31 @@
         }
 
         Query query = QueryFactory.read(queryFile);
-        Dataset ds = DatasetFactory.create(defaultGraphURIs, namedGraphURIs);
+        
+        Dataset ds = DatasetFactory.create();
+        for ( String fn : defaultGraphURIs )
+            RDFDataMgr.read(ds, fn);    // Allow quads
+        for ( String fn : namedGraphURIs )
+            RDFDataMgr.read(ds.getNamedModel(fn), fn) ;
 
         // ---- First, get the expected results by executing in-memory or from a results file.
 
-        ResultSetRewindable rs1$ = null;
-        String expectedLabel$ = "";
+        ResultSetRewindable rs1;
+        String expectedLabel;
         if ( results != null )
         {
-            rs1$ = ResultSetFactory.makeRewindable(results.getResultSet());
-            expectedLabel$ = "Results file";
+            rs1 = ResultSetFactory.makeRewindable(results.getResultSet());
+            expectedLabel = "Results file";
         }
         else
         {
             QueryEngineFactory f = QueryEngineRef.getFactory();
             try(QueryExecution qExec1 = new QueryExecutionBase(query, ds, null, f)) {
-                rs1$ = ResultSetFactory.makeRewindable(qExec1.execSelect());
+                rs1 = ResultSetFactory.makeRewindable(qExec1.execSelect());
             }
-            expectedLabel$ = "Standard engine";
+            expectedLabel = "Standard engine";
         }
         // Effectively final.
-        ResultSetRewindable rs1 = rs1$;
-        String expectedLabel = expectedLabel$;
         // ---- Second, execute in persistent graph
 
         Dataset ds2 = dataset; //DatasetFactory.create(model) ;
@@ -179,11 +182,6 @@
         });
     }
 
-    private static void load(Model model, String fn)
-    {
-        FileManager.get().readModel(model, fn);
-    }
-
     private static boolean compareLists(List<String> list1, List<String> list2)
     {
         if ( list1 == null )
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/TestFactoryTDB.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/TestFactoryTDB2.java
similarity index 73%
rename from jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/TestFactoryTDB.java
rename to jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/TestFactoryTDB2.java
index 67e1dc6..4a77800 100644
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/TestFactoryTDB.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/junit/TestFactoryTDB2.java
@@ -28,7 +28,7 @@
 import org.apache.jena.sparql.vocabulary.TestManifestX;
 import org.apache.jena.util.junit.TestFactoryManifest;
 
-public class TestFactoryTDB extends TestFactoryManifest
+public class TestFactoryTDB2 extends TestFactoryManifest
 {
     public static EarlReport report = null;
 
@@ -41,7 +41,7 @@
 
     public static TestSuite makeSuite(String manifestFile, String testRootName)
     {
-        TestFactoryTDB f = new TestFactoryTDB(testRootName);
+        TestFactoryTDB2 f = new TestFactoryTDB2(testRootName);
         TestSuite ts = f.process(manifestFile);
         if ( testRootName != null )
             ts.setName(testRootName+ts.getName());
@@ -52,7 +52,7 @@
 
     public String testRootName;
 
-    public TestFactoryTDB(String testRootName)
+    public TestFactoryTDB2(String testRootName)
     {
         this.testRootName = testRootName;
     }
@@ -70,17 +70,32 @@
         if ( testItem.getTestType() != null )
         {
             if ( testItem.getTestType().equals(TestManifestX.TestQuery) )
-                test = new QueryTestTDB(testName, report, testItem);
+                test = new QueryTestTDB2(testName, report, testItem);
 
             if ( testItem.getTestType().equals(TestManifestX.TestSurpressed) )
                 test = new SurpressedTest(testName, report, testItem);
+            
+            // Ignore syntax tests
+            if ( testItem.getTestType().equals(TestManifestX.PositiveSyntaxTestARQ) )
+                // Ignore
+                return null;
+            if ( testItem.getTestType().equals(TestManifestX.NegativeSyntaxTestARQ) )
+                // Ignore
+                return null;
+            if ( testItem.getTestType().equals(TestManifestX.PositiveUpdateSyntaxTestARQ) )
+                // Ignore
+                return null;
+            if ( testItem.getTestType().equals(TestManifestX.NegativeUpdateSyntaxTestARQ) )
+                // Ignore
+                return null;
+
 
             if ( test == null )
                 System.err.println("Unrecognized test type: "+testItem.getTestType());
         }
         // Default
         if ( test == null )
-            test = new QueryTestTDB(testName, report, testItem);
+            test = new QueryTestTDB2(testName, report, testItem);
 
         return test;
     }
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TS_Store.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TS_Store.java
index c57ea61..9051864 100644
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TS_Store.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TS_Store.java
@@ -41,9 +41,6 @@
     , TestGraphNamedTDB.class
     , TestDatasetTDB.class
     , TestDatasetTDBPersist.class
-    // The script suite
-    , TestSuiteGraphTDB.class
-
     , Test_SPARQL_TDB.class
     , TestDynamicDatasetTDB.class
     , TestStoreConnectionMem.class
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestQuadFilter.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestQuadFilter.java
index 87302bb..2046458 100644
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestQuadFilter.java
+++ b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestQuadFilter.java
@@ -18,12 +18,14 @@
 
 package org.apache.jena.tdb2.store;
 
+import static org.junit.Assert.assertEquals;
+
 import java.util.function.Predicate;
 
-import static org.junit.Assert.*;
 import org.apache.jena.atlas.lib.tuple.Tuple;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.query.*;
+import org.apache.jena.sparql.core.DatasetGraph;
 import org.apache.jena.sparql.core.Quad;
 import org.apache.jena.sparql.sse.SSE;
 import org.apache.jena.system.Txn;
@@ -31,31 +33,19 @@
 import org.apache.jena.tdb2.TDB2Factory;
 import org.apache.jena.tdb2.store.nodetable.NodeTable;
 import org.apache.jena.tdb2.sys.SystemTDB;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Ignore;
+import org.apache.jena.tdb2.sys.TDBInternal;
 import org.junit.Test;
 
-@Ignore("Quad filter tests not ready (transactions)")
 public class TestQuadFilter
 {
     private static String graphToHide = "http://example/g2";
     private static Dataset ds = setup();
 
-
-    @BeforeClass public static void beforeClass()
-    {
-
-    }
-
-    @AfterClass public static void afterClass() {}
-
     /** Example setup - in-memory dataset with two graphs, one triple in each */
-    private static Dataset setup()
-    {
+    private static Dataset setup() {
         Dataset ds = TDB2Factory.createDataset();
-        DatasetGraphTDB dsg = (DatasetGraphTDB)(ds.asDatasetGraph());
-        Txn.executeWrite(dsg,  ()->{
+        DatasetGraph dsg = ds.asDatasetGraph();
+        Txn.executeWrite(dsg, () -> {
             Quad q1 = SSE.parseQuad("(<http://example/g1> <http://example/s> <http://example/p> <http://example/o1>)");
             Quad q2 = SSE.parseQuad("(<http://example/g2> <http://example/s> <http://example/p> <http://example/o2>)");
             dsg.add(q1);
@@ -65,12 +55,11 @@
     }
 
     /** Create a filter to exclude the graph http://example/g2 */
-    private static Predicate<Tuple<NodeId>> createFilter(Dataset ds)
-    {
-        DatasetGraphTDB dsg = (DatasetGraphTDB)(ds.asDatasetGraph());
+    private static Predicate<Tuple<NodeId>> createFilter(Dataset ds) {
+        DatasetGraphTDB dsg = TDBInternal.getDatasetGraphTDB(ds);
         final NodeTable nodeTable = dsg.getQuadTable().getNodeTupleTable().getNodeTable();
         final NodeId target = nodeTable.getNodeIdForNode(NodeFactory.createURI(graphToHide));
-        return item -> !( item.len() == 4 && item.get(0).equals(target) );
+        return item -> !(item.len() == 4 && item.get(0).equals(target));
     }
 
     @Test public void quad_filter_1()   { test("SELECT * { GRAPH ?g { ?s ?p ?o } }", 1, 2); }
@@ -80,32 +69,22 @@
     private void test(String qs, int withFilter, int withoutFilter)
     {
         Predicate<Tuple<NodeId>> filter = createFilter(ds);
-
-//    private static void example(Dataset ds, Filter<Tuple<NodeId>> filter)
-//    {
-//        String[] x = {
-//            "SELECT * { GRAPH ?g { ?s ?p ?o } }",
-//            "SELECT * { ?s ?p ?o }",
-//            // THis filter does not hide the graph itself, just the quads associated with the graph.
-//            "SELECT * { GRAPH ?g {} }"
-//            };
         Query query = QueryFactory.create(qs);
-
-        try(QueryExecution qExec = QueryExecutionFactory.create(query, ds)) {
-            // Install filter for this query only.
-            qExec.getContext().set(SystemTDB.symTupleFilter, filter);
-            qExec.getContext().setTrue(TDB2.symUnionDefaultGraph);
-            long x1 = ResultSetFormatter.consume(qExec.execSelect());
-            assertEquals(withFilter, x1);
-        }
-        // No filter.
-        try(QueryExecution qExec = QueryExecutionFactory.create(query, ds)) {
-            qExec.getContext().setTrue(TDB2.symUnionDefaultGraph);
-            long x2 = ResultSetFormatter.consume(qExec.execSelect());
-            assertEquals(withoutFilter, x2);
-        }
-
+        
+        Txn.executeRead(ds, ()->{
+            try(QueryExecution qExec = QueryExecutionFactory.create(query, ds)) {
+                // Install filter for this query only.
+                qExec.getContext().set(SystemTDB.symTupleFilter, filter);
+                qExec.getContext().setTrue(TDB2.symUnionDefaultGraph);
+                long x1 = ResultSetFormatter.consume(qExec.execSelect());
+                assertEquals(withFilter, x1);
+            }
+            // No filter.
+            try(QueryExecution qExec = QueryExecutionFactory.create(query, ds)) {
+                qExec.getContext().setTrue(TDB2.symUnionDefaultGraph);
+                long x2 = ResultSetFormatter.consume(qExec.execSelect());
+                assertEquals(withoutFilter, x2);
+            }
+        });
     }
-
-
 }
diff --git a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestSuiteGraphTDB.java b/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestSuiteGraphTDB.java
deleted file mode 100644
index ad639cf..0000000
--- a/jena-db/jena-tdb2/src/test/java/org/apache/jena/tdb2/store/TestSuiteGraphTDB.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you 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.apache.jena.tdb2.store;
-
-import junit.framework.TestSuite;
-import org.apache.jena.tdb2.ConfigTest;
-import org.apache.jena.tdb2.junit.TestFactoryTDB;
-import org.junit.runner.RunWith;
-import org.junit.runners.AllTests;
-
-/** Scripted test generation */
-
-@RunWith(AllTests.class)
-public class TestSuiteGraphTDB extends TestSuite
-{
-    static public TestSuite suite() { return new TestSuiteGraphTDB(); }
-
-    private TestSuiteGraphTDB()
-    {
-        super("TDB-Scripts");
-        String manifestMain = ConfigTest.getTestingDataRoot()+"/manifest.ttl";
-        TestFactoryTDB.make(this, manifestMain, "TDB-");
-    }
-}
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverRX.java b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverRX.java
index 0c8adef..7b661f6 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverRX.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/solver/SolverRX.java
@@ -31,12 +31,12 @@
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.NodeFactory;
 import org.apache.jena.graph.Triple;
-import org.apache.jena.sparql.ARQException;
-import org.apache.jena.sparql.core.Quad;
+import org.apache.jena.sparql.ARQConstants;
 import org.apache.jena.sparql.core.Var;
 import org.apache.jena.sparql.core.VarAlloc;
 import org.apache.jena.sparql.engine.ExecutionContext;
 import org.apache.jena.sparql.engine.iterator.RX;
+import org.apache.jena.sparql.util.Context;
 import org.apache.jena.tdb.TDBException;
 import org.apache.jena.tdb.store.NodeId;
 import org.apache.jena.tdb.store.nodetable.NodeTable;
@@ -50,34 +50,66 @@
     // These argument get passed around a lot, making the argument lists long.
     private static class Args {
         final NodeTupleTable nodeTupleTable;
-        final boolean anyGraphs;
+        final boolean anyGraph;
         final Predicate<Tuple<NodeId>> filter;
         final ExecutionContext execCxt;
-        Args(NodeTupleTable nodeTupleTable, boolean anyGraphs, Predicate<Tuple<NodeId>> filter, ExecutionContext execCxt) {
+        final VarAlloc varAlloc;
+        Args(NodeTupleTable nodeTupleTable, boolean anyGraph, Predicate<Tuple<NodeId>> filter, ExecutionContext execCxt) {
             super();
             this.nodeTupleTable = nodeTupleTable;
-            this.anyGraphs = anyGraphs;
+            this.anyGraph = anyGraph;
             this.filter = filter;
             this.execCxt = execCxt;
+            this.varAlloc = varAlloc(execCxt);
         }
     }
 
-
-    // Call point for SolverLib.execute
-    public static Iterator<BindingNodeId> solveRX(NodeTupleTable nodeTupleTable, Tuple<Node> tuple, boolean anyGraph,
-                                                  Iterator<BindingNodeId> chain, Predicate<Tuple<NodeId>> filter,
-                                                  ExecutionContext execCxt) {
-        Args args = new Args(nodeTupleTable, anyGraph, filter, execCxt);
-        return rdfStarTriple(chain, tuple, args);
+    private static VarAlloc varAlloc(ExecutionContext execCxt) {
+        Context context = execCxt.getContext();
+        VarAlloc varAlloc = VarAlloc.get(context, ARQConstants.sysVarAllocRDFStar);
+        if ( varAlloc == null ) {
+            varAlloc = new VarAlloc(ARQConstants.allocVarTripleTerm);
+            context.set(ARQConstants.sysVarAllocRDFStar, varAlloc);  
+        }
+        return varAlloc;
     }
 
+    // Call point for SolverLib.execute
+    public static Iterator<BindingNodeId> solveRX(NodeTupleTable nodeTupleTable, Tuple<Node> pattern, boolean anyGraph,
+                                                  Iterator<BindingNodeId> chain, Predicate<Tuple<NodeId>> filter,
+                                                  ExecutionContext execCxt) {
+        if ( ! tripleHasNodeTriple(pattern) )
+            SolverLib.solve(nodeTupleTable, pattern, anyGraph, chain, filter, execCxt);
+        
+        Args args = new Args(nodeTupleTable, anyGraph, filter, execCxt);
+        return rdfStarTriple(chain, pattern, args);
+    }
 
+    /**
+     * Match a single triple pattern that may involve RDF* terms. This is the top
+     * level function for matching triples. The function {@link #matchTripleStar}
+     * matches a triple term and assigns the triple matched to a variable. It is used
+     * within {@link #rdfStarTriple} for nested triple term and a temporary allocated
+     * variable as well can for {@code FIND(<<...>> AS ?t)}.
+     *
+     * @implNote 
+     * Without RDF*, this would be a plain call of {@link #matchData} which
+     * is simply a call to {@link SolverLib#solve}.
+     */
     private static Iterator<BindingNodeId> rdfStarTriple(Iterator<BindingNodeId> input, Tuple<Node> pattern, Args args) {
+        // Should all work without this trap for plain RDF.
         if ( ! tripleHasNodeTriple(pattern) )
             return matchData( input, pattern, args);
         return rdfStarTripleSub(input, pattern, args);
     }
 
+    /**
+     * Insert the stages necessary for a triple with triple pattern term inside it.
+     * If the triple pattern has a triple term, possibly with variables, introduce
+     * an iterator to solve for that, assign the matching triple term to a hidden
+     * variable, and put allocated variable in to main triple pattern. Do for subject
+     * and object positions, and also any nested triple pattern terms.
+     */
     private static Iterator<BindingNodeId> rdfStarTripleSub(Iterator<BindingNodeId> input,
                                                             Tuple<Node> pattern, Args args) {
         Pair<Iterator<BindingNodeId>, Tuple<Node>> pair = preprocessForTripleTerms(input, pattern, args);
@@ -101,9 +133,11 @@
         return qIter;
     }
 
-    // XXX RX
-    private static VarAlloc varAlloc = new VarAlloc("*1*"/*allocTripleTerms*/) ;
-
+    /**
+     * Process a triple for triple terms.
+     * <p>
+     * This creates additional matchers for triple terms in the pattern triple recursively.
+     */
     private static Pair<Iterator<BindingNodeId>, Tuple<Node>>
             preprocessForTripleTerms(Iterator<BindingNodeId> chain, Tuple<Node> patternTuple, Args args) {
         int sIdx = subjectIdx(patternTuple);
@@ -111,24 +145,29 @@
 
         Node subject = patternTuple.get(sIdx);
         Node object = patternTuple.get(oIdx);
+        Node subject1 = null;
+        Node object1 = null;
 
         if ( subject.isNodeTriple() && ! subject.isConcrete() ) {
             Triple tripleTerm = triple(subject);
-            Var var = varAlloc.allocVar();
+            Var var = args.varAlloc.allocVar();
             patternTuple = createTuple(patternTuple, var, sIdx);
-            Tuple<Node> patternTuple2 = tuple(tripleTerm);
+            Tuple<Node> patternTuple2 = tuple(patternTuple, tripleTerm);
             chain = matchTripleStar(chain, var, patternTuple2, args);
+            subject1 = var;
         }
 
         if ( object.isNodeTriple() && ! object.isConcrete() ) {
             Triple tripleTerm = triple(object);
-            Var var = varAlloc.allocVar();
+            Var var = args.varAlloc.allocVar();
             patternTuple = createTuple(patternTuple, var, oIdx);
-            Tuple<Node> patternTuple2 = tuple(tripleTerm);
+            Tuple<Node> patternTuple2 = tuple(patternTuple, tripleTerm);
             chain = matchTripleStar(chain, var, patternTuple2, args);
+            object1 = var;
         }
 
-        // XXX Optimize for no change. But we caught that earlier?
+        if ( subject1 == null && object1 == null )
+            return Pair.create(chain, patternTuple);
         return Pair.create(chain, patternTuple);
     }
 
@@ -175,6 +214,14 @@
         // Should not happen.
         if ( NodeId.isDoesNotExist(tid) )
             return null;
+        // Already bound (FIND)?
+        if ( binding.containsKey(var) ) {
+            NodeId tid2 = binding.get(var);
+            if ( tid.equals(tid2) )
+                return binding;
+            return null;
+        }
+        
         BindingNodeId b2 = new BindingNodeId(binding);
         b2.put(var, tid);
         return b2;
@@ -202,8 +249,14 @@
         }
     }
 
+    /**
+     * Match the NodeTupleTable with a tuple pattern.
+     * This is the accessor to the data.
+     * It assumes any triple terms have been dealt with.
+     */
+
     private static Iterator<BindingNodeId> matchData(Iterator<BindingNodeId> chain, Tuple<Node> pattern, Args args) {
-        return SolverLib.solve(args.nodeTupleTable, pattern, args.anyGraphs, chain, args.filter, args.execCxt);
+        return SolverLib.solve(args.nodeTupleTable, pattern, args.anyGraph, chain, args.filter, args.execCxt);
     }
 
     private static Tuple<Node> createTuple(Tuple<Node> tuple, Var var, int idx) {
@@ -213,7 +266,7 @@
             case 2: return TupleFactory.create3(tuple.get(0), tuple.get(1), var);
             case 3: return TupleFactory.create4(tuple.get(0), tuple.get(1), tuple.get(2), var);
             default:
-                throw new ARQException("Index is not recognized: "+idx);
+                throw new TDBException("Index is not recognized: "+idx);
         }
     }
 
@@ -221,7 +274,7 @@
         switch(pattern.len()) {
             case 3: return 0;
             case 4: return 1;
-            default: throw new ARQException("Tuple not of length 3 or 4");
+            default: throw new TDBException("Tuple not of length 3 or 4");
         }
     }
 
@@ -229,7 +282,7 @@
         switch(pattern.len()) {
             case 3: return 2;
             case 4: return 3;
-            default: throw new ARQException("Tuple not of length 3 or 4");
+            default: throw new TDBException("Tuple not of length 3 or 4");
         }
     }
 
@@ -250,13 +303,13 @@
         return false;
     }
 
-    // XXX Somewhere
-    private static Tuple<Node> tuple(Triple triple) {
-        return TupleFactory.create3(triple.getSubject(), triple.getPredicate(), triple.getObject());
-    }
-
-    private static Tuple<Node> tuple(Quad quad) {
-        return TupleFactory.create4(quad.getGraph(), quad.getSubject(), quad.getPredicate(), quad.getObject());
+    private static Tuple<Node> tuple(Tuple<Node> base, Triple triple) {
+        switch(base.len()){
+            case 3: 
+                return TupleFactory.create3(triple.getSubject(), triple.getPredicate(), triple.getObject());   
+            case 4:
+                return TupleFactory.create4(base.get(0), triple.getSubject(), triple.getPredicate(), triple.getObject());
+            default:
+        }       throw new TDBException("Tuple not of length 3 or 4"); 
     }
 }
-
diff --git a/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableInline.java b/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableInline.java
index bc84919..4eaa31d 100644
--- a/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableInline.java
+++ b/jena-tdb/src/main/java/org/apache/jena/tdb/store/nodetable/NodeTableInline.java
@@ -21,7 +21,6 @@
 
 import org.apache.jena.graph.Node ;
 import org.apache.jena.tdb.store.NodeId ;
-import org.apache.jena.tdb.store.nodetable.NodeTable ;
 
 /** NodeTable wrapper to handle inline node ids.
  * If a node can be made inline, then the underlying table never sees it.
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/TC_TDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/TC_TDB.java
index 2fe1429..e8c8821 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/TC_TDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/TC_TDB.java
@@ -61,6 +61,7 @@
     , TS_TDBAssembler.class
     , TS_TransactionTDB.class
     , TS_ObjectFile.class
+    , TS_ScriptsTDB1.class
 } )
 
 public class TC_TDB
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/TS_ScriptsTDB1.java b/jena-tdb/src/test/java/org/apache/jena/tdb/TS_ScriptsTDB1.java
new file mode 100644
index 0000000..92beb39
--- /dev/null
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/TS_ScriptsTDB1.java
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.apache.jena.tdb;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses( {
+    TestScriptsTDB1.class
+})
+
+public class TS_ScriptsTDB1 {}
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestSuiteGraphTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/TestScriptsTDB1.java
similarity index 65%
rename from jena-tdb/src/test/java/org/apache/jena/tdb/store/TestSuiteGraphTDB.java
rename to jena-tdb/src/test/java/org/apache/jena/tdb/TestScriptsTDB1.java
index 22cc7e7..f678d84 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TestSuiteGraphTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/TestScriptsTDB1.java
@@ -16,10 +16,9 @@
  * limitations under the License.
  */
 
-package org.apache.jena.tdb.store;
+package org.apache.jena.tdb;
 
 import junit.framework.TestSuite ;
-import org.apache.jena.tdb.ConfigTest ;
 import org.apache.jena.tdb.junit.TestFactoryTDB ;
 import org.junit.runner.RunWith ;
 import org.junit.runners.AllTests ;
@@ -27,14 +26,20 @@
 /** Scripted test generation */
 
 @RunWith(AllTests.class)
-public class TestSuiteGraphTDB extends TestSuite
+public class TestScriptsTDB1 extends TestSuite
 {
-    static public TestSuite suite() { return new TestSuiteGraphTDB() ; }
+    static final String ARQ_DIR = "../jena-arq/testing/ARQ";
+
+    static public TestSuite suite() { return new TestScriptsTDB1() ; }
     
-    private TestSuiteGraphTDB()
+    private TestScriptsTDB1()
     {
         super("TDB-Scripts") ;
-        String manifestMain = ConfigTest.getTestingDataRoot()+"/manifest.ttl" ;
-        TestFactoryTDB.make(this, manifestMain, "TDB-") ;
+//        String manifestMain1 = ConfigTest.getTestingDataRoot()+"/manifest.ttl" ;
+//        TestFactoryTDB.make(this, manifestMain1, "TDB-") ;
+        
+        // From ARQ
+        String manifestMain2 = ARQ_DIR + "/RDF-Star/SPARQL-Star/manifest.ttl";
+        TestFactoryTDB.make(this, manifestMain2, "TDB-");
     }
 }
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/junit/QueryTestTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/junit/QueryTestTDB1.java
similarity index 75%
rename from jena-tdb/src/test/java/org/apache/jena/tdb/junit/QueryTestTDB.java
rename to jena-tdb/src/test/java/org/apache/jena/tdb/junit/QueryTestTDB1.java
index d9ecc22..f1ab67c 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/junit/QueryTestTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/junit/QueryTestTDB1.java
@@ -21,7 +21,7 @@
 import java.util.List ;
 
 import org.apache.jena.query.* ;
-import org.apache.jena.rdf.model.Model ;
+import org.apache.jena.riot.RDFDataMgr;
 import org.apache.jena.sparql.SystemARQ ;
 import org.apache.jena.sparql.engine.QueryEngineFactory ;
 import org.apache.jena.sparql.engine.QueryExecutionBase ;
@@ -31,17 +31,17 @@
 import org.apache.jena.sparql.junit.TestItem ;
 import org.apache.jena.sparql.resultset.ResultSetCompare ;
 import org.apache.jena.sparql.resultset.SPARQLResult ;
+import org.apache.jena.system.Txn;
 import org.apache.jena.tdb.TDBFactory ;
-import org.apache.jena.util.FileManager ;
 import org.slf4j.Logger ;
 import org.slf4j.LoggerFactory ;
 
-public class QueryTestTDB extends EarlTestCase
+public class QueryTestTDB1 extends EarlTestCase
 {
     // Changed to using in-memory graphs/datasets because this is testing the query
     // processing.  Physical graph/datsets is in package "store". 
     
-    private static Logger log = LoggerFactory.getLogger(QueryTestTDB.class) ;
+    private static Logger log = LoggerFactory.getLogger(QueryTestTDB1.class) ;
     private Dataset dataset = null ;
 
     boolean skipThisTest = false ;
@@ -56,7 +56,7 @@
     private static List<String> currentNamedGraphs = null ;
 
     // Old style (Junit3)
-    public QueryTestTDB(String testName, EarlReport report, TestItem item)
+    public QueryTestTDB1(String testName, EarlReport report, TestItem item)
     {
         this(testName, report, item.getURI(), 
              item.getDefaultGraphURIs(), item.getNamedGraphURIs(), 
@@ -64,7 +64,7 @@
              ) ;
     }
     
-    public QueryTestTDB(String testName, EarlReport report, 
+    public QueryTestTDB1(String testName, EarlReport report, 
                         String uri,
                         List<String> dftGraphs,
                         List<String> namedGraphs,
@@ -111,11 +111,12 @@
 
         //graphLocation.clear() ;
         
+        // Allow "qt:data" to be quads in defaultGraphURIs.
         for ( String fn : defaultGraphURIs )
-            load(dataset.getDefaultModel(), fn) ;
+            RDFDataMgr.read(dataset, fn);
         
         for ( String fn : namedGraphURIs )
-            load(dataset.getNamedModel(fn), fn) ;
+            RDFDataMgr.read(dataset.getNamedModel(fn), fn) ;
     }
     
     
@@ -129,12 +130,16 @@
         }
         
         Query query = QueryFactory.read(queryFile) ;
-        Dataset ds = DatasetFactory.create(defaultGraphURIs, namedGraphURIs) ;
+        Dataset ds = DatasetFactory.create();
+        for ( String fn : defaultGraphURIs )
+            RDFDataMgr.read(ds, fn);    // Allow quads
+        for ( String fn : namedGraphURIs )
+            RDFDataMgr.read(ds.getNamedModel(fn), fn) ;
         
         // ---- First, get the expected results by executing in-memory or from a results file.
         
-        ResultSetRewindable rs1 = null ;
-        String expectedLabel = "" ;
+        ResultSetRewindable rs1;
+        String expectedLabel;
         if ( results != null )
         {
             rs1 = ResultSetFactory.makeRewindable(results.getResultSet()) ;
@@ -151,32 +156,29 @@
         
         // ---- Second, execute in persistent graph
 
-        Dataset ds2 = dataset ; //DatasetFactory.create(model) ;
-        QueryExecution qExec2 = QueryExecutionFactory.create(query, ds2) ;
-        ResultSet rs = qExec2.execSelect() ;
-        ResultSetRewindable rs2 = ResultSetFactory.makeRewindable(rs) ;
+        Dataset ds2 = dataset ;
+        Txn.executeRead(ds2, ()->{
+            QueryExecution qExec2 = QueryExecutionFactory.create(query, ds2) ;
+            ResultSet rs = qExec2.execSelect() ;
+            ResultSetRewindable rs2 = ResultSetFactory.makeRewindable(rs) ;
+
+            // See if the same.
+            boolean b = ResultSetCompare.equalsByValue(rs1, rs2) ;
+            if ( !b )
+            {
+                rs1.reset() ;
+                rs2.reset() ;
+                System.out.println("------------------- "+this.getName());
+                System.out.printf("**** Expected (%s)", expectedLabel) ;
+                ResultSetFormatter.out(System.out, rs1) ; 
+                System.out.println("**** Got (TDB)") ;
+                ResultSetFormatter.out(System.out, rs2) ;
+            }
+            assertTrue("Results sets not the same", b) ; 
+        });
         
-        // See if the same.
-        boolean b = ResultSetCompare.equalsByValue(rs1, rs2) ;
-        if ( !b )
-        {
-            rs1.reset() ;
-            rs2.reset() ;
-            System.out.println("------------------- "+this.getName());
-            System.out.printf("**** Expected (%s)", expectedLabel) ;
-            ResultSetFormatter.out(System.out, rs1) ; 
-            System.out.println("**** Got (TDB)") ;
-            ResultSetFormatter.out(System.out, rs2) ;
-        }
-        
-        assertTrue("Results sets not the same", b) ; 
     }
 
-    private static void load(Model model, String fn)
-    {
-        FileManager.get().readModel(model, fn) ;
-    }
-    
     private static boolean compareLists(List<String> list1, List<String> list2)
     {
         if ( list1 == null )
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/junit/TestFactoryTDB.java b/jena-tdb/src/test/java/org/apache/jena/tdb/junit/TestFactoryTDB.java
index 792d429..a8baa0a 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/junit/TestFactoryTDB.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/junit/TestFactoryTDB.java
@@ -18,71 +18,82 @@
 
 package org.apache.jena.tdb.junit;
 
-import junit.framework.Test ;
-import junit.framework.TestCase ;
-import junit.framework.TestSuite ;
-import org.apache.jena.rdf.model.Resource ;
-import org.apache.jena.sparql.junit.EarlReport ;
-import org.apache.jena.sparql.junit.SurpressedTest ;
-import org.apache.jena.sparql.junit.TestItem ;
-import org.apache.jena.sparql.vocabulary.TestManifestX ;
-import org.apache.jena.util.junit.TestFactoryManifest ;
+import junit.framework.Test;
+import junit.framework.TestCase;
+import junit.framework.TestSuite;
+import org.apache.jena.rdf.model.Resource;
+import org.apache.jena.sparql.junit.EarlReport;
+import org.apache.jena.sparql.junit.SurpressedTest;
+import org.apache.jena.sparql.junit.TestItem;
+import org.apache.jena.sparql.vocabulary.TestManifestX;
+import org.apache.jena.util.junit.TestFactoryManifest;
 
 public class TestFactoryTDB extends TestFactoryManifest
 {
-    public static EarlReport report = null ;
+    public static EarlReport report = null;
     
-    public static void make(TestSuite ts, String manifestFile, String testRootName)
-    {
+    public static void make(TestSuite ts, String manifestFile, String testRootName) {
         // for each graph type do
-        TestSuite ts2 = makeSuite(manifestFile, testRootName) ;
-        ts.addTest(ts2) ;
+        TestSuite ts2 = makeSuite(manifestFile, testRootName);
+        ts.addTest(ts2);
     }
-    
-    public static TestSuite makeSuite(String manifestFile, String testRootName)
-    {
-        TestFactoryTDB f = new TestFactoryTDB(testRootName) ;
-        TestSuite ts = f.process(manifestFile) ;
-        if ( testRootName != null )
-            ts.setName(testRootName+ts.getName()) ;
-        return ts ;
-    }
-    
-    // Factory
-    
-    public String testRootName ;
 
-    public TestFactoryTDB(String testRootName)
-    {
-        this.testRootName = testRootName ;
+    public static TestSuite makeSuite(String manifestFile, String testRootName) {
+        TestFactoryTDB f = new TestFactoryTDB(testRootName);
+        TestSuite ts = f.process(manifestFile);
+        if ( testRootName != null )
+            ts.setName(testRootName + ts.getName());
+        return ts;
+    }
+
+    // Factory
+
+    public String testRootName;
+
+    public TestFactoryTDB(String testRootName) {
+        this.testRootName = testRootName;
     }
     
     @Override
     protected Test makeTest(Resource manifest, Resource entry, String testName, Resource action, Resource result)
     {
         if ( testRootName != null )
-            testName = testRootName+testName ;
+            testName = testRootName+testName;
         
-        TestItem testItem = TestItem.create(entry, null) ;
+        TestItem testItem = TestItem.create(entry, null);
         
-        TestCase test = null ;
+        TestCase test = null;
         
         if ( testItem.getTestType() != null )
         {
             if ( testItem.getTestType().equals(TestManifestX.TestQuery) )
-                test = new QueryTestTDB(testName, report, testItem) ;
+                test = new QueryTestTDB1(testName, report, testItem);
             
             if ( testItem.getTestType().equals(TestManifestX.TestSurpressed) )
-                test = new SurpressedTest(testName, report, testItem) ;
+                test = new SurpressedTest(testName, report, testItem);
+            
+            // Ignore syntax tests
+            if ( testItem.getTestType().equals(TestManifestX.PositiveSyntaxTestARQ) )
+                // Ignore
+                return null;
+            if ( testItem.getTestType().equals(TestManifestX.NegativeSyntaxTestARQ) )
+                // Ignore
+                return null;
+            if ( testItem.getTestType().equals(TestManifestX.PositiveUpdateSyntaxTestARQ) )
+                // Ignore
+                return null;
+            if ( testItem.getTestType().equals(TestManifestX.NegativeUpdateSyntaxTestARQ) )
+                // Ignore
+                return null;
             
             if ( test == null )
-                System.err.println("Unrecognized test type: "+testItem.getTestType()) ;
+                System.err.println("Unrecognized test type: "+testItem.getTestType());
         }
         // Default 
         if ( test == null )
-            test = new QueryTestTDB(testName, report, testItem) ;
+            test = new QueryTestTDB1(testName, report, testItem);
 
-        return test ;
+        return test;
     }
 
 }
diff --git a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TS_Store.java b/jena-tdb/src/test/java/org/apache/jena/tdb/store/TS_Store.java
index f85c73b..5d8f355 100644
--- a/jena-tdb/src/test/java/org/apache/jena/tdb/store/TS_Store.java
+++ b/jena-tdb/src/test/java/org/apache/jena/tdb/store/TS_Store.java
@@ -37,8 +37,6 @@
     , TestDatasetGraphTDBFind.class
     , TestDatasetGraphTDBFindPattern.class
     , TestLoader.class
-    // The script suite
-    , TestSuiteGraphTDB.class
     , Test_SPARQL_TDB.class
     , TestConcurrentAccess.class
     , TestDynamicDatasetTDB.class
diff --git a/jena-tdb/testing/manifest.ttl b/jena-tdb/testing/manifest.ttl
index aeaf80e..3a0d0e9 100644
--- a/jena-tdb/testing/manifest.ttl
+++ b/jena-tdb/testing/manifest.ttl
@@ -27,5 +27,3 @@
         <Values/manifest.ttl>
         <UnionGraph/manifest.ttl>
     ) .
-
-