You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@clerezza.apache.org by ha...@apache.org on 2019/02/03 17:37:27 UTC

[clerezza] 02/02: CLEREZZA-1031: Move rdf.core access to a new module called dataset

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

hasan pushed a commit to branch reunited
in repository https://gitbox.apache.org/repos/asf/clerezza.git

commit 50211e4260e2b30e4b36ea95be29f3bbbb1fc811
Author: Hasan <ha...@apache.org>
AuthorDate: Sun Feb 3 18:36:35 2019 +0100

    CLEREZZA-1031: Move rdf.core access to a new module called dataset
---
 dataset/pom.xml                                    | 114 ++++
 .../dataset/EntityAlreadyExistsException.java      |  50 ++
 .../dataset/EntityUndeletableException.java        |  50 ++
 .../dataset/ImmutableGraphServiceFactory.java      |  58 ++
 .../clerezza/dataset/MGraphServiceFactory.java     |  54 ++
 .../clerezza/dataset/NoSuchEntityException.java    |  51 ++
 .../clerezza/dataset/QueryableTcProvider.java      |  41 ++
 .../org/apache/clerezza/dataset/SecuredGraph.java  | 191 +++++++
 .../org/apache/clerezza/dataset/TcManager.java     | 613 +++++++++++++++++++++
 .../org/apache/clerezza/dataset/TcProvider.java    | 151 +++++
 .../clerezza/dataset/TcProviderMultiplexer.java    | 446 +++++++++++++++
 .../dataset/WeightedProviderComparator.java        |  41 ++
 .../clerezza/dataset/WeightedTcProvider.java       |  36 ++
 .../java/org/apache/clerezza/dataset/package.html  |  56 ++
 .../dataset/security/TcAccessController.java       | 342 ++++++++++++
 .../clerezza/dataset/security/TcPermission.java    | 149 +++++
 .../org/apache/clerezza/dataset/SecurityTest.java  | 175 ++++++
 .../org/apache/clerezza/dataset/TcManagerTest.java | 299 ++++++++++
 .../clerezza/dataset/providers/WeightedA.java      | 103 ++++
 .../clerezza/dataset/providers/WeightedA1.java     | 103 ++++
 .../clerezza/dataset/providers/WeightedAHeavy.java | 101 ++++
 .../clerezza/dataset/providers/WeightedBlight.java | 106 ++++
 .../clerezza/dataset/providers/WeightedDummy.java  | 155 ++++++
 23 files changed, 3485 insertions(+)

