This is an automated email from the ASF dual-hosted git repository.

andy pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/jena.git

commit 2962991f1a819c695d18fa8e12f27c7607c78bdc
Author: Andy Seaborne <[email protected]>
AuthorDate: Wed May 14 19:23:48 2025 +0100

    GH-3194: Deprecation-removal of Graph.getCapabilities
---
 .../org/apache/jena/sparql/graph/GraphWrapper.java |    8 +-
 .../org/apache/jena/sparql/core/TestSpecials.java  |   34 +-
 .../src/main/java/org/apache/jena/graph/Graph.java |   12 +-
 .../java/org/apache/jena/graph/compose/Delta.java  |   11 +-
 .../org/apache/jena/graph/compose/Polyadic.java    |   11 +-
 .../java/org/apache/jena/graph/impl/GraphBase.java |    5 -
 .../org/apache/jena/graph/impl/GraphMatcher.java   |   25 +-
 .../org/apache/jena/graph/impl/GraphPlain.java     |   10 -
 .../org/apache/jena/graph/impl/WrappedGraph.java   |    1 +
 .../main/java/org/apache/jena/mem2/GraphMem2.java  |   11 +-
 .../org/apache/jena/reasoner/BaseInfGraph.java     |    1 +
 .../org/apache/jena/graph/GraphContractTest.java   | 1525 ++++++++++++++++++++
 .../apache/jena/graph/compose/test/TestDelta.java  |    2 +-
 .../jena/graph/compose/test/TestDifference.java    |    2 +-
 .../jena/graph/compose/test/TestDisjointUnion.java |    2 +-
 .../jena/graph/compose/test/TestIntersection.java  |    2 +-
 .../jena/graph/compose/test/TestMultiUnion.java    |    2 +-
 .../apache/jena/graph/compose/test/TestUnion.java  |    2 +-
 .../apache/jena/graph/test/AbstractTestGraph.java  |  199 +--
 .../org/apache/jena/graph/test/MetaTestGraph.java  |    2 +-
 .../apache/jena/graph/test/TestGraphListener.java  |    4 +-
 .../org/apache/jena/mem/test/TestGraphMem2.java    |    2 +-
 .../apache/jena/mem/test/TestGraphMemValue.java    |  276 +++-
 .../apache/jena/ontology/impl/TestOntGraph.java    |    2 +-
 .../rulesys/test/FRuleEngineIFactoryTest.java      |    3 -
 .../apache/jena/reasoner/test/TestInfGraph.java    |    2 +-
 .../contract/graph/SecuredGraphContractTests.java  |    2 +-
 .../contract/graph/SecuredGraphListenerTest.java   |    2 +-
 .../graph/SecuredTDBGraphContractTests.java        |    2 +-
 29 files changed, 1894 insertions(+), 268 deletions(-)

diff --git 
a/jena-arq/src/main/java/org/apache/jena/sparql/graph/GraphWrapper.java 
b/jena-arq/src/main/java/org/apache/jena/sparql/graph/GraphWrapper.java
index 7a58057e62..3c150f58e3 100644
--- a/jena-arq/src/main/java/org/apache/jena/sparql/graph/GraphWrapper.java
+++ b/jena-arq/src/main/java/org/apache/jena/sparql/graph/GraphWrapper.java
@@ -50,10 +50,10 @@ public class GraphWrapper implements Graph
         return get().getTransactionHandler();
     }
 
