http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/RecordingGraphListener.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/RecordingGraphListener.java 
b/jena-core/src/test/java/org/apache/jena/graph/RecordingGraphListener.java
new file mode 100644
index 0000000..ed94c8f
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/RecordingGraphListener.java
@@ -0,0 +1,92 @@
+/*
+ * 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 java.util.Iterator;
+import java.util.List;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphListener;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.testing_framework.AbstractRecordingListener;
+import org.apache.jena.testing_framework.GraphHelper;
+
+/**
+ * This testing listener records the event names and data, and provides a 
method
+ * for comparing the actual with the expected history.
+ */
+public class RecordingGraphListener extends AbstractRecordingListener 
implements
+               GraphListener {
+
+       @Override
+       public void notifyAddTriple(Graph g, Triple t) {
+               record("add", g, t);
+       }
+
+       @Override
+       public void notifyAddArray(Graph g, Triple[] triples) {
+               record("add[]", g, triples);
+       }
+
+       @Override
+       public void notifyAddList(Graph g, List<Triple> triples) {
+               record("addList", g, triples);
+       }
+
+       @Override
+       public void notifyAddIterator(Graph g, Iterator<Triple> it) {
+               record("addIterator", g, GraphHelper.iteratorToList(it));
+       }
+
+       @Override
+       public void notifyAddGraph(Graph g, Graph added) {
+               record("addGraph", g, added);
+       }
+
+       @Override
+       public void notifyDeleteTriple(Graph g, Triple t) {
+               record("delete", g, t);
+       }
+
+       @Override
+       public void notifyDeleteArray(Graph g, Triple[] triples) {
+               record("delete[]", g, triples);
+       }
+
+       @Override
+       public void notifyDeleteList(Graph g, List<Triple> triples) {
+               record("deleteList", g, triples);
+       }
+
+       @Override
+       public void notifyDeleteIterator(Graph g, Iterator<Triple> it) {
+               record("deleteIterator", g, GraphHelper.iteratorToList(it));
+       }
+
+       @Override
+       public void notifyDeleteGraph(Graph g, Graph removed) {
+               record("deleteGraph", g, removed);
+       }
+
+       @Override
+       public void notifyEvent(Graph source, Object event) {
+               record("someEvent", source, event);
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/TransactionHandlerContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/TransactionHandlerContractTest.java
 
b/jena-core/src/test/java/org/apache/jena/graph/TransactionHandlerContractTest.java
new file mode 100644
index 0000000..d26d7e9
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/TransactionHandlerContractTest.java
@@ -0,0 +1,149 @@
+/*
+ * 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 java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import static org.junit.Assert.*;
+
+import org.apache.jena.graph.TransactionHandler;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.impl.SimpleTransactionHandler;
+import org.apache.jena.shared.Command;
+import org.apache.jena.shared.JenaException;
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.util.CollectionFactory;
+import static org.apache.jena.testing_framework.GraphHelper.*;
+
+/**
+ * AbstractTestGraph provides a bunch of basic tests for something that 
purports
+ * to be a Graph. The abstract method getGraph must be overridden in subclasses
+ * to deliver a Graph of interest.
+ */
+@Contract(TransactionHandler.class)
+public class TransactionHandlerContractTest {
+
+       private IProducer<TransactionHandler> producer;
+
+       public TransactionHandlerContractTest() {
+//             producer = new IProducer<TransactionHandler>() {
+//
+//                     @Override
+//                     public TransactionHandler newInstance() {
+//                             return new SimpleTransactionHandler();
+//                     }
+//
+//                     @Override
+//                     public void cleanUp() {
+//
+//                     }
+//             };
+       }
+
+       @Contract.Inject
+       public void setProducer(IProducer<TransactionHandler> producer) {
+               this.producer = producer;
+       }
+
+       protected IProducer<TransactionHandler> getTransactionHandlerProducer() 
{
+               return producer;
+       }
+
+       /**
+        * Test that Graphs have transaction support methods, and that if they 
fail
+        * on some g they fail because they do not support the operation.
+        */
+       @ContractTest
+       public void testTransactionsExistAsPerTransactionSupported() {
+               Command cmd = new Command() {
+                       @Override
+                       public Object execute() {
+                               return null;
+                       }
+               };
+
+               TransactionHandler th = 
getTransactionHandlerProducer().newInstance();
+
+               if (th.transactionsSupported()) {
+                       th.begin();
+                       th.abort();
+                       th.begin();
+                       th.commit();
+                       th.executeInTransaction(cmd);
+               } else {
+                       try {
+                               th.begin();
+                               fail("Should have thrown 
UnsupportedOperationException");
+                       } catch (UnsupportedOperationException x) {
+                       }
+
+                       try {
+                               th.abort();
+                               fail("Should have thrown 
UnsupportedOperationException");
+                       } catch (UnsupportedOperationException x) {
+                       }
+                       try {
+                               th.commit();
+                               fail("Should have thrown 
UnsupportedOperationException");
+                       } catch (UnsupportedOperationException x) {
+                       }
+                       /* */
+                       try {
+                               th.executeInTransaction(cmd);
+                               fail("Should have thrown 
UnsupportedOperationException");
+                       } catch (UnsupportedOperationException x) {
+                       }
+               }
+       }
+
+       @ContractTest
+       public void testExecuteInTransactionCatchesThrowable() {
+               TransactionHandler th = 
getTransactionHandlerProducer().newInstance();
+
+               if (th.transactionsSupported()) {
+                       Command cmd = new Command() {
+                               @Override
+                               public Object execute() throws Error {
+                                       throw new Error();
+                               }
+                       };
+                       try {
+                               th.executeInTransaction(cmd);
+                               fail("Should have thrown JenaException");
+                       } catch (JenaException x) {
+                       }
+               }
+       }
+
+       static final Triple[] tripleArray = tripleArray("S P O; Foo R B; X Q 
Y");
+
+       static final List<Triple> tripleList = Arrays
+                       .asList(tripleArray("i lt j; p equals q"));
+
+       static final Triple[] setTriples = tripleArray("scissors cut paper; 
paper wraps stone; stone breaks scissors");
+
+       static final Set<Triple> tripleSet = CollectionFactory
+                       .createHashedSet(Arrays.asList(setTriples));
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/compose/DeltaTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/DeltaTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/compose/DeltaTest.java
new file mode 100755
index 0000000..a0bf737
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/compose/DeltaTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.compose;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.ContractTest;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.xenei.junit.contract.IProducer;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(Delta.class)
+public class DeltaTest  {
+
+       protected IProducer<Delta> graphProducer;
+       
+       public DeltaTest() {
+               super();
+               graphProducer = new AbstractGraphProducer<Delta>() {
+                       private Map<Graph, Graph> map = new HashMap<Graph, 
Graph>();
+
+                       @Override
+                       protected Delta createNewGraph() {
+                               Graph g = memGraph();
+                               Delta d = new Delta(g);
+                               map.put(d, g);
+                               return d;
+                       }
+
+                       @Override
+                       public Graph[] getDependsOn(Graph d) {
+//                             Delta dl = (Delta)d;
+//                             Graph g = map.get(d);
+//                             if (g == null) {
+//                                     throw new IllegalStateException("graph 
missing from map");
+//                             }
+//                             return new Graph[] { g,  (Graph)dl.getL(), 
(Graph)dl.getR() };
+                               return null;
+                       }
+
+                       @Override
+                       public Graph[] getNotDependsOn(Graph g) {
+                               return new Graph[] { memGraph() };
+                       }
+
+                       @Override
+                       protected void afterClose(Graph g) {
+                               map.remove(g);
+                       }
+               };
+       }
+
+       @Contract.Inject
+       public final IProducer<Delta> getDeltaTestProducer() {
+               return graphProducer;
+       }
+
+       @ContractTest
+       public void testDelta() {
+               Graph x = graphWith(getDeltaTestProducer().newInstance(), "x R 
y");
+               assertContains("x", "x R y", x);
+               x.delete(triple("x R y"));
+               assertOmits("x", x, "x R y");
+               /* */
+               Graph base = graphWith("x R y; p S q; I like cheese; pins pop 
balloons");
+               Delta delta = new Delta(base);
+               assertContainsAll("Delta", delta,
+                               "x R y; p S q; I like cheese; pins pop 
balloons");
+               assertContainsAll("Base", base,
+                               "x R y; p S q; I like cheese; pins pop 
balloons");
+               /* */
+               delta.add(triple("pigs fly winglessly"));
+               delta.delete(triple("I like cheese"));
+               /* */
+               assertContainsAll("changed Delta", delta,
+                               "x R y; p S q; pins pop balloons; pigs fly 
winglessly");
+               assertOmits("changed delta", delta, "I like cheese");
+               assertContains("delta additions", "pigs fly winglessly",
+                               delta.getAdditions());
+               assertOmits("delta additions", delta.getAdditions(), "I like 
cheese");
+               assertContains("delta deletions", "I like cheese", 
delta.getDeletions());
+               assertOmits("delta deletions", delta.getDeletions(),
+                               "pigs fly winglessly");
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/compose/DifferenceTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/DifferenceTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/compose/DifferenceTest.java
new file mode 100755
index 0000000..213ae36
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/compose/DifferenceTest.java
@@ -0,0 +1,97 @@
+/*
+ * 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.compose;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.ContractTest;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.compose.Difference;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.xenei.junit.contract.IProducer;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(Difference.class)
+public class DifferenceTest {
+
+       protected IProducer<Difference> graphProducer;
+       
+       public DifferenceTest() {
+               graphProducer = new AbstractGraphProducer<Difference>() {
+                       private Map<Graph, Graph[]> map = new HashMap<Graph, 
Graph[]>();
+
+                       @Override
+                       protected Difference createNewGraph() {
+                               Graph g1 = memGraph();
+                               Graph g2 = memGraph();
+                               Difference d = new Difference(g1, g2);
+                               map.put(d, new Graph[] { g1, g2 });
+                               return d;
+                       }
+
+                       @Override
+                       public Graph[] getDependsOn(Graph d) {
+                               Graph[] dg = map.get(d);
+                               if (dg == null) {
+                                       throw new IllegalStateException("graph 
not in map");
+                               }
+                               return dg;
+                       }
+
+                       @Override
+                       public Graph[] getNotDependsOn(Graph g) {
+                               return new Graph[] { memGraph() };
+                       }
+
+                       @Override
+                       protected void afterClose(Graph g) {
+                               map.remove(g);
+                       }
+               };
+       }
+
+       @Contract.Inject
+       public final IProducer<Difference> getDifferenceTestProducer() {
+               return graphProducer;
+       }
+
+       @ContractTest
+       public void testDifference() {
+               Graph g1 = graphWith("x R y; p R q");
+               Graph g2 = graphWith("r Foo s; x R y");
+               Graph d = new Difference(g1, g2);
+               assertOmits("Difference", d, "x R y");
+               assertContains("Difference", "p R q", d);
+               assertOmits("Difference", d, "r Foo s");
+               if (d.size() != 1)
+                       fail("oops: size of difference is not 1");
+               d.add(triple("cats eat cheese"));
+               assertContains("Difference.L", "cats eat cheese", g1);
+               assertOmits("Difference.R", g2, "cats eat cheese");
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/compose/IntersectionTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/IntersectionTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/compose/IntersectionTest.java
new file mode 100755
index 0000000..1e6db9b
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/compose/IntersectionTest.java
@@ -0,0 +1,109 @@
+/*
+ * 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.compose;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.ContractTest;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphUtil;
+import org.apache.jena.graph.compose.Intersection;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.xenei.junit.contract.IProducer;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(Intersection.class)
+public class IntersectionTest {
+
+       protected IProducer<Intersection> graphProducer;
+       
+       public IntersectionTest() {
+               super();
+               graphProducer = new AbstractGraphProducer<Intersection>() {
+                       private Map<Graph, Graph[]> dependencyGraph = new 
HashMap<Graph, Graph[]>();
+
+                       @Override
+                       protected Intersection createNewGraph() {
+                               Graph g1 = memGraph();
+                               Graph g2 = memGraph();
+                               Intersection retval = new Intersection(g1, g2);
+                               dependencyGraph.put(retval, new Graph[] { g1, 
g2 });
+                               return retval;
+                       }
+
+                       @Override
+                       public Graph[] getDependsOn(Graph g) {
+                               Graph[] dg = dependencyGraph.get(g);
+                               if (dg == null) {
+                                       throw new IllegalStateException("graph 
missing from map");
+                               }
+                               return dg;
+                       }
+
+                       @Override
+                       public Graph[] getNotDependsOn(Graph g) {
+                               return new Graph[] { memGraph() };
+                       }
+
+                       @Override
+                       protected void afterClose(Graph g) {
+                               dependencyGraph.remove(g);
+                       }
+               };
+       }
+
+       @Contract.Inject
+       public final IProducer<Intersection> getIntersectionTestProducer() {
+               return graphProducer;
+       }
+
+       @ContractTest
+       public void testIntersection() {
+               Graph g1 = graphWith( "x R y; p R q");
+               Graph g2 = graphWith( "r Foo s; x R y");
+               Intersection i = new Intersection(g1, g2);
+               assertContains("Intersection", "x R y", i);
+               assertOmits("Intersection", i, "p R q");
+               assertOmits("Intersection", i, "r Foo s");
+               if (i.size() != 1)
+                       fail("oops: size of intersection is not 1");
+               i.add(triple("cats eat cheese"));
+               assertContains("Intersection.L", "cats eat cheese", g1);
+               assertContains("Intersection.R", "cats eat cheese", g2);
+       }
+
+       @ContractTest
+       public void testDeleteDoesNotUpdateR() {
+               Graph L = graphWith("a pings b; b pings c; c pings a");
+               Graph R = graphWith("c pings a; b pings c; x captures y");
+               Graph join = new Intersection(L, R);
+               GraphUtil.deleteFrom(L, R);
+               assertIsomorphic("R should not change",
+                               graphWith("c pings a; b pings c; x captures 
y"), R);
+               assertIsomorphic(graphWith("a pings b"), L);
+       }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/compose/UnionTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/compose/UnionTest.java 
b/jena-core/src/test/java/org/apache/jena/graph/compose/UnionTest.java
new file mode 100755
index 0000000..44bf9fb
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/compose/UnionTest.java
@@ -0,0 +1,185 @@
+/*
+ * 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.compose;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.ContractTest;
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphStatisticsHandler;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.graph.compose.Union;
+import org.apache.jena.graph.impl.GraphBase;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(Union.class)
+public class UnionTest {
+       
+       protected IProducer<Union> graphProducer;
+       
+       public UnionTest() {
+               graphProducer = new AbstractGraphProducer<Union>() {
+                       private Map<Graph, Graph[]> map = new HashMap<Graph, 
Graph[]>();
+
+                       @Override
+                       protected Union createNewGraph() {
+                               Graph[] g = { memGraph(), memGraph() };
+                               Union u = new Union(g[0], g[1]);
+                               map.put(u, g);
+                               return u;
+                       }
+
+                       @Override
+                       public Graph[] getDependsOn(Graph d) {
+                               Graph[] dg = map.get(d);
+                               if (dg == null) {
+                                       throw new IllegalStateException("graph 
not in map");
+                               }
+                               return dg;
+                       }
+
+                       @Override
+                       public Graph[] getNotDependsOn(Graph g) {
+                               return new Graph[] { memGraph() };
+                       }
+
+                       @Override
+                       protected void afterClose(Graph g) {
+                               map.remove(g);
+                       }
+               };
+
+       }
+
+       @Contract.Inject
+       public final IProducer<Union> getUnionTestProducer() {
+               return graphProducer;
+       }
+
+       @ContractTest
+       public void testUnion() {
+               Graph g1 = graphWith("x R y; p R q");
+               Graph g2 = graphWith("r Foo s; x R y");
+               Union u = new Union(g1, g2);
+               assertContains("Union", "x R y", u);
+               assertContains("Union", "p R q", u);
+               assertContains("Union", "r Foo s", u);
+               if (u.size() != 3)
+                       fail("oops: size of union is not 3");
+               u.add(triple("cats eat cheese"));
+               assertContains("Union", "cats eat cheese", u);
+               if (contains(g1, "cats eat cheese") == false
+                               && contains(g2, "cats eat cheese") == false)
+                       fail("oops: neither g1 nor g2 contains `cats eat 
cheese`");
+       }
+
+       static class AnInteger {
+               public int value = 0;
+
+               public AnInteger(int value) {
+                       this.value = value;
+               }
+       }
+
+       @ContractTest
+       public void testUnionValues() {
+               testUnion(0, 0, 0, 0);
+       }
+
+       @ContractTest
+       public void testCopiesSingleNonZeroResult() {
+               testUnion(1, 1, 0, 0);
+               testUnion(1, 0, 1, 0);
+               testUnion(1, 0, 0, 1);
+               testUnion(1, 1, 0, 0);
+               testUnion(2, 0, 2, 0);
+               testUnion(4, 0, 0, 4);
+       }
+
+       @ContractTest
+       public void testResultIsSumOfBaseResults() {
+               testUnion(3, 1, 2, 0);
+               testUnion(5, 1, 0, 4);
+               testUnion(6, 0, 2, 4);
+               testUnion(7, 1, 2, 4);
+               testUnion(3, 0, 2, 1);
+               testUnion(5, 4, 1, 0);
+               testUnion(6, 2, 2, 2);
+               testUnion(7, 6, 0, 1);
+       }
+
+       @ContractTest
+       public void testUnknownOverrulesAll() {
+               testUnion(-1, -1, 0, 0);
+               testUnion(-1, 0, -1, 0);
+               testUnion(-1, 0, 0, -1);
+               testUnion(-1, -1, 1, 1);
+               testUnion(-1, 1, -1, 1);
+               testUnion(-1, 1, 1, -1);
+       }
+
+       /**
+        * Asserts that the statistic obtained by probing the three-element 
union
+        * with statistics <code>av</code>, <code>bv</code>, and 
<code>cv</code> is
+        * <code>expected</code>.
+        */
+       private void testUnion(int expected, int av, int bv, int cv) {
+               AnInteger a = new AnInteger(av), b = new AnInteger(bv), c = new 
AnInteger(
+                               cv);
+               Graph g1 = graphWithGivenStatistic(a);
+               Graph g2 = graphWithGivenStatistic(b);
+               Graph g3 = graphWithGivenStatistic(c);
+               Graph[] graphs = new Graph[] { g1, g2, g3 };
+               MultiUnion mu = new MultiUnion(graphs);
+               GraphStatisticsHandler gs = new 
MultiUnion.MultiUnionStatisticsHandler(
+                               mu);
+               assertEquals(expected, gs.getStatistic(Node.ANY, Node.ANY, 
Node.ANY));
+       }
+
+       static Graph graphWithGivenStatistic(final AnInteger x) {
+               return new GraphBase() {
+                       @Override
+                       protected ExtendedIterator<Triple> graphBaseFind(Triple 
t) {
+                               throw new RuntimeException("should never be 
called");
+                       }
+
+                       @Override
+                       protected GraphStatisticsHandler 
createStatisticsHandler() {
+                               return new GraphStatisticsHandler() {
+                                       @Override
+                                       public long getStatistic(Node S, Node 
P, Node O) {
+                                               return x.value;
+                                       }
+                               };
+                       }
+               };
+       }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/impl/TestCollectionGraph.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/impl/TestCollectionGraph.java 
b/jena-core/src/test/java/org/apache/jena/graph/impl/TestCollectionGraph.java
index 3334da7..4d9f40d 100644
--- 
a/jena-core/src/test/java/org/apache/jena/graph/impl/TestCollectionGraph.java
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/impl/TestCollectionGraph.java
@@ -18,22 +18,50 @@
 
 package org.apache.jena.graph.impl;
 
+import static org.apache.jena.testing_framework.GraphHelper.memGraph;
+
 import java.util.HashSet;
 
 import org.apache.jena.graph.Graph ;
 import org.apache.jena.graph.Triple ;
 import org.apache.jena.graph.impl.CollectionGraph ;
-import org.apache.jena.graph.test.AbstractTestGraph ;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.IProducer;
 
-public class TestCollectionGraph extends AbstractTestGraph {
+@RunWith(ContractSuite.class)
+@ContractImpl(CollectionGraph.class)
+public class TestCollectionGraph {
         
-       public TestCollectionGraph(String name) {
-               super(name);
+       protected IProducer<CollectionGraph> graphProducer;
+       
+       public TestCollectionGraph() {
+               graphProducer = new AbstractGraphProducer<CollectionGraph>() {
+                       
+                       @Override
+                       protected CollectionGraph createNewGraph() {
+                               return new CollectionGraph( new 
HashSet<Triple>() );
+                       }
+
+                       @Override
+                       public Graph[] getDependsOn(Graph d) {
+                               return null;
+                       }
+
+                       @Override
+                       public Graph[] getNotDependsOn(Graph g) {
+                               return new Graph[] { memGraph() };
+                       }
+
+               };
        }
 
-       @Override
-       public Graph getGraph() {
-               return new CollectionGraph( new HashSet<Triple>() );
+       @Contract.Inject
+       public final IProducer<CollectionGraph> getDeltaTestProducer() {
+               return graphProducer;
        }
 
 }

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/impl/TestWrappedGraph.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/impl/TestWrappedGraph.java 
b/jena-core/src/test/java/org/apache/jena/graph/impl/TestWrappedGraph.java
new file mode 100644
index 0000000..7910660
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/graph/impl/TestWrappedGraph.java
@@ -0,0 +1,63 @@
+/*
+ * 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.impl;
+
+import static org.apache.jena.testing_framework.GraphHelper.memGraph;
+
+import org.apache.jena.graph.Graph ;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.IProducer;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(WrappedGraph.class)
+public class TestWrappedGraph {
+        
+       protected IProducer<WrappedGraph> graphProducer;
+       
+       public TestWrappedGraph() {
+               graphProducer = new AbstractGraphProducer<WrappedGraph>() {
+                       
+                       @Override
+                       protected WrappedGraph createNewGraph() {
+                               return new WrappedGraph( memGraph() );
+                       }
+
+                       @Override
+                       public Graph[] getDependsOn(Graph d) {
+                               return null;
+                       }
+
+                       @Override
+                       public Graph[] getNotDependsOn(Graph g) {
+                               return new Graph[] { memGraph() };
+                       }
+
+               };
+       }
+
+       @Contract.Inject
+       public final IProducer<WrappedGraph> getDeltaTestProducer() {
+               return graphProducer;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/graph/impl/TripleStoreContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/graph/impl/TripleStoreContractTest.java
 
b/jena-core/src/test/java/org/apache/jena/graph/impl/TripleStoreContractTest.java
new file mode 100644
index 0000000..0b074aa
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/graph/impl/TripleStoreContractTest.java
@@ -0,0 +1,176 @@
+/*
+ * 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.impl;
+
+import org.junit.After;
+import org.junit.Before;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import static org.junit.Assert.*;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import org.apache.jena.mem.GraphTripleStore;
+import org.apache.jena.graph.impl.TripleStore;
+import org.apache.jena.testing_framework.ContractTemplate;
+
+import org.xenei.junit.contract.IProducer;
+
+/**
+ * AbstractTestTripleStore - post-hoc tests for TripleStores.
+ */
+
+@Contract(TripleStore.class)
+public class TripleStoreContractTest<T extends TripleStore> extends
+               ContractTemplate<IProducer<T>> {
+
+       protected TripleStore store;
+
+       public TripleStoreContractTest() {
+               IProducer<TripleStore> producer = new IProducer<TripleStore>() {
+
+                       @Override
+                       public TripleStore newInstance() {
+                               return new GraphTripleStore(memGraph());
+                       }
+
+                       @Override
+                       public void cleanUp() {
+                               // TODO Auto-generated method stub
+
+                       }
+
+               };
+               setProducer((IProducer<T>) producer);
+       }
+
+       /**
+        * Subclasses must over-ride to return a new empty TripleStore.
+        */
+       @Contract.Inject
+       public final void setTripleStoreContractTestProducer(IProducer<T> 
producer) {
+               super.setProducer(producer);
+       }
+
+       @Before
+       public final void beforeAbstractTripleStoreTest() {
+               store = getProducer().newInstance();
+       }
+
+       @After
+       public final void afterAbstractTripleStoreTest() {
+               getProducer().cleanUp();
+       }
+
+       @ContractTest
+       public void testEmpty() {
+               testEmpty(store);
+       }
+
+       @ContractTest
+       public void testAddOne() {
+               store.add(triple("x P y"));
+               assertEquals(false, store.isEmpty());
+               assertEquals(1, store.size());
+               assertEquals(true, store.contains(triple("x P y")));
+               assertEquals(nodeSet("x"), iteratorToSet(store.listSubjects()));
+               assertEquals(nodeSet("y"), iteratorToSet(store.listObjects()));
+               assertEquals(tripleSet("x P y"),
+                               iteratorToSet(store.find(triple("?? ?? ??"))));
+       }
+
+       @ContractTest
+       public void testListSubjects() {
+               someStatements(store);
+               assertEquals(nodeSet("a x _z r q"), 
iteratorToSet(store.listSubjects()));
+       }
+
+       @ContractTest
+       public void testListObjects() {
+               someStatements(store);
+               assertEquals(nodeSet("b y i _j _t 17"),
+                               iteratorToSet(store.listObjects()));
+       }
+
+       @ContractTest
+       public void testContains() {
+               someStatements(store);
+               assertEquals(true, store.contains(triple("a P b")));
+               assertEquals(true, store.contains(triple("x P y")));
+               assertEquals(true, store.contains(triple("a P i")));
+               assertEquals(true, store.contains(triple("_z Q _j")));
+               assertEquals(true, store.contains(triple("x R y")));
+               assertEquals(true, store.contains(triple("r S _t")));
+               assertEquals(true, store.contains(triple("q R 17")));
+               /* */
+               assertEquals(false, store.contains(triple("a P x")));
+               assertEquals(false, store.contains(triple("a P _j")));
+               assertEquals(false, store.contains(triple("b Z r")));
+               assertEquals(false, store.contains(triple("_a P x")));
+       }
+
+       @ContractTest
+       public void testFind() {
+               someStatements(store);
+               assertEquals(tripleSet(""),
+                               iteratorToSet(store.find(triple("no such 
thing"))));
+               assertEquals(tripleSet("a P b; a P i"),
+                               iteratorToSet(store.find(triple("a P ??"))));
+               assertEquals(tripleSet("a P b; x P y; a P i"),
+                               iteratorToSet(store.find(triple("?? P ??"))));
+               assertEquals(tripleSet("x P y; x R y"),
+                               iteratorToSet(store.find(triple("x ?? y"))));
+               assertEquals(tripleSet("_z Q _j"),
+                               iteratorToSet(store.find(triple("?? ?? _j"))));
+               assertEquals(tripleSet("q R 17"),
+                               iteratorToSet(store.find(triple("?? ?? 17"))));
+       }
+
+       @ContractTest
+       public void testRemove() {
+               store.add(triple("nothing before ace"));
+               store.add(triple("ace before king"));
+               store.add(triple("king before queen"));
+               store.delete(triple("ace before king"));
+               assertEquals(tripleSet("king before queen; nothing before ace"),
+                               iteratorToSet(store.find(triple("?? ?? ??"))));
+               store.delete(triple("king before queen"));
+               assertEquals(tripleSet("nothing before ace"),
+                               iteratorToSet(store.find(triple("?? ?? ??"))));
+       }
+
+       protected void someStatements(TripleStore ts) {
+               ts.add(triple("a P b"));
+               ts.add(triple("x P y"));
+               ts.add(triple("a P i"));
+               ts.add(triple("_z Q _j"));
+               ts.add(triple("x R y"));
+               ts.add(triple("r S _t"));
+               ts.add(triple("q R 17"));
+       }
+
+       protected void testEmpty(TripleStore ts) {
+               assertEquals(true, ts.isEmpty());
+               assertEquals(0, ts.size());
+               assertEquals(false, ts.find(triple("?? ?? ??")).hasNext());
+               assertEquals(false, ts.listObjects().hasNext());
+               assertEquals(false, ts.listSubjects().hasNext());
+               assertFalse(ts.contains(triple("x P y")));
+       }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/mem/BunchMapContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/mem/BunchMapContractTest.java 
b/jena-core/src/test/java/org/apache/jena/mem/BunchMapContractTest.java
new file mode 100644
index 0000000..7807248
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/mem/BunchMapContractTest.java
@@ -0,0 +1,163 @@
+/*
+ * 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.mem;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.After;
+import org.junit.Before;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+/**
+ * Test triple bunch implementations - NOT YET FINISHED
+ */
+@Contract(BunchMap.class)
+public class BunchMapContractTest {
+       private BunchMap map;
+
+       private IProducer<? extends BunchMap> producer;
+
+       @Contract.Inject
+       public final void setBunchMapProducer(IProducer<? extends BunchMap> 
producer) {
+               this.producer = producer;
+       }
+
+       protected final IProducer<? extends BunchMap> getBunchMapProducer() {
+               return producer;
+       }
+
+       @Before
+       public final void beforeAbstractBunchMapTest() {
+               map = getBunchMapProducer().newInstance();
+       }
+
+       @After
+       public final void afterAbstractBunchMapTest() {
+               getBunchMapProducer().cleanUp();
+       }
+
+       @ContractTest
+       public void testClear() {
+               for (int i = 0; i < 5; i++) {
+                       map.put(i, mock(TripleBunch.class));
+               }
+               assertEquals(5, map.size());
+
+               map.clear();
+               assertEquals(0, map.size());
+       }
+
+       @ContractTest
+       public void testSize() {
+               assertEquals(0, map.size());
+               for (int i = 0; i < 5; i++) {
+                       map.put(i, mock(TripleBunch.class));
+                       assertEquals(i + 1, map.size());
+               }
+       }
+
+       @ContractTest
+       public void testGet() {
+               List<TripleBunch> lst = new ArrayList<TripleBunch>();
+               for (int i = 0; i < 5; i++) {
+                       TripleBunch tb = mock(TripleBunch.class);
+                       lst.add(tb);
+                       map.put(i, tb);
+               }
+               for (int i = 0; i < 5; i++) {
+                       assertEquals(lst.get(i), map.get(i));
+               }
+       }
+
+       @ContractTest
+       public void testPut() {
+               List<TripleBunch> lst = new ArrayList<TripleBunch>();
+               for (int i = 0; i < 5; i++) {
+                       map.put(i, mock(TripleBunch.class));
+               }
+               for (int i = 0; i < 5; i++) {
+                       TripleBunch tb = mock(TripleBunch.class);
+                       lst.add(tb);
+                       map.put(i, tb);
+               }
+               for (int i = 0; i < 5; i++) {
+                       assertEquals(lst.get(i), map.get(i));
+               }
+       }
+
+       @ContractTest
+       public void testRemove() {
+               List<TripleBunch> lst = new ArrayList<TripleBunch>();
+               for (int i = 0; i < 5; i++) {
+                       TripleBunch tb = mock(TripleBunch.class);
+                       lst.add(tb);
+                       map.put(i, tb);
+               }
+
+               map.remove(0);
+               assertNull(map.get(0));
+               for (int i = 1; i < 5; i++) {
+                       assertEquals(lst.get(i), map.get(i));
+               }
+               assertEquals(4, map.size());
+
+               map.remove(2);
+               assertNull(map.get(0));
+               assertEquals(lst.get(1), map.get(1));
+               assertNull(map.get(2));
+               assertEquals(lst.get(3), map.get(3));
+               assertEquals(lst.get(4), map.get(4));
+               assertEquals(3, map.size());
+
+               map.remove(4);
+               assertNull(map.get(0));
+               assertEquals(lst.get(1), map.get(1));
+               assertNull(map.get(2));
+               assertEquals(lst.get(3), map.get(3));
+               assertNull(map.get(4));
+               assertEquals(2, map.size());
+
+       }
+
+       @ContractTest
+       public void testKeyIterator() {
+               List<Integer> lst = new ArrayList<Integer>();
+               for (int i = 0; i < 5; i++) {
+                       lst.add(i);
+                       map.put(i, mock(TripleBunch.class));
+               }
+               ExtendedIterator<Object> iter = map.keyIterator();
+               while (iter.hasNext()) {
+                       assertFalse("List is empty", lst.isEmpty());
+                       Integer i = (Integer) iter.next();
+                       assertTrue("Missing index: " + i, lst.contains(i));
+                       lst.remove(i);
+               }
+               assertTrue("List is not empty", lst.isEmpty());
+       }
+}
+

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/mem/GraphMemTest.java
----------------------------------------------------------------------
diff --git a/jena-core/src/test/java/org/apache/jena/mem/GraphMemTest.java 
b/jena-core/src/test/java/org/apache/jena/mem/GraphMemTest.java
new file mode 100644
index 0000000..8fed109
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/mem/GraphMemTest.java
@@ -0,0 +1,115 @@
+/*
+    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.mem;
+
+import static org.apache.jena.testing_framework.GraphHelper.*;
+import static org.junit.Assert.*;
+
+import java.util.Iterator;
+
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract.Inject;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+import org.xenei.junit.contract.ContractTest;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.graph.GraphStatisticsHandler;
+import org.apache.jena.graph.Node;
+import org.apache.jena.graph.Node_URI;
+import org.apache.jena.graph.Triple;
+import org.apache.jena.shared.JenaException;
+import org.apache.jena.testing_framework.AbstractGraphProducer;
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(GraphMem.class)
+public class GraphMemTest {
+
+       protected IProducer<GraphMem> graphProducer = new 
AbstractGraphProducer<GraphMem>() {
+
+               @Override
+               protected GraphMem createNewGraph() {
+                       return new GraphMem();
+               }
+
+               @Override
+               public Graph[] getDependsOn(Graph g) {
+                       return null;
+               }
+
+               @Override
+               public Graph[] getNotDependsOn(Graph g) {
+                       return new Graph[] { memGraph() };
+               }
+
+       };
+
+       @Inject
+       public IProducer<GraphMem> getGraphProducer() {
+               return graphProducer;
+       }
+
+       @ContractTest
+       public void testHasStatistics() {
+               GraphStatisticsHandler h = graphProducer.newInstance()
+                               .getStatisticsHandler();
+               assertNotNull(h);
+       }
+
+       @ContractTest
+       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")));
+       }
+
+       protected final class GraphMemWithoutFind extends GraphMem {
+               @Override
+               public ExtendedIterator<Triple> graphBaseFind(Triple t) {
+                       throw new JenaException("find is Not Allowed");
+               }
+       }
+
+       @ContractTest
+       public void testUnnecessaryMatches() {
+               Node special = new Node_URI("eg:foo") {
+                       @Override
+                       public boolean matches(Node s) {
+                               fail("Matched called superfluously.");
+                               return true;
+                       }
+               };
+               Graph g = graphWith(graphProducer.newInstance(), "x p y");
+               g.add(new Triple(special, special, special));
+               exhaust(g.find(special, Node.ANY, Node.ANY));
+               exhaust(g.find(Node.ANY, special, Node.ANY));
+               exhaust(g.find(Node.ANY, Node.ANY, special));
+
+       }
+
+       protected void exhaust(Iterator<?> it) {
+               while (it.hasNext())
+                       it.next();
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/mem/GraphTripleStoreTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/mem/GraphTripleStoreTest.java 
b/jena-core/src/test/java/org/apache/jena/mem/GraphTripleStoreTest.java
new file mode 100644
index 0000000..1f82935
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/mem/GraphTripleStoreTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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.mem;
+
+import org.junit.runner.RunWith;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractImpl;
+import org.xenei.junit.contract.ContractSuite;
+
+import org.apache.jena.graph.Graph;
+import org.apache.jena.mem.GraphTripleStore;
+import org.xenei.junit.contract.IProducer;
+
+@RunWith(ContractSuite.class)
+@ContractImpl(GraphTripleStore.class)
+public class GraphTripleStoreTest {
+
+       private IProducer<GraphTripleStore> producer = new 
IProducer<GraphTripleStore>() {
+
+               @Override
+               public GraphTripleStore newInstance() {
+                       return new GraphTripleStore(Graph.emptyGraph);
+               }
+
+               @Override
+               public void cleanUp() {
+               }
+
+       };
+
+       @Contract.Inject
+       public IProducer<GraphTripleStore> getTripleStore() {
+               return producer;
+       }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/mem/TripleBunchContractTest.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/mem/TripleBunchContractTest.java 
b/jena-core/src/test/java/org/apache/jena/mem/TripleBunchContractTest.java
new file mode 100644
index 0000000..505b57f
--- /dev/null
+++ b/jena-core/src/test/java/org/apache/jena/mem/TripleBunchContractTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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.mem;
+
+import static org.junit.Assert.*;
+import static org.apache.jena.testing_framework.GraphHelper.*;
+
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.xenei.junit.contract.Contract;
+import org.xenei.junit.contract.ContractTest;
+
+import org.apache.jena.graph.Triple;
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.testing_framework.NodeCreateUtils;
+import org.apache.jena.util.iterator.ExtendedIterator;
+
+/**
+ * Test triple bunch implementations - NOT YET FINISHED
+ */
+@Contract(TripleBunch.class)
+public class TripleBunchContractTest {
+       private IProducer<? extends TripleBunch> producer;
+
+       @Contract.Inject
+       public final void setTripleBunchProducer(
+                       IProducer<? extends TripleBunch> producer) {
+               this.producer = producer;
+       }
+
+       protected final IProducer<? extends TripleBunch> 
getTripleBunchProducer() {
+               return producer;
+       }
+
+       public static final TripleBunch EMPTY_BUNCH = new ArrayBunch();
+
+       protected static final Triple tripleSPO = triple("s P o");
+       protected static final Triple tripleXQY = triple("x Q y");
+
+       private TripleBunch testingBunch;
+
+       @Before
+       public final void beforeAbstractTripleBunchTest() {
+               testingBunch = getTripleBunchProducer().newInstance();
+       }
+
+       @After
+       public final void afterAbstractTripleBunchTest() {
+               getTripleBunchProducer().cleanUp();
+       }
+
+       @ContractTest
+       public void testEmptyBunch() {
+               assertEquals(0, testingBunch.size());
+               assertFalse(testingBunch.contains(tripleSPO));
+               assertFalse(testingBunch.contains(tripleXQY));
+               assertFalse(testingBunch.iterator().hasNext());
+       }
+
+       @ContractTest
+       public void testAddElement() {
+               testingBunch.add(tripleSPO);
+               assertEquals(1, testingBunch.size());
+               assertTrue(testingBunch.contains(tripleSPO));
+               assertEquals(listOf(tripleSPO), 
iteratorToList(testingBunch.iterator()));
+       }
+
+       @ContractTest
+       public void testAddElements() {
+               testingBunch.add(tripleSPO);
+               testingBunch.add(tripleXQY);
+               assertEquals(2, testingBunch.size());
+               assertTrue(testingBunch.contains(tripleSPO));
+               assertTrue(testingBunch.contains(tripleXQY));
+               assertEquals(setOf(tripleSPO, tripleXQY),
+                               iteratorToSet(testingBunch.iterator()));
+       }
+
+       @ContractTest
+       public void testRemoveOnlyElement() {
+               testingBunch.add(tripleSPO);
+               testingBunch.remove(tripleSPO);
+               assertEquals(0, testingBunch.size());
+               assertFalse(testingBunch.contains(tripleSPO));
+               assertFalse(testingBunch.iterator().hasNext());
+       }
+
+       @ContractTest
+       public void testRemoveFirstOfTwo() {
+               testingBunch.add(tripleSPO);
+               testingBunch.add(tripleXQY);
+               testingBunch.remove(tripleSPO);
+               assertEquals(1, testingBunch.size());
+               assertFalse(testingBunch.contains(tripleSPO));
+               assertTrue(testingBunch.contains(tripleXQY));
+               assertEquals(listOf(tripleXQY), 
iteratorToList(testingBunch.iterator()));
+       }
+
+       @ContractTest
+       public void testTableGrows() {
+               testingBunch.add(tripleSPO);
+               testingBunch.add(tripleXQY);
+               testingBunch.add(triple("a I b"));
+               testingBunch.add(triple("c J d"));
+       }
+
+       @ContractTest
+       public void testIterator() {
+               testingBunch.add(triple("a P b"));
+               testingBunch.add(triple("c Q d"));
+               testingBunch.add(triple("e R f"));
+               assertEquals(tripleSet("a P b; c Q d; e R f"), 
testingBunch.iterator()
+                               .toSet());
+       }
+
+       @ContractTest
+       public void testIteratorRemoveOneItem() {
+               testingBunch.add(triple("a P b"));
+               testingBunch.add(triple("c Q d"));
+               testingBunch.add(triple("e R f"));
+               ExtendedIterator<Triple> it = testingBunch.iterator();
+               while (it.hasNext())
+                       if (it.next().equals(triple("c Q d")))
+                               it.remove();
+               assertEquals(tripleSet("a P b; e R f"), 
testingBunch.iterator().toSet());
+       }
+
+       @ContractTest
+       public void testIteratorRemoveAlltems() {
+               testingBunch.add(triple("a P b"));
+               testingBunch.add(triple("c Q d"));
+               testingBunch.add(triple("e R f"));
+               ExtendedIterator<Triple> it = testingBunch.iterator();
+               while (it.hasNext())
+                       it.removeNext();
+               assertEquals(tripleSet(""), testingBunch.iterator().toSet());
+       }
+
+       protected List<Triple> listOf(Triple x) {
+               List<Triple> result = new ArrayList<Triple>();
+               result.add(x);
+               return result;
+       }
+
+       protected Set<Triple> setOf(Triple x, Triple y) {
+               Set<Triple> result = setOf(x);
+               result.add(y);
+               return result;
+       }
+
+       protected Set<Triple> setOf(Triple x) {
+               Set<Triple> result = new HashSet<Triple>();
+               result.add(x);
+               return result;
+       }
+
+       public void testAddThenNextThrowsCME() {
+               testingBunch.add(NodeCreateUtils.createTriple("a P b"));
+               testingBunch.add(NodeCreateUtils.createTriple("c Q d"));
+               ExtendedIterator<Triple> it = testingBunch.iterator();
+               it.next();
+               testingBunch.add(NodeCreateUtils.createTriple("change its 
state"));
+               try {
+                       it.next();
+                       fail("should have thrown 
ConcurrentModificationException");
+               } catch (ConcurrentModificationException e) {
+                       // expected
+               }
+       }
+
+       public void testDeleteThenNextThrowsCME() {
+               testingBunch.add(NodeCreateUtils.createTriple("a P b"));
+               testingBunch.add(NodeCreateUtils.createTriple("c Q d"));
+               ExtendedIterator<Triple> it = testingBunch.iterator();
+               it.next();
+               testingBunch.remove(NodeCreateUtils.createTriple("a P b"));
+               try {
+                       it.next();
+                       fail("should have thrown 
ConcurrentModificationException");
+               } catch (ConcurrentModificationException e) {
+                       // expected
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractGraphProducer.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractGraphProducer.java
 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractGraphProducer.java
new file mode 100644
index 0000000..29cf9f0
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractGraphProducer.java
@@ -0,0 +1,104 @@
+/*
+    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.testing_framework;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.xenei.junit.contract.IProducer;
+
+import org.apache.jena.graph.Graph;
+
+/**
+ * An abstract implementation of the GraphProducerInterface.
+ * 
+ * This class handles tracking of the created graphs and closing them. It also
+ * provides a callback for the implementing class to perform extra cleanup when
+ * the graph is closed.
+ * 
+ */
+public abstract class AbstractGraphProducer<T extends Graph> implements
+               IProducer<T> {
+
+       /**
+        * The list of graphs that have been opened in this test.
+        */
+       protected List<Graph> graphList = new ArrayList<Graph>();
+
+       /**
+        * The method to create a new graph.
+        * 
+        * @return a newly constructed graph of type under test.
+        */
+       abstract protected T createNewGraph();
+
+       @Override
+       final public T newInstance() {
+               T retval = createNewGraph();
+               graphList.add(retval);
+               return retval;
+       }
+
+       /**
+        * Method called after the graph is closed. This allows the implementer 
to
+        * perform extra cleanup activities, like deleting the file associated 
with
+        * a file based graph.
+        * <p>
+        * By default this does nothing.
+        * </p>
+        * 
+        * @param g
+        *            The graph that is closed
+        */
+       protected void afterClose(Graph g) {
+       };
+
+       @Override
+       final public void cleanUp() {
+               for (Graph g : graphList) {
+                       if (!g.isClosed()) {
+                               g.close();
+                       }
+                       afterClose(g);
+               }
+               graphList.clear();
+       }
+
+       /**
+        * Get a list of graphs that the created graph is dependent upon. The 
graph
+        * must return true for each call to dependsOn() with one of the 
returned
+        * graphs. Method may return null to disable the check.
+        * 
+        * @param g
+        *            The graph we are looking for.
+        * @return
+        */
+       public abstract Graph[] getDependsOn(Graph g);
+
+       /**
+        * Get a list of graphs that the created graph is not dependent upon. 
The
+        * graph must return false for each call to dependsOn() with one of the
+        * returned graphs. Method may return null to disable the check.
+        * 
+        * @param g
+        *            The graph we are looking for.
+        * @return
+        */
+       public abstract Graph[] getNotDependsOn(Graph g);
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractInfModelProducer.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractInfModelProducer.java
 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractInfModelProducer.java
new file mode 100644
index 0000000..898503d
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractInfModelProducer.java
@@ -0,0 +1,91 @@
+/*
+    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.testing_framework;
+
+import org.apache.jena.rdf.model.InfModel;
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.Statement;
+import org.apache.jena.reasoner.Reasoner;
+
+/**
+ * An abstract implementation of the ModelProducerInterface.
+ * 
+ * This class handles tracking of the created models and closing them. It also
+ * provides a callback for the implementing class to perform extra cleanup when
+ * the model is closed.
+ * 
+ */
+public abstract class AbstractInfModelProducer<T extends InfModel> extends
+               AbstractModelProducer<T> {
+
+       
+       public boolean canBeEmpty( Model m ) 
+       {
+               return false;
+       }
+       /**
+        * @return true if the models returned by this poducer are independent,
+        *         false otherwise.
+        * 
+        */
+       abstract public Reasoner getReasoner();
+
+       /**
+        * Returns the model that was used in the reasoner.bind() call.
+        * 
+        * @return
+        */
+       abstract public Model getBoundModel();
+
+       /**
+        * Populate the model with test data for the derivation test.
+        * 
+        * @param model
+        */
+       abstract public void populateModel(InfModel model);
+
+       /**
+        * Using the reasoner and the populated model, this statement should 
return
+        * a derivation iterator when getDerivation() is called.
+        * 
+        * This is not a complete test but a simple test to show that the system
+        * works in this specific case. A complete set of tests is left for 
later
+        * development.
+        * 
+        * @return The Statement that should have at least one derivation.
+        */
+       abstract public Statement getDerivationStatement();
+
+       /**
+        * Using the reasoner and the populated model, this statement should 
return
+        * an EMPTY derivation iterator when getDerivation() is called.
+        * 
+        * This is not a complete test but a simple test to show that the system
+        * works in this specific case. A complete set of tests is left for 
later
+        * development.
+        * 
+        * @return The Statement that should have no derivations.
+        */
+       abstract public Statement getNoDerivationStatement();
+
+       /**
+        * @return true if the InfModel supports the getDeductionsModel() call.
+        */
+       abstract public boolean supportsDeductionsModel();
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractModelProducer.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractModelProducer.java
 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractModelProducer.java
new file mode 100644
index 0000000..882e9d3
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractModelProducer.java
@@ -0,0 +1,88 @@
+/*
+    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.testing_framework;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.xenei.junit.contract.IProducer;
+import org.apache.jena.rdf.model.Model;
+
+/**
+ * An abstract implementation of the ModelProducerInterface.
+ * 
+ * This class handles tracking of the created models and closing them. It also
+ * provides a callback for the implementing class to perform extra cleanup when
+ * the model is closed.
+ * 
+ */
+public abstract class AbstractModelProducer<T extends Model> implements
+               IProducer<T> {
+
+       /**
+        * The list of graphs that have been opened in this test.
+        */
+       protected List<Model> modelList = new ArrayList<Model>();
+
+       /**
+        * @return true if the models returned by this poducer are independent,
+        *         false otherwise.
+        * 
+        */
+       abstract public boolean areIndependent();
+
+       /**
+        * The method to create a new model.
+        * 
+        * @return a newly constructed model of type under test.
+        */
+       abstract protected T createNewModel();
+
+       @Override
+       final public T newInstance() {
+               T retval = createNewModel();
+               modelList.add(retval);
+               return retval;
+       }
+
+       /**
+        * Method called after the graph is closed. This allows the implementer 
to
+        * perform extra cleanup activities, like deleting the file associated 
with
+        * a file based graph.
+        * <p>
+        * By default this does nothing.
+        * </p>
+        * 
+        * @param g
+        *            The graph that is closed
+        */
+       protected void afterClose(T g) {
+       };
+
+       @Override
+       final public void cleanUp() {
+               for (Model m : modelList) {
+                       if (!m.isClosed()) {
+                               m.close();
+                       }
+                       afterClose((T) m);
+               }
+               modelList.clear();
+       }
+       
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractRecordingListener.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractRecordingListener.java
 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractRecordingListener.java
new file mode 100644
index 0000000..e9e26a1
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/testing_framework/AbstractRecordingListener.java
@@ -0,0 +1,190 @@
+/*
+ * 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.testing_framework;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Assert;
+
+import org.apache.jena.rdf.model.Model;
+import org.apache.jena.rdf.model.Statement;
+
+/**
+ * This testing listener records the event names and data, and provides a 
method
+ * for comparing the actual with the expected history.
+ */
+public class AbstractRecordingListener {
+
+       @SuppressWarnings("unchecked")
+       public static boolean checkEquality(final Object o1, final Object o2) {
+               if (o1 == o2) {
+                       return true;
+               }
+               if (o1.getClass().isArray() && o2.getClass().isArray()) {
+                       final Object[] o1a = (Object[]) o1;
+                       final Object[] o2a = (Object[]) o2;
+
+                       if (o1a.length == o2a.length) {
+                               for (int i = 0; i < o1a.length; i++) {
+                                       if (!checkEquality(o1a[i], o2a[i])) {
+                                               return false;
+                                       }
+                               }
+                               return true;
+                       }
+                       return false;
+               } else if ((o1 instanceof Collection<?>)
+                               && (o2 instanceof Collection<?>)) {
+                       return checkEquality(((Collection<Object>) 
o1).toArray(),
+                                       ((Collection<Object>) o2).toArray());
+
+               } else if ((o1 instanceof Model) && (o2 instanceof Model)) {
+                       return checkEquality(((Model) 
o1).listStatements().toList(),
+                                       ((Model) o2).listStatements().toList());
+
+               } else if ((o1 instanceof Statement) && (o2 instanceof 
Statement)) {
+                       return checkEquality(((Statement) o1).asTriple(),
+                                       ((Statement) o2).asTriple());
+
+               } else {
+                       return o1.equals(o2);
+               }
+       }
+
+       private List<Object> history = new ArrayList<Object>();
+
+       protected final void record(String tag, Object x, Object y) {
+               history.add(tag);
+               history.add(x);
+               history.add(y);
+       }
+
+       protected final void record(String tag, Object info) {
+               history.add(tag);
+               history.add(info);
+       }
+
+       public final int differ(Object... things) {
+               for (int i = 0; i < history.size(); i++) {
+                       if (!things[i].equals(history.get(i))) {
+                               return i;
+                       }
+               }
+               return -1;
+       }
+
+       public final boolean has(Object... things) {
+               return history.equals(Arrays.asList(things));
+       }
+
+       public final void assertHas(Object... things) {
+               if (has(things) == false) {
+                       int idx = differ(things);
+                       Assert.fail("expected " + Arrays.asList(things) + " but 
got "
+                                       + history + " differ at position " + 
idx);
+               }
+       }
+
+       public final void assertEmpty() {
+               if (history.size() > 0) {
+                       Assert.fail("Should be no history but got " + history);
+               }
+       }
+
+       public final int size() {
+               return history.size();
+       }
+
+       public final boolean has(List<?> things) {
+               return history.equals(things);
+       }
+
+       public final boolean hasStart(List<Object> L) {
+               return L.size() <= history.size()
+                               && L.equals(history.subList(0, L.size()));
+       }
+
+       public final boolean hasEnd(List<Object> L) {
+               return L.size() <= history.size()
+                               && L.equals(history.subList(history.size() - 
L.size(),
+                                               history.size()));
+       }
+
+       public final void assertHas(List<?> things) {
+               if (has(things) == false)
+                       Assert.fail("expected " + things + " but got " + 
history);
+       }
+
+       public final void assertContains(Object... things) {
+               if (contains(things) == false)
+                       Assert.fail(String.format("expected %s but got %s",
+                                       Arrays.asList(things), history));
+       }
+
+       public final void assertHasStart(Object... start) {
+               List<Object> L = Arrays.asList(start);
+               if (hasStart(L) == false)
+                       Assert.fail("expected " + L + " at the beginning of " + 
history);
+       }
+
+       public final void assertHasEnd(Object... end) {
+               List<Object> L = Arrays.asList(end);
+               if (hasEnd(L) == false)
+                       Assert.fail("expected " + L + " at the end of " + 
history);
+       }
+
+       public final void clear() {
+               history.clear();
+       }
+
+       public final boolean contains(Object... objects) {
+               for (int i = 0; i < history.size(); i++) {
+                       if (history.get(i).equals(objects[0])) {
+                               boolean found = true;
+                               for (int j = 1; j < objects.length; j++) {
+                                       if (i + j >= history.size()) {
+                                               found = false;
+                                               break;
+                                       }
+                                       if (!history.get(i + 
j).equals(objects[j])) {
+                                               found = false;
+                                               break;
+                                       }
+                               }
+                               if (found) {
+                                       return true;
+                               }
+                       }
+
+               }
+               return false;
+
+       }
+
+       public final Iterator<Object> from(Object start) {
+               Iterator<Object> iter = history.iterator();
+               while (iter.hasNext() && !iter.next().equals(start))
+                       ; // loop
+               return iter;
+       }
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/ContractTemplate.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/testing_framework/ContractTemplate.java
 
b/jena-core/src/test/java/org/apache/jena/testing_framework/ContractTemplate.java
new file mode 100644
index 0000000..f7a16e5
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/testing_framework/ContractTemplate.java
@@ -0,0 +1,17 @@
+package org.apache.jena.testing_framework;
+
+import org.xenei.junit.contract.IProducer;
+
+public class ContractTemplate<P extends IProducer<?>> {
+
+       private P producer;
+
+       public final void setProducer(P producer) {
+               this.producer = producer;
+       }
+
+       protected final P getProducer() {
+               return producer;
+       }
+
+}

http://git-wip-us.apache.org/repos/asf/jena/blob/b293ee8a/jena-core/src/test/java/org/apache/jena/testing_framework/GraphEventManagerProducerInterface.java
----------------------------------------------------------------------
diff --git 
a/jena-core/src/test/java/org/apache/jena/testing_framework/GraphEventManagerProducerInterface.java
 
b/jena-core/src/test/java/org/apache/jena/testing_framework/GraphEventManagerProducerInterface.java
new file mode 100644
index 0000000..70e8182
--- /dev/null
+++ 
b/jena-core/src/test/java/org/apache/jena/testing_framework/GraphEventManagerProducerInterface.java
@@ -0,0 +1,35 @@
+/*
+    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.testing_framework;
+
+import org.apache.jena.graph.GraphEventManager;
+
+/**
+ * Foo producer for GraphEventManager testing.
+ * 
+ */
+public interface GraphEventManagerProducerInterface {
+
+       /**
+        * Returns a GraphEventManager to take part in the test. Must be 
overridden
+        * in a subclass.
+        * 
+        * @return The GraphEventManager implementation to test.
+        */
+       public abstract GraphEventManager newEventManager();
+}

Reply via email to