diff --git a/dataset/pom.xml b/dataset/pom.xml
new file mode 100644
index 0000000..3ce095f
--- /dev/null
+++ b/dataset/pom.xml
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+
+   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.
+
+-->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.clerezza</groupId>
+        <artifactId>clerezza</artifactId>
+        <version>8-SNAPSHOT</version>
+        <relativePath/>
+    </parent>
+
+    <artifactId>dataset</artifactId>
+    <packaging>bundle</packaging>
+    <version>8-SNAPSHOT</version>
+    <name>Clerezza - DataSet</name>
+    <description>Interfaces and utilities to access RDF Graphs</description>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>api</artifactId>
+            <version>8-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>api.impl</artifactId>
+            <version>8-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>sparql</artifactId>
+            <version>8-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.ds-annotations</artifactId>
+            <version>1.2.8</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.clerezza</groupId>
+            <artifactId>utils</artifactId>
+            <version>0.2</version>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <version>1.9.5</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>org.apache.clerezza.dataset.*</Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <id>generate-scr-scrdescriptor</id>
+                        <goals>
+                            <goal>scr</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/EntityAlreadyExistsException.java b/dataset/src/main/java/org/apache/clerezza/dataset/EntityAlreadyExistsException.java
new file mode 100644
index 0000000..15dcb56
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/EntityAlreadyExistsException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.IRI;
+
+/**
+ * is thrown on an attempt to create an entity with a name which already exists
+ *
+ * @author hasan
+ */
+public class EntityAlreadyExistsException extends RuntimeException {
+
+    private IRI entityName;
+
+    /**
+     * creates an exception indicating that an entity with the specified name
+     * already exists.
+     * 
+     * @param entityName the name of the entity which already exists
+     */
+    public EntityAlreadyExistsException(IRI entityName) {
+        super("An entity with this name already exists: "+entityName);
+        this.entityName = entityName;
+    }
+
+    /**
+     * 
+     * @return the name of the entity which already exists
+     */
+    public IRI getEntityName() {
+        return entityName;
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/EntityUndeletableException.java b/dataset/src/main/java/org/apache/clerezza/dataset/EntityUndeletableException.java
new file mode 100644
index 0000000..32c5088
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/EntityUndeletableException.java
@@ -0,0 +1,50 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.IRI;
+
+/**
+ * is thrown on an attempt to delete an entity with a provider that
+ * supports the delete operation when the specified entity cannot be deleted
+ *
+ * @author reto
+ */
+public class EntityUndeletableException extends RuntimeException {
+    private IRI entityName;
+
+    /**
+     * creates an exception indicating that the entity with the specified name
+     * cannot be deleted
+     * 
+     * @param entityName the name of the entity which is undeletable
+     */
+    public EntityUndeletableException(IRI entityName) {
+        super("This entity is undeletable: "+entityName);
+        this.entityName = entityName;
+    }
+
+    /**
+     * 
+     * @return the name of the entity which is undeletable
+     */
+    public IRI getEntityName() {
+        return entityName;
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/ImmutableGraphServiceFactory.java b/dataset/src/main/java/org/apache/clerezza/dataset/ImmutableGraphServiceFactory.java
new file mode 100644
index 0000000..b775d82
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/ImmutableGraphServiceFactory.java
@@ -0,0 +1,58 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.dataset.security.TcAccessController;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @see <a href="http://www.osgi.org/javadoc/r4v41/org/osgi/framework/ServiceFactory.html">
+ * Interface ServiceFactory</a>
+ *
+ * @author mir
+ */
+public class ImmutableGraphServiceFactory implements ServiceFactory {
+    
+    private final TcManager tcManager;
+    private final IRI name;
+    private final TcAccessController tcAccessController;
+
+    ImmutableGraphServiceFactory(TcManager tcManager, IRI name,
+                                 TcAccessController tcAccessController) {
+        this.tcManager = tcManager;
+        this.name = name;
+        this.tcAccessController = tcAccessController;
+    }
+
+    @Override
+    public Object getService(Bundle arg0, ServiceRegistration arg1) {
+        Graph tc = 
+                new SecuredGraph(tcManager.getImmutableGraph(name), name,
+                tcAccessController);
+        return tc.getImmutableGraph();
+    }
+
+    @Override
+    public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/MGraphServiceFactory.java b/dataset/src/main/java/org/apache/clerezza/dataset/MGraphServiceFactory.java
new file mode 100644
index 0000000..cf3435c
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/MGraphServiceFactory.java
@@ -0,0 +1,54 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.dataset.security.TcAccessController;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceFactory;
+import org.osgi.framework.ServiceRegistration;
+
+/**
+ * @see <a href="http://www.osgi.org/javadoc/r4v41/org/osgi/framework/ServiceFactory.html">
+ * Interface ServiceFactory</a>
+ *
+ * @author mir
+ */
+public class MGraphServiceFactory implements ServiceFactory {
+    
+    private TcManager tcManager;
+    private IRI name;
+    private final TcAccessController tcAccessController;
+
+    MGraphServiceFactory(TcManager tcManager, IRI name,
+                         TcAccessController tcAccessController) {
+        this.tcManager = tcManager;
+        this.name = name;
+        this.tcAccessController = tcAccessController;
+    }
+
+    @Override
+    public Object getService(Bundle arg0, ServiceRegistration arg1) {
+        return new SecuredGraph(tcManager.getMGraph(name), name, tcAccessController);
+    }
+
+    @Override
+    public void ungetService(Bundle arg0, ServiceRegistration arg1, Object arg2) {
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/NoSuchEntityException.java b/dataset/src/main/java/org/apache/clerezza/dataset/NoSuchEntityException.java
new file mode 100644
index 0000000..789dc6b
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/NoSuchEntityException.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.clerezza.dataset;
+
+import org.apache.clerezza.api.IRI;
+
+/**
+ * is thrown on an attempt to perform an operation on an entity (i.e. a
+ * <code>ImmutableGraph</code> or <code>Graph</code> that does not exist.
+ *
+ * @author reto
+ */
+public class NoSuchEntityException extends RuntimeException {
+    private IRI entityName;
+
+    /**
+     * creates an exception indicating that the entity with the specified name
+     * does not exist.
+     * 
+     * @param entityName the name for which no entity exists
+     */
+    public NoSuchEntityException(IRI entityName) {
+        super("No such entity: "+entityName);
+        this.entityName = entityName;
+    }
+
+    /**
+     * the name for which no entity exists.
+     * 
+     * @return the name of the entity that doesn't exist
+     */
+    public IRI getEntityName() {
+        return entityName;
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/QueryableTcProvider.java b/dataset/src/main/java/org/apache/clerezza/dataset/QueryableTcProvider.java
new file mode 100644
index 0000000..0490a4c
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/QueryableTcProvider.java
@@ -0,0 +1,41 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.IRI;
+
+/**
+ * Extends the TcProvider interface for providers that support sparql queries.
+ */
+public interface QueryableTcProvider extends TcProvider {
+
+    /**
+     * Executes any sparql query. The type of the result object will vary
+     * depending on the type of the query.
+     * 
+     * @param query
+     *            the sparql query to execute
+     * @param defaultGraph
+     *            the default ImmutableGraph against which to execute the query if not
+     *            FROM clause is present
+     * @return the resulting ResultSet, ImmutableGraph or Boolean value
+     */
+    public Object executeSparqlQuery(String query, IRI defaultGraphUri);
+
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/SecuredGraph.java b/dataset/src/main/java/org/apache/clerezza/dataset/SecuredGraph.java
new file mode 100644
index 0000000..afc2102
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/SecuredGraph.java
@@ -0,0 +1,191 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.*;
+import org.apache.clerezza.api.impl.graph.SimpleImmutableGraph;
+import org.apache.clerezza.api.impl.graph.WriteBlockedGraph;
+import org.apache.clerezza.dataset.security.TcAccessController;
+
+import java.security.AccessControlException;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.concurrent.locks.ReadWriteLock;
+
+/**
+ * A Secured triple collection wraps a triple collection checking each access
+ * for the rights on a the ImmutableGraph for which the uri is passed to the 
+ * constructor.
+ *
+ * @author mir, hasan
+ */
+public class SecuredGraph implements Graph {
+
+    private final Graph wrapped;
+    private final IRI name;
+    private final TcAccessController tcAccessController;
+
+    public SecuredGraph(Graph wrapped, IRI name,
+                        TcAccessController tcAccessController) {
+        this.wrapped = wrapped;
+        this.name = name;
+        this.tcAccessController = tcAccessController;
+    }
+
+    @Override
+    public Iterator<Triple> filter(final BlankNodeOrIRI subject, final IRI predicate, final RDFTerm object) {
+        final Iterator<Triple> baseIter = wrapped.filter(subject, predicate, object);
+        return new Iterator<Triple>() {
+
+            @Override
+            public boolean hasNext() {
+                checkRead();
+                return baseIter.hasNext();
+            }
+
+            @Override
+            public Triple next() {
+                checkRead();
+                return baseIter.next();
+            }
+
+            @Override
+            public void remove() {
+                checkWrite();
+                baseIter.remove();
+            }
+        };
+    }
+
+    @Override
+    public int size() {
+        checkRead();
+        return wrapped.size();
+    }
+
+    @Override
+    public boolean isEmpty() {
+        checkRead();
+        return wrapped.isEmpty();
+    }
+
+    @Override
+    public Object[] toArray() {
+        checkRead();
+        return wrapped.toArray();
+    }
+
+    @Override
+    public <T> T[] toArray(T[] a) {
+        checkRead();
+        return wrapped.toArray(a);
+    }
+
+    @Override
+    public boolean add(Triple e) {
+        checkWrite();
+        return wrapped.add(e);
+    }
+
+    @Override
+    public boolean remove(Object o) {
+        checkWrite();
+        return wrapped.remove(o);
+    }
+
+    @Override
+    public boolean addAll(Collection<? extends Triple> c) {
+        checkWrite();
+        return wrapped.addAll(c);
+    }
+
+    @Override
+    public boolean removeAll(Collection<?> c) {
+        checkWrite();
+        return wrapped.removeAll(c);
+    }
+
+    @Override
+    public boolean retainAll(Collection<?> c) {
+        checkWrite();
+        return wrapped.retainAll(c);
+    }
+
+    @Override
+    public void clear() {
+        checkWrite();
+        wrapped.clear();
+    }
+
+    void checkRead() {
+        tcAccessController.checkReadPermission(name);
+    }
+
+    void checkWrite() {
+        tcAccessController.checkReadWritePermission(name);
+    }
+
+    @Override
+    public boolean contains(Object o) {
+        checkRead();
+        return wrapped.contains((Triple) o);
+    }
+
+
+    @Override
+    public Iterator<Triple> iterator() {
+        return filter(null, null, null);
+    }
+
+    @Override
+    public boolean containsAll(Collection<?> c) {
+        checkRead();
+        return wrapped.containsAll(c);
+    }
+    
+    @Override
+    public ImmutableGraph getImmutableGraph() {
+        return new SimpleImmutableGraph(this);
+    }
+
+    @Override
+    public ReadWriteLock getLock() {
+        return wrapped.getLock();
+    }
+    
+    /**
+     * Returns the wrapped Graph if the caller has all access rights.
+     * If the caller has only the read access right, then a write-blocked
+     * Graph is returned. If the caller has neither the read nor the write
+     * access right then an AccessControlException is thrown.
+     *
+     * @return the wrapped Graph or a write-block Graph depending
+     *        on the access rights of the caller.
+     */
+    public Graph getUnsecuredGraph() {
+        try {
+            checkWrite();
+            return wrapped;
+        } catch (AccessControlException ex) {
+            checkRead();
+            return new WriteBlockedGraph(wrapped);
+        }
+        
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/TcManager.java b/dataset/src/main/java/org/apache/clerezza/dataset/TcManager.java
new file mode 100644
index 0000000..8981ad3
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/TcManager.java
@@ -0,0 +1,613 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.impl.graph.SimpleGraph;
+import org.apache.clerezza.api.impl.graph.WriteBlockedGraph;
+import org.apache.clerezza.dataset.security.TcAccessController;
+import org.apache.clerezza.sparql.*;
+import org.apache.clerezza.sparql.query.*;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Reference;
+import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+
+import java.security.AccessControlException;
+import java.util.*;
+
+/**
+ * This class implements
+ * <code>TcManager</code>, delegating the actual provision and creation of
+ * Graphs or MGraphs to registered
+ * <code>TcProvider</code>s. The class attempts to satisfy the request using the
+ * register
+ * <code>WeightedTcProvider</code> in decreasing order of weight. If multiple
+ * providers have the same weight the lexicographical order of the fully
+ * qualified class name determines which one is used, namely the one that occurs
+ * earlier. If a call to a registered provider causes an
+ * <code>IllegalArgumentException</code>,
+ * <code>NoSuchEntityException</code> or
+ * <code>UnsupportedOperationException</code> then the call is delegated to the
+ * next provider.
+ *
+ * Only one instance of this class should exist in a system, the public no
+ * argument constructor is meant for initialization by dependency injection
+ * systems such as OSGi-DS. Applications should use the static
+ * <code>getInstance()</code> method if they aren't using a framework that
+ * injects them the instance.
+ *
+ * This class returns
+ * <code>Graph</code>s a subtype of
+ * <code>Graph</code> that allows read/write locks.
+ *
+ * This class also registers all Graphs as services with the property
+ * 'name' indicating there name.
+ *
+ * Security checks are done when a Graph is retrieved. The returned
+ * Graph will do no further security checks. Because of this it
+ * should not be passed to a context where different access control applies. If
+ * an Graph is retrieved without having write permission the returned graph
+ * will be read-only.
+ *
+ * If a Graphs needs to passed around across different security
+ * contexts the one retrieved from the OSGi service whiteboard should be used as
+ * this performs access control on every access.
+ *
+ * @author reto, mir, hasan
+ *
+ */
+//immedia is set to true as this should register the ImmutableGraph services (even if manager service is not required)
+@Component(service = TcManager.class, immediate = true,
+        property={
+            "graph.cache.enabled=true",
+            "Graph.services.enabled=true"})
+public class TcManager extends TcProviderMultiplexer implements GraphStore {
+
+    public final static String GENERAL_PURPOSE_TC = "general.purpose.tc";
+    public final static String Graph_SERVICES_ENABLED = "Graph.services.enabled";
+    public final static String MGRAPH_CACHE_ENABLED = "graph.cache.enabled";
+
+    private static volatile TcManager instance;
+    private TcAccessController tcAccessController = new TcAccessController() {
+
+        @Override
+        protected TcManager getTcManager() {
+            return TcManager.this;
+        }
+            
+    };
+    private Map<IRI, ServiceRegistration> serviceRegistrations = Collections
+            .synchronizedMap(new HashMap<IRI, ServiceRegistration>());
+    
+    protected QueryEngine queryEngine;
+    private boolean isActivated = false;
+    private boolean isTcServicesEnabled = true;
+
+    private ComponentContext componentContext;
+    protected SortedSet<WeightedTcProvider> tempProviderList = new TreeSet<WeightedTcProvider>(
+            new WeightedProviderComparator());
+
+    /**
+     * the constructor sets the singleton instance to allow instantiation by
+     * OSGi-DS. This constructor should not be called except by OSGi-DS,
+     * otherwise the static
+     * <code>getInstance</code> method should be used.
+     */
+    public TcManager() {
+        TcManager.instance = this;
+    }
+
+    /**
+     * This returns the singleton instance. If an instance has been previously
+     * created (e.g. by OSGi declarative services) this instance is returned,
+     * otherwise a new instance is created and providers are injected using the
+     * service provider interface (META-INF/services/)
+     *
+     * @return the singleton instance
+     */
+    public static TcManager getInstance() {
+        if (instance == null) {
+            synchronized (TcManager.class) {
+                if (instance == null) {
+                    instance = new TcManager();
+                    instance.isActivated = true;
+                    Iterator<WeightedTcProvider> weightedProviders = ServiceLoader
+                            .load(WeightedTcProvider.class).iterator();
+                    while (weightedProviders.hasNext()) {
+                        WeightedTcProvider weightedProvider = weightedProviders
+                                .next();
+                        instance
+                                .bindWeightedTcProvider(weightedProvider);
+                    }
+                    Iterator<QueryEngine> queryEngines = ServiceLoader.load(
+                            QueryEngine.class).iterator();
+                    System.out.println("looking for QE");
+                    if (queryEngines.hasNext()) {
+                        instance.queryEngine = queryEngines.next();
+                        System.out.println("QE: "
+                                + instance.queryEngine.getClass());
+                    }
+                }
+            }
+        }
+        return instance;
+    }
+    
+    protected void activate(final ComponentContext componentContext) {
+        this.componentContext = componentContext;
+        
+        // Read configuration
+		isTcServicesEnabled = true;
+		Object configTcServicesEnabled = componentContext.getProperties().get(Graph_SERVICES_ENABLED);
+		if ( configTcServicesEnabled != null && configTcServicesEnabled instanceof String ) {
+			isTcServicesEnabled = Boolean.valueOf((String)configTcServicesEnabled);				
+		}
+		Object configCacheEnabled = componentContext.getProperties().get(MGRAPH_CACHE_ENABLED);
+		if ( configCacheEnabled != null && configCacheEnabled instanceof String ) {
+			setCachingEnabled(Boolean.valueOf((String)configCacheEnabled));				
+		}
+		isActivated = true;
+		
+        for (WeightedTcProvider provider : tempProviderList) {
+        	addWeightedTcProvider(provider);
+        }
+        tempProviderList.clear();
+    }
+
+    protected void deactivate(final ComponentContext componentContext) {
+        for (ServiceRegistration registration : serviceRegistrations.values()) {
+            registration.unregister();
+        }
+        serviceRegistrations.clear();
+        this.componentContext = null;
+		isActivated = false;
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        tcAccessController.checkReadPermission(name);
+        return super.getImmutableGraph(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name) {
+        try {
+            tcAccessController.checkReadWritePermission(name);
+        } catch (AccessControlException e) {
+            tcAccessController.checkReadPermission(name);
+            return new WriteBlockedGraph(super.getMGraph(name));
+        }
+        return super.getMGraph(name);
+    }
+
+    @Override
+    public Graph getGraph(IRI name) {
+        try {
+            tcAccessController.checkReadWritePermission(name);
+        } catch (AccessControlException e) {
+            tcAccessController.checkReadPermission(name);
+            return new WriteBlockedGraph(
+                    super.getGraph(name));
+        }
+        return super.getGraph(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name)
+            throws UnsupportedOperationException {
+        tcAccessController.checkReadWritePermission(name);
+        return super.createGraph(name);
+    }
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples) {
+        tcAccessController.checkReadWritePermission(name);
+        return super.createImmutableGraph(name, triples);
+    }
+
+    @Override
+    public void deleteGraph(IRI name) {
+        tcAccessController.checkReadWritePermission(name);
+        super.deleteGraph(name);
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        return super.getNames(ImmutableGraph);
+    }
+
+    @Override
+    public Set<IRI> listNamedGraphs() {
+        return this.listGraphs();
+    }
+
+    @Override
+    public Set<IRI> listGraphs() {
+        Set<IRI> result = super.listGraphs();
+        return excludeNonReadable(result);
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        Set<IRI> result = super.listMGraphs();
+        return excludeNonReadable(result);
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        Set<IRI> result = super.listImmutableGraphs();
+        return excludeNonReadable(result);
+    }
+
+    private Set<IRI> excludeNonReadable(Set<IRI> tcNames) {
+        SecurityManager security = System.getSecurityManager();
+        if (security == null) {
+            return tcNames;
+        }
+        Set<IRI> result = new HashSet<IRI>();
+        for (IRI name : tcNames) {
+            try {
+                tcAccessController.checkReadPermission(name);
+            } catch (AccessControlException e) {
+                continue;
+            }
+            result.add(name);
+        }
+        return result;
+    }
+
+    /**
+     * Executes any sparql query. The type of the result object will vary
+     * depending on the type of the query. If the defaultGraph is available
+     * in this TcManages executeSparqlQuery(String, UriRef) should be used instead.
+     *
+     * @param query the sparql query to execute
+     * @param defaultGraph the default ImmutableGraph against which to execute the query
+     * if no FROM clause is present
+     * @return the resulting ResultSet, ImmutableGraph or Boolean value
+     */
+    public Object executeSparqlQuery(String query, Graph defaultGraph) throws ParseException {
+        TcProvider singleTargetTcProvider = null;
+
+        final IRI defaultGraphName = new IRI("urn:x-temp:/kjsfadfhfasdffds");
+        final SparqlPreParser sparqlPreParser = new SparqlPreParser(this);
+        final Set<IRI> referencedGraphs = sparqlPreParser.getReferredGraphs(query, defaultGraphName);
+        if ((referencedGraphs != null) && (!referencedGraphs.contains(defaultGraphName))) {
+            singleTargetTcProvider = getSingleTargetTcProvider(referencedGraphs);
+        }
+        if ((singleTargetTcProvider != null) && (singleTargetTcProvider instanceof QueryableTcProvider)) {
+            return ((QueryableTcProvider) singleTargetTcProvider).executeSparqlQuery(query, null);
+        }
+        final QueryEngine queryEngine = this.queryEngine;
+        if (queryEngine != null) {
+            return queryEngine.execute(this, defaultGraph, query);
+        } else {
+            throw new NoQueryEngineException();
+        }
+    }
+
+    /**
+     * Executes any sparql query. The type of the result object will vary
+     * depending on the type of the query. Note that this method only works for
+     * queries that do not need a default ImmutableGraph.
+     *
+     * @param query the sparql query to execute
+     * @param forceFastlane indicate whether to force fastlane usage.
+     * @return the resulting ResultSet, ImmutableGraph or Boolean value
+     */
+    public Object executeSparqlQuery(String query, boolean forceFastlane) throws ParseException {
+        TcProvider singleTargetTcProvider = null;
+    	if (forceFastlane) {
+            singleTargetTcProvider = getSingleTargetTcProvider(Collections.EMPTY_SET);
+    	} else {
+	        final IRI defaultGraphName = new IRI("urn:x-temp:/kjsfadfhfasdffds");
+	        SparqlPreParser sparqlPreParser = new SparqlPreParser(this);
+	        final Set<IRI> referencedGraphs = sparqlPreParser.getReferredGraphs(query, defaultGraphName);
+	        if ((referencedGraphs != null) && (!referencedGraphs.contains(defaultGraphName))) {
+	            singleTargetTcProvider = getSingleTargetTcProvider(referencedGraphs);
+	        }
+    	}
+
+        if ((singleTargetTcProvider != null) && (singleTargetTcProvider instanceof QueryableTcProvider)) {
+            return ((QueryableTcProvider)singleTargetTcProvider).executeSparqlQuery(query, null);
+        }
+        final QueryEngine queryEngine = this.queryEngine;
+        if (queryEngine != null) {
+            return queryEngine.execute(this, new SimpleGraph(), query);
+        } else {
+            throw new NoQueryEngineException();
+        }
+    }
+
+    /**
+     * Executes any sparql query. The type of the result object will vary
+     * depending on the type of the query. If the defaultGraph is available
+     * in this TcManages executeSparqlQuery(String, UriRef) should be used instead.
+     *
+     * @param query the sparql query to execute
+     * @param defaultGraphName the ImmutableGraph to be used as default ImmutableGraph in the Sparql ImmutableGraph Store
+     * @return the resulting ResultSet, ImmutableGraph or Boolean value
+     */
+    public Object executeSparqlQuery(String query, IRI defaultGraphName) throws ParseException {
+      return executeSparqlQuery(query, defaultGraphName, false);
+    }
+
+    /**
+     * Executes any sparql query. The type of the result object will vary
+     * depending on the type of the query. If the defaultGraph is available
+     * in this TcManages executeSparqlQuery(String, UriRef) should be used instead.
+     *
+     * @param query the sparql query to execute
+     * @param defaultGraph the ImmutableGraph to be used as default ImmutableGraph in the Sparql ImmutableGraph Store
+     * @param forceFastlane indicate whether to force fastlane usage.
+     * @return the resulting ResultSet, ImmutableGraph or Boolean value
+     */
+    public Object executeSparqlQuery(String query, IRI defaultGraphName, boolean forceFastlane) throws ParseException {
+        TcProvider singleTargetTcProvider = null;
+    	if (forceFastlane) {
+            singleTargetTcProvider = getSingleTargetTcProvider(Collections.singleton(defaultGraphName));
+    	} else {
+	        SparqlPreParser sparqlPreParser = new SparqlPreParser(this);
+	        final Set<IRI> referencedGraphs = sparqlPreParser.getReferredGraphs(query, defaultGraphName);
+	        if ((referencedGraphs != null)) {
+	            singleTargetTcProvider = getSingleTargetTcProvider(referencedGraphs);
+	        }
+    	}
+        if ((singleTargetTcProvider != null) && (singleTargetTcProvider instanceof QueryableTcProvider)) {
+            return ((QueryableTcProvider)singleTargetTcProvider).executeSparqlQuery(query, defaultGraphName);
+        }
+        final QueryEngine queryEngine = this.queryEngine;
+        if (queryEngine != null) {
+            return queryEngine.execute(this, this.getGraph(defaultGraphName), query);
+        } else {
+            throw new NoQueryEngineException();
+        }
+    }
+
+    /**
+     * Executes any sparql query. The type of the result object will vary
+     * depending on the type of the query.
+     *
+     * @param query the sparql query to execute
+     * @param defaultGraph the default ImmutableGraph against which to execute the query
+     * if no FROM clause is present
+     * @return the resulting ResultSet, ImmutableGraph or Boolean value
+     *
+     * @deprecated Query is discontinued
+     */
+    @Deprecated
+    public Object executeSparqlQuery(Query query, Graph defaultGraph) {
+        final QueryEngine queryEngine = this.queryEngine;
+        if (queryEngine != null) {
+            return queryEngine.execute(this, defaultGraph, query.toString());
+        } else {
+            throw new NoQueryEngineException();
+        }
+    }
+
+    /**
+     * Executes a sparql SELECT query.
+     *
+     * @param query the sparql SELECT query to execute
+     * @param defaultGraph the default ImmutableGraph against which to execute the query
+     * if not FROM clause is present
+     * @return the resulting ResultSet
+     * @deprecated Query is discontinued
+     */
+    @Deprecated
+    public ResultSet executeSparqlQuery(SelectQuery query,
+                                        Graph defaultGraph) {
+        return (ResultSet) executeSparqlQuery((Query) query, defaultGraph);
+    }
+
+    /**
+     * Executes a sparql ASK query.
+     *
+     * @param query the sparql ASK query to execute
+     * @param defaultGraph the default ImmutableGraph against which to execute the query
+     * if not FROM clause is present
+     * @return the boolean value this query evaluates to
+     * @deprecated Query is discontinued
+     */
+    @Deprecated
+    public boolean executeSparqlQuery(AskQuery query,
+            Graph defaultGraph) {
+        return (Boolean) executeSparqlQuery((Query) query, defaultGraph);
+    }
+
+    /**
+     * Executes a sparql DESCRIBE query.
+     *
+     * @param query the sparql DESCRIBE query to execute
+     * @param defaultGraph the default ImmutableGraph against which to execute the query
+     * if not FROM clause is present
+     * @return the resulting ImmutableGraph
+     * @deprecated Query is discontinued
+     */
+    @Deprecated
+    public ImmutableGraph executeSparqlQuery(DescribeQuery query,
+            Graph defaultGraph) {
+        return (ImmutableGraph) executeSparqlQuery((Query) query, defaultGraph);
+    }
+
+    /**
+     * Executes a sparql CONSTRUCT query.
+     *
+     * @param query the sparql CONSTRUCT query to execute
+     * @param defaultGraph the default ImmutableGraph against which to execute the query
+     * if not FROM clause is present
+     * @return the resulting ImmutableGraph
+     * @deprecated Query is discontinued
+     */
+    @Deprecated
+    public ImmutableGraph executeSparqlQuery(ConstructQuery query,
+            Graph defaultGraph) {
+        return (ImmutableGraph) executeSparqlQuery((Query) query, defaultGraph);
+    }
+
+    /**
+     * @return the TcAccessController that can be used to set the permissions
+     * needed to access a Triple Collection
+     */
+    public TcAccessController getTcAccessController() {
+        return tcAccessController;
+    }
+
+    /**
+     * Registers a provider
+     *
+     * @param provider the provider to be registered
+     */
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.MULTIPLE)
+    protected void bindWeightedTcProvider(WeightedTcProvider provider) {
+    	if (isActivated) {
+    		addWeightedTcProvider(provider);
+    	} else {
+    		tempProviderList.add(provider);
+    	}
+    }
+
+    /**
+     * Unregister a provider
+     *
+     * @param provider the provider to be deregistered
+     */
+    protected void unbindWeightedTcProvider(
+            WeightedTcProvider provider) {
+        removeWeightedTcProvider(provider);
+    }
+
+    /**
+     * Registers a provider
+     *
+     * @param provider the provider to be registered
+     */
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.AT_LEAST_ONE,
+            target = "("+ TcManager.GENERAL_PURPOSE_TC+"=true)")
+    protected void bindGpWeightedTcProvider(WeightedTcProvider provider) {
+    	if (isActivated) {
+    		addWeightedTcProvider(provider);
+    	} else {
+    		tempProviderList.add(provider);
+    	}
+    }
+
+    /**
+     * Unregister a provider
+     *
+     * @param provider the provider to be deregistered
+     */
+    protected void unbindGpWeightedTcProvider(
+            WeightedTcProvider provider) {
+        removeWeightedTcProvider(provider);
+    }
+
+    @Reference(policy = ReferencePolicy.DYNAMIC,
+            cardinality = ReferenceCardinality.OPTIONAL)
+    protected void bindQueryEngine(QueryEngine queryEngine) {
+        this.queryEngine = queryEngine;
+    }
+
+    protected void unbindQueryEngine(QueryEngine queryEngine) {
+        this.queryEngine = null;
+    }
+
+    @Override
+    protected void mGraphAppears(IRI name) {
+    	if (isTcServicesEnabled()) {
+    		// Only create the service when activated. When not activated
+    		// creating will be delayed till after activation.
+	        if (componentContext != null) {
+	            registerGraphAsService(name, true);
+	        }
+    	}
+    }
+
+    @Override
+    protected void graphAppears(IRI name) {
+    	if (isTcServicesEnabled()) {
+    		// Only create the service when activated. When not activated
+    		// creating will be delayed till after activation.
+	        if (componentContext != null) {
+	            registerGraphAsService(name, false);
+	        }
+    	}
+    }
+
+    private void registerGraphAsService(IRI name, boolean isMGraph) {
+        Dictionary<String,Object> props = new Hashtable<String, Object>();
+        props.put("name", name.getUnicodeString());
+        String[] interfaceNames;
+        Object service;
+        if (isMGraph) {
+            interfaceNames = new String[]{
+                Graph.class.getName(),
+                Graph.class.getName()
+            };
+            service = new MGraphServiceFactory(this, name, tcAccessController);
+        } else {
+            interfaceNames = new String[]{ImmutableGraph.class.getName()};
+            service = new ImmutableGraphServiceFactory(this, name, tcAccessController);
+        }
+        final int bundleState = componentContext.getBundleContext().getBundle().getState();
+        if ((bundleState == Bundle.ACTIVE) || (bundleState == Bundle.STARTING)) {
+            ServiceRegistration serviceReg = componentContext.getBundleContext()
+                    .registerService(interfaceNames, service, props);
+            serviceRegistrations.put(name, serviceReg);
+        }
+    }
+
+    @Override
+    protected void tcDisappears(IRI name) {
+        ServiceRegistration reg = serviceRegistrations.get(name);
+        if (reg != null) {
+            reg.unregister();
+            serviceRegistrations.remove(name);
+        }
+    }
+
+    private TcProvider getSingleTargetTcProvider(final Set<IRI> referencedGraphs) {
+        TcProvider singleTargetTcProvider = null;
+        for (WeightedTcProvider provider : providerList) {
+            final Set<IRI> providerGraphs = provider.listGraphs();
+            if (providerGraphs.containsAll(referencedGraphs)) {
+               singleTargetTcProvider = provider;
+               break; //success
+            }
+            for (IRI graphName : referencedGraphs) {
+                if (providerGraphs.contains(graphName)) {
+                    break; //failure
+                }
+            }      
+        }
+        return singleTargetTcProvider;
+    }
+
+    public boolean isTcServicesEnabled() {
+		return isTcServicesEnabled;
+	}
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/TcProvider.java b/dataset/src/main/java/org/apache/clerezza/dataset/TcProvider.java
new file mode 100644
index 0000000..6135790
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/TcProvider.java
@@ -0,0 +1,151 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+
+import java.util.Set;
+
+/**
+ * A TC (Graph) Provider allows access to and optionally 
+ * creation of named {@link ImmutableGraph}s and {@link Graph}s (mutable graphs)
+ *
+ * @author reto
+ */
+public interface TcProvider {
+
+    /**
+     * Get a <code>ImmutableGraph</code> by its name
+     *
+     * @param name the name of the ImmutableGraph
+     * @return the <code>ImmutableGraph</code> with the specified name
+     * @throws NoSuchEntityException if there is no <code>ImmutableGraph</code>
+     *         with the specified name
+     */
+    ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException;
+
+    /**
+     * Get an <code>Graph</code> taht is not <code>ImmutableGrah</code>. The instances
+     * returned in different invocations are <code>equals</code>.
+     *
+     * @param the name of the <code>Graph</code>
+     * @return name the <code>Graph</code> with the specified name
+     * @throws NoSuchEntityException if there is no <code>Graph</code>
+     *         with the specified name
+     */
+    Graph getMGraph(IRI name) throws NoSuchEntityException;
+
+    /**
+     * This method is used to get a <code>Graph</code> indifferently
+     * whether it's a ImmutableGraph or not. If the <code>name</code> names an
+     * <code>Graph</code> the result is the same as when invoking
+     * <code>getMGraph</code> with that argument, analogously for
+     * <code>ImmutableGraph</code>S the method returns an instance equals to what
+     * <code>getImmutableGraph</code> would return.
+     *
+     * @param name the name of the <Code>ImmutableGraph</code> or <code>Graph</code>
+     * @return the <Code>ImmutableGraph</code> or <code>Graph</code>
+     * @throws NoSuchEntityException if there is no <code>ImmutableGraph</code>
+     *         or <code>Graph</code> with the specified name
+     */
+    Graph getGraph(IRI name) throws NoSuchEntityException;
+
+    /**
+     * Lists the name of the <Code>ImmutableGraph</code>s available through this
+     * <code>TcProvider</code>, implementations may take into account the
+     * security context and omit <Code>ImmutableGraph</code>s for which access is not
+     * allowed.
+     *
+     * @return the list of <Code>ImmutableGraph</code>s
+     */
+    Set<IRI> listImmutableGraphs();
+
+    /**
+     * Lists the name of the <Code>Graph</code>s available through this
+     * <code>TcProvider</code> that are not <Code>ImmutableGraph</code>, implementations may take into account the
+     * security context and omit <Code>Graph</code>s for which access is not
+     * allowed.
+     *
+     * @return the list of <Code>Graph</code>s
+     */
+    Set<IRI> listMGraphs();
+
+    /**
+     * Lists the name of the <Code>Graph</code>s available through this
+     * <code>TcProvider</code> indifferently whether they are mutables or
+     * immutables, implementations may take into account the security context and
+     * omit <Code>Graph</code>s for which access is not allowed.
+     *
+     * @return the list of <Code>Graph</code>s
+     */
+    Set<IRI> listGraphs();
+
+    /**
+     * Creates an initially empty <code>Graph</code> with a specified name
+     *
+     * @param name names the new <code>Graph</code>
+     * @return the newly created <code>Graph</code>
+     * @throws UnsupportedOperationException if this provider doesn't support
+     *         creating <code>Graph</code>S
+     * @throws EntityAlreadyExistsException if an Graph with the specified name
+     *         already exists
+     */
+    Graph createGraph(IRI name) throws UnsupportedOperationException,
+            EntityAlreadyExistsException;
+
+    /**
+     * Creates a <code>ImmutableGraph</code> with a specified name
+     *
+     * @param name the name of the <code>ImmutableGraph</code> to be created
+     * @param triples the triples of the new <code>ImmutableGraph</code>
+     * @return the newly created <code>ImmutableGraph</code>
+     * @throws UnsupportedOperationException if this provider doesn't support
+     *         creating <code>ImmutableGraph</code>S
+     * @throws EntityAlreadyExistsException if a ImmutableGraph with the specified name
+     *         already exists
+     */
+    ImmutableGraph createImmutableGraph(IRI name, Graph triples)
+            throws UnsupportedOperationException, EntityAlreadyExistsException;
+
+    /**
+     * Deletes the <code>ImmutableGraph</code> or <code>Graph</code> of a specified name.
+     * If <code>name</code> references a ImmutableGraph and the ImmutableGraph has other names, it
+     * will still be available with those other names.
+     *
+     * @param name the entity to be removed
+     * @throws UnsupportedOperationException if this provider doesn't support
+     *         entities deletion.
+     * @throws NoSuchEntityException if <code>name</code> doesn't refer to a
+     *           <code>ImmutableGraph</code> or an <code>Graph</code>.
+     * @throws EntityUndeletableException if the specified ImmutableGraph is undeletable
+     */
+    void deleteGraph(IRI name) throws UnsupportedOperationException,
+            NoSuchEntityException, EntityUndeletableException;
+
+    /**
+     * get a set of the names of a <code>ImmutableGraph</code>
+     *
+     * @param ImmutableGraph
+     * @return the set names of <code>ImmutableGraph</code>, the set is empty if
+     *         <code>ImmutableGraph</code> is unknown
+     */
+    Set<IRI> getNames(ImmutableGraph immutableGraph);
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/TcProviderMultiplexer.java b/dataset/src/main/java/org/apache/clerezza/dataset/TcProviderMultiplexer.java
new file mode 100644
index 0000000..ceaddc3
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/TcProviderMultiplexer.java
@@ -0,0 +1,446 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+
+import java.lang.ref.WeakReference;
+import java.util.*;
+
+/**
+ * This makes a set of WeightedTcProvider appear as one TcProvider. It delegates
+ * requests to the WeightedTcProvider with the highest Weight
+ *
+ * @author reto
+ */
+public class TcProviderMultiplexer implements TcProvider {
+
+    protected SortedSet<WeightedTcProvider> providerList = new TreeSet<>(
+            new WeightedProviderComparator());
+    /**
+     * Mapping to Graph's and ServiceRegistration using their URI's as key.
+     * Makes sure that per URI only one instance of the Graph is used,
+     * otherwise the locks in the <code>Graph</code>s would have no effect
+     * between different instances and concurrency issues could occur.
+     */
+    private Map<IRI, MGraphHolder> mGraphCache = Collections.synchronizedMap(new HashMap<IRI, MGraphHolder>());
+
+	/**
+	 * Flag to indicate whether mgraphs should be cached for faster access. By
+	 * default caching is enabled for backward compatibility.
+	 */
+	private boolean isCachingEnabled = true;
+
+    /**
+     * Registers a provider
+     *
+     * @param provider
+     *            the provider to be registered
+     */
+    public void addWeightedTcProvider(WeightedTcProvider provider) {
+        providerList.add(provider);
+        updateGraphCache(provider, true);
+    }
+
+    /**
+     * Unregister a provider
+     *
+     * @param provider
+     *            the provider to be deregistered
+     */
+    public void removeWeightedTcProvider(
+            WeightedTcProvider provider) {
+        providerList.remove(provider);
+        updateGraphCache(provider, false);
+    }
+
+    /**
+     * subclasses overwrite this method to be notified when a new
+     * ImmutableGraph is available (either because it has been created or being
+     * provided by a newly added WeightedTcProvider). The default implementation
+     * does nothing.
+     *
+     * @param name
+     */
+    protected void graphAppears(IRI name) {
+    }
+
+    /**
+     * subclasses overwrite this method to be notified when a new
+     * Graph is available (either because it has been created or being
+     * provided by a newly added WeightedTcProvider). The default implementation
+     * does nothing.
+     *
+     * @param name
+     */
+    protected void mGraphAppears(IRI name) {
+    }
+
+    /**
+     * subclasses overwrite this method to be notified whenGraph is
+     * no longer available (either because it has been deleted or bacause its
+     * WeightedTcProvider was removed). The default implementation does nothing.
+     *
+     * for implementational reasons even for name of Graph not
+     * previously registered.
+     *
+     * @param name
+     */
+    protected void tcDisappears(IRI name) {
+    }
+
+    /**
+     * Updates the lockableMGraphCache AFTER a new <code>provider</code> was
+     * bound or unbound.
+     * This method also takes care of registering and unregistering
+     * provided triple collections as services based on the weight of
+     * all affected providers.
+     *
+     * @param provider
+     *            the provider that was added or removed
+     * @param providerAdded
+     *            <code>boolean</code> that should be set as <code>true</code>
+     *            if <code>provider</code> was added to
+     *            <code>org.apache.clerezza.rdf.core.TcManager.providerList</code>
+     *            otherwise <code>false</code>
+     */
+    private void updateGraphCache(WeightedTcProvider provider,
+            boolean providerAdded) {
+        Set<IRI> uriSet = provider.listGraphs();
+        if (!(uriSet == null || uriSet.isEmpty())) {
+            if (providerAdded) {
+                weightedProviderAdded(provider, uriSet);
+            } else {
+                weightedProviderRemoved(provider, uriSet);
+            }
+        }
+    }
+
+    private void weightedProviderAdded(WeightedTcProvider newProvider,
+            Set<IRI> newProvidedUris) {
+        Set<WeightedTcProvider> lowerWeightedProviderList = getLowerWeightedProvider(newProvider);
+    	if (isCachingEnabled()) {
+	        for (IRI name : newProvidedUris) {
+	            final MGraphHolder holder = mGraphCache.get(name);
+	            if ((holder != null) && (holder.getWeightedTcProvider() != null)) {
+	                if (lowerWeightedProviderList.contains(holder.getWeightedTcProvider())) {
+	                    tcDisappears(name);
+	                    mGraphCache.remove(name);
+	                } else {
+	                    continue;
+	                }
+	            }
+	            Graph triples = newProvider.getGraph(name);
+	            if (triples instanceof Graph) {
+	           		mGraphCache.put(name, new MGraphHolder(newProvider, ensureLockable((Graph)triples)));
+	                mGraphAppears(name);
+	            } else {
+	                graphAppears(name);
+	            }
+	    	}
+        }
+    }
+
+
+
+    private Set<WeightedTcProvider> getLowerWeightedProvider(
+            WeightedTcProvider newProvider) {
+        boolean referenceProviderPassed = false;
+        Set<WeightedTcProvider> lowerWeightedProviderList = new HashSet<WeightedTcProvider>();
+        for (WeightedTcProvider weightedProvider : providerList) {
+            if (referenceProviderPassed) {
+                lowerWeightedProviderList.add(weightedProvider);
+            } else if (newProvider.equals(weightedProvider)) {
+                referenceProviderPassed = true;
+            }
+        }
+        return lowerWeightedProviderList;
+    }
+
+    private void weightedProviderRemoved(WeightedTcProvider oldProvider,
+            Set<IRI> oldProvidedUris) {
+        for (IRI name : oldProvidedUris) {
+            final MGraphHolder holder = mGraphCache.get(name);
+            if ((holder != null) && (holder.getWeightedTcProvider() != null)
+                    && holder.getWeightedTcProvider().equals(oldProvider)) {
+                tcDisappears(name);
+                mGraphCache.remove(name);
+
+            	if (isCachingEnabled()) {
+	                // check if another WeightedTcProvider has the Graph.
+	                // And if so register as service.
+	                for (WeightedTcProvider provider : providerList) {
+	                    try {
+	                        Graph triples = provider.getGraph(name);
+	                        if (triples instanceof Graph) {
+	                       		mGraphCache.put(name, new MGraphHolder(provider, ensureLockable((Graph)triples)));
+	                            mGraphAppears(name);
+	                        } else {
+	                            graphAppears(name);
+	                        }
+	                        break;
+	                    } catch (NoSuchEntityException e) {
+	                        // continue;
+	                    }
+	                }
+            	}
+            }
+        }
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        for (TcProvider provider : providerList) {
+            try {
+                return provider.getImmutableGraph(name);
+            } catch (NoSuchEntityException e) {
+                //we do nothing and try our luck with the next provider
+            } catch (IllegalArgumentException e) {
+                //we do nothing and try our luck with the next provider
+            }
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name)
+            throws NoSuchEntityException {
+        Graph result = getMGraphFromCache(name);
+        if (result == null) {
+            synchronized (this) {
+                result = getMGraphFromCache(name);
+                if (result == null) {
+                    result = getUnsecuredMGraphAndAddToCache(name);
+                }
+            }
+        }
+        return result;
+    }
+
+    private Graph getMGraphFromCache(IRI name) {
+        MGraphHolder holder = mGraphCache.get(name);
+        if (holder == null) {
+            return null;
+        }
+        return holder.getMGraph();
+    }
+
+    private Graph getUnsecuredMGraphAndAddToCache(IRI name)
+            throws NoSuchEntityException {
+        for (WeightedTcProvider provider : providerList) {
+            try {
+                Graph providedMGraph = provider.getMGraph(name);
+                Graph result = ensureLockable(providedMGraph);
+
+                if (isCachingEnabled()) {
+	                mGraphCache.put(name, new MGraphHolder(
+	                        provider, result));
+                }
+                return result;
+            } catch (NoSuchEntityException e) {
+                //we do nothing and try our luck with the next provider
+            } catch (IllegalArgumentException e) {
+                //we do nothing and try our luck with the next provider
+            }
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getGraph(IRI name)
+            throws NoSuchEntityException {
+        Graph result;
+        for (WeightedTcProvider provider : providerList) {
+            try {
+                result = provider.getGraph(name);
+                if (result instanceof ImmutableGraph) {
+                    return result;
+                } else {
+                    // This is to ensure the Graph gets added to the cache
+                    return getMGraph(name);
+                }
+            } catch (NoSuchEntityException e) {
+                //we do nothing and try our luck with the next provider
+            } catch (IllegalArgumentException e) {
+                //we do nothing and try our luck with the next provider
+            }
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name)
+            throws UnsupportedOperationException {
+
+        for (WeightedTcProvider provider : providerList) {
+            try {
+                Graph result = provider.createGraph(name);
+                // unregisters a possible ImmutableGraph or Graph service under this name
+                // provided by a WeightedTcProvider with a lower weight.
+                tcDisappears(name);
+                if (isCachingEnabled()) {
+                	mGraphCache.put(name, new MGraphHolder(provider, null));
+                }
+                mGraphAppears(name);
+                return result;
+            } catch (UnsupportedOperationException e) {
+                //we do nothing and try our luck with the next provider
+            } catch (IllegalArgumentException e) {
+                //we do nothing and try our luck with the next provider
+            }
+        }
+        throw new UnsupportedOperationException(
+                "No provider could create Graph.");
+    }
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples) {
+        for (WeightedTcProvider provider : providerList) {
+            try {
+                ImmutableGraph result = provider.createImmutableGraph(name, triples);
+
+                // unregisters a possible ImmutableGraph or Graph service under this name
+                // provided by a WeightedTcProvider with a lower weight.
+                tcDisappears(name);
+                if (isCachingEnabled()) {
+                	mGraphCache.put(name, new MGraphHolder(provider, null));
+                }
+                graphAppears(name);
+                return result;
+            } catch (UnsupportedOperationException e) {
+                //we do nothing and try our luck with the next provider
+            } catch (IllegalArgumentException e) {
+                //we do nothing and try our luck with the next provider
+            }
+        }
+        throw new UnsupportedOperationException(
+                "No provider could create ImmutableGraph.");
+    }
+
+    @Override
+    public void deleteGraph(IRI name) {
+        for (TcProvider provider : providerList) {
+            try {
+                provider.deleteGraph(name);
+                final MGraphHolder holder = mGraphCache.get(name);
+                if ((holder != null)
+                        && (holder.getWeightedTcProvider() != null)
+                        && holder.getWeightedTcProvider().equals(provider)) {
+                    tcDisappears(name);
+                    mGraphCache.remove(name);
+                }
+                return;
+            } catch (UnsupportedOperationException e) {
+                // we do nothing and try our luck with the next provider
+            } catch (NoSuchEntityException e) {
+                //we do nothing and try our luck with the next provider
+            } catch (IllegalArgumentException e) {
+                //we do nothing and try our luck with the next provider
+            }
+        }
+        // this throws a NoSuchEntityException if the ImmutableGraph doesn't exist
+        getGraph(name);
+        // the entity exists but cannot be deleted
+        throw new UnsupportedOperationException(
+                "No provider could delete the entity.");
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        Set<IRI> result = new HashSet<IRI>();
+        for (TcProvider provider : providerList) {
+            result.addAll(provider.getNames(ImmutableGraph));
+        }
+        return result;
+    }
+
+    @Override
+    public Set<IRI> listGraphs() {
+        Set<IRI> result = new HashSet<IRI>();
+        for (TcProvider provider : providerList) {
+            result.addAll(provider.listGraphs());
+        }
+        return result;
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        Set<IRI> result = new HashSet<IRI>();
+        for (TcProvider provider : providerList) {
+            result.addAll(provider.listMGraphs());
+        }
+        return result;
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        Set<IRI> result = new HashSet<IRI>();
+        for (TcProvider provider : providerList) {
+            result.addAll(provider.listImmutableGraphs());
+        }
+        return result;
+    }
+
+    private Graph ensureLockable(Graph providedMGraph) {
+        //Graphs are alway locable now
+        return providedMGraph;
+    }
+
+    /**
+     * Contains an unsecured Graph, a ServiceRegistration and
+     * the WeightedTcProvider that generated the ImmutableGraph
+     */
+    private static class MGraphHolder {
+
+        private WeightedTcProvider tcProvider;
+        private WeakReference<Graph> mGraphReference;
+
+        MGraphHolder(WeightedTcProvider tcProvider, Graph graph) {
+            this.tcProvider = tcProvider;
+            this.mGraphReference = new WeakReference<Graph>(graph);
+        }
+
+        Graph getMGraph() {
+            return this.mGraphReference.get();
+        }
+
+        WeightedTcProvider getWeightedTcProvider() {
+            return this.tcProvider;
+        }
+    }
+
+    //methods for debuging / monitoring
+    public SortedSet<WeightedTcProvider> getProviderList() {
+        return providerList;
+    }
+
+    public boolean isCachingEnabled() {
+		return isCachingEnabled;
+	}
+    
+    public void setCachingEnabled(boolean isCachingEnabled) {
+		this.isCachingEnabled = isCachingEnabled;
+		
+		if (!isCachingEnabled()) {
+			mGraphCache.clear();
+		}
+	}
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/WeightedProviderComparator.java b/dataset/src/main/java/org/apache/clerezza/dataset/WeightedProviderComparator.java
new file mode 100644
index 0000000..66752f3
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/WeightedProviderComparator.java
@@ -0,0 +1,41 @@
+package org.apache.clerezza.dataset;
+/*
+ *
+ * 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.
+ *
+*/
+
+
+import java.util.Comparator;
+
+/**
+ * Compares the WeightedTcManagementProviders, descending for weight and
+ * ascending by name
+ */
+public class WeightedProviderComparator implements Comparator<WeightedTcProvider> {
+
+    @Override
+    public int compare(WeightedTcProvider o1, WeightedTcProvider o2) {
+        int o1Weight = o1.getWeight();
+        int o2Weight = o2.getWeight();
+        if (o1Weight != o2Weight) {
+            return o2Weight - o1Weight;
+        }
+        return o1.getClass().toString().compareTo(o2.getClass().toString());
+    }
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/WeightedTcProvider.java b/dataset/src/main/java/org/apache/clerezza/dataset/WeightedTcProvider.java
new file mode 100644
index 0000000..e50514d
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/WeightedTcProvider.java
@@ -0,0 +1,36 @@
+/*
+ * 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.clerezza.dataset;
+
+/**
+ * This interface is implemented by providers to which {@link TcManagerImpl}
+ * delegates.
+ *
+ * @author reto
+ */
+public interface WeightedTcProvider extends TcProvider {
+
+    /**
+     * Get the weight of this provider. {@link TcManager} will prioritize
+     * <code>TcProvider</code>s with greater weight.
+     * 
+     * @return a positive number indicating the weight of the provider
+     */
+    int getWeight();
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/package.html b/dataset/src/main/java/org/apache/clerezza/dataset/package.html
new file mode 100644
index 0000000..8d136ed
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/package.html
@@ -0,0 +1,56 @@
+
+	<!--
+/*
+ * 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.
+ */
+-->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+	<head>
+		<title>org.apache.clerezza.dataset</title>
+		<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	</head>
+	<body>
+		<p>This package provides access to named {@link
+			org.apache.clerezza.api.ImmutableGraph}S and {@link
+			org.apache.clerezza.api.Graph}S that may originate from various
+			implementations.</p>
+		<h3>Accessing</h3>
+		<p>
+			If running in a dependency injection system you should get an instance
+			of
+			<code>TcManager</code>
+			by the framework, otherwise use the static method
+			<code>TcManager.getInstance</code>
+			.
+		</p>
+		<h3>Adding a provider</h3>
+		<p>A provider implements {@link WeightedTcProvider}.</p>
+		<p>
+			To work outside a component injection framework it contains a file
+			<code>META-INF/services/org.apache.clerezza.dataset.WeightedTcProvider</code>
+			containing the name of the implementing class.
+		</p>
+		<p>
+			To work in a OSGi-DS context the provider register a component
+			exposing
+			<code>org.apache.clerezza.dataset.WeightedTcProvider</code>
+			as service interface.
+		</p>
+	</body>
+</html>
\ No newline at end of file
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/security/TcAccessController.java b/dataset/src/main/java/org/apache/clerezza/dataset/security/TcAccessController.java
new file mode 100644
index 0000000..93b54ff
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/security/TcAccessController.java
@@ -0,0 +1,342 @@
+/*
+ * 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.clerezza.dataset.security;
+
+import org.apache.clerezza.api.*;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.api.impl.literal.LiteralFactory;
+import org.apache.clerezza.dataset.NoSuchEntityException;
+import org.apache.clerezza.dataset.TcManager;
+import org.apache.clerezza.utils.security.PermissionParser;
+
+import java.security.AccessControlException;
+import java.security.AccessController;
+import java.security.AllPermission;
+import java.security.Permission;
+import java.util.*;
+import java.util.concurrent.locks.Lock;
+
+/**
+ * Controls the permissions needed to access a triple collection provided by
+ * <code>TcManager</code>.
+ *
+ * Clients with a ConfigureTcAcessPermission can set the permissions required to
+ * access a Graph. These permissions are stored persistently in an
+ * Graph named urn:x-localinstance:/graph-access.graph
+ *
+ * Clients should get an instance from TcManager.getTcAccessController()
+ * 
+ * @author reto
+ */
+public abstract class TcAccessController {
+
+    private final TcManager tcManager;
+    private final IRI permissionGraphName = new IRI("urn:x-localinstance:/graph-access.graph");
+    //we can't rely on ontology plugin in rdf core
+    private String ontologyNamespace = "http://clerezza.apache.org/2010/07/10/graphpermssions#";
+    private final IRI readPermissionListProperty = new IRI(ontologyNamespace + "readPermissionList");
+    private final IRI readWritePermissionListProperty = new IRI(ontologyNamespace + "readWritePermissionList");
+    /**
+     * The first item in the subject RDF list.
+     */
+    public static final IRI first = new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#first");
+    /**
+     * The rest of the subject RDF list after the first item.
+     */
+    public static final IRI rest = new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#rest");
+    public static final IRI rdfNil = new IRI("http://www.w3.org/1999/02/22-rdf-syntax-ns#nil");
+    private final Map<IRI, Collection<Permission>> readPermissionCache =
+            Collections.synchronizedMap(new HashMap<IRI, Collection<Permission>>());
+    private final Map<IRI, Collection<Permission>> readWritePermissionCache =
+            Collections.synchronizedMap(new HashMap<IRI, Collection<Permission>>());
+
+    /**
+     *
+     * @param tcManager the tcManager used to locate urn:x-localinstance:/graph-access.graph
+     */
+    public TcAccessController() {
+        this.tcManager = getTcManager();
+    }
+
+    public void checkReadPermission(IRI GraphUri) {
+        if (GraphUri.equals(permissionGraphName)) {
+            //This is world readable, as this prevents as from doingf things as
+            //priviledged during verfification
+            return;
+        }
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            //will AllPermissions the rest is obsolete
+            try {
+                AccessController.checkPermission(new AllPermission());
+            } catch (AccessControlException e) {
+                Collection<Permission> perms = getRequiredReadPermissions(GraphUri);
+                if (perms.size() > 0) {
+                    for (Permission permission : perms) {
+                        AccessController.checkPermission(permission);
+                    }
+                } else {
+                    AccessController.checkPermission(new TcPermission(
+                            GraphUri.getUnicodeString(), TcPermission.READ));
+                }
+            }
+        }
+    }
+
+    public void checkReadWritePermission(IRI GraphUri) {
+        SecurityManager security = System.getSecurityManager();
+        if (security != null) {
+            //will AllPermissions the rest is obsolete
+            try {
+                AccessController.checkPermission(new AllPermission());
+            } catch (AccessControlException e) {
+                if (GraphUri.equals(permissionGraphName)) {
+                    AccessController.checkPermission(new TcPermission(
+                            GraphUri.getUnicodeString(), TcPermission.READWRITE));
+                } else {
+                    Collection<Permission> perms = getRequiredReadWritePermissions(GraphUri);
+                    if (perms.size() > 0) {
+                        for (Permission permission : perms) {
+                            AccessController.checkPermission(permission);
+                        }
+                    } else {
+                        AccessController.checkPermission(new TcPermission(
+                                GraphUri.getUnicodeString(), TcPermission.READWRITE));
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Set the set of permissions required for read access to a triple-collection, if
+     * the set is non-empty the default TCPermisson is no longer required.
+     *
+     * @param GraphUri
+     * @param permissionDescriptions
+     */
+    public void setRequiredReadPermissionStrings(IRI GraphUri,
+            Collection<String> permissionDescriptions) {
+        readPermissionCache.remove(GraphUri);
+        final Graph permissionMGraph = getOrCreatePermisionGraph();
+        Lock l = permissionMGraph.getLock().writeLock();
+        l.lock();
+        try {
+            removeExistingRequiredReadPermissions(GraphUri, permissionMGraph);
+            final BlankNodeOrIRI permissionList = createList(permissionDescriptions.iterator(), permissionMGraph);
+            permissionMGraph.add(new TripleImpl(GraphUri,
+                    readPermissionListProperty, permissionList));
+        } finally {
+            l.unlock();
+        }
+    }
+
+    /**
+     * Set the set of permissions required for read access to a triple-collection, if
+     * the set is non-empty the default TCPermisson is no longer required.
+     *
+     * @param GraphUri
+     * @param permissionDescriptions
+     */
+    public void setRequiredReadPermissions(IRI GraphUri,
+            Collection<Permission> permissions) {
+        Collection<String> permissionStrings = new ArrayList<String>();
+        for (Permission permission : permissions) {
+            permissionStrings.add(permission.toString());
+        }
+        setRequiredReadPermissionStrings(GraphUri, permissionStrings);
+    }
+
+    /**
+     * Set the set of permissions required for read-write access to a
+     * triple-collection, if
+     * the set is non-empty the default TCPermisson is no longer required.
+     *
+     * @param GraphUri
+     * @param permissionDescriptions
+     */
+    public void setRequiredReadWritePermissionStrings(IRI GraphUri,
+            Collection<String> permissionDescriptions) {
+        readWritePermissionCache.remove(GraphUri);
+        final Graph permissionMGraph = getOrCreatePermisionGraph();
+        Lock l = permissionMGraph.getLock().writeLock();
+        l.lock();
+        try {
+            removeExistingRequiredReadPermissions(GraphUri, permissionMGraph);
+            final BlankNodeOrIRI permissionList = createList(permissionDescriptions.iterator(), permissionMGraph);
+            permissionMGraph.add(new TripleImpl(GraphUri,
+                    readWritePermissionListProperty, permissionList));
+        } finally {
+            l.unlock();
+        }
+    }
+
+    /**
+     * Set the set of permissions required for read-write access to a
+     * triple-collection, if
+     * the set is non-empty the default TCPermisson is no longer required.
+     *
+     * @param GraphUri
+     * @param permissionDescriptions
+     */
+    public void setRequiredReadWritePermissions(IRI GraphUri,
+            Collection<Permission> permissions) {
+        Collection<String> permissionStrings = new ArrayList<String>();
+        for (Permission permission : permissions) {
+            permissionStrings.add(permission.toString());
+        }
+        setRequiredReadWritePermissionStrings(GraphUri, permissionStrings);
+    }
+
+    /**
+     * Get the set of permissions required for read access to the
+     * triple-collection, the set may be empty meaning that the default
+     * TCPermission is required.
+     *
+     * @param GraphUri
+     * @return the collection of permissions
+     */
+    public Collection<Permission> getRequiredReadPermissions(IRI GraphUri) {
+        Collection<Permission> result = readPermissionCache.get(GraphUri);
+        if (result == null) {
+            result = new ArrayList<Permission>();
+            Collection<String> permissionStrings = getRequiredReadPermissionStrings(GraphUri);
+            for (String string : permissionStrings) {
+                result.add(PermissionParser.getPermission(string, getClass().getClassLoader()));
+            }
+            readPermissionCache.put(GraphUri, result);
+        }
+        return result;
+    }
+
+    /**
+     * Get the set of permissions required for read-write access to the
+     * triple-collection, the set may be empty meaning that the default
+     * TCPermission is required.
+     *
+     * @param GraphUri
+     * @return the collection of permissions
+     */
+    public Collection<Permission> getRequiredReadWritePermissions(IRI GraphUri) {
+        Collection<Permission> result = readWritePermissionCache.get(GraphUri);
+        if (result == null) {
+            result = new ArrayList<Permission>();
+            Collection<String> permissionStrings = getRequiredReadWritePermissionStrings(GraphUri);
+            for (String string : permissionStrings) {
+                result.add(PermissionParser.getPermission(string, getClass().getClassLoader()));
+            }
+            readWritePermissionCache.put(GraphUri, result);
+        }
+        return result;
+    }
+
+    private BlankNodeOrIRI createList(Iterator<String> iterator, Graph permissionMGraph) {
+        if (!iterator.hasNext()) {
+            return rdfNil;
+        }
+        final BlankNode result = new BlankNode();
+        permissionMGraph.add(new TripleImpl(result, first,
+                LiteralFactory.getInstance().createTypedLiteral(iterator.next())));
+        permissionMGraph.add(new TripleImpl(result, rest,
+                createList(iterator, permissionMGraph)));
+        return result;
+
+    }
+
+    //called withiong write-lock
+    private void removeExistingRequiredReadPermissions(IRI GraphUri,
+            Graph permissionMGraph) {
+        try {
+            Triple t = permissionMGraph.filter(GraphUri, readPermissionListProperty, null).next();
+            RDFTerm list = t.getObject();
+            removeList((BlankNodeOrIRI) list, permissionMGraph);
+            permissionMGraph.remove(t);
+        } catch (NoSuchElementException e) {
+            //There was no existing to remove
+        }
+    }
+
+    private void removeList(BlankNodeOrIRI list, Graph permissionMGraph) {
+        try {
+            Triple t = permissionMGraph.filter(list, rest, null).next();
+            RDFTerm restList = t.getObject();
+            removeList((BlankNodeOrIRI) restList, permissionMGraph);
+            permissionMGraph.remove(t);
+            Iterator<Triple> iter = permissionMGraph.filter(list, first, null);
+            iter.next();
+            iter.remove();
+        } catch (NoSuchElementException e) {
+            //if it has no rest its rdf:NIL and has no first
+        }
+    }
+
+    private Collection<String> getRequiredReadWritePermissionStrings(final IRI GraphUri) {
+        return getRequiredPermissionStrings(GraphUri, readWritePermissionListProperty);
+    }
+    private Collection<String> getRequiredReadPermissionStrings(final IRI GraphUri) {
+        return getRequiredPermissionStrings(GraphUri, readPermissionListProperty);
+    }
+    private Collection<String> getRequiredPermissionStrings(final IRI GraphUri, IRI property) {
+        try {
+            final Graph permissionMGraph = tcManager.getMGraph(permissionGraphName);
+            Lock l = permissionMGraph.getLock().readLock();
+            l.lock();
+            try {
+                Triple t = permissionMGraph.filter(GraphUri, property, null).next();
+                BlankNodeOrIRI list = (BlankNodeOrIRI) t.getObject();
+                LinkedList<String> result = new LinkedList<String>();
+                readList(list, permissionMGraph, result);
+                return result;
+            } catch (NoSuchElementException e) {
+                return new ArrayList<String>(0);
+            } finally {
+                l.unlock();
+            }
+        } catch (NoSuchEntityException e) {
+            return new ArrayList<String>(0);
+        }
+    }
+
+    private void readList(BlankNodeOrIRI list, Graph permissionMGraph, LinkedList<String> target) {
+        if (list.equals(rdfNil)) {
+            return;
+        }
+        Triple restTriple = permissionMGraph.filter(list, rest, null).next();
+        BlankNodeOrIRI restList = (BlankNodeOrIRI) restTriple.getObject();
+        readList(restList, permissionMGraph, target);
+        Triple firstTriple = permissionMGraph.filter(list, first, null).next();
+        Literal firstValue = (Literal) firstTriple.getObject();
+        String value = LiteralFactory.getInstance().createObject(String.class, firstValue);
+        target.addFirst(value);
+    }
+
+    private Graph getOrCreatePermisionGraph() {
+        try {
+            return tcManager.getMGraph(permissionGraphName);
+        } catch (NoSuchEntityException e) {
+            return tcManager.createGraph(permissionGraphName);
+        }
+    }
+
+    /**
+     * Note that this will only be invoked once
+     * @return 
+     */
+    protected abstract TcManager getTcManager();
+}
diff --git a/dataset/src/main/java/org/apache/clerezza/dataset/security/TcPermission.java b/dataset/src/main/java/org/apache/clerezza/dataset/security/TcPermission.java
new file mode 100644
index 0000000..c218dd9
--- /dev/null
+++ b/dataset/src/main/java/org/apache/clerezza/dataset/security/TcPermission.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.clerezza.dataset.security;
+
+import java.security.Permission;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Pattern;
+
+/**
+ * A permission to access <code>Graph<code>s matching a specified 
+ * name pattern. A pattern is matched if and only if the pattern is equals
+ * to name of the <code>Graph<code> or the pattern ends with "/*" and
+ * the name of the <code>Graph<code> starts with the characters
+ * preceding the '*' in the pattern.
+ *
+ * @author reto, tsuy
+ */
+public class TcPermission extends Permission {
+    public final static String READWRITE = "readwrite";
+    public final static String READ = "read";
+
+    private String tcNamePattern;
+    /**
+     * true if readwrite granted false if only read
+     */
+    private boolean allowReadWrite = false;
+
+    final static Pattern actionPattern = Pattern.compile(",( *)");
+    /**
+     * Conststructs a TcPermission for a specified name pattern and a list of
+     * actions.
+     *
+     * @param tcNamePattern see class description
+     * @param actions a comma separated list of the strings "read" and "readwrite",
+     *        the canonical form is just "read" or "readwrite" as "readwrite"
+     *        implies "read".
+     */
+    public TcPermission(String tcNamePattern, String actions)  {
+        super(tcNamePattern);
+        this.tcNamePattern = tcNamePattern;
+        //check and set actions
+        final Set actionSet = new HashSet(Arrays.asList(actionPattern.split(actions)));
+        if (actionSet.remove(READWRITE)) {
+            allowReadWrite = true;
+        } else {
+            if (!actionSet.contains(READ)) {
+                throw new IllegalArgumentException("actions must be either \"read\" or \"readwrite\"");
+            }
+        }
+        actionSet.remove(READ);
+        if (actionSet.size() > 0) {
+            throw new IllegalArgumentException("actions must only contain \"read\" and \"readwrite\"");
+        }
+    }
+
+    @Override
+    public boolean implies(Permission permission) {
+        if (permission instanceof TcPermission) {
+            TcPermission other = (TcPermission) permission;
+            if (!patternImplies(other.tcNamePattern)) {
+                return false;
+            }
+            if (!actionsImplies(other.allowReadWrite)) {
+                return false;
+            }
+            return true;
+            
+            
+        }
+        return false;
+    }
+
+    private boolean actionsImplies(boolean readwriteOther) {
+        if (!readwriteOther) {
+            return true;
+        } else {
+            return allowReadWrite;
+        }
+        
+    }
+
+    private boolean patternImplies(String tcNamePatternOther) {
+        if (tcNamePattern.equals(tcNamePatternOther)) {
+            return true;
+        }
+        if (tcNamePattern.endsWith("/*")) {
+            return tcNamePatternOther.startsWith(
+                    tcNamePattern.substring(0, tcNamePattern.length()-1));
+        }
+        return false;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj == null) {
+            return false;
+        }
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+        final TcPermission other = (TcPermission) obj;
+        if (this.tcNamePattern != other.tcNamePattern 
+                && (this.tcNamePattern == null
+                || !this.tcNamePattern.equals(other.tcNamePattern))) {
+            return false;
+        }
+        if (this.allowReadWrite != other.allowReadWrite) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = 3;
+        hash = 97 * hash + (this.tcNamePattern != null ?
+            this.tcNamePattern.hashCode() : 0);
+        if (allowReadWrite) {
+            hash++;
+        }
+        return hash;
+    }
+
+    
+
+    @Override
+    public String getActions() {
+        return allowReadWrite ? READWRITE : READ;
+    }
+
+}
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/SecurityTest.java b/dataset/src/test/java/org/apache/clerezza/dataset/SecurityTest.java
new file mode 100644
index 0000000..ffea930
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/SecurityTest.java
@@ -0,0 +1,175 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.Triple;
+import org.apache.clerezza.api.impl.graph.ReadOnlyException;
+import org.apache.clerezza.api.impl.literal.PlainLiteralImpl;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.dataset.providers.WeightedA;
+import org.apache.clerezza.dataset.providers.WeightedDummy;
+import org.apache.clerezza.dataset.security.TcPermission;
+import org.junit.*;
+
+import java.io.FilePermission;
+import java.lang.reflect.ReflectPermission;
+import java.security.*;
+import java.util.Collections;
+import java.util.PropertyPermission;
+
+/**
+ *
+ * @author reto
+ */
+public class SecurityTest {
+    
+    public SecurityTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        ////needed to unbind because this is injected with META-INF/services - file
+        TcManager.getInstance().unbindWeightedTcProvider(new WeightedA());
+        TcManager.getInstance().bindWeightedTcProvider(new WeightedDummy());
+        TcManager.getInstance().createGraph(new IRI("http://example.org/ImmutableGraph/alreadyexists"));
+        TcManager.getInstance().createGraph(new IRI("http://example.org/read/ImmutableGraph"));
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+        
+        Policy.setPolicy(new Policy() {
+
+            @Override
+            public PermissionCollection getPermissions(CodeSource codeSource) {
+                PermissionCollection result = new Permissions();
+                result.add(new TcPermission("http://example.org/permitted", "read"));
+                result.add(new TcPermission("http://example.org/ImmutableGraph/alreadyexists", "readwrite"));
+                result.add(new TcPermission("http://example.org/read/ImmutableGraph", "read"));
+                result.add(new TcPermission("http://example.org/area/allowed/*", "readwrite"));
+                result.add(new TcPermission("urn:x-localinstance:/graph-access.graph", "readwrite"));
+                //result.add(new AllPermission());
+                result.add(new RuntimePermission("*"));
+                result.add(new ReflectPermission("suppressAccessChecks"));
+                result.add(new PropertyPermission("*", "read"));
+                //(java.util.PropertyPermission line.separator read)
+                result.add(new FilePermission("/-", "read,write"));
+                return result;
+            }
+        });
+        System.setSecurityManager(new SecurityManager() {
+
+            @Override
+            public void checkPermission(Permission perm) {
+                //System.out.println("Checking "+perm);
+                super.checkPermission(perm);
+            }
+
+            @Override
+            public void checkPermission(Permission perm, Object context) {
+                //System.out.println("Checking "+perm);
+                super.checkPermission(perm, context);
+            }
+
+        });
+    }
+
+    @After
+    public void tearDown() {
+        System.setSecurityManager(null);
+    }
+
+
+    @Test(expected=NoSuchEntityException.class)
+    public void testAcessGraph() {        
+        TcManager.getInstance().getImmutableGraph(new IRI("http://example.org/permitted"));
+    }
+    
+    @Test(expected=AccessControlException.class)
+    public void testNoWildCard() {
+        TcManager.getInstance().getImmutableGraph(new IRI("http://example.org/permitted/subthing"));
+    }
+    
+    @Test(expected=NoSuchEntityException.class)
+    public void testAllowedArea() {
+        TcManager.getInstance().getImmutableGraph(new IRI("http://example.org/area/allowed/something"));
+    }
+    
+    @Test(expected=AccessControlException.class)
+    public void testAcessForbiddenGraph() {
+        TcManager.getInstance().getImmutableGraph(new IRI("http://example.org/forbidden"));
+    }
+
+    @Test(expected=NoSuchEntityException.class)
+    public void testCustomPermissions() {
+        IRI graphUri = new IRI("http://example.org/custom");
+        TcManager.getInstance().getTcAccessController().setRequiredReadPermissionStrings(graphUri,
+                Collections.singletonList("(java.io.FilePermission \"/etc\" \"write\")"));
+        //new FilePermission("/etc", "write").toString()));
+        Graph ag = TcManager.getInstance().getGraph(new IRI("urn:x-localinstance:/graph-access.graph"));
+        System.out.print(ag.toString());
+        TcManager.getInstance().getMGraph(graphUri);
+    }
+
+    @Test(expected=AccessControlException.class)
+    public void testCustomPermissionsIncorrect() {
+        IRI graphUri = new IRI("http://example.org/custom");
+        TcManager.getInstance().getTcAccessController().setRequiredReadPermissionStrings(graphUri,
+                Collections.singletonList("(java.io.FilePermission \"/etc\" \"write\")"));
+        //new FilePermission("/etc", "write").toString()));
+        Graph ag = TcManager.getInstance().getGraph(new IRI("urn:x-localinstance:/graph-access.graph"));
+        System.out.print(ag.toString());
+        TcManager.getInstance().createGraph(graphUri);
+    }
+
+    @Test
+    public void testCustomReadWritePermissions() {
+        IRI graphUri = new IRI("http://example.org/read-write-custom");
+        TcManager.getInstance().getTcAccessController().setRequiredReadWritePermissionStrings(graphUri,
+                Collections.singletonList("(java.io.FilePermission \"/etc\" \"write\")"));
+        //new FilePermission("/etc", "write").toString()));
+        Graph ag = TcManager.getInstance().getGraph(new IRI("urn:x-localinstance:/graph-access.graph"));
+        System.out.print(ag.toString());
+        TcManager.getInstance().createGraph(graphUri);
+    }
+    
+    @Test(expected=EntityAlreadyExistsException.class)
+    public void testCreateMGraph() {
+        TcManager.getInstance().createGraph(new IRI("http://example.org/ImmutableGraph/alreadyexists"));
+    }
+    @Test(expected=AccessControlException.class)
+    public void testCreateMGraphWithoutWritePermission() {
+        TcManager.getInstance().createGraph(new IRI("http://example.org/read/ImmutableGraph"));
+    }
+    @Test(expected=ReadOnlyException.class)
+    public void testAddTripleToMGraph() {
+        Graph graph = TcManager.getInstance().getMGraph(new IRI("http://example.org/read/ImmutableGraph"));
+        Triple triple = new TripleImpl(
+                new IRI("http://example.org/definition/isNonLiteral"),
+                new IRI("http://example.org/definition/isTest"),
+                new PlainLiteralImpl("test"));
+        graph.add(triple);
+    }
+}
\ No newline at end of file
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/TcManagerTest.java b/dataset/src/test/java/org/apache/clerezza/dataset/TcManagerTest.java
new file mode 100644
index 0000000..619e86a
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/TcManagerTest.java
@@ -0,0 +1,299 @@
+/*
+ * 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.clerezza.dataset;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.Triple;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.api.impl.graph.SimpleMGraph;
+import org.apache.clerezza.dataset.providers.WeightedA;
+import org.apache.clerezza.dataset.providers.WeightedA1;
+import org.apache.clerezza.dataset.providers.WeightedAHeavy;
+import org.apache.clerezza.dataset.providers.WeightedBlight;
+import org.apache.clerezza.sparql.NoQueryEngineException;
+import org.apache.clerezza.sparql.QueryEngine;
+import org.apache.clerezza.sparql.query.*;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.lang.reflect.Field;
+import java.util.Iterator;
+
+import static org.junit.Assert.*;
+
+/**
+ * 
+ * @author reto
+ */
+public class TcManagerTest {
+
+	public static IRI uriRefAHeavy = new IRI("http://example.org/aHeavy");
+	public static IRI uriRefB = new IRI("http://example.org/b");;
+	public static final IRI uriRefA = new IRI("http://example.org/a");
+	public static final IRI uriRefA1 = new IRI("http://example.org/a1");
+	private TcManager graphAccess;
+	private QueryEngine queryEngine;
+	private final WeightedA weightedA = new WeightedA();
+	private final WeightedA1 weightedA1 = new WeightedA1();
+	private WeightedTcProvider weightedBlight = new WeightedBlight();
+
+	@Before
+	public void setUp() {
+		graphAccess = TcManager.getInstance();
+		graphAccess.bindWeightedTcProvider(weightedA);
+		graphAccess.bindWeightedTcProvider(weightedA1);
+		graphAccess.bindWeightedTcProvider(weightedBlight);
+
+		queryEngine = Mockito.mock(QueryEngine.class);
+	}
+
+	@After
+	public void tearDown() {
+		graphAccess = TcManager.getInstance();
+		graphAccess.unbindWeightedTcProvider(weightedA);
+		graphAccess.unbindWeightedTcProvider(weightedA1);
+		graphAccess.unbindWeightedTcProvider(weightedBlight);
+
+		queryEngine = null;
+	}
+
+	@Test
+	public void getGraphFromA() {
+		ImmutableGraph graphA = graphAccess.getImmutableGraph(uriRefA);
+		Iterator<Triple> iterator = graphA.iterator();
+		assertEquals(new TripleImpl(uriRefA, uriRefA, uriRefA), iterator.next());
+		assertFalse(iterator.hasNext());
+		Graph triplesA = graphAccess.getGraph(uriRefA);
+		iterator = triplesA.iterator();
+		assertEquals(new TripleImpl(uriRefA, uriRefA, uriRefA), iterator.next());
+		assertFalse(iterator.hasNext());
+	}
+
+	@Test
+	public void getGraphFromB() {
+		ImmutableGraph graphA = graphAccess.getImmutableGraph(uriRefB);
+		Iterator<Triple> iterator = graphA.iterator();
+		assertEquals(new TripleImpl(uriRefB, uriRefB, uriRefB), iterator.next());
+		assertFalse(iterator.hasNext());
+		Graph triplesA = graphAccess.getGraph(uriRefB);
+		iterator = triplesA.iterator();
+		assertEquals(new TripleImpl(uriRefB, uriRefB, uriRefB), iterator.next());
+		assertFalse(iterator.hasNext());
+	}
+
+	@Test
+	public void getGraphFromAAfterUnbinding() {
+		graphAccess.unbindWeightedTcProvider(weightedA);
+		ImmutableGraph graphA = graphAccess.getImmutableGraph(uriRefA);
+		Iterator<Triple> iterator = graphA.iterator();
+		assertEquals(new TripleImpl(uriRefA1, uriRefA1, uriRefA1),
+				iterator.next());
+		assertFalse(iterator.hasNext());
+		Graph triplesA = graphAccess.getGraph(uriRefA);
+		iterator = triplesA.iterator();
+		assertEquals(new TripleImpl(uriRefA1, uriRefA1, uriRefA1),
+				iterator.next());
+		assertFalse(iterator.hasNext());
+	}
+
+	@Test
+	public void getGraphFromAWithHeavy() {
+		final WeightedAHeavy weightedAHeavy = new WeightedAHeavy();
+		graphAccess.bindWeightedTcProvider(weightedAHeavy);
+		ImmutableGraph graphA = graphAccess.getImmutableGraph(uriRefA);
+		Iterator<Triple> iterator = graphA.iterator();
+		assertEquals(new TripleImpl(uriRefAHeavy, uriRefAHeavy, uriRefAHeavy),
+				iterator.next());
+		assertFalse(iterator.hasNext());
+		Graph triplesA = graphAccess.getGraph(uriRefA);
+		iterator = triplesA.iterator();
+		assertEquals(new TripleImpl(uriRefAHeavy, uriRefAHeavy, uriRefAHeavy),
+				iterator.next());
+		assertFalse(iterator.hasNext());
+		graphAccess.unbindWeightedTcProvider(weightedAHeavy);
+	}
+
+	@Test(expected = NoQueryEngineException.class)
+	public void executeSparqlQueryNoEngineWithString() throws Exception {
+		// Prepare
+		injectQueryEngine(null);
+
+		// Execute
+		graphAccess.executeSparqlQuery("", new SimpleMGraph());
+	}
+
+	@Test(expected = NoQueryEngineException.class)
+	public void executeSparqlQueryNoEngineWithQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(null);
+
+		// Execute
+		graphAccess.executeSparqlQuery((Query) null, new SimpleMGraph());
+	}
+
+	@Test(expected = NoQueryEngineException.class)
+	public void executeSparqlQueryNoEngineWithSelectQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(null);
+
+		// Execute
+		graphAccess.executeSparqlQuery((SelectQuery) null, new SimpleMGraph());
+	}
+
+	@Test(expected = NoQueryEngineException.class)
+	public void executeSparqlQueryNoEngineWithAskQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(null);
+
+		// Execute
+		graphAccess.executeSparqlQuery((AskQuery) null, new SimpleMGraph());
+	}
+
+	@Test(expected = NoQueryEngineException.class)
+	public void executeSparqlQueryNoEngineWithDescribeQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(null);
+
+		// Execute
+		graphAccess
+				.executeSparqlQuery((DescribeQuery) null, new SimpleMGraph());
+	}
+
+	@Test(expected = NoQueryEngineException.class)
+	public void executeSparqlQueryNoEngineWithConstructQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(null);
+
+		// Execute
+		graphAccess.executeSparqlQuery((ConstructQuery) null,
+				new SimpleMGraph());
+	}
+
+	@Test
+	public void executeSparqlQueryWithEngineWithString() throws Exception {
+		// Prepare
+		injectQueryEngine(queryEngine);
+		Graph Graph = new SimpleMGraph();
+
+		// Execute
+		graphAccess.executeSparqlQuery("", Graph);
+
+		// Verify
+		Mockito.verify(queryEngine).execute(graphAccess, Graph, "");
+//		Mockito.verify(queryEngine, Mockito.never()).execute(
+//				(TcManager) Mockito.anyObject(),
+//				(Graph) Mockito.anyObject(),
+//				Mockito.anyString());
+	}
+
+	@Test
+	public void executeSparqlQueryWithEngineWithSelectQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(queryEngine);
+		Graph Graph = new SimpleMGraph();
+		SelectQuery query = Mockito.mock(SelectQuery.class);
+
+		// Execute
+		graphAccess.executeSparqlQuery(query, Graph);
+
+		// Verify
+		Mockito.verify(queryEngine).execute(graphAccess, Graph,
+				query.toString());
+//		Mockito.verify(queryEngine, Mockito.never()).execute(
+//				(TcManager) Mockito.anyObject(),
+//				(Graph) Mockito.anyObject(), Mockito.anyString());
+	}
+
+	@Test
+	public void executeSparqlQueryWithEngineWithAskQuery() throws Exception {
+		// Prepare
+		injectQueryEngine(queryEngine);
+		Graph Graph = new SimpleMGraph();
+		AskQuery query = Mockito.mock(AskQuery.class);
+
+		Mockito.when(
+				queryEngine.execute((TcManager) Mockito.anyObject(),
+						(Graph) Mockito.anyObject(),
+						Mockito.anyString())).thenReturn(Boolean.TRUE);
+
+		// Execute
+		graphAccess.executeSparqlQuery(query, Graph);
+
+		// Verify
+		Mockito.verify(queryEngine).execute(graphAccess, Graph,
+				query.toString());
+//		Mockito.verify(queryEngine, Mockito.never()).execute(
+//				(TcManager) Mockito.anyObject(),
+//				(Graph) Mockito.anyObject(), Mockito.anyString());
+	}
+
+	@Test
+	public void executeSparqlQueryWithEngineWithDescribeQuery()
+			throws Exception {
+		// Prepare
+		injectQueryEngine(queryEngine);
+		Graph Graph = new SimpleMGraph();
+		DescribeQuery query = Mockito.mock(DescribeQuery.class);
+
+		// Execute
+		graphAccess.executeSparqlQuery(query, Graph);
+
+		// Verify
+		Mockito.verify(queryEngine).execute(graphAccess, Graph,
+				query.toString());
+//		Mockito.verify(queryEngine, Mockito.never()).execute(
+//				(TcManager) Mockito.anyObject(),
+//				(Graph) Mockito.anyObject(), Mockito.anyString());
+	}
+
+	@Test
+	public void executeSparqlQueryWithEngineWithConstructQuery()
+			throws Exception {
+		// Prepare
+		injectQueryEngine(queryEngine);
+		Graph Graph = new SimpleMGraph();
+		ConstructQuery query = Mockito.mock(ConstructQuery.class);
+
+		// Execute
+		graphAccess.executeSparqlQuery(query, Graph);
+
+		// Verify
+		Mockito.verify(queryEngine).execute(graphAccess, Graph,
+				query.toString());
+//		Mockito.verify(queryEngine, Mockito.never()).execute(
+//				(TcManager) Mockito.anyObject(),
+//				(Graph) Mockito.anyObject(), Mockito.anyString());
+	}
+
+	// ------------------------------------------------------------------------
+	// Implementing QueryableTcProvider
+	// ------------------------------------------------------------------------
+
+	private void injectQueryEngine(QueryEngine engine)
+			throws NoSuchFieldException, IllegalAccessException {
+		Field queryEngineField = TcManager.class
+				.getDeclaredField("queryEngine");
+		queryEngineField.setAccessible(true);
+		queryEngineField.set(graphAccess, engine);
+	}
+}
\ No newline at end of file
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedA.java b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedA.java
new file mode 100644
index 0000000..76b6f36
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedA.java
@@ -0,0 +1,103 @@
+/*
+ * 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.clerezza.dataset.providers;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.api.impl.graph.SimpleMGraph;
+import org.apache.clerezza.dataset.EntityUndeletableException;
+import org.apache.clerezza.dataset.NoSuchEntityException;
+import org.apache.clerezza.dataset.TcManagerTest;
+import org.apache.clerezza.dataset.WeightedTcProvider;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author reto
+ */
+public class WeightedA implements WeightedTcProvider {
+    private Set<IRI> mGraphList = new HashSet<IRI>();
+    @Override
+    public int getWeight() {
+        return 5;
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        if (name.equals(TcManagerTest.uriRefA)) {
+            Graph mResult = new SimpleMGraph();
+            mResult.add(new TripleImpl(TcManagerTest.uriRefA, 
+                    TcManagerTest.uriRefA, TcManagerTest.uriRefA));
+            mGraphList.add(name);
+            return mResult.getImmutableGraph();
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name) throws NoSuchEntityException {
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getGraph(IRI name) throws NoSuchEntityException {
+        return getImmutableGraph(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void deleteGraph(IRI name) throws NoSuchEntityException, 
+            EntityUndeletableException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> listGraphs() {
+        return Collections.singleton(TcManagerTest.uriRefA);
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        return mGraphList;
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        return listGraphs();
+    }
+}
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedA1.java b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedA1.java
new file mode 100644
index 0000000..effd599
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedA1.java
@@ -0,0 +1,103 @@
+/*
+ * 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.clerezza.dataset.providers;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.api.impl.graph.SimpleMGraph;
+import org.apache.clerezza.dataset.EntityUndeletableException;
+import org.apache.clerezza.dataset.NoSuchEntityException;
+import org.apache.clerezza.dataset.TcManagerTest;
+import org.apache.clerezza.dataset.WeightedTcProvider;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Same weight as WeightedA, but later in string-ordering
+ *
+ * @author reto
+ */
+public class WeightedA1 implements WeightedTcProvider {
+    private Set<IRI> mGraphList = new HashSet<IRI>();
+    @Override
+    public int getWeight() {
+        return 5;
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        if (name.equals(TcManagerTest.uriRefA)) {
+            Graph mResult = new SimpleMGraph();
+            mResult.add(new TripleImpl(TcManagerTest.uriRefA1, 
+                    TcManagerTest.uriRefA1, TcManagerTest.uriRefA1));
+            mGraphList.add(name);
+            return mResult.getImmutableGraph();
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name) throws NoSuchEntityException {
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getGraph(IRI name) throws NoSuchEntityException {
+        return getImmutableGraph(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void deleteGraph(IRI name) throws NoSuchEntityException, 
+            EntityUndeletableException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        return mGraphList;
+    }
+
+    @Override
+    public Set<IRI> listGraphs() {
+        return listMGraphs();
+    }
+}
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedAHeavy.java b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedAHeavy.java
new file mode 100644
index 0000000..3cc1421
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedAHeavy.java
@@ -0,0 +1,101 @@
+/*
+ * 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.clerezza.dataset.providers;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.api.impl.graph.SimpleGraph;
+import org.apache.clerezza.dataset.EntityUndeletableException;
+import org.apache.clerezza.dataset.NoSuchEntityException;
+import org.apache.clerezza.dataset.TcManagerTest;
+import org.apache.clerezza.dataset.WeightedTcProvider;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author reto
+ */
+public class WeightedAHeavy implements WeightedTcProvider {
+
+    @Override
+    public int getWeight() {
+        return 20;
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        if (name.equals(TcManagerTest.uriRefA)) {
+            Graph mResult = new SimpleGraph();
+            mResult.add(new TripleImpl(TcManagerTest.uriRefAHeavy, 
+                    TcManagerTest.uriRefAHeavy, TcManagerTest.uriRefAHeavy));
+            return mResult.getImmutableGraph();
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name) throws NoSuchEntityException {
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getGraph(IRI name) throws NoSuchEntityException {
+        return getImmutableGraph(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void deleteGraph(IRI name) throws NoSuchEntityException, 
+            EntityUndeletableException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+    @Override
+    public Set<IRI> listGraphs() {
+        return Collections.singleton(TcManagerTest.uriRefA);
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        return new HashSet<IRI>();
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        return listGraphs();
+    }
+}
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedBlight.java b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedBlight.java
new file mode 100644
index 0000000..161599b
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedBlight.java
@@ -0,0 +1,106 @@
+/*
+ * 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.clerezza.dataset.providers;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.impl.TripleImpl;
+import org.apache.clerezza.api.impl.graph.SimpleMGraph;
+import org.apache.clerezza.dataset.EntityUndeletableException;
+import org.apache.clerezza.dataset.NoSuchEntityException;
+import org.apache.clerezza.dataset.TcManagerTest;
+import org.apache.clerezza.dataset.WeightedTcProvider;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author reto
+ */
+public class WeightedBlight implements WeightedTcProvider {
+
+    @Override
+    public int getWeight() {
+        return 2;
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        if (name.equals(TcManagerTest.uriRefB)) {
+            Graph mResult = new SimpleMGraph();
+            mResult.add(new TripleImpl(TcManagerTest.uriRefB, TcManagerTest.uriRefB, TcManagerTest.uriRefB));
+            return mResult.getImmutableGraph();
+        }
+        if (name.equals(TcManagerTest.uriRefA)) {
+            Graph mResult = new SimpleMGraph();
+            //empty ImmutableGraph
+            return mResult.getImmutableGraph();
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name) throws NoSuchEntityException {
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getGraph(IRI name) throws NoSuchEntityException {
+        return getImmutableGraph(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void deleteGraph(IRI name) throws NoSuchEntityException, 
+            EntityUndeletableException {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        return new HashSet<IRI>();
+    }
+
+    @Override
+    public Set<IRI> listGraphs() {
+        return listMGraphs();
+    }
+
+}
diff --git a/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedDummy.java b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedDummy.java
new file mode 100644
index 0000000..44ace0e
--- /dev/null
+++ b/dataset/src/test/java/org/apache/clerezza/dataset/providers/WeightedDummy.java
@@ -0,0 +1,155 @@
+/*
+ * 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.clerezza.dataset.providers;
+
+import org.apache.clerezza.api.Graph;
+import org.apache.clerezza.api.IRI;
+import org.apache.clerezza.api.ImmutableGraph;
+import org.apache.clerezza.api.impl.graph.SimpleImmutableGraph;
+import org.apache.clerezza.api.impl.graph.SimpleMGraph;
+import org.apache.clerezza.dataset.EntityAlreadyExistsException;
+import org.apache.clerezza.dataset.EntityUndeletableException;
+import org.apache.clerezza.dataset.NoSuchEntityException;
+import org.apache.clerezza.dataset.WeightedTcProvider;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author mir
+ */
+public class WeightedDummy implements WeightedTcProvider {
+
+    private Map<IRI, Graph> tripleMap = new HashMap<IRI, Graph>();
+
+    @Override
+    public ImmutableGraph createImmutableGraph(IRI name, Graph triples)
+            throws EntityAlreadyExistsException {
+        if ((name == null) || (name.getUnicodeString() == null)
+                || (name.getUnicodeString().trim().length() == 0)) {
+            throw new IllegalArgumentException("Name must not be null");
+        }
+
+        try {
+            // throws NoSuchEntityException if a Graph with that name
+            // already exists
+            this.getGraph(name);
+        } catch (NoSuchEntityException e) {
+            ImmutableGraph result;
+            if (ImmutableGraph.class.isAssignableFrom(triples.getClass())) {
+                result = (ImmutableGraph) triples;
+            } else {
+                result = new SimpleImmutableGraph(triples);
+            }
+            tripleMap.put(name, result);
+
+            return result;
+        }
+        throw new EntityAlreadyExistsException(name);
+    }
+
+    @Override
+    public Graph createGraph(IRI name) throws EntityAlreadyExistsException {
+        if ((name == null) || (name.getUnicodeString() == null)
+                || (name.getUnicodeString().trim().length() == 0)) {
+            throw new IllegalArgumentException("Name must not be null");
+        }
+
+        try {
+            // throws NoSuchEntityException if a Graph with that name
+            // already exists
+            this.getGraph(name);
+        } catch (NoSuchEntityException e) {
+            Graph result = new SimpleMGraph();
+            tripleMap.put(name, result);
+            return result;
+        }
+        throw new EntityAlreadyExistsException(name);
+    }
+
+    @Override
+    public void deleteGraph(IRI name)
+            throws NoSuchEntityException, EntityUndeletableException {
+        if (tripleMap.remove(name) == null) {
+            throw new NoSuchEntityException(name);
+        }
+    }
+
+    @Override
+    public ImmutableGraph getImmutableGraph(IRI name) throws NoSuchEntityException {
+        Graph Graph = tripleMap.get(name);
+        if (Graph == null) {
+            throw new NoSuchEntityException(name);
+        } else if (ImmutableGraph.class.isAssignableFrom(Graph.getClass())) {
+            return (ImmutableGraph) Graph;
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Graph getMGraph(IRI name) throws NoSuchEntityException {
+        Graph Graph = tripleMap.get(name);
+        if (Graph == null) {
+            throw new NoSuchEntityException(name);
+        } else if (Graph.class.isAssignableFrom(Graph.getClass())) {
+            return (Graph) Graph;
+        }
+        throw new NoSuchEntityException(name);
+    }
+
+    @Override
+    public Set<IRI> getNames(ImmutableGraph ImmutableGraph) {
+        throw new UnsupportedOperationException(
+                "Not supported yet. equals() has to be implemented first");
+    }
+
+    @Override
+    public Graph getGraph(IRI name)
+            throws NoSuchEntityException {
+        Graph Graph = tripleMap.get(name);
+        if (Graph == null) {
+            throw new NoSuchEntityException(name);
+        } else {
+            return Graph;
+        }
+    }
+
+    @Override
+    public int getWeight() {
+        return 1;
+    }
+
+    @Override
+    public Set<IRI> listImmutableGraphs() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public Set<IRI> listMGraphs() {
+        return new HashSet<IRI>();
+    }
+
+    @Override
+    public Set<IRI> listGraphs() {
+        return listMGraphs();
+    }
+}