-    @Override
-    public Capabilities getCapabilities() {
-        return get().getCapabilities();
-    }
+//    @Override
+//    public Capabilities getCapabilities() {
+//        return get().getCapabilities();
+//    }
 
     @Override
     public GraphEventManager getEventManager() {
diff --git 
a/jena-arq/src/test/java/org/apache/jena/sparql/core/TestSpecials.java 
b/jena-arq/src/test/java/org/apache/jena/sparql/core/TestSpecials.java
index b2ac2ad683..2b2882e87c 100644
--- a/jena-arq/src/test/java/org/apache/jena/sparql/core/TestSpecials.java
+++ b/jena-arq/src/test/java/org/apache/jena/sparql/core/TestSpecials.java
@@ -46,26 +46,26 @@ import org.junit.Test;
  * {@link GraphSink}
 */
 public class TestSpecials {
-    
+
     private static Quad quad = SSE.parseQuad("(:g :s :p :o)");
     private static Triple triple = SSE.parseTriple("(:s :p :o)");
     private static Node gn = SSE.parseNode(":gn");
-    
+
     // -- zero
-    
+
     @Test public void zero_basic_1() {
         DatasetGraph dsg = DatasetGraphZero.create();
         assertFalse(dsg.find().hasNext());
         assertTrue(dsg.supportsTransactionAbort());
         assertEquals(0, dsg.getDefaultGraph().size());
-        assertFalse(dsg.getDefaultGraph().getCapabilities().addAllowed());
+        //assertFalse(dsg.getDefaultGraph().getCapabilities().addAllowed());
     }
-    
+
     @Test public void zero_basic_2() {
         DatasetGraph dsg = DatasetGraphZero.create();
         assertNull(dsg.getGraph(gn));
     }
-    
+
     @Test(expected=UnsupportedOperationException.class)
     public void zero_add_1() {
         DatasetGraph dsg = DatasetGraphZero.create();
@@ -120,7 +120,7 @@ public class TestSpecials {
         DatasetGraph dsg = DatasetGraphZero.create();
         dsg.commit();
     }
-    
+
     @Test(expected=JenaTransactionException.class)
     public void zero_txn_4() {
         DatasetGraph dsg = DatasetGraphZero.create();
@@ -128,7 +128,7 @@ public class TestSpecials {
         dsg.commit();
         dsg.commit();
     }
-    
+
     @Test public void zero_graph_txn_1() {
         DatasetGraph dsg = DatasetGraphZero.create();
         Graph g = dsg.getDefaultGraph();
@@ -169,22 +169,22 @@ public class TestSpecials {
         TransactionHandler h = g.getTransactionHandler();
         h.commit();
     }
-    
+
     // -- sink
-    
+
     @Test public void sink_basic_1() {
         DatasetGraph dsg = DatasetGraphSink.create();
         assertFalse(dsg.find().hasNext());
         assertTrue(dsg.supportsTransactionAbort());
         assertEquals(0, dsg.getDefaultGraph().size());
-        assertTrue(dsg.getDefaultGraph().getCapabilities().addAllowed());
+        //assertTrue(dsg.getDefaultGraph().getCapabilities().addAllowed());
     }
-    
+
     @Test public void sink_basic_2() {
         DatasetGraph dsg = DatasetGraphSink.create();
         assertNull(dsg.getGraph(gn));
     }
-    
+
     @Test public void sink_add_1() {
         DatasetGraph dsg = DatasetGraphSink.create();
         dsg.add(quad);
@@ -210,7 +210,7 @@ public class TestSpecials {
         DatasetGraph dsg = DatasetGraphSink.create();
         dsg.getDefaultGraph().add(triple);
     }
-    
+
     @Test
     public void sink_delete_3() {
         DatasetGraph dsg = DatasetGraphSink.create();
@@ -222,7 +222,7 @@ public class TestSpecials {
         Txn.executeRead(dsg, ()->{});
         Txn.executeWrite(dsg, ()->{});
     }
-    
+
     @Test(expected=JenaTransactionException.class)
     public void sink_txn_2() {
         DatasetGraph dsg = DatasetGraphSink.create();
@@ -235,7 +235,7 @@ public class TestSpecials {
         DatasetGraph dsg = DatasetGraphSink.create();
         dsg.commit();
     }
-    
+
     @Test(expected=JenaTransactionException.class)
     public void sink_txn_4() {
         DatasetGraph dsg = DatasetGraphSink.create();
@@ -243,7 +243,7 @@ public class TestSpecials {
         dsg.commit();
         dsg.commit();
     }
-    
+
     @Test public void sink_graph_txn_1() {
         DatasetGraph dsg = DatasetGraphSink.create();
         Graph g = dsg.getDefaultGraph();
diff --git a/jena-core/src/main/java/org/apache/jena/graph/Graph.java 
b/jena-core/src/main/java/org/apache/jena/graph/Graph.java
index 330fd62356..bb6c43ae68 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/Graph.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/Graph.java
@@ -22,6 +22,7 @@ import java.util.Objects;
 import java.util.stream.Stream;
 
 import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.impl.AllCapabilities;
 import org.apache.jena.graph.impl.GraphBase ;
 import org.apache.jena.shared.AddDeniedException ;
 import org.apache.jena.shared.DeleteDeniedException ;
@@ -57,7 +58,7 @@ public interface Graph {
 
     /**
         true if this graph's content depends on the other graph. May be
-        pessimistic (ie return true if it's not sure). Typically true when a
+        pessimistic (i.e. return true if it's not sure). Typically true when a
         graph is a composition of other graphs, eg union.
 
          @param other the graph this graph may depend on
@@ -68,8 +69,13 @@ public interface Graph {
     /** returns this Graph's transaction handler */
     TransactionHandler getTransactionHandler();
 
-    /** returns this Graph's capabilities */
-    Capabilities getCapabilities();
+
+    /**
+     * returns this Graph's capabilities
+     * @deprecated To be removed.
+     */
+    @Deprecated(forRemoval = true)
+    default Capabilities getCapabilities() { return 
AllCapabilities.updateAllowed; }
 
     /**
         Answer this Graph's event manager.
diff --git a/jena-core/src/main/java/org/apache/jena/graph/compose/Delta.java 
b/jena-core/src/main/java/org/apache/jena/graph/compose/Delta.java
index a54521cad2..eeea73cee5 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/compose/Delta.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/compose/Delta.java
@@ -18,7 +18,6 @@
 
 package org.apache.jena.graph.compose;
 
-import org.apache.jena.graph.Capabilities;
 import org.apache.jena.graph.Graph;
 import org.apache.jena.graph.Triple;
 import org.apache.jena.graph.impl.GraphPlain;
@@ -45,11 +44,11 @@ public class Delta extends CompositionBase implements Graph 
{
         this.deletions = GraphPlain.plain();
     }
 
-    @Override
-    public Capabilities getCapabilities() {
-        // Not strictly accurate.
-        return base.getCapabilities();
-    }
+//    @Override
+//    public Capabilities getCapabilities() {
+//        // Not strictly accurate.
+//        return base.getCapabilities();
+//    }
 
     /**
      * Answer the graph of all triples added.
diff --git 
a/jena-core/src/main/java/org/apache/jena/graph/compose/Polyadic.java 
b/jena-core/src/main/java/org/apache/jena/graph/compose/Polyadic.java
index 9f2d6cb600..8c531dcdc1 100755
--- a/jena-core/src/main/java/org/apache/jena/graph/compose/Polyadic.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/compose/Polyadic.java
@@ -27,7 +27,6 @@ import java.util.ArrayList ;
 import java.util.Iterator ;
 import java.util.List ;
 
-import org.apache.jena.graph.Capabilities ;
 import org.apache.jena.graph.Graph ;
 import org.apache.jena.graph.TransactionHandler ;
 import org.apache.jena.shared.JenaException ;
@@ -92,10 +91,10 @@ public abstract class Polyadic extends CompositionBase
 
     @Override
     protected PrefixMapping createPrefixMapping()
-    { 
+    {
         return new PolyadicPrefixMappingImpl( this );
     }
-    
+
     /**
      * <p>
      * Construct a composition of all of the given graphs.
@@ -263,10 +262,4 @@ public abstract class Polyadic extends CompositionBase
     public TransactionHandler getTransactionHandler() {
         return (getBaseGraph() == null) ? super.getTransactionHandler() : 
getBaseGraph().getTransactionHandler();
         }
-
-    @Override
-    public Capabilities getCapabilities() {
-        return (getBaseGraph() == null) ? super.getCapabilities() : 
getBaseGraph().getCapabilities();
-    }
-
 }
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/GraphBase.java 
b/jena-core/src/main/java/org/apache/jena/graph/impl/GraphBase.java
index a3d0cb446f..64be06a73d 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/GraphBase.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/GraphBase.java
@@ -127,11 +127,6 @@ public abstract class GraphBase implements GraphWithPerform
     public TransactionHandler getTransactionHandler()
         { return new SimpleTransactionHandler(); }
 
-    @Override
-    public Capabilities getCapabilities() {
-        return AllCapabilities.updateAllowed;
-    }
-
     /**
         Answer the PrefixMapping object for this graph, the same one each time.
      */
diff --git 
a/jena-core/src/main/java/org/apache/jena/graph/impl/GraphMatcher.java 
b/jena-core/src/main/java/org/apache/jena/graph/impl/GraphMatcher.java
index a0465b63b1..5d9ebcd0af 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/GraphMatcher.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/GraphMatcher.java
@@ -22,6 +22,7 @@ import static 
org.apache.jena.util.iterator.WrappedIterator.create;
 import java.util.*;
 
 import org.apache.jena.graph.* ;
+import org.apache.jena.reasoner.InfGraph;
 import org.apache.jena.shared.* ;
 import org.apache.jena.util.CollectionFactory ;
 import org.apache.jena.util.iterator.* ;
@@ -153,12 +154,24 @@ public class GraphMatcher extends java.lang.Object {
         // check that the size's are the same.
         // If the size is not accurate then it is a lower bound
 
-        if (m.getCapabilities().sizeAccurate()
-                && m.size() < other.m.size() )
-            return null;
-        if (other.m.getCapabilities().sizeAccurate()
-                && m.size() > other.m.size() )
-            return null;
+//        @SuppressWarnings("removal")
+//        boolean testForSize = m.getCapabilities().sizeAccurate() && 
other.m.getCapabilities().sizeAccurate() ;
+        boolean testForSize = ! ( m instanceof InfGraph || other.m instanceof 
InfGraph );
+        if ( testForSize ) {
+            if ( m.size() != -1 && ( m.size() != other.m.size() ) )
+                return null;
+        }
+
+        // Old code up to Jena 5.4.0, prior to removing capabilities.
+        // Size is lower bound
+        // Only InfGraphs have inaccurate size (GraphMatech is not designed 
for large database-stored graphs.
+
+//        if (m.getCapabilities().sizeAccurate()
+//                && m.size() < other.m.size() )
+//            return null;
+//        if (other.m.getCapabilities().sizeAccurate()
+//                && m.size() > other.m.size() )
+//            return null;
         int myPrep = prepare(other.m);
         if ( myPrep == -1 || myPrep != other.prepare(m) ) {
             return null;
diff --git a/jena-core/src/main/java/org/apache/jena/graph/impl/GraphPlain.java 
b/jena-core/src/main/java/org/apache/jena/graph/impl/GraphPlain.java
index ded3b415c8..5b46af032a 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/GraphPlain.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/GraphPlain.java
@@ -57,20 +57,10 @@ public class GraphPlain extends WrappedGraph
         return plain(GraphMemFactory.createDefaultGraph());
     }
 
-    private final Capabilities capabilities;
-
     private GraphPlain(Graph other) {
         super(other);
-        capabilities = new WrappedCapabilities(base.getCapabilities()) {
-            @Override public boolean handlesLiteralTyping() { return false; }
-        };
     }
 
-    @Override
-       public Capabilities getCapabilities() {
-               return capabilities;
-       }
-
     @Override
     public void remove( Node s, Node p, Node o ) {
         GraphUtil.remove(this, s, p, o) ;
diff --git 
a/jena-core/src/main/java/org/apache/jena/graph/impl/WrappedGraph.java 
b/jena-core/src/main/java/org/apache/jena/graph/impl/WrappedGraph.java
index af57d05be4..8de2b3ad92 100644
--- a/jena-core/src/main/java/org/apache/jena/graph/impl/WrappedGraph.java
+++ b/jena-core/src/main/java/org/apache/jena/graph/impl/WrappedGraph.java
@@ -43,6 +43,7 @@ public class WrappedGraph implements GraphWithPerform
     public TransactionHandler getTransactionHandler()
     { return base.getTransactionHandler(); }
 
+    @Deprecated(forRemoval = true)
     @Override
     public Capabilities getCapabilities()
     { return base.getCapabilities(); }
diff --git a/jena-core/src/main/java/org/apache/jena/mem2/GraphMem2.java 
b/jena-core/src/main/java/org/apache/jena/mem2/GraphMem2.java
index cb2be229ce..04750138e6 100644
--- a/jena-core/src/main/java/org/apache/jena/mem2/GraphMem2.java
+++ b/jena-core/src/main/java/org/apache/jena/mem2/GraphMem2.java
@@ -18,18 +18,16 @@
 
 package org.apache.jena.mem2;
 
+import java.util.stream.Stream;
+
 import org.apache.jena.atlas.lib.Copyable;
-import org.apache.jena.graph.Capabilities;
 import org.apache.jena.graph.Node;
 import org.apache.jena.graph.Triple;
-import org.apache.jena.graph.impl.AllCapabilities;
 import org.apache.jena.graph.impl.GraphWithPerform;
 import org.apache.jena.mem.GraphMemBase;
 import org.apache.jena.mem2.store.TripleStore;
 import org.apache.jena.util.iterator.ExtendedIterator;
 
-import java.util.stream.Stream;
-
 /**
  * A graph that stores triples in memory. This class is not thread-safe.
  * All triples are stored in a {@link TripleStore}.
@@ -143,11 +141,6 @@ public class GraphMem2 extends GraphMemBase implements 
GraphWithPerform, Copyabl
         return this.tripleStore.countTriples();
     }
 
-    @Override
-    public Capabilities getCapabilities() {
-        return AllCapabilities.updateAllowed;
-    }
-
     /**
      * Creates a copy of this graph.
      * Since the triples and nodes are immutable, the copy contains the same 
triples and nodes as this graph.
diff --git a/jena-core/src/main/java/org/apache/jena/reasoner/BaseInfGraph.java 
b/jena-core/src/main/java/org/apache/jena/reasoner/BaseInfGraph.java
index c3f3ee72b6..1412b21d54 100644
--- a/jena-core/src/main/java/org/apache/jena/reasoner/BaseInfGraph.java
+++ b/jena-core/src/main/java/org/apache/jena/reasoner/BaseInfGraph.java
@@ -74,6 +74,7 @@ public abstract class BaseInfGraph extends GraphBase 
implements InfGraph {
     private Capabilities calcCapabilitiesFrom(Graph data) {
         if ( data == null )
             return reasonerInfCapabilities;
+
         // Same as data graph except size is not accurate.
         Capabilities baseCapabilities = data.getCapabilities();
         return AllCapabilities.create(false,
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
new file mode 100644
index 0000000000..6a1353ba13
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/GraphContractTest.java
@@ -0,0 +1,1525 @@
+/*
+ * 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.graph;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import static org.junit.Assert.*;
+
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.function.Function;
+
+import org.apache.jena.mem.TrackingTripleIterator;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.ModelFactory;
+import org.apache.jena.rdf.model.impl.ReifierStd;
+import org.apache.jena.shared.ClosedException;
+import org.apache.jena.shared.DeleteDeniedException;
+import org.apache.jena.shared.PrefixMapping;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.apache.jena.testing_framework.NodeCreateUtils;
+import org.apache.jena.util.iterator.ClosableIterator;
+import org.apache.jena.util.iterator.ExtendedIterator;
+import org.junit.After;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+/**
+ * Graph contract test.
+ */
+@Contract(Graph.class)
+public class GraphContractTest<T extends Graph>
+{
+
+       private static final Logger LOG = LoggerFactory
+                       .getLogger(GraphContractTest.class);
+
+       private AbstractGraphProducer<T> producer;
+
+       protected RecordingGraphListener GL = new RecordingGraphListener();
+
+       @Contract.Inject
+       public final void setGraphContractTestProducer(
+                       AbstractGraphProducer<T> graphProducer)
+       {
+               producer = graphProducer;
+       }
+
+       @After
+       public final void afterGraphContractTest()
+       {
+               producer.cleanUp();
+               GL.clear();
+       }
+
+       @ContractTest
+       public void testAdd_Triple()
+       {
+               Graph graph = producer.newInstance();
+               graph.getEventManager().register(GL);
+               txnBegin(graph);
+               graph.add(triple("S P O"));
+               txnCommit(graph);
+               GL.assertHasStart("add", graph, triple("S P O"));
+               txnRun(graph, () -> assertTrue("Graph should contain <S P O>",
+                               graph.contains(triple("S P O"))));
+
+       }
+
+       /**
+        * Inference graphs can not be truly empty.
+        *
+        * @param g
+        * @param b
+        */
+       private void assertEmpty(Graph g, Graph b)
+       {
+               if (b.isEmpty())
+               {
+                       assertTrue("Graph should be empty", g.isEmpty());
+               } else
+               {
+                       assertEquals("Graph should be in base state",
+                                       b.find(Triple.ANY).toList(), 
g.find(Triple.ANY).toList());
+               }
+       }
+
+       /**
+        * Inference graphs can not be truly empty
+        *
+        * @param g
+        * @param b
+        */
+       private void assertNotEmpty(Graph g, Graph b)
+       {
+               if (b.isEmpty())
+               {
+                       assertFalse("Graph not should be empty", g.isEmpty());
+               } else
+               {
+                       assertNotEquals("Graph should not be in base state",
+                                       b.find(Triple.ANY).toList(), 
g.find(Triple.ANY).toList());
+               }
+       }
+
+       @SuppressWarnings("deprecation")
+    private static boolean xsupportsLiteralTyping(Graph g) {
+           //return g.getCapabilities().handlesLiteralTyping();
+           return g instanceof org.apache.jena.mem.GraphMem;
+    }
+
+    /**
+        * Test that clear works, in the presence of inferencing graphs that 
mean
+        * emptyness isn't available. This is why we go round the houses and 
test
+        * that expected ~= initialContent + addedStuff - removed - 
initialContent.
+        */
+       @ContractTest
+       public void testClear_Empty()
+       {
+               Graph graph = producer.newInstance();
+               Graph base = copy(graph);
+
+               graph.getEventManager().register(GL);
+               txnRun(graph, () -> graph.clear());
+
+               txnRun(graph, () -> assertEmpty(graph, base));
+               GL.assertHasStart("someEvent", graph, GraphEvents.removeAll);
+               GL.clear();
+       }
+
+       @ContractTest
+       public void testClear()
+       {
+               Graph graph = producer.newInstance();
+               Graph base = copy(graph);
+               // test after adding
+               graphWith(graph, "S P O; S e:ff 27; _1 P P3; S4 P4 'en'");
+               graph.getEventManager().register(GL);
+               txnRun(graph, () -> graph.clear());
+
+               txnRun(graph, () -> assertEmpty(graph, base));
+               if (GL.contains("delete"))
+               {
+                       // deletes are listed -- ensure all deletes are listed
+                       GL.assertContains("delete", graph, triple("S P O"));
+                       GL.assertContains("delete", graph, triple("S e:ff 27"));
+                       GL.assertContains("delete", graph, triple("_1 P P3"));
+                       GL.assertContains("delete", graph, triple("S4 P4 
'en'"));
+               }
+               GL.assertHasEnd("someEvent", graph, GraphEvents.removeAll);
+               GL.clear();
+
+       }
+
+       @ContractTest
+       public void testClose()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S P2 O2; S3 P P3");
+               graph.getEventManager().register(GL);
+               assertFalse("Graph was constructed closed", graph.isClosed());
+
+               txnRun(graph, () -> graph.close());
+
+               assertTrue("Graph should be closed", graph.isClosed());
+
+               // exception may be thrown on begin or on execution.
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.add(triple("S P O"));
+                               fail("added when closed");
+                       } catch (Exception expected)
+                       {
+                               GL.assertEmpty();
+                               // expected
+                       } finally
+                       {
+                               txnRollback(graph);
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.delete(triple("x R y"));
+                               fail("delete when closed");
+                       } catch (ClosedException c)
+                       {
+                               // Expected
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+
+                       try
+                       {
+                               graph.add(triple("x R y"));
+                               fail("add when closed");
+                       } catch (ClosedException c)
+                       { /* as required */
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.contains(triple("x R y"));
+                               fail("contains[triple] when closed");
+                       } catch (ClosedException c)
+                       { /* as required */
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.contains(Node.ANY, Node.ANY, Node.ANY);
+                               fail("contains[SPO] when closed");
+                       } catch (ClosedException c)
+                       { /* as required */
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.find(triple("x R y"));
+                               fail("find [triple] when closed");
+                       } catch (ClosedException c)
+                       { /* as required */
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.find(Node.ANY, Node.ANY, Node.ANY);
+                               fail("find[SPO] when closed");
+                       } catch (ClosedException c)
+                       { /* as required */
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+
+               try
+               {
+                       txnBegin(graph);
+                       try
+                       {
+                               graph.size();
+                               fail("size when closed (" + this.getClass() + 
")");
+                       } catch (ClosedException c)
+                       { /* as required */
+                       } finally
+                       {
+                               txnRollback(graph);
+                               GL.assertEmpty();
+                       }
+               } catch (Exception expected)
+               {
+                       GL.assertEmpty();
+                       // expected
+               }
+       }
+
+       @ContractTest
+       public void testContains_Node_Node_Node()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+
+               txnRun(graph, () -> {
+                       assertTrue(graph.contains(node("S"), node("P"), 
node("O")));
+                       assertFalse(graph.contains(node("S"), node("P"), 
node("O2")));
+                       assertFalse(graph.contains(node("S"), node("P2"), 
node("O")));
+                       assertFalse(graph.contains(node("S2"), node("P"), 
node("O")));
+                       assertTrue(graph.contains(Node.ANY, Node.ANY, 
Node.ANY));
+                       assertTrue(graph.contains(Node.ANY, Node.ANY, 
node("O")));
+                       assertTrue(graph.contains(Node.ANY, node("P"), 
Node.ANY));
+                       assertTrue(graph.contains(node("S"), Node.ANY, 
Node.ANY));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Node_Node_Node_RepeatedSubjectDoesNotConceal()
+       {
+
+               Graph g = graphWith(producer.newInstance(), "s P o; s Q r");
+               Node s = node("s");
+               Node P = node("P");
+               Node o = node("o");
+               Node Q = node("Q");
+               Node r = node("r");
+               Node any = node("??");
+               txnRun(g, () -> {
+                       assertTrue(g.contains(s, P, o));
+                       assertTrue(g.contains(s, Q, r));
+                       assertTrue(g.contains(any, P, o));
+                       assertTrue(g.contains(any, Q, r));
+                       assertTrue(g.contains(any, P, any));
+                       assertTrue(g.contains(any, Q, any));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Node_Node_Node_Concrete()
+       {
+               Node s = node("s");
+               Node P = node("P");
+               Node o = node("o");
+
+               Node _x = node("_x");
+               Node R = node("R");
+               Node _y = node("_y");
+
+               Node x = node("x");
+               Node S = node("S");
+
+               Graph g = graphWith(producer.newInstance(), "s P o; _x R _y; x 
S 0");
+               txnRun(g, () -> {
+
+                       assertTrue("Graph should have contained s P o",
+                                       g.contains(s, P, o));
+                       assertTrue("Graph should have contained _x _R _y",
+                                       g.contains(_x, R, _y));
+                       assertTrue("Graph should have contained x S 'O'",
+                                       g.contains(x, S, node("0")));
+                       /* */
+                       assertFalse(g.contains(s, P, node("Oh")));
+                       assertFalse(g.contains(S, P, node("O")));
+                       assertFalse(g.contains(s, node("p"), o));
+                       assertFalse(g.contains(_x, node("_r"), _y));
+                       assertFalse(g.contains(x, S, node("1")));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Node_Node_Node_Concrete_BlankPredicate()
+       {
+               Node s = node("s");
+               Node P = node("P");
+               Node o = node("o");
+
+               Node _x = node("_x");
+               Node _R = node("_R");
+               Node _y = node("_y");
+
+               Node x = node("x");
+               Node S = node("S");
+
+               Graph g = graphWith(producer.newInstance(), "s P o; _x _R _y; x 
S 0");
+               txnRun(g, () -> {
+
+                       assertTrue("Graph should have contained _x _R _y",
+                                       g.contains(_x, _R, _y));
+                       assertFalse(g.contains(_x, node("_r"), _y));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Node_Node_Node_Fluid()
+       {
+               Node x = node("x");
+               Node R = node("R");
+               Node P = node("P");
+               Node y = node("y");
+               Node a = node("a");
+               Node b = node("b");
+               Graph g = graphWith(producer.newInstance(), "x R y; a P b");
+
+               txnRun(g, () -> {
+                       assertTrue(g.contains(Node.ANY, R, y));
+                       assertTrue(g.contains(x, Node.ANY, y));
+                       assertTrue(g.contains(x, R, Node.ANY));
+                       assertTrue(g.contains(Node.ANY, P, b));
+                       assertTrue(g.contains(a, Node.ANY, b));
+                       assertTrue(g.contains(a, P, Node.ANY));
+                       assertTrue(g.contains(Node.ANY, R, y));
+                       /* */
+                       assertFalse(g.contains(Node.ANY, R, b));
+                       assertFalse(g.contains(a, Node.ANY, y));
+                       assertFalse(g.contains(x, P, Node.ANY));
+                       assertFalse(g.contains(Node.ANY, R, x));
+                       assertFalse(g.contains(x, Node.ANY, R));
+                       assertFalse(g.contains(a, node("S"), Node.ANY));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Triple()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               txnRun(graph, () -> {
+                       assertTrue(graph.contains(triple("S P O")));
+                       assertFalse(graph.contains(triple("S P O2")));
+                       assertFalse(graph.contains(triple("S P2 O")));
+                       assertFalse(graph.contains(triple("S2 P O")));
+                       assertTrue(graph.contains(Triple.ANY));
+                       assertTrue(
+                                       graph.contains(Triple.create(Node.ANY, 
Node.ANY, node("O"))));
+                       assertTrue(
+                                       graph.contains(Triple.create(Node.ANY, 
node("P"), Node.ANY)));
+                       assertTrue(
+                                       graph.contains(Triple.create(node("S"), 
Node.ANY, Node.ANY)));
+               });
+
+       }
+
+       @ContractTest
+       public void testContains_Triple_RepeatedSubjectDoesNotConceal()
+       {
+
+               Graph g = graphWith(producer.newInstance(), "s P o; s Q r");
+               txnRun(g, () -> {
+                       assertTrue(g.contains(triple("s P o")));
+                       assertTrue(g.contains(triple("s Q r")));
+                       assertTrue(g.contains(triple("?? P o")));
+                       assertTrue(g.contains(triple("?? Q r")));
+                       assertTrue(g.contains(triple("?? P ??")));
+                       assertTrue(g.contains(triple("?? Q ??")));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Triple_Concrete()
+       {
+               Graph g = graphWith(producer.newInstance(), "s P o; _x R _y; x 
S 0");
+               txnRun(g, () -> {
+                       assertTrue(g.contains(triple("s P o")));
+                       assertTrue(g.contains(triple("_x R _y")));
+                       assertTrue(g.contains(triple("x S 0")));
+                       /* */
+                       assertFalse(g.contains(triple("s P Oh")));
+                       assertFalse(g.contains(triple("S P O")));
+                       assertFalse(g.contains(triple("s p o")));
+                       assertFalse(g.contains(triple("_x _r _y")));
+                       assertFalse(g.contains(triple("x S 1")));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Triple_Concrete_BlankPredicate()
+       {
+               Graph g = graphWith(producer.newInstance(), "s P o; _x _R _y; x 
S 0");
+               txnRun(g, () -> {
+                       assertTrue(g.contains(triple("s P o")));
+                       assertTrue(g.contains(triple("_x _R _y")));
+                       assertTrue(g.contains(triple("x S 0")));
+                       /* */
+                       assertFalse(g.contains(triple("s P Oh")));
+                       assertFalse(g.contains(triple("S P O")));
+                       assertFalse(g.contains(triple("s p o")));
+                       assertFalse(g.contains(triple("_x _r _y")));
+                       assertFalse(g.contains(triple("x S 1")));
+               });
+       }
+
+       @ContractTest
+       public void testContains_Triple_Fluid()
+       {
+               Graph g = graphWith(producer.newInstance(), "x R y; a P b");
+               txnRun(g, () -> {
+
+                       assertTrue(g.contains(triple("?? R y")));
+                       assertTrue(g.contains(triple("x ?? y")));
+                       assertTrue(g.contains(triple("x R ??")));
+                       assertTrue(g.contains(triple("?? P b")));
+                       assertTrue(g.contains(triple("a ?? b")));
+                       assertTrue(g.contains(triple("a P ??")));
+                       assertTrue(g.contains(triple("?? R y")));
+                       /* */
+                       assertFalse(g.contains(triple("?? R b")));
+                       assertFalse(g.contains(triple("a ?? y")));
+                       assertFalse(g.contains(triple("x P ??")));
+                       assertFalse(g.contains(triple("?? R x")));
+                       assertFalse(g.contains(triple("x ?? R")));
+                       assertFalse(g.contains(triple("a S ??")));
+               });
+       }
+
+       /**
+        * Inference graphs can not be empty
+        */
+       @ContractTest
+       public void testDelete_Triple()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               Graph base = producer.newInstance();
+               graph.getEventManager().register(GL);
+
+               try
+               {
+                       txnBegin(graph);
+                       graph.delete(triple("S P O"));
+                       txnCommit(graph);
+               } catch (DeleteDeniedException expected)
+               {
+                       txnRollback(graph);
+                       fail("delete( S P O ) failed: " + 
expected.getMessage());
+               }
+
+               GL.assertContains("delete", graph, triple("S P O"));
+
+               txnRun(graph, () -> {
+                       assertFalse("Graph should not contain <S P O>",
+                                       graph.contains(triple("S P O")));
+                       assertNotEmpty(graph, base);
+                       assertTrue("Graph should contain <S2 P2 O2>",
+                                       graph.contains(triple("S2 P2 O2")));
+                       assertTrue("Graph should contain <S3 P3 O3>",
+                                       graph.contains(triple("S3 P3 O3")));
+               });
+       }
+
+       @ContractTest
+       public void testDelete_Triple_Wildcard()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               Graph base = producer.newInstance();
+               graph.getEventManager().register(GL);
+
+               // should not modify anything on wildcard delete
+               GL.clear();
+               try
+               {
+                       txnBegin(graph);
+                       graph.delete(Triple.create(node("S2"), node("P2"), 
Node.ANY));
+                       txnCommit(graph);
+               } catch (DeleteDeniedException expected)
+               {
+                       txnRollback(graph);
+               }
+               txnRun(graph, () -> {
+
+                       assertTrue("Graph should contain <S2 P2 O2>",
+                                       graph.contains(triple("S2 P2 O2")));
+                       assertTrue("Graph should contain <S3 P3 O3>",
+                                       graph.contains(triple("S3 P3 O3")));
+               });
+               GL.assertHas("delete", graph,
+                               Triple.create(node("S2"), node("P2"), 
Node.ANY));
+       }
+
+       @ContractTest
+       public void testDelete_Triple_FromNothing()
+       {
+               Graph g = producer.newInstance();
+               g.getEventManager().register(GL);
+               txnBegin(g);
+               g.delete(triple("quint rdf:subject S"));
+               txnCommit(g);
+               GL.assertContains("delete", g, triple("quint rdf:subject S"));
+       }
+
+       @ContractTest
+       public void testDependsOn()
+       {
+               Graph g = producer.newInstance();
+               Graph[] depGraphs = producer.getDependsOn(g);
+               if (depGraphs != null)
+               {
+                       for (Graph dg : depGraphs)
+                       {
+                               assertTrue(
+                                               String.format("Graph %s should 
depend upon %s", g, dg),
+                                               g.dependsOn(dg));
+                       }
+               }
+               depGraphs = producer.getNotDependsOn(g);
+               if (depGraphs != null)
+               {
+                       for (Graph dg : depGraphs)
+                       {
+                               assertFalse(String.format("Graph %s should not 
depend upon %s",
+                                               g, dg), g.dependsOn(dg));
+                       }
+               }
+       }
+
+       @ContractTest
+       public void testFind_Node_Node_Node()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               txnBegin(graph);
+               List<Triple> s = graph.find(Node.ANY, Node.ANY, 
Node.ANY).toList();
+               assertEquals(3, s.size());
+               List<Triple> expected = Arrays.asList(new Triple[] { triple("S 
P O"),
+                               triple("S2 P2 O2"), triple("S3 P3 O3") });
+               assertTrue("Missing some values",
+                               expected.containsAll(s) && 
s.containsAll(expected));
+
+               s = graph.find(node("S"), Node.ANY, Node.ANY).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S P O")));
+
+               s = graph.find(Node.ANY, node("P"), Node.ANY).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S P O")));
+
+               s = graph.find(Node.ANY, Node.ANY, node("O")).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S P O")));
+
+               s = graph.find(node("S2"), node("P2"), node("O2")).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S2 P2 
O2")));
+
+               s = graph.find(node("S2"), node("P3"), node("O2")).toList();
+               assertEquals(0, s.size());
+
+               s = graph.find(Node.ANY, node("P3"), node("O2")).toList();
+               assertEquals(0, s.size());
+
+               s = graph.find(node("S3"), Node.ANY, node("O2")).toList();
+               assertEquals(0, s.size());
+
+               s = graph.find(node("S3"), node("P2"), Node.ANY).toList();
+               assertEquals(0, s.size());
+               txnRollback(graph);
+       }
+
+       @ContractTest
+       public void testFind_Node_Node_Node_ByFluidTriple()
+       {
+               Node x = node("x");
+               Node y = node("y");
+               Node z = node("z");
+               Graph g = graphWith(producer.newInstance(), "x y z ");
+               Set<Triple> expect = tripleSet("x y z");
+               txnBegin(g);
+               assertEquals(expect, g.find(Node.ANY, y, z).toSet());
+               assertEquals(expect, g.find(x, Node.ANY, z).toSet());
+               assertEquals(expect, g.find(x, y, Node.ANY).toSet());
+               txnRollback(g);
+       }
+
+       @ContractTest
+       public void 
testFind_Node_Node_Node_MatchLanguagedLiteralCaseInsensitive()
+       {
+           Graph g = graphWith(producer.newInstance(), "a p 'chat'en");
+           Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
+           assertEquals(chaten, chatEN);
+           assertTrue(chaten.sameValueAs(chatEN));
+           assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
+           txnBegin(g);
+           assertEquals(1, g.find(Node.ANY, Node.ANY, chaten).toList().size());
+           assertEquals(1, g.find(Node.ANY, Node.ANY, chatEN).toList().size());
+           txnRollback(g);
+       }
+
+       @ContractTest
+       public void testFind_Node_Node_Node_NoMatchAgainstUnlanguagesLiteral()
+       {
+               Graph g = graphWith(producer.newInstance(), "a p 'chat'en; a p 
'chat'");
+               Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
+               assertEquals(chaten, chatEN);
+               assertTrue(chaten.sameValueAs(chatEN));
+               assertEquals(chaten.getIndexingValue(), 
chatEN.getIndexingValue());
+               txnBegin(g);
+               assertEquals(1, g.find(Node.ANY, Node.ANY, 
chaten).toList().size());
+               assertEquals(1, g.find(Node.ANY, Node.ANY, 
chatEN).toList().size());
+               txnRollback(g);
+       }
+
+       @ContractTest
+       public void testFind_Triple()
+       {
+               Graph graph = graphWith(producer.newInstance(),
+                               "S P O; S2 P2 O2; S3 P3 O3");
+               txnBegin(graph);
+               List<Triple> s = graph.find(Triple.ANY).toList();
+               assertEquals(3, s.size());
+               List<Triple> expected = Arrays.asList(new Triple[] { triple("S 
P O"),
+                               triple("S2 P2 O2"), triple("S3 P3 O3") });
+               assertTrue("Missing some values", expected.containsAll(s));
+
+               s = graph.find(Triple.create(node("S"), Node.ANY, 
Node.ANY)).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S P O")));
+
+               s = graph.find(Triple.create(Node.ANY, node("P"), 
Node.ANY)).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S P O")));
+
+               s = graph.find(Triple.create(Node.ANY, Node.ANY, 
node("O"))).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S P O")));
+
+               s = graph.find(Triple.create(node("S2"), node("P2"), 
node("O2"))).toList();
+               assertEquals(1, s.size());
+               assertTrue("Missing some values", s.contains(triple("S2 P2 
O2")));
+
+               s = graph.find(Triple.create(node("S2"), node("P3"), 
node("O2"))).toList();
+               assertEquals(0, s.size());
+
+               s = graph.find(Triple.create(Node.ANY, node("P3"), 
node("O2"))).toList();
+               assertEquals(0, s.size());
+
+               s = graph.find(Triple.create(node("S3"), Node.ANY, 
node("O2"))).toList();
+               assertEquals(0, s.size());
+
+               s = graph.find(Triple.create(node("S3"), node("P2"), 
Node.ANY)).toList();
+               assertEquals(0, s.size());
+               txnRollback(graph);
+       }
+
+       @ContractTest
+       public void testFind_Triple_ByFluidTriple()
+       {
+               Graph g = graphWith(producer.newInstance(), "x y z ");
+               Set<Triple> expect = tripleSet("x y z");
+               txnBegin(g);
+               assertEquals(expect, g.find(triple("?? y z")).toSet());
+               assertEquals(expect, g.find(triple("x ?? z")).toSet());
+               assertEquals(expect, g.find(triple("x y ??")).toSet());
+               txnRollback(g);
+       }
+
+       @ContractTest
+       public void testFind_Triple_NoMatchAgainstUnlanguagesLiteral()
+       {
+           Graph g = graphWith(producer.newInstance(), "a p 'chat'en; a p 
'chat'");
+           Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
+           assertEquals(chaten, chatEN);
+           assertTrue(chaten.sameValueAs(chatEN));
+           assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
+           txnBegin(g);
+           assertEquals(1, g.find(Triple.create(Node.ANY, Node.ANY, chaten))
+                        .toList().size());
+           assertEquals(1, g.find(Triple.create(Node.ANY, Node.ANY, chatEN))
+                        .toList().size());
+           txnRollback(g);
+       }
+
+       @ContractTest
+       public void testGetEventManager()
+       {
+               assertNotNull("Must return an EventManager",
+                               producer.newInstance().getEventManager());
+       }
+
+       @ContractTest
+       public void testGetPrefixMapping()
+       {
+               Graph g = producer.newInstance();
+               txnBegin(g);
+               PrefixMapping pm = g.getPrefixMapping();
+               assertNotNull("Must return prefix mapping", pm);
+               assertSame("getPrefixMapping must always return the same 
object", pm,
+                               g.getPrefixMapping());
+               txnRollback(g);
+               pm.setNsPrefix("pfx1", "http://example.com/";);
+               pm.setNsPrefix("pfx2", "scheme:rope/string#");
+
+               txnBegin(g);
+               // assert same after adding to other mapl
+               assertSame("getPrefixMapping must always return the same 
object", pm,
+                               g.getPrefixMapping());
+               txnRollback(g);
+
+       }
+
+       @ContractTest
+       public void testGetTransactionHandler()
+       {
+               Graph g = producer.newInstance();
+               assertNotNull("Must return a Transaction handler",
+                               g.getTransactionHandler());
+       }
+
+       @ContractTest
+       public void testIsClosed()
+       {
+               Graph g = producer.newInstance();
+               assertFalse("Graph created in closed state", g.isClosed());
+               txnBegin(g);
+               g.close();
+               txnCommit(g);
+               txnBegin(g);
+               assertTrue("Graph does not report closed state after close 
called",
+                               g.isClosed());
+               txnRollback(g);
+       }
+
+       @ContractTest
+       public void testIsEmpty()
+       {
+               Graph g = producer.newInstance();
+               txnBegin(g);
+               if (!g.isEmpty())
+               {
+                       LOG.warn(String.format(
+                                       "Graph type %s can not be empty (Empty 
test skipped)",
+                                       g.getClass()));
+                       txnRollback(g);
+               } else
+               {
+                       txnRollback(g);
+                       graphAddTxn(g, "S P O");
+                       txnBegin(g);
+                       assertFalse("Graph reports empty after add", 
g.isEmpty());
+                       txnRollback(g);
+
+                       txnBegin(g);
+                       g.add(NodeCreateUtils.createTriple("Foo B C"));
+                       g.delete(NodeCreateUtils.createTriple("S P O"));
+                       txnCommit(g);
+                       txnBegin(g);
+                       assertFalse("Should not report empty", g.isEmpty());
+                       txnRollback(g);
+
+                       txnBegin(g);
+                       g.delete(NodeCreateUtils.createTriple("Foo B C"));
+                       txnCommit(g);
+                       txnBegin(g);
+                       assertTrue("Should report empty after all entries 
deleted",
+                                       g.isEmpty());
+                       txnRollback(g);
+               }
+       }
+
+       @ContractTest
+       public void testIsIsomorphicWith_Graph()
+       {
+               Graph graph = producer.newInstance();
+               Graph g2 = memGraph();
+               txnBegin(graph);
+               assertTrue("Empty graphs should be isomorphic",
+                               graph.isIsomorphicWith(g2));
+               txnRollback(graph);
+               graphWith(graph, "S P O; S2 P2 O2; S3 P3 O3");
+               g2 = graphWith("S3 P3 O3; S2 P2 O2; S P O");
+               txnBegin(graph);
+               assertTrue("Should be isomorphic", graph.isIsomorphicWith(g2));
+               txnRollback(graph);
+               txnBegin(graph);
+               graph.add(triple("_1, P4 S4"));
+               txnCommit(graph);
+
+               txnBegin(g2);
+               g2.add(triple("_2, P4 S4"));
+               txnCommit(g2);
+               txnBegin(graph);
+               assertTrue("Should be isomorphic after adding anonymous nodes",
+                               graph.isIsomorphicWith(g2));
+               txnRollback(graph);
+
+               txnBegin(graph);
+               graph.add(triple("_1, P3 S4"));
+               txnCommit(graph);
+
+               txnBegin(g2);
+               g2.add(triple("_2, P4 S4"));
+               txnCommit(g2);
+               txnBegin(graph);
+               assertFalse("Should not be isomorphic", 
graph.isIsomorphicWith(g2));
+               txnRollback(graph);
+       }
+
+       private Graph copy(Graph g)
+       {
+               Graph result = producer.newInstance();
+               txnBegin(result);
+               GraphUtil.addInto(result, g);
+               txnCommit(result);
+               return result;
+       }
+
+       private Graph remove(Graph toUpdate, Graph toRemove)
+       {
+               txnBegin(toUpdate);
+               GraphUtil.deleteFrom(toUpdate, toRemove);
+               txnCommit(toUpdate);
+               return toUpdate;
+       }
+
+       /**
+        * Test that remove(s, p, o) works, in the presence of inferencing 
graphs
+        * that mean emptyness isn't available. This is why we go round the 
houses
+        * and test that expected ~= initialContent + addedStuff - removed -
+        * initialContent.
+        */
+       @ContractTest
+       public void testRemove_Node_Node_Node()
+       {
+               for (int i = 0; i < cases.length; i += 1)
+                       for (int j = 0; j < 3; j += 1)
+                       {
+                               Graph content = producer.newInstance();
+
+                               Graph baseContent = copy(content);
+                               graphAddTxn(content, cases[i][0]);
+                               Triple remove = triple(cases[i][1]);
+                               Graph expected = graphWith(cases[i][2]);
+                               Triple[] removed = tripleArray(cases[i][3]);
+                               content.getEventManager().register(GL);
+                               GL.clear();
+                               txnBegin(content);
+                               content.remove(remove.getSubject(), 
remove.getPredicate(),
+                                               remove.getObject());
+                               txnCommit(content);
+
+                               // check for optional delete notifications
+                               if (GL.contains("delete"))
+                               {
+                                       // if it contains any it must contain 
all.
+                                       for (Triple t : removed)
+                                       {
+                                               GL.assertContains("delete", 
content, t);
+                                       }
+                               }
+                               GL.assertHasEnd("someEvent", content,
+                                               
GraphEvents.remove(remove.getSubject(),
+                                                               
remove.getPredicate(), remove.getObject()));
+
+                               content.getEventManager().unregister(GL);
+                               Graph finalContent = remove(copy(content), 
baseContent);
+                               txnBegin(finalContent);
+                               assertIsomorphic(cases[i][1], expected, 
finalContent);
+                               txnRollback(finalContent);
+                       }
+       }
+
+       @ContractTest
+       public void testRemove_ByIterator()
+       {
+               testRemove("?? ?? ??", "?? ?? ??");
+               testRemove("S ?? ??", "S ?? ??");
+               testRemove("S ?? ??", "?? P ??");
+               testRemove("S ?? ??", "?? ?? O");
+               testRemove("?? P ??", "S ?? ??");
+               testRemove("?? P ??", "?? P ??");
+               testRemove("?? P ??", "?? ?? O");
+               testRemove("?? ?? O", "S ?? ??");
+               testRemove("?? ?? O", "?? P ??");
+               testRemove("?? ?? O", "?? ?? O");
+       }
+
+       private void testRemove(String findRemove, String findCheck)
+       {
+               Graph g = graphWith(producer.newInstance(), "S P O");
+               txnBegin(g);
+               ExtendedIterator<Triple> it = g
+                               .find(NodeCreateUtils.createTriple(findRemove));
+               txnRollback(g);
+               try
+               {
+                       it.next();
+                       it.remove();
+                       it.close();
+                       assertEquals("remove with " + findRemove + ":", 0, 
g.size());
+                       
assertFalse(g.contains(NodeCreateUtils.createTriple(findCheck)));
+               } catch (UnsupportedOperationException e)
+               {
+                       it.close();
+               }
+       }
+
+       /**
+        * This test case was generated by Ian and was caused by GraphMem not
+        * keeping up with changes to the find interface.
+        */
+       @ContractTest
+       public void testFindAndContains()
+       {
+               Graph g = producer.newInstance();
+               Node r = NodeCreateUtils.create("r"), s = 
NodeCreateUtils.create("s"),
+                               p = NodeCreateUtils.create("P");
+               txnBegin(g);
+               try
+               {
+                       g.add(Triple.create(r, p, s));
+                       txnCommit(g);
+                       txnBegin(g);
+                       assertTrue(g.contains(r, p, Node.ANY));
+                       assertEquals(1, g.find(r, p, Node.ANY).toList().size());
+               } catch (Exception e)
+               {
+                       fail(e.getMessage());
+               } finally
+               {
+                       txnRollback(g);
+               }
+       }
+
+       /**
+        * Check that contains respects by-value semantics.
+        */
+
+       @ContractTest
+       public void testAGraph()
+       {
+               String title = this.getClass().getName();
+               Graph g = producer.newInstance();
+               txnBegin(g);
+               int baseSize = g.size();
+               txnRollback(g);
+               graphAddTxn(g, "x R y; p S q; a T b");
+               /* */
+               txnBegin(g);
+               assertContainsAll(title + ": simple graph", g, "x R y; p S q; a 
T b");
+               assertEquals(title + ": size", baseSize + 3, g.size());
+               txnRollback(g);
+
+               graphAddTxn(g,
+                               "spindizzies lift cities; Diracs communicate 
instantaneously");
+               txnBegin(g);
+               assertEquals(title + ": size after adding", baseSize + 5, 
g.size());
+
+               g.delete(triple("x R y"));
+               g.delete(triple("a T b"));
+               txnCommit(g);
+               txnBegin(g);
+               assertEquals(title + ": size after deleting", baseSize + 3, 
g.size());
+               assertContainsAll(title + ": modified simple graph", g,
+                               "p S q; spindizzies lift cities; Diracs 
communicate instantaneously");
+               assertOmitsAll(title + ": modified simple graph", g, "x R y; a 
T b");
+               /* */
+               ClosableIterator<Triple> it = g.find(Node.ANY, node("lift"), 
Node.ANY);
+               assertTrue(title + ": finds some triple(s)", it.hasNext());
+               assertEquals(title + ": finds a 'lift' triple",
+                               triple("spindizzies lift cities"), it.next());
+               assertFalse(title + ": finds exactly one triple", it.hasNext());
+               txnRollback(g);
+               it.close();
+       }
+
+       @ContractTest
+       public void testAddWithReificationPreamble()
+       {
+               Graph g = producer.newInstance();
+               txnBegin(g);
+               xSPO(g);
+               txnCommit(g);
+               txnBegin(g);
+               assertFalse(g.isEmpty());
+               txnRollback(g);
+       }
+
+       protected void xSPOyXYZ(Graph g)
+       {
+               xSPO(g);
+               ReifierStd.reifyAs(g, NodeCreateUtils.create("y"),
+                               NodeCreateUtils.createTriple("X Y Z"));
+       }
+
+       protected void aABC(Graph g)
+       {
+               ReifierStd.reifyAs(g, NodeCreateUtils.create("a"),
+                               NodeCreateUtils.createTriple("Foo B C"));
+       }
+
+       protected void xSPO(Graph g)
+       {
+               ReifierStd.reifyAs(g, NodeCreateUtils.create("x"),
+                               NodeCreateUtils.createTriple("S P O"));
+       }
+
+       @ContractTest
+       public void failingTestDoubleRemoveAll()
+       {
+               final Graph g = producer.newInstance();
+               try
+               {
+                       graphAddTxn(g, "c S d; e:ff GGG hhhh; _i J 27; Ell Em 
'en'");
+                       txnBegin(g);
+                       Iterator<Triple> it = new 
TrackingTripleIterator(g.find(Triple.ANY))
+                       {
+                               @Override
+                               public void remove()
+                               {
+                                       super.remove(); // removes current
+                                       g.delete(current); // no-op.
+                               }
+                       };
+                       txnRollback(g);
+                       while (it.hasNext())
+                       {
+                               it.next();
+                               it.remove();
+                       }
+                       txnBegin(g);
+                       assertTrue(g.isEmpty());
+                       txnRollback(g);
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+       }
+
+       /**
+        * Test cases for RemoveSPO(); each entry is a triple (add, remove, 
result).
+        * <ul>
+        * <li>add - the triples to add to the graph to start with
+        * <li>remove - the pattern to use in the removal
+        * <li>result - the triples that should remain in the graph
+        * </ul>
+        */
+       protected static String[][] cases = { { "x R y", "x R y", "", "x R y" },
+                       { "x R y; a P b", "x R y", "a P b", "x R y" },
+                       { "x R y; a P b", "?? R y", "a P b", "x R y" },
+                       { "x R y; a P b", "x R ??", "a P b", "x R y" },
+                       { "x R y; a P b", "x ?? y", "a P b", "x R y" },
+                       { "x R y; a P b", "?? ?? ??", "", "x R y; a P b" },
+                       { "x R y; a P b; c P d", "?? P ??", "x R y", "a P b; c 
P d" },
+                       { "x R y; a P b; x S y", "x ?? ??", "a P b", "x R y; x 
S y" }, };
+
+       /**
+        * testIsomorphism from file data
+        *
+        * @throws URISyntaxException
+        * @throws MalformedURLException
+        */
+       @ContractTest
+       public void testIsomorphismFile()
+                       throws URISyntaxException, MalformedURLException
+       {
+               testIsomorphismXMLFile(1, true);
+               testIsomorphismXMLFile(2, true);
+               testIsomorphismXMLFile(3, true);
+               testIsomorphismXMLFile(4, true);
+               testIsomorphismXMLFile(5, false);
+               testIsomorphismXMLFile(6, false);
+               testIsomorphismNTripleFile(7, true);
+               testIsomorphismNTripleFile(8, false);
+
+       }
+
+       private void testIsomorphismNTripleFile(int i, boolean result)
+       {
+               testIsomorphismFile(i, "N-TRIPLE", "nt", result);
+       }
+
+       private void testIsomorphismXMLFile(int i, boolean result)
+       {
+               testIsomorphismFile(i, "RDF/XML", "rdf", result);
+       }
+
+       private InputStream getInputStream(int n, int n2, String suffix)
+       {
+               String urlStr = 
String.format("regression/testModelEquals/%s-%s.%s", n,
+                               n2, suffix);
+               return GraphContractTest.class.getClassLoader()
+                               .getResourceAsStream(urlStr);
+       }
+
+       private void testIsomorphismFile(int n, String lang, String suffix,
+                       boolean result)
+       {
+               Graph g1 = producer.newInstance();
+               Graph g2 = producer.newInstance();
+               Model m1 = ModelFactory.createModelForGraph(g1);
+               Model m2 = ModelFactory.createModelForGraph(g2);
+
+               txnBegin(g1);
+               m1.read(getInputStream(n, 1, suffix), 
"http://www.example.org/";, lang);
+               txnCommit(g1);
+
+               txnBegin(g2);
+               m2.read(getInputStream(n, 2, suffix), 
"http://www.example.org/";, lang);
+               txnCommit(g2);
+
+               txnBegin(g1);
+               boolean rslt = g1.isIsomorphicWith(g2) == result;
+               txnRollback(g1);
+               if (!rslt)
+               {
+                       System.out.println("g1:");
+                       m1.write(System.out, "N-TRIPLE");
+                       System.out.println("g2:");
+                       m2.write(System.out, "N-TRIPLE");
+               }
+               assertTrue("Isomorphism test failed", rslt);
+       }
+
+       protected Graph getClosed()
+       {
+               Graph result = producer.newInstance();
+               result.close();
+               return result;
+       }
+
+       /**
+        * Ensure that triples removed by calling .remove() on the iterator 
returned
+        * by a find() will generate deletion notifications.
+        */
+       @ContractTest
+       public void testIterator_Remove()
+       {
+               Graph graph = graphWith(producer.newInstance(), "a R b; b S e");
+               graph.getEventManager().register(GL);
+               txnBegin(graph);
+               Triple toRemove = triple("a R b");
+               ExtendedIterator<Triple> rtr = graph.find(toRemove);
+               assertTrue("ensure a(t least) one triple", rtr.hasNext());
+               txnRollback(graph);
+               try
+               {
+                       rtr.next();
+                       rtr.remove();
+                       rtr.close();
+                       GL.assertHas("delete", graph, toRemove);
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+       }
+
+       @ContractTest
+       public void testTransactionHandler_Commit()
+       {
+               Graph g = producer.newInstance();
+               if (g.getTransactionHandler().transactionsSupported())
+               {
+                       Graph initial = graphWith("initial hasValue 42; also 
hasURI hello");
+                       Graph extra = graphWith("extra hasValue 17; also hasURI 
world");
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, initial);
+                       g.getTransactionHandler().commit();
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, extra);
+                       g.getTransactionHandler().commit();
+                       Graph union = memGraph();
+                       GraphUtil.addInto(union, initial);
+                       GraphUtil.addInto(union, extra);
+                       g.getTransactionHandler().begin();
+                       assertIsomorphic(union, g);
+                       g.getTransactionHandler().abort();
+                       // Model inFiIProducer<TransactionHandler>le =
+                       // ModelFactory.createDefaultModel();
+                       // inFile.read( "file:///" + foo, "N-TRIPLES" );
+                       // assertIsomorphic( union, inFile.getGraph() );
+               }
+       }
+
+       @ContractTest
+       public void testTransactionHandler_Abort()
+       {
+               Graph g = producer.newInstance();
+               if (g.getTransactionHandler().transactionsSupported())
+               {
+                       Graph initial = graphWith(producer.newInstance(),
+                                       "initial hasValue 42; also hasURI 
hello");
+                       Graph extra = graphWith(producer.newInstance(),
+                                       "extra hasValue 17; also hasURI world");
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, initial);
+                       g.getTransactionHandler().commit();
+
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, extra);
+                       g.getTransactionHandler().abort();
+
+                       g.getTransactionHandler().begin();
+                       assertIsomorphic(initial, g);
+                       g.getTransactionHandler().abort();
+               }
+       }
+
+       @ContractTest
+       public void testTransactionHandler_CommitThenAbort()
+       {
+               Graph g = producer.newInstance();
+               if (g.getTransactionHandler().transactionsSupported())
+               {
+                       Graph initial = graphWith(producer.newInstance(),
+                                       "Foo pings B; B pings C");
+                       Graph extra = graphWith(producer.newInstance(),
+                                       "C pingedBy B; fileGraph rdf:type 
Graph");
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, initial);
+                       g.getTransactionHandler().commit();
+                       g.getTransactionHandler().begin();
+                       GraphUtil.addInto(g, extra);
+                       g.getTransactionHandler().abort();
+                       g.getTransactionHandler().begin();
+                       assertIsomorphic(initial, g);
+                       g.getTransactionHandler().abort();
+                       // Model inFile = ModelFactory.createDefaultModel();
+                       // inFile.read( "file:///" + foo, "N-TRIPLES" );
+                       // assertIsomorphic( initial, inFile.getGraph() );
+               }
+       }
+
+       //
+       // Test that literal typing works when supported
+       //
+
+       // used to find the object set from the returned set for literal testing
+
+       private static final Function<Triple, Node> getObject = new 
Function<Triple, Node>()
+       {
+               @Override
+               public Node apply(Triple t)
+               {
+                       return t.getObject();
+               }
+       };
+
+       @ContractTest
+       public void testQuadRemove()
+       {
+               Graph g = producer.newInstance();
+               txnBegin(g);
+               assertEquals(0, g.size());
+               txnRollback(g);
+               Triple s = triple("x rdf:subject s");
+               Triple p = triple("x rdf:predicate p");
+               Triple o = triple("x rdf:object o");
+               Triple t = triple("x rdf:type rdf:Statement");
+               txnBegin(g);
+               g.add(s);
+               g.add(p);
+               g.add(o);
+               g.add(t);
+               txnCommit(g);
+               txnBegin(g);
+               assertEquals(4, g.size());
+               txnRollback(g);
+               txnBegin(g);
+               g.delete(s);
+               g.delete(p);
+               g.delete(o);
+               g.delete(t);
+               txnCommit(g);
+               txnBegin(g);
+               assertEquals(0, g.size());
+               txnRollback(g);
+       }
+
+       @ContractTest
+       public void testSizeAfterRemove()
+       {
+               Graph g = graphWith(producer.newInstance(), "x p y");
+               try
+               {
+                       txnBegin(g);
+                       ExtendedIterator<Triple> it = g.find(triple("x ?? ??"));
+                       txnRollback(g);
+                       it.removeNext();
+                       txnBegin(g);
+                       assertEquals(0, g.size());
+                       txnRollback(g);
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+       }
+
+       @ContractTest
+       public void testBrokenIndexes()
+       {
+               Graph g = graphWith(producer.newInstance(), "x R y; x S z");
+               try
+               {
+                       txnBegin(g);
+                       ExtendedIterator<Triple> it = g.find(Node.ANY, 
Node.ANY, Node.ANY);
+                       txnRollback(g);
+                       it.removeNext();
+                       it.removeNext();
+                       txnBegin(g);
+                       assertFalse(g.find(node("x"), Node.ANY, 
Node.ANY).hasNext());
+                       assertFalse(g.find(Node.ANY, node("R"), 
Node.ANY).hasNext());
+                       assertFalse(g.find(Node.ANY, Node.ANY, 
node("y")).hasNext());
+                       txnRollback(g);
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+       }
+
+       @ContractTest
+       public void testBrokenSubject()
+       {
+               Graph g = graphWith(producer.newInstance(), "x brokenSubject 
y");
+               try
+               {
+                       txnBegin(g);
+                       ExtendedIterator<Triple> it = g.find(node("x"), 
Node.ANY, Node.ANY);
+                       txnRollback(g);
+                       it.removeNext();
+                       txnBegin(g);
+                       assertFalse(g.find(Node.ANY, Node.ANY, 
Node.ANY).hasNext());
+                       txnRollback(g);
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+       }
+
+       @ContractTest
+       public void testBrokenPredicate()
+       {
+               Graph g = graphWith(producer.newInstance(), "x brokenPredicate 
y");
+               try
+               {
+                       txnBegin(g);
+                       ExtendedIterator<Triple> it = g.find(Node.ANY,
+                                       node("brokenPredicate"), Node.ANY);
+                       txnRollback(g);
+                       it.removeNext();
+                       txnBegin(g);
+                       assertFalse(g.find(Node.ANY, Node.ANY, 
Node.ANY).hasNext());
+                       txnRollback(g);
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+       }
+
+       @ContractTest
+       public void testBrokenObject()
+       {
+               Graph g = graphWith(producer.newInstance(), "x brokenObject y");
+
+               try
+               {
+                       txnBegin(g);
+                       ExtendedIterator<Triple> it = g.find(Node.ANY, 
Node.ANY, node("y"));
+                       txnRollback(g);
+                       it.removeNext();
+                       txnBegin(g);
+                       assertFalse(g.find(Node.ANY, Node.ANY, 
Node.ANY).hasNext());
+                       txnRollback(g);
+
+               } catch (UnsupportedOperationException e)
+               {
+                       // No Iterator.remove
+               }
+
+       }
+
+}
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDelta.java 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDelta.java
index 0ab76a7730..5b4fedb0ba 100755
--- a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDelta.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDelta.java
@@ -40,7 +40,7 @@ public class TestDelta extends AbstractTestGraph
     }
 
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
     {
         Graph gBase = graphWith( "" );
         return new Delta( gBase ); 
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDifference.java
 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDifference.java
index 66ed0d31f0..7ad74f74db 100755
--- 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDifference.java
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDifference.java
@@ -31,7 +31,7 @@ public class TestDifference extends TestDyadic
     { return new TestSuite( TestDifference.class ); }  
 
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
     {
         Graph gBase = graphWith( "" ), g1 = graphWith( "" );
         return new Difference( gBase, g1 ); 
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDisjointUnion.java
 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDisjointUnion.java
index 04e7a94ca5..89501e4c15 100644
--- 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDisjointUnion.java
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestDisjointUnion.java
@@ -35,7 +35,7 @@ public class TestDisjointUnion extends TestDyadic
     
     
     @Override
-       public Graph getGraph()
+       public Graph getNewGraph()
        {
                Graph gBase = graphWith( "" ), g1 = graphWith( "" );
         return new DisjointUnion( gBase, g1 ); 
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestIntersection.java
 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestIntersection.java
index 25ad131e50..9bff6673a7 100755
--- 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestIntersection.java
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestIntersection.java
@@ -31,7 +31,7 @@ public class TestIntersection extends TestDyadic
     { return new TestSuite( TestIntersection.class ); }
 
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
     {
         Graph gBase = graphWith( "" ), g1 = graphWith( "" );
         return new Intersection( gBase, g1 ); 
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestMultiUnion.java
 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestMultiUnion.java
index 9ed93acf1f..ef8b3669a1 100755
--- 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestMultiUnion.java
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestMultiUnion.java
@@ -55,7 +55,7 @@ public class TestMultiUnion extends AbstractTestGraph
         { return new TestSuite( TestMultiUnion.class ); }   
     
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
         {
         Graph gBase = graphWith( "" ), g1 = graphWith( "" );
         return new MultiUnion( new Graph[] {gBase, g1} ); 
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestUnion.java 
b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestUnion.java
index 886e3a9065..dfec39f166 100755
--- a/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestUnion.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/compose/test/TestUnion.java
@@ -31,7 +31,7 @@ public class TestUnion extends TestDyadic
     { return new TestSuite( TestUnion.class ); }
 
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
     {
         Graph gBase = graphWith( "" ), g1 = graphWith( "" );
         return new Union( gBase, g1 ); 
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java 
b/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java
index 69d1170226..7c0e170347 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/AbstractTestGraph.java
@@ -45,20 +45,18 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
         Returns a Graph to take part in the test. Must be overridden in
         a subclass.
      */
-    public abstract Graph getGraph();
-
-     //public Graph getGraph() { return Factory.createGraphMem(); }
+    public abstract Graph getNewGraph();
 
     public Graph getGraphWith( String facts )
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         graphAdd( g, facts );
         return g;
     }
 
     public void testCloseSetsIsClosed()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         assertFalse( "unclosed Graph shouild not be isClosed()", g.isClosed() 
);
         g.close();
         assertTrue( "closed Graph should be isClosed()", g.isClosed() );
@@ -70,7 +68,7 @@ public abstract class AbstractTestGraph extends GraphTestBase
      */
     public void testFindAndContains()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         Node r = NodeCreateUtils.create( "r" ), s = NodeCreateUtils.create( 
"s" ), p = NodeCreateUtils.create( "P" );
         g.add( Triple.create( r, p, s ) );
         assertTrue( g.contains( r, p, Node.ANY ) );
@@ -130,79 +128,35 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
         assertFalse( g.contains( triple( "a S ??" ) ) );
     }
 
-    /**
-        Check that contains respects by-value semantics.
-     */
-    public void testContainsByValue()
-    {
-        if (getGraph().getCapabilities().handlesLiteralTyping())
-        {
-            Graph g1 = getGraphWith( "x P '1'xsd:integer" );
-
-            boolean b = g1.contains( triple( "x P '01'xsd:int" ) );
-            if ( !b )
-                System.err.println("No value match: 
"+g1.getClass().getSimpleName());
-
-            assertTrue( g1.contains( triple( "x P '01'xsd:int" ) ) );
-            //
-            Graph g2 = getGraphWith( "x P '1'xsd:int" );
-            assertTrue( g2.contains( triple( "x P '1'xsd:integer" ) ) );
-            //
-            Graph g3 = getGraphWith( "x P '123'xsd:string" );
-            assertTrue( g3.contains( triple( "x P '123'" ) ) );
-        }
-    }
-
     public void testMatchLanguagedLiteralCaseInsensitive()
     {
         Graph m = graphWith( "a p 'chat'en" );
-        if (m.getCapabilities().handlesLiteralTyping())
-        {
-            Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
-            //assertDiffer( chaten, chatEN ); // Up to Jena4.
-            assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the 
same due to normalized langtags
-            assertTrue( chaten.sameValueAs( chatEN ) );
-            assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() 
);
-            assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten 
).toList().size() );
-            assertEquals( 1, m.find( Node.ANY, Node.ANY, chatEN 
).toList().size() );
-        }
+        Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
+        //assertDiffer( chaten, chatEN ); // Up to Jena4.
+        assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the same 
due to normalized langtags
+        assertTrue( chaten.sameValueAs( chatEN ) );
+        assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
+        assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten ).toList().size() 
);
+        assertEquals( 1, m.find( Node.ANY, Node.ANY, chatEN ).toList().size() 
);
     }
 
     public void testMatchBothLanguagedLiteralsCaseInsensitive()
     {
         Graph m = graphWith( "a p 'chat'en; a p 'chat'EN" );
-        if (m.getCapabilities().handlesLiteralTyping())
-        {
-            Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
-            // Jena4.
-//            assertDiffer( chaten, chatEN ); // Up to Jena4.
-//            assertTrue( chaten.sameValueAs( chatEN ) );
-//            assertEquals( chaten.getIndexingValue(), 
chatEN.getIndexingValue() );
-//            assertEquals( 2, m.find( Node.ANY, Node.ANY, chaten 
).toList().size() );
-//            assertEquals( 2, m.find( Node.ANY, Node.ANY, chatEN 
).toList().size() );
-
-            // Jena5 -- the nodes are now the same due to normalized langtags
-            assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the 
same due to normalized langtags
-            assertTrue( chaten.sameValueAs( chatEN ) );
-            assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() 
);
-            assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten 
).toList().size() );
-            assertEquals( 1, m.find( Node.ANY, Node.ANY, chatEN 
).toList().size() );
-        }
-    }
-
-    public void testNoMatchAgainstUnlanguagesLiteral()
-    {
-        Graph m = graphWith( "a p 'chat'en; a p 'chat'" );
-        if (m.getCapabilities().handlesLiteralTyping())
-        {
-            Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
-            //assertDiffer( chaten, chatEN ); // Up to Jena4.
-            assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the 
same due to normalized langtags
-            assertTrue( chaten.sameValueAs( chatEN ) );
-            assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() 
);
-            assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten 
).toList().size() );
-            assertEquals( 1, m.find( Node.ANY, Node.ANY, chatEN 
).toList().size() );
-        }
+        Node chaten = node( "'chat'en" ), chatEN = node( "'chat'EN" );
+        // Jena4.
+//        assertDiffer( chaten, chatEN ); // Up to Jena4.
+//        assertTrue( chaten.sameValueAs( chatEN ) );
+//        assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
+//        assertEquals( 2, m.find( Node.ANY, Node.ANY, chaten 
).toList().size() );
+//        assertEquals( 2, m.find( Node.ANY, Node.ANY, chatEN 
).toList().size() );
+
+        // Jena5 -- the nodes are now the same due to normalized langtags
+        assertEquals( chaten, chatEN ); // Jena5 -- the nodes are now the same 
due to normalized langtags
+        assertTrue( chaten.sameValueAs( chatEN ) );
+        assertEquals( chaten.getIndexingValue(), chatEN.getIndexingValue() );
+        assertEquals( 1, m.find( Node.ANY, Node.ANY, chaten ).toList().size() 
);
+        assertEquals( 1, m.find( Node.ANY, Node.ANY, chatEN ).toList().size() 
);
     }
 
     /**
@@ -210,7 +164,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
      */
     public void testIsEmpty()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         if (canBeEmpty( g ))
         {
             assertTrue( g.isEmpty() );
@@ -231,7 +185,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
     public void testAGraph()
     {
         String title = this.getClass().getName();
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         int baseSize = g.size();
         graphAdd( g, "x R y; p S q; a T b" );
         /* */
@@ -252,28 +206,13 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
         it.close();
     }
 
-    //    public void testStuff()
-    //        {
-    ////        testAGraph( "StoreMem", new GraphMem() );
-    ////        testAGraph( "StoreMemBySubject", new GraphMem() );
-    ////        String [] empty = new String [] {};
-    ////        Graph g = graphWith( "x R y; p S q; a T b" );
-    ////    /* */
-    ////        assertContainsAll( "simple graph", g, "x R y; p S q; a T b" );
-    ////        graphAdd( g, "spindizzies lift cities; Diracs communicate 
instantaneously" );
-    ////        g.delete( triple( "x R y" ) );
-    ////        g.delete( triple( "a T b" ) );
-    ////        assertContainsAll( "modified simple graph", g, "p S q; 
spindizzies lift cities; Diracs communicate instantaneously" );
-    ////        assertOmitsAll( "modified simple graph", g, "x R y; a T b" );
-    //        }
-
     /**
         Test that Graphs have transaction support methods, and that if they 
fail
         on some g they fail because they do not support the operation.
      */
     public void testHasTransactions()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         TransactionHandler th = g.getTransactionHandler();
         th.transactionsSupported();
         try { th.begin(); }                 catch 
(UnsupportedOperationException x) {}
@@ -283,14 +222,14 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
     }
 
     public void testExecuteInTransactionCatchesThrowable() {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         TransactionHandler th = g.getTransactionHandler();
         try { th.executeAlways( ()-> { throw new Error() ; } ); }
         catch (JenaException x) {}
     }
 
     public void testCalculateInTransactionCatchesThrowable() {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         TransactionHandler th = g.getTransactionHandler();
         try { th.calculateAlways( ()-> { throw new Error() ; } ); }
         catch (JenaException x) {}
@@ -307,7 +246,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testBulkUpdate()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         Graph items = graphWith( "pigs might fly; dead can dance" );
         int initialSize = g.size();
         /* */
@@ -354,7 +293,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testAddWithReificationPreamble()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         xSPO( g );
         assertFalse( g.isEmpty() );
     }
@@ -403,7 +342,8 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testHasCapabilities()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
+        @SuppressWarnings("removal")
         Capabilities c = g.getCapabilities();
         boolean sa = c.sizeAccurate();
         boolean aaSome = c.addAllowed();
@@ -412,7 +352,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testFind()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         graphAdd( g, "S P O" );
         assertDiffer( Set.of(), g.find( Node.ANY, Node.ANY, Node.ANY ).toSet() 
);
         assertDiffer( Set.of(), g.find( Triple.ANY ).toSet() );
@@ -423,7 +363,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testEventRegister()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         GraphEventManager gem = g.getEventManager();
         assertSame( gem, gem.register( new RecordingListener() ) );
     }
@@ -433,7 +373,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
      */
     public void testEventUnregister()
     {
-        getGraph().getEventManager().unregister( L );
+        getNewGraph().getEventManager().unregister( L );
     }
 
     /**
@@ -447,7 +387,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
      */
     protected Graph getAndRegister( GraphListener gl )
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         g.getEventManager().register( gl );
         return g;
     }
@@ -543,7 +483,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
     {
         RecordingListener L1 = new RecordingListener();
         RecordingListener L2 = new RecordingListener();
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         GraphEventManager gem = g.getEventManager();
         gem.register( L1 ).register( L2 );
         g.add( SPO );
@@ -553,7 +493,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testUnregisterWorks()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         GraphEventManager gem = g.getEventManager();
         gem.register( L ).unregister( L );
         g.add( SPO );
@@ -705,7 +645,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
      */
     public void testContainsNode()
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         graphAdd( g, "a P b; _c _Q _d; a 11 12" );
         assertTrue( containsNode( g, node( "a" ) ) );
         assertTrue( containsNode( g, node( "P" ) ) );
@@ -849,14 +789,14 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     public void testRemoveAll( String triples )
     {
-        Graph g = getGraph();
+        Graph g = getNewGraph();
         graphAdd( g, triples );
         g.clear();
         assertTrue( g.isEmpty() );
     }
 
     public void failingTestDoubleRemoveAll() {
-        final Graph g = getGraph();
+        final Graph g = getNewGraph();
         graphAdd(g,"c S d; e:ff GGG hhhh; _i J 27; Ell Em 'en'"  );
         try {
             Iterator<Triple> it = new 
TrackingTripleIterator(g.find(Triple.ANY)){
@@ -907,7 +847,7 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
         {
             for ( int j = 0; j < 3; j += 1 )
             {
-                Graph content = getGraph();
+                Graph content = getNewGraph();
                 Graph baseContent = copy( content );
                 graphAdd( content, aCase[0] );
                 Triple remove = triple( aCase[1] );
@@ -947,8 +887,8 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     private void testIsomorphismFile(int n, String lang, String suffix, 
boolean result) {
 
-        Graph g1 = getGraph();
-        Graph g2 = getGraph();
+        Graph g1 = getNewGraph();
+        Graph g2 = getNewGraph();
         Model m1 = ModelFactory.createModelForGraph(g1);
         Model m2 = ModelFactory.createModelForGraph(g2);
 
@@ -992,53 +932,8 @@ public abstract class AbstractTestGraph extends 
GraphTestBase
 
     protected Graph getClosed()
     {
-        Graph result = getGraph();
+        Graph result = getNewGraph();
         result.close();
         return result;
     }
-
-    //    public void testClosedDelete()
-    //        {
-    //        try { getClosed().delete( triple( "x R y" ) ); fail( "delete 
when closed" ); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-    //
-    //    public void testClosedAdd()
-    //        {
-    //        try { getClosed().add( triple( "x R y" ) ); fail( "add when 
closed" ); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-    //
-    //    public void testClosedContainsTriple()
-    //        {
-    //        try { getClosed().contains( triple( "x R y" ) ); fail( 
"contains[triple] when closed" ); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-    //
-    //    public void testClosedContainsSPO()
-    //        {
-    //        Node a = Node.ANY;
-    //        try { getClosed().contains( a, a, a ); fail( "contains[SPO] when 
closed" ); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-    //
-    //    public void testClosedFindTriple()
-    //        {
-    //        try { getClosed().find( triple( "x R y" ) ); fail( "find 
[triple] when closed" ); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-    //
-    //    public void testClosedFindSPO()
-    //        {
-    //        Node a = Node.ANY;
-    //        try { getClosed().find( a, a, a ); fail( "find[SPO] when closed" 
); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-    //
-    //    public void testClosedSize()
-    //        {
-    //        try { getClosed().size(); fail( "size when closed (" + 
this.getClass() + ")" ); }
-    //        catch (ClosedException c) { /* as required */ }
-    //        }
-
 }
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/test/MetaTestGraph.java 
b/jena-core/src/test/java/org/apache/jena/graph/test/MetaTestGraph.java
index 2471829d50..bfb731eacf 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/MetaTestGraph.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/MetaTestGraph.java
@@ -85,7 +85,7 @@ public class MetaTestGraph extends AbstractTestGraph
         catch (Exception e) { throw new JenaException( e ); }
         }
 
-       @Override public Graph getGraph() 
+       @Override public Graph getNewGraph() 
         { return getGraph( this, graphClass); }
         
     }
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/test/TestGraphListener.java 
b/jena-core/src/test/java/org/apache/jena/graph/test/TestGraphListener.java
index 48dfcf8feb..7f2d13fe99 100644
--- a/jena-core/src/test/java/org/apache/jena/graph/test/TestGraphListener.java
+++ b/jena-core/src/test/java/org/apache/jena/graph/test/TestGraphListener.java
@@ -52,7 +52,7 @@ public class TestGraphListener extends MetaTestGraph {
                public CheckChanges(String description, Graph g) {
                        original = g;
                        desc = description;
-                       copy = TestGraphListener.super.getGraph();
+                       copy = TestGraphListener.super.getNewGraph();
                }
 
 
@@ -143,7 +143,7 @@ public class TestGraphListener extends MetaTestGraph {
        }
 
     @Override
-       public Graph getGraph() {
+       public Graph getNewGraph() {
        Graph g = GraphMemFactory.createGraphMem();
 
        g.getEventManager().register(new CheckChanges("simple tracking",g));
diff --git 
a/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMem2.java 
b/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMem2.java
index 990137e22f..3d943424df 100644
--- a/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMem2.java
+++ b/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMem2.java
@@ -34,7 +34,7 @@ public class TestGraphMem2 extends AbstractTestGraph
     { return new TestSuite( TestGraphMem2.class ); }
     
     @Override
-    public Graph getGraph() { return GraphMemFactory.createGraphMem(); }
+    public Graph getNewGraph() { return GraphMemFactory.createGraphMem(); }
     
     public void testBrokenIndexes()
         {
diff --git 
a/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMemValue.java 
b/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMemValue.java
index 4920f40e18..1b8f8ebd6d 100644
--- a/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMemValue.java
+++ b/jena-core/src/test/java/org/apache/jena/mem/test/TestGraphMemValue.java
@@ -18,46 +18,264 @@
 
 package org.apache.jena.mem.test;
 
-import junit.framework.TestSuite;
-import org.apache.jena.graph.* ;
-import org.apache.jena.graph.test.* ;
+import static org.apache.jena.testing_framework.GraphHelper.txnBegin;
+import static org.apache.jena.testing_framework.GraphHelper.txnCommit;
+import static org.apache.jena.testing_framework.GraphHelper.txnRollback;
+import static org.apache.jena.testing_framework.GraphHelper.txnRun;
+
+import java.util.Set;
+
+import junit.framework.JUnit4TestAdapter;
+import org.apache.jena.atlas.iterator.Iter;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.NodeFactory;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.impl.LiteralLabelFactory;
+import org.apache.jena.graph.test.AbstractTestGraph;
 import org.apache.jena.mem.GraphMem ;
-import org.apache.jena.shared.* ;
+import org.apache.jena.testing_framework.NodeCreateUtils;
 import org.apache.jena.util.iterator.ExtendedIterator ;
+import org.junit.Test;
 
-@SuppressWarnings("deprecation")
-public class TestGraphMemValue extends AbstractTestGraph
-    {
-    public TestGraphMemValue( String name )
-        { super( name ); }
+/**
+ * Tests of {@link GraphMem} based on (Java object) value handling.
+ * <p>
+ * This is used by the Model API.
+ * <p>
+ * Jena5+ : Only {@link GraphMem} supports this. Other graph are "same term", 
not "same value"
+ * and language tags are held in canonical form.
+ */
+public class TestGraphMemValue extends AbstractTestGraph {
+    public TestGraphMemValue(String name) {
+        super(name);
+    }
 
-    public static TestSuite suite()
-        { return new TestSuite( TestGraphMemValue.class ); }
+    public static junit.framework.Test suite() {
+        return new JUnit4TestAdapter(TestGraphMemValue.class);
+    }
 
-    @Override public Graph getGraph()
-        { return new GraphMem(); }
+    @SuppressWarnings("deprecation")
+    @Override
+    public Graph getNewGraph() {
+        return new GraphMem();
+    }
 
-    public void testSizeAfterRemove()
-        {
-        Graph g = getGraphWith( "x p y" );
-        ExtendedIterator<Triple> it = g.find( triple( "x ?? ??" ) );
+    @Test public void testSizeAfterRemove() {
+        Graph g = getGraphWith("x p y");
+        ExtendedIterator<Triple> it = g.find(triple("x ?? ??"));
         it.removeNext();
-        assertEquals( 0, g.size() );
+        assertEquals(0, g.size());
+    }
+
+    /**
+     * Check that contains respects by-value semantics.
+     */
+    @Test public void testContainsByValue() {
+        Graph g1 = getGraphWith("x P '1'xsd:integer");
+
+        boolean b = g1.contains(triple("x P '01'xsd:int"));
+        if ( !b )
+            System.err.println("No value match: " + 
g1.getClass().getSimpleName());
+
+        assertTrue(g1.contains(triple("x P '01'xsd:int")));
+        //
+        Graph g2 = getGraphWith("x P '1'xsd:int");
+        assertTrue(g2.contains(triple("x P '1'xsd:integer")));
+        //
+        Graph g3 = getGraphWith("x P '123'xsd:string");
+        assertTrue(g3.contains(triple("x P '123'")));
+    }
+
+    // From the contract tests
+
+    @SuppressWarnings("deprecation")
+    @Test public void test_ProgrammaticValue() {
+        Graph g = getNewGraph();
+        Node ab = 
NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(Byte.valueOf((byte)42)));
+        Node as = 
NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(Short.valueOf((short)42)));
+        Node ai = 
NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(Integer.valueOf(42)));
+        Node al = 
NodeFactory.createLiteral(LiteralLabelFactory.createTypedLiteral(Long.valueOf(42)));
+
+        Node SB = NodeCreateUtils.create("SB");
+        Node SS = NodeCreateUtils.create("SS");
+        Node SI = NodeCreateUtils.create("SI");
+        Node SL = NodeCreateUtils.create("SL");
+        Node P = NodeCreateUtils.create("P");
+
+        try {
+            g.add(Triple.create(SB, P, ab));
+            g.add(Triple.create(SS, P, as));
+            g.add(Triple.create(SI, P, ai));
+            g.add(Triple.create(SL, P, al));
+        } catch (Exception e) {
+            fail(e.getMessage());
         }
+        assertEquals(String.format("Should have found 4 elements, does %s 
really implement literal typing", g.getClass()), 4,
+                     Iter.toSet(g.find(Node.ANY, P, 
NodeCreateUtils.create("42"))).size());
+    }
 
-    public void testContainsConcreteDoesntUseFind()
-        {
-        Graph g = new GraphMemWithoutFind();
-        graphAdd( g, "x P y; a Q b" );
-        assertTrue( g.contains( triple( "x P y" ) ) );
-        assertTrue( g.contains( triple( "a Q b" ) ) );
-        assertFalse( g.contains( triple( "a P y" ) ) );
-        assertFalse( g.contains( triple( "y R b" ) ) );
+    @Test
+    public void test_Contains_Node_Node_Node_ByValue()
+    {
+        Node x = node("x");
+        Node P = node("P");
+        Graph g1 = graphWith("x P '1'xsd:integer");
+            txnRun(g1,
+                    () -> assertTrue(
+                            String.format(
+                                    "literal type equality failed, does %s 
really implement literal typing",
+                                    g1.getClass()),
+                            g1.contains(x, P, node("'01'xsd:int"))));
+            //
+            Graph g2 = graphWith("x P '1'xsd:int");
+            txnRun(g2, () -> {
+                assertTrue("Literal equality with '1'xsd:integer failed",
+                        g2.contains(x, P, node("'1'xsd:integer")));
+            });
+            //
+            Graph g3 = graphWith("x P '123'xsd:string");
+            txnRun(g3, () -> {
+                assertTrue("Literal equality with '123' failed",
+                        g3.contains(x, P, node("'123'")));
+            });
         }
 
-    protected final class GraphMemWithoutFind extends GraphMem
+
+    @Test
+    public void test_Contains_Triple_ByValue()
+    {
+        Graph g1 = graphWith("x P '1'xsd:integer");
+            txnRun(g1, () -> {
+                assertTrue(
+                        String.format(
+                                "did not find x P '01'xsd:int, does %s really 
implement literal typing",
+                                g1.getClass()),
+                        g1.contains(triple("x P '01'xsd:int")));
+            });
+            //
+            Graph g2 = graphWith("x P '1'xsd:int");
+            txnRun(g2, () -> {
+                assertTrue("did not find x P '1'xsd:integer",
+                        g2.contains(triple("x P '1'xsd:integer")));
+            });
+            //
+            Graph g3 = graphWith("x P '123'xsd:string");
+            txnRun(g3, () -> assertTrue("did not find x P '123'xsd:string",
+                    g3.contains(triple("x P '123'"))));
+        }
+
+    @Test
+    public void test_Find_Triple_ProgrammaticValues()
+    {
+        Graph g = getNewGraph();
+            @SuppressWarnings("deprecation")
+            Node ab = NodeFactory.createLiteral(LiteralLabelFactory
+                    .createTypedLiteral(Byte.valueOf((byte) 42)));
+            @SuppressWarnings("deprecation")
+            Node as = NodeFactory.createLiteral(LiteralLabelFactory
+                    .createTypedLiteral(Short.valueOf((short) 42)));
+            @SuppressWarnings("deprecation")
+            Node ai = NodeFactory.createLiteral(
+                    
LiteralLabelFactory.createTypedLiteral(Integer.valueOf(42)));
+            @SuppressWarnings("deprecation")
+            Node al = NodeFactory.createLiteral(
+                    LiteralLabelFactory.createTypedLiteral(Long.valueOf(42)));
+
+            Node SB = NodeCreateUtils.create("SB");
+            Node SS = NodeCreateUtils.create("SS");
+            Node SI = NodeCreateUtils.create("SI");
+            Node SL = NodeCreateUtils.create("SL");
+            Node P = NodeCreateUtils.create("P");
+
+            txnBegin(g);
+            try
+            {
+                g.add(Triple.create(SB, P, ab));
+                g.add(Triple.create(SS, P, as));
+                g.add(Triple.create(SI, P, ai));
+                g.add(Triple.create(SL, P, al));
+            } catch (Exception e)
+            {
+                txnRollback(g);
+                fail(e.getMessage());
+            }
+            txnCommit(g);
+            txnBegin(g);
+            assertEquals(
+                    String.format(
+                            "Should have found 4 elements, does %s really 
implement literal typing",
+                            g.getClass()),
+                    4, Iter.toSet(g.find(Triple.create(Node.ANY, P,
+                            NodeCreateUtils.create("42")))).size());
+            txnRollback(g);
+        }
+
+    @Test
+    public void test_Find_Triple_MatchLanguagedLiteralCaseInsensitive()
+    {
+        Graph g = graphWith("a p 'chat'en");
+        Node chaten = node("'chat'en"), chatEN = node("'chat'EN");
+        assertEquals(chaten, chatEN);
+        assertTrue(chaten.sameValueAs(chatEN));
+        assertEquals(chaten.getIndexingValue(), chatEN.getIndexingValue());
+        txnBegin(g);
+        assertEquals(1, g.find(Triple.create(Node.ANY, Node.ANY, chaten))
+                     .toList().size());
+        assertEquals(1, g.find(Triple.create(Node.ANY, Node.ANY, chatEN))
+                     .toList().size());
+        txnRollback(g);
+    }
+
+    private void literalTypingBasedFindTest(final String data, final int size,
+                                            final String search, final String 
results, boolean reqLitType) {
+        if (!reqLitType)
         {
-        @Override public ExtendedIterator<Triple> graphBaseFind( Triple t )
-            { throw new JenaException( "find is Not Allowed" ); }
+            Graph g = graphWith(data);
+
+            Node literal = NodeCreateUtils.create(search);
+            //
+            txnBegin(g);
+            assertEquals("graph has wrong size", size, g.size());
+            Set<Node> got = g.find(Node.ANY, Node.ANY, 
literal).mapWith(t->t.getObject()).toSet();
+            assertEquals(nodeSet(results), got);
+            txnRollback(g);
         }
     }
+
+    @Test
+    public void testLiteralTypingBasedFind() {
+        literalTypingBasedFindTest("a P 'simple'", 1, "'simple'", "'simple'", 
false);
+        literalTypingBasedFindTest("a P 'simple'xsd:string", 1, "'simple'", 
"'simple'xsd:string", true);
+        literalTypingBasedFindTest("a P 'simple'", 1, "'simple'xsd:string", 
"'simple'", true);
+        // ensure that adding identical strings one with type yields single 
result
+        // and that querying with or without type works
+        literalTypingBasedFindTest("a P 'simple'xsd:string", 1, 
"'simple'xsd:string", "'simple'xsd:string",
+                                   false);
+        literalTypingBasedFindTest("a P 'simple'; a P 'simple'xsd:string", 1, 
"'simple'",
+                                   "'simple'xsd:string", true);
+        literalTypingBasedFindTest("a P 'simple'; a P 'simple'xsd:string", 1, 
"'simple'xsd:string",
+                                   "'simple'", true);
+        literalTypingBasedFindTest("a P 'simple'; a P 'simple'xsd:string", 1, 
"'simple'", "'simple'", true);
+        literalTypingBasedFindTest("a P 'simple'; a P 'simple'xsd:string", 1, 
"'simple'xsd:string",
+                                   "'simple'xsd:string", true);
+        literalTypingBasedFindTest("a P 1", 1, "1", "1", false);
+        literalTypingBasedFindTest("a P '1'xsd:float", 1, "'1'xsd:float", 
"'1'xsd:float", false);
+        literalTypingBasedFindTest("a P '1'xsd:double", 1, "'1'xsd:double", 
"'1'xsd:double", false);
+        literalTypingBasedFindTest("a P '1'xsd:float", 1, "'1'xsd:float", 
"'1'xsd:float", false);
+        literalTypingBasedFindTest("a P '1.1'xsd:float", 1, "'1'xsd:float", 
"", false);
+        literalTypingBasedFindTest("a P '1'xsd:double", 1, "'1'xsd:int", "", 
false);
+        literalTypingBasedFindTest("a P 'abc'rdf:XMLLiteral", 1, "'abc'", "", 
false);
+        literalTypingBasedFindTest("a P 'abc'", 1, "'abc'rdf:XMLLiteral", "", 
false);
+        //
+        // floats & doubles are not compatible
+        //
+        literalTypingBasedFindTest("a P '1'xsd:float", 1, "'1'xsd:double", "", 
false);
+        literalTypingBasedFindTest("a P '1'xsd:double", 1, "'1'xsd:float", "", 
false);
+        literalTypingBasedFindTest("a P 1", 1, "'1'", "", false);
+        literalTypingBasedFindTest("a P 1", 1, "'1'xsd:integer", 
"'1'xsd:integer", false);
+        literalTypingBasedFindTest("a P 1", 1, "'1'", "", false);
+        literalTypingBasedFindTest("a P '1'xsd:short", 1, "'1'xsd:integer", 
"'1'xsd:short", true);
+        literalTypingBasedFindTest("a P '1'xsd:int", 1, "'1'xsd:integer", 
"'1'xsd:int", true);
+    }
+}
diff --git 
a/jena-core/src/test/java/org/apache/jena/ontology/impl/TestOntGraph.java 
b/jena-core/src/test/java/org/apache/jena/ontology/impl/TestOntGraph.java
index 30b8ab4982..a96af17dd8 100644
--- a/jena-core/src/test/java/org/apache/jena/ontology/impl/TestOntGraph.java
+++ b/jena-core/src/test/java/org/apache/jena/ontology/impl/TestOntGraph.java
@@ -37,6 +37,6 @@ public class TestOntGraph extends AbstractTestGraph
         { return new TestSuite( TestOntGraph.class ); }
 
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
         { return ModelFactory.createOntologyModel().getGraph(); }
     }
diff --git 
a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/FRuleEngineIFactoryTest.java
 
b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/FRuleEngineIFactoryTest.java
index 13704e8487..29630f82ea 100644
--- 
a/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/FRuleEngineIFactoryTest.java
+++ 
b/jena-core/src/test/java/org/apache/jena/reasoner/rulesys/test/FRuleEngineIFactoryTest.java
@@ -133,9 +133,6 @@ public class FRuleEngineIFactoryTest extends TestCase {
         @Override
         public TransactionHandler getTransactionHandler() { return null; }
 
-        @Override
-        public Capabilities getCapabilities() { return null; }
-
         @Override
         public GraphEventManager getEventManager() { return null; }
 
diff --git 
a/jena-core/src/test/java/org/apache/jena/reasoner/test/TestInfGraph.java 
b/jena-core/src/test/java/org/apache/jena/reasoner/test/TestInfGraph.java
index 76413319ec..dfa7c061e3 100644
--- a/jena-core/src/test/java/org/apache/jena/reasoner/test/TestInfGraph.java
+++ b/jena-core/src/test/java/org/apache/jena/reasoner/test/TestInfGraph.java
@@ -44,7 +44,7 @@ public class TestInfGraph extends AbstractTestGraph
         }
     
     @Override
-    public Graph getGraph()
+    public Graph getNewGraph()
         { return getInfGraph(); }
     
     public void testInfGraph()
diff --git 
a/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphContractTests.java
 
b/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphContractTests.java
index f73da1ba55..84aabe373d 100644
--- 
a/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphContractTests.java
+++ 
b/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphContractTests.java
@@ -38,7 +38,7 @@ public class SecuredGraphContractTests extends MetaTestGraph {
     }
 
     @Override
-    public Graph getGraph() {
+    public Graph getNewGraph() {
         return org.apache.jena.permissions.Factory.getInstance(eval, 
getName(), GraphMemFactory.createDefaultGraph());
     }
 
diff --git 
a/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphListenerTest.java
 
b/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphListenerTest.java
index bb5806cc99..3b05877d22 100644
--- 
a/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphListenerTest.java
+++ 
b/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredGraphListenerTest.java
@@ -37,7 +37,7 @@ public class SecuredGraphListenerTest extends 
TestGraphListener {
     }
 
     @Override
-    public Graph getGraph() {
+    public Graph getNewGraph() {
         final Graph graph = 
org.apache.jena.permissions.Factory.getInstance(eval, getName(),
                                                                             
GraphMemFactory.createDefaultGraph());
         graph.getEventManager().register(new CheckChanges("simple tracking", 
graph));
diff --git 
a/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredTDBGraphContractTests.java
 
b/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredTDBGraphContractTests.java
index f7f971cd99..56bf0b3f9d 100644
--- 
a/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredTDBGraphContractTests.java
+++ 
b/jena-permissions/src/test/java/org/apache/jena/permissions/contract/graph/SecuredTDBGraphContractTests.java
@@ -38,7 +38,7 @@ public class SecuredTDBGraphContractTests extends 
MetaTestGraph {
     }
 
     @Override
-    public Graph getGraph() {
+    public Graph getNewGraph() {
         return org.apache.jena.permissions.Factory.getInstance(eval, getName(),
                 TDB1Factory.createDatasetGraph().getDefaultGraph());
     }

Reply via email to