]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/QuerySupportImpl.java
Fail safe import fixes made by Antti
[simantics/platform.git] / bundles / org.simantics.db.procore / src / fi / vtt / simantics / procore / internal / QuerySupportImpl.java
index c2af01289ceb5ae79815b7aa1180f02b601172e7..1d3563fc1a3b5fca63688dca04a52c4805bdee50 100644 (file)
-package fi.vtt.simantics.procore.internal;\r
-\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-import java.io.ByteArrayInputStream;\r
-import java.io.InputStream;\r
-import java.util.Collection;\r
-\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.VirtualGraph;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.StandardStatement;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.InvalidResourceReferenceException;\r
-import org.simantics.db.exception.ResourceNotFoundException;\r
-import org.simantics.db.impl.ClusterI;\r
-import org.simantics.db.impl.ClusterSupport;\r
-import org.simantics.db.impl.ForEachObjectContextProcedure;\r
-import org.simantics.db.impl.ForEachObjectProcedure;\r
-import org.simantics.db.impl.ResourceImpl;\r
-import org.simantics.db.impl.TransientGraph;\r
-import org.simantics.db.impl.VirtualGraphImpl;\r
-import org.simantics.db.impl.graph.ReadGraphImpl;\r
-import org.simantics.db.impl.query.IntProcedure;\r
-import org.simantics.db.impl.query.QueryProcessor;\r
-import org.simantics.db.impl.query.QuerySupport;\r
-import org.simantics.db.impl.support.BuiltinSupport;\r
-import org.simantics.db.impl.support.ResourceSupport;\r
-import org.simantics.db.procore.cluster.ClusterImpl;\r
-import org.simantics.db.procore.cluster.ClusterSmall;\r
-import org.simantics.db.service.SerialisationSupport;\r
-import org.simantics.utils.DataContainer;\r
-import org.simantics.utils.datastructures.Callback;\r
-\r
-public class QuerySupportImpl implements QuerySupport {\r
-       \r
-       final SessionImplSocket session;\r
-       final State state;\r
-       final ClusterTable clusterTable;\r
-       final BuiltinSupport builtinSupport;\r
-       final ClusterSupport clusterSupport;\r
-       final ResourceSupport resourceSupport;\r
-       final SerialisationSupport serializationSupport;\r
-       final VirtualGraphServerSupportImpl virtualGraphServerSupport;\r
-       final GraphSession graphSession;\r
-       final SessionRequestManager syncThreads;\r
-       final int root;\r
-\r
-    private boolean pendingPrimitives = false;\r
-       \r
-       QuerySupportImpl(SessionImplSocket session, ClusterSupport clusterSupport, SerialisationSupport serializationSupport, SessionRequestManager syncThreads) {\r
-               this.session = session;\r
-               this.state = session.state;\r
-               this.clusterTable = session.clusterTable;\r
-               this.resourceSupport = session.resourceSupport;\r
-               this.virtualGraphServerSupport = session.virtualGraphServerSupport;\r
-               this.graphSession = session.graphSession;\r
-               this.builtinSupport = session.builtinSupport;\r
-               this.clusterSupport = clusterSupport;\r
-               this.serializationSupport = serializationSupport;\r
-               this.syncThreads = syncThreads;\r
-               this.root = getBuiltin("http:/");\r
-               assert(this.session != null);\r
-               assert(this.state != null);\r
-               assert(this.clusterTable != null);\r
-               assert(this.resourceSupport != null);\r
-               assert(this.virtualGraphServerSupport != null);\r
-               assert(this.graphSession != null);\r
-               assert(this.builtinSupport != null);\r
-               assert(this.clusterSupport != null);\r
-               assert(this.serializationSupport != null);\r
-               assert(this.syncThreads != null);\r
-       }\r
-\r
-       @Override\r
-       public ResourceSupport getSupport() {\r
-               return resourceSupport;\r
-       }\r
-       \r
-    @Override\r
-    public Statement getStatement(int s, int p, int o) {\r
-        return getStatement(null, s, p, o);\r
-    }\r
-\r
-    @Override\r
-    public Statement getStatement(ReadGraphImpl graph, int s, int p, int o) {\r
-        Resource sr = getResource(s);\r
-        Resource pr = getResource(p);\r
-        Resource or = getResource(o);\r
-        return new StandardStatement(sr, pr, or);\r
-    }\r
-\r
-       @Override\r
-       public Session getSession() {\r
-               return session;\r
-       }\r
-\r
-    @Override\r
-    public long getClusterId(int id) {\r
-       ClusterI cluster = clusterTable.getClusterByResourceKey(id);\r
-       if(cluster == null) return 0;\r
-       return cluster.getClusterId();\r
-    }\r
-    \r
-    @Override\r
-    public boolean isImmutable(int id) {\r
-       // Virtuals are mutable\r
-       if(id < 0) return false;\r
-       // Root library is mutable\r
-       if(root == id) return false;\r
-       // Anything goes in service mode\r
-       if(session.serviceMode > 0) return false;\r
-       return clusterTable.isImmutable(id);\r
-    }\r
-\r
-    @Override\r
-    public int getId(Resource resource) {\r
-        if (resource instanceof ResourceImpl)\r
-            return ((ResourceImpl)resource).id;\r
-        return 0;\r
-    }\r
-\r
-       @Override\r
-       public Resource getResource(int id) {\r
-               try {\r
-                       return serializationSupport.getResource(id);\r
-               } catch (DatabaseException e) {\r
-                       e.printStackTrace();\r
-               }\r
-               return null;\r
-       }\r
-\r
-       @Override\r
-    public boolean resume(ReadGraphImpl graph) {\r
-               \r
-               return syncThreads.session.queryProvider2.resume(graph);\r
-               \r
-    }\r
-\r
-//    @Override\r
-//    final public void sync(int resumeThread, final SessionRunnable runnable) {\r
-//     \r
-//     syncThreads.session.queryProvider2.schedule(Integer.MIN_VALUE, new SessionTask(resumeThread) {\r
-//\r
-//                     @Override\r
-//                     public void run(int thread) {\r
-//                             runnable.run(thread);\r
-//                     }\r
-//             \r
-//     });\r
-//     \r
-//    }\r
-\r
-//    @Override\r
-//    final public int nextSyncThread() {\r
-//     throw new Error();\r
-////        return syncThreads.nextThread();\r
-//    }\r
-\r
-       @Override\r
-    public void dirtyPrimitives() {\r
-        session.dirtyPrimitives = true;\r
-        if(state.getWriteCount() == 0 && !pendingPrimitives) {\r
-            pendingPrimitives = true;\r
-            session.asyncRequest(new WriteRequest() {\r
-\r
-                @Override\r
-                public void perform(WriteGraph graph) throws DatabaseException {\r
-                    pendingPrimitives = false;\r
-                }\r
-                \r
-            });\r
-        }\r
-    }\r
-\r
-    @Override\r
-    @Deprecated\r
-    final public void aboutToRead() {\r
-    }\r
-\r
-//    @Override\r
-//    public void increaseReferenceCount(int callerThread, int subject) {\r
-//        if (subject < 0)\r
-//            return;\r
-//        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);\r
-//        if (null == proxy)\r
-//            return;\r
-//        proxy.increaseReferenceCount(callerThread, 1);\r
-//    }\r
-//\r
-//    @Override\r
-//    public void decreaseReferenceCount(int callerThread, int subject) {\r
-//        if (subject < 0)\r
-//            return;\r
-//        ClusterProxy proxy = clusterTable.getClusterByResourceKey(subject);\r
-//        if (null == proxy)\r
-//            return;\r
-//        proxy.decreaseReferenceCount(callerThread, 1);\r
-//    }\r
-\r
-//     @Override\r
-       public void getObjects4(final ReadGraphImpl graph, final int subject, final ForEachObjectProcedure procedure) {\r
-               \r
-               if(subject < 0) {\r
-                       \r
-                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
-\r
-//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
-//                    if(graph.callerThread == suggestSchedule) {\r
-                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));\r
-//                    } else {\r
-//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
-//             \r
-//                             @Override\r
-//                             public void run(int thread) {\r
-//                             procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));\r
-//                             }\r
-//             \r
-//                     });\r
-//                    }\r
-                       \r
-                }\r
-                       }\r
-                       procedure.finished(graph);\r
-//             graph.dec();\r
-               return;\r
-               \r
-               } \r
-               \r
-        final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
-        if(!cluster.isLoaded()) {\r
-               cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
-                               @Override\r
-                               public void run() {\r
-                                       getObjects4(graph, subject, procedure);\r
-                               }\r
-                       \r
-               });\r
-               return;\r
-        }\r
-               \r
-               if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
-                       \r
-                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
-//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
-//                    if(graph.callerThread == suggestSchedule) {\r
-                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));\r
-//                    } else {\r
-//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
-//             \r
-//                             @Override\r
-//                             public void run(int thread) {\r
-//                             procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));\r
-//                             }\r
-//             \r
-//                     });\r
-//                    }\r
-                }\r
-                       }\r
-                       \r
-                       try {\r
-                               cluster.forObjects(graph, subject, procedure);\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-                       \r
-               } else {\r
-                       \r
-                       try {\r
-                               cluster.forObjects(graph, subject, procedure);\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-                       \r
-               }\r
-               \r
-       }\r
-\r
-       public <C> void getObjects4(final ReadGraphImpl graph, final int subject, final C context, final ForEachObjectContextProcedure<C> procedure) {\r
-               \r
-               if(subject < 0) {\r
-                       \r
-                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
-\r
-//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
-//                    if(graph.callerThread == suggestSchedule) {\r
-                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));\r
-//                    } else {\r
-//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
-//             \r
-//                             @Override\r
-//                             public void run(int thread) {\r
-//                             procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));\r
-//                             }\r
-//             \r
-//                     });\r
-//                    }\r
-                       \r
-                }\r
-                       }\r
-                       procedure.finished(graph);\r
-//             graph.dec();\r
-               return;\r
-               \r
-               } \r
-               \r
-        final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
-        if(!cluster.isLoaded()) {\r
-               cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
-                               @Override\r
-                               public void run() {\r
-                                       getObjects4(graph, subject, context, procedure);\r
-                               }\r
-                       \r
-               });\r
-               return;\r
-        }\r
-               \r
-               if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
-                       \r
-                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-                for (final int id : g.getObjects(subject, procedure.predicateKey)) {\r
-//                    int suggestSchedule = graph.processor.processor.resourceThread(id);\r
-//                    if(graph.callerThread == suggestSchedule) {\r
-                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));\r
-//                    } else {\r
-//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {\r
-//             \r
-//                             @Override\r
-//                             public void run(int thread) {\r
-//                             procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));\r
-//                             }\r
-//             \r
-//                     });\r
-//                    }\r
-                }\r
-                       }\r
-                       \r
-                       try {\r
-                               cluster.forObjects(graph, subject, context, procedure);\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-                       \r
-               } else {\r
-                       \r
-                       try {\r
-                               cluster.forObjects(graph, subject, context, procedure);\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-                       \r
-               }\r
-               \r
-       }\r
-       \r
-       @Override\r
-    public int getSingleInstance(final int subject) {\r
-       \r
-       // Do not process this information for virtual resources\r
-       if(subject < 0) return 0;\r
-       \r
-        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-        if (cluster == null)\r
-            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
-        assert (cluster != null);\r
-\r
-        try {\r
-        \r
-               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);\r
-               if(ClusterI.CompleteTypeEnum.InstanceOf == type) {\r
-                       int result = cluster.getCompleteObjectKey(subject, clusterSupport);\r
-                       assert(result > 0);\r
-                       return result;\r
-               } else {\r
-                       return 0;\r
-               }\r
-        \r
-        } catch (DatabaseException e) {\r
-               \r
-               Logger.defaultLogError(e);\r
-               return 0;\r
-               \r
-        }\r
-        // This happens is the resource is bogus\r
-        catch (Throwable t) {\r
-               \r
-               analyseProblem(cluster);\r
-               \r
-               Logger.defaultLogError(t);\r
-               \r
-               return 0;\r
-               \r
-        }\r
-       \r
-    }\r
-\r
-       @Override\r
-    public int getSingleSuperrelation(final int subject) {\r
-       \r
-       // Do not process this information for virtual resources\r
-       if(subject < 0) return 0;\r
-\r
-       final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-        if (cluster == null)\r
-            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
-        assert (cluster != null);\r
-\r
-        try {\r
-        \r
-               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);\r
-               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {\r
-                       int result = cluster.getCompleteObjectKey(subject, clusterSupport);\r
-                       assert(result > 0);\r
-                       return result;\r
-               } else {\r
-                       return 0;\r
-               }\r
-        \r
-        } catch (DatabaseException e) {\r
-               \r
-               Logger.defaultLogError(e);\r
-               return 0;\r
-               \r
-        }\r
-       \r
-    }\r
-\r
-//     @Override\r
-//    public void getSingleSuperrelation(ReadGraphImpl graph, final int subject, final AsyncProcedure<Resource> procedure) {\r
-//     \r
-//     // Do not process this information for virtual resources\r
-//     if(subject < 0) {\r
-//             procedure.execute(graph, null);\r
-//                     graph.state.barrier.dec();\r
-//             return;\r
-//     }\r
-//\r
-//     final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-//        if (cluster == null)\r
-//            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
-//        \r
-//        assert (cluster != null);\r
-//\r
-//        if(!cluster.isLoaded()) {\r
-//            \r
-//             procedure.execute(graph, null);\r
-//                     graph.state.barrier.dec();\r
-//             return;\r
-//\r
-////           queryProvider2.requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {\r
-////   \r
-////                           @Override\r
-////                           public void run(Integer i) {\r
-////   \r
-////                                   queryProvider2.schedule(i, callerThread, new Runnable() {\r
-////   \r
-////                                           @Override\r
-////                                           public void run() {\r
-////                                                   \r
-////                                                   try  {\r
-////                                                   \r
-////                                               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(callerThread, subject, SessionImplSocket.this);\r
-////                                               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {\r
-////                                                   int result = cluster.getCompleteObjectKey(callerThread, subject, SessionImplSocket.this);\r
-////                                                   assert(result > 0);\r
-////                                                   procedure.execute(graph, getResourceByKey(result));\r
-////                                               } else {\r
-////                                                   procedure.execute(graph, null);\r
-////                                               }\r
-////                                                           graph.state.barrier.dec();\r
-////                                                           \r
-////                                                   } catch (DatabaseException e) {\r
-////                                                           e.printStackTrace();\r
-////                                                   }\r
-////                                                   \r
-////                                           }\r
-////   \r
-////                                   });\r
-////   \r
-////                           }\r
-////   \r
-////                   });\r
-//                     \r
-//        } else {\r
-//\r
-//             try {\r
-//\r
-//                     ClusterI.CompleteTypeEnum type = cluster.getCompleteType(graph.callerThread, subject, clusterSupport);\r
-//                     if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {\r
-//                             int result = cluster.getCompleteObjectKey(graph.callerThread, subject, clusterSupport);\r
-//                             assert(result > 0);\r
-//                             procedure.execute(graph, new ResourceImpl(resourceSupport, result));\r
-//                     } else {\r
-//                             procedure.execute(graph, null);\r
-//                     }\r
-//                     graph.state.barrier.dec();\r
-//\r
-//             } catch (DatabaseException e) {\r
-//                     e.printStackTrace();\r
-//             }\r
-//                     \r
-//        }\r
-//        \r
-//        \r
-//    }\r
-\r
-//     @Override\r
-//    public void getObjects2(final int callerThread, final int subject, final int predicate, final IntProcedure procedure) {\r
-//             ensureLoaded(callerThread, subject, predicate, new Runnable() {\r
-//\r
-//                     @Override\r
-//                     public void run() {\r
-//                             safeGetObjects2(callerThread, subject, predicate, procedure);\r
-//                     }\r
-//                     \r
-//             });\r
-//     }\r
-\r
-//    public void safeGetObjects2(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {\r
-//\r
-//        assert (subject != 0);\r
-//        assert (predicate != 0);\r
-////        System.out.println("getObjects2: s=" + subject + "p=" + predicate);\r
-//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-//        if (providers != null) {\r
-//\r
-//            final TIntHashSet result = new TIntHashSet(16);\r
-//\r
-//            for (VirtualGraph provider : providers) {\r
-//\r
-//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
-//\r
-//                    if (result.add(id)) {\r
-//                     procedure.execute(graph, id);\r
-//                    }\r
-//\r
-//                }\r
-//\r
-//            }\r
-//\r
-//            if (subject < 0)\r
-//                return;\r
-//\r
-//            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-//\r
-//            assert (testCluster(subject, cluster));\r
-//            \r
-//            // wheels within wheels\r
-//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
-//\r
-//                @Override\r
-//                public boolean execute(int callerThread, Object context, int object) {\r
-//\r
-//                    if (result.add(object)) {\r
-//                     procedure.execute(graph.newAsync(callerThread), object);\r
-//                    }\r
-//\r
-//                    return false; // continue looping\r
-//\r
-//                }\r
-//                \r
-//                             @Override\r
-//                             public boolean found() {\r
-//                                     throw new UnsupportedOperationException();\r
-//                             }\r
-//                \r
-//            };\r
-//\r
-//            try {\r
-//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
-//            } catch (DatabaseException e) {\r
-//                Logger.defaultLogError(e);\r
-//            } catch (Throwable t) {\r
-//                Logger.defaultLogError(t);\r
-//             t.printStackTrace();\r
-//            }\r
-//            return;\r
-//            \r
-//        }\r
-//        \r
-//        assert(subject > 0);\r
-//\r
-//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-//\r
-//        assert (testCluster(subject, cluster));\r
-//        \r
-//        try {\r
-//            cluster.forObjects(graph.callerThread, subject, predicate, new Wheels(procedure), null, clusterSupport);\r
-//        } catch (DatabaseException e) {\r
-//            Logger.defaultLogError(e);\r
-//        } catch (Throwable t) {\r
-//             t.printStackTrace();\r
-//            Logger.defaultLogError(t);\r
-//        }\r
-//        \r
-//    }\r
-\r
-       @Override\r
-    public boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {\r
-               \r
-               assert (subject != 0);\r
-               assert (predicate != 0);\r
-\r
-               if(subject < 0) {\r
-\r
-                       boolean found = false;\r
-                       \r
-                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-                               for (final int id : g.getObjects(subject, predicate)) {\r
-                                       found = true;\r
-                                       procedure.execute(graph, id);\r
-                               }\r
-                       }\r
-                       \r
-                       return found;\r
-\r
-               }\r
-\r
-               final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-               assert(cluster.isLoaded());\r
-        \r
-        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
-               \r
-               final DataContainer<Boolean> found = new DataContainer<Boolean>(Boolean.FALSE);\r
-               final TIntHashSet result = new TIntHashSet(5);\r
-               \r
-                       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-                               for (final int id : g.getObjects(subject, predicate)) {\r
-\r
-                                       found.set(true);\r
-                                       if (result.add(id)) {\r
-                                               procedure.execute(graph, id);\r
-                                       }\r
-\r
-                               }\r
-                       }\r
-                       \r
-                       // Virtual predicates are not found from persistent clusters\r
-                       if(predicate < 0) return found.get();\r
-\r
-               // wheels within wheels\r
-               final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
-\r
-                       @Override\r
-                       public boolean execute(Object context, int object) {\r
-\r
-                               found.set(true);\r
-                               if (result.add(object)) {\r
-                                       procedure.execute(graph, object);\r
-                               }\r
-\r
-                               return false; // continue looping\r
-\r
-                       }\r
-\r
-               };\r
-                       \r
-                       try {\r
-                cluster.forObjects(subject, predicate, proc, null, clusterSupport);\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-                       \r
-                       return found.get();\r
-                       \r
-               } else {\r
-                       \r
-                       // Virtual predicates are not found from persistent clusters\r
-                       if(predicate < 0) return false;\r
-                       \r
-                       class A implements ClusterI.ObjectProcedure<Object> {\r
-\r
-                       boolean found = false;\r
-\r
-                       @Override\r
-                       public boolean execute(Object context, int object) {\r
-\r
-                               found = true;\r
-                               procedure.execute(graph, object);\r
-\r
-                               return false; // continue looping\r
-\r
-                       }\r
-\r
-                               public boolean found() {\r
-                                       return found;\r
-                               }\r
-\r
-                       }\r
-                       \r
-               // wheels within wheels\r
-               final A proc = new A();\r
-               \r
-                       try {\r
-                cluster.forObjects(subject, predicate, proc, null, clusterSupport);\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       } \r
-                       // This happens if resource is bogus\r
-                       catch (Throwable t) {\r
-                               \r
-                       analyseProblem(cluster);\r
-                       \r
-                       Logger.defaultLogError(t);\r
-                               \r
-                       }\r
-               \r
-               return proc.found();\r
-                       \r
-               }\r
-        \r
-    }\r
-\r
-//     @Override\r
-//    public boolean getFunctionalObject(final ReadGraphImpl graph, final int subject, final int predicate,\r
-//            final IntProcedure procedure) {\r
-//\r
-//        assert (subject != 0);\r
-//        assert (predicate != 0);\r
-//\r
-//        if(subject < 0) {\r
-//\r
-//             boolean found = false;\r
-//\r
-//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-//             if (providers != null) {\r
-//\r
-//                     for (VirtualGraph provider : providers) {\r
-//\r
-//                             for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
-//                                     found = true;\r
-//                     procedure.execute(graph, id);\r
-//                    }\r
-//\r
-//                }\r
-//\r
-//            }\r
-//             \r
-//             return found;\r
-//             \r
-//        }\r
-//        \r
-//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-//        \r
-//        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
-//        \r
-//             final DataContainer<Boolean> found = new DataContainer<Boolean>(false);\r
-//             final TIntHashSet result = new TIntHashSet(5);\r
-//\r
-//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-//             if (providers != null) {\r
-//\r
-//                     for (VirtualGraph provider : providers) {\r
-//\r
-//                             for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
-//                                     found.set(true);\r
-//                     procedure.execute(graph, id);\r
-//                    }\r
-//\r
-//                }\r
-//\r
-//            }\r
-//             \r
-//            // wheels within wheels\r
-//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
-//\r
-//                @Override\r
-//                public boolean execute(int callerThread, Object context, int object) {\r
-//\r
-//                    found.set(true);\r
-//                    System.out.println("-found object " + object);\r
-//                    if (result.add(object)) {\r
-//                     procedure.execute(graph.newAsync(callerThread), object);\r
-//                    }\r
-//\r
-//                    return false; // continue looping\r
-//\r
-//                }\r
-//                \r
-//                             @Override\r
-//                             public boolean found() {\r
-//                                     throw new UnsupportedOperationException();\r
-//                             }\r
-//                \r
-//            };\r
-//            \r
-//            try {\r
-//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
-//            } catch (DatabaseException e) {\r
-//                Logger.defaultLogError(e);\r
-//                return false;\r
-//            } catch (Throwable t) {\r
-//                Logger.defaultLogError(t);\r
-//             t.printStackTrace();\r
-//            }\r
-//            \r
-//            return found.get();\r
-//            \r
-//        } else {\r
-//\r
-//             // wheels within wheels\r
-//             final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
-//                 \r
-//                     boolean found = false;\r
-//                     \r
-//                 @Override\r
-//                 public boolean execute(int callerThread, Object context, int object) {\r
-//     \r
-//                     found = true;\r
-//                     procedure.execute(graph.newAsync(callerThread), object);\r
-//                     return false; // continue looping\r
-//                     \r
-//                 }\r
-//                 \r
-//                             @Override\r
-//                             public boolean found() {\r
-//                                     return found;\r
-//                             }\r
-//                 \r
-//                 @Override\r
-//                 public String toString() {\r
-//                     return "Wheels for " + procedure;\r
-//                 }\r
-//                 \r
-//             };\r
-//             \r
-//             try {\r
-//                 cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
-//             } catch (DatabaseException e) {\r
-//                 Logger.defaultLogError(e);\r
-//                 return false;\r
-//             } catch (Throwable t) {\r
-//                     t.printStackTrace();\r
-//                 Logger.defaultLogError(t);\r
-//                 return false;\r
-//             }\r
-//             \r
-//             return proc.found();\r
-//        \r
-//        }\r
-//        \r
-//    }\r
-       \r
-       @Override\r
-    public int getFunctionalObject(final int subject, final int predicate) {\r
-\r
-        assert (subject != 0);\r
-        assert (predicate != 0);\r
-\r
-        if(subject < 0) {\r
-\r
-               int found = 0;\r
-\r
-               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-               if (providers != null) {\r
-\r
-                       for (VirtualGraph provider : providers) {\r
-\r
-                               for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
-                                       if(found == 0) found = id;\r
-                                       else found = -1;\r
-                    }\r
-\r
-                }\r
-\r
-            }\r
-               \r
-               return found;\r
-//             if(found == -1) return 0;\r
-//             else return found;\r
-               \r
-        }\r
-        \r
-        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-        \r
-        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {\r
-\r
-               int result = 0;\r
-               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-               if (providers != null) {\r
-\r
-                       for (VirtualGraph provider : providers) {\r
-\r
-                               for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
-                                       if(result == 0) result = id;\r
-                                       else result = -1;\r
-                    }\r
-\r
-                }\r
-\r
-            }\r
-               \r
-               if(result != 0) return result; \r
-            \r
-               try {\r
-                               return cluster.getSingleObject(subject, predicate, clusterSupport);\r
-                       } catch (DatabaseException e) {\r
-                               return -1;\r
-                       }\r
-            \r
-        } else {\r
-\r
-               try {\r
-                               return cluster.getSingleObject(subject, predicate, clusterSupport);\r
-                       } catch (DatabaseException e) {\r
-                               return -1;\r
-                       }\r
-               // This comes if the resource is bogus\r
-               catch (Throwable t) {\r
-                       \r
-               analyseProblem(cluster);\r
-               \r
-               Logger.defaultLogError(t);\r
-                       \r
-                               return -1;\r
-                               \r
-                       }\r
-        \r
-        }\r
-        \r
-    }\r
-\r
-//     @Override\r
-//    public boolean getStatements(final ReadGraphImpl graph, final int subject, final int predicate,\r
-//            final TripleIntProcedure procedure, final Statements entry) {\r
-//\r
-//        assert (subject != 0);\r
-//        assert (predicate != 0);\r
-//\r
-//        final TIntHashSet result = new TIntHashSet(16);\r
-//        final DataContainer<Boolean> found = new DataContainer<Boolean>(false);\r
-//\r
-//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-//        \r
-//        if (providers != null) {\r
-//\r
-//            for (VirtualGraph provider : providers) {\r
-//\r
-//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {\r
-//\r
-//                    found.set(true);\r
-//\r
-//                    if (result.add(id)) {\r
-//                        if (null != entry) {\r
-//                            entry.addOrSet(subject, predicate, id);\r
-//                            procedure.execute(graph, subject, predicate, id);\r
-//                            return true; // break;\r
-//                        } else {\r
-//                            procedure.execute(graph, subject, predicate, id);\r
-//                        }\r
-//                    }\r
-//\r
-//                }\r
-//\r
-//            }\r
-//\r
-//        }\r
-//\r
-//        if (subject < 0)\r
-//            return found.get();\r
-//\r
-//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-//        assert (cluster != null);\r
-//\r
-//        // wheels within wheels\r
-//        final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {\r
-//            @Override\r
-//            public boolean execute(int callerThread, Object context, int object) {\r
-//\r
-//                found.set(true);\r
-//\r
-//                if (result.add(object)) {\r
-//                    if (null != entry) {\r
-//                        entry.addOrSet(subject, predicate, object);\r
-//                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);\r
-//                        return true; // break;\r
-//                    } else {\r
-//                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);\r
-//                    }\r
-//                }\r
-//\r
-//                return false; // continue looping\r
-//\r
-//            }\r
-//            \r
-//                     @Override\r
-//                     public boolean found() {\r
-//                             throw new UnsupportedOperationException();\r
-//                     }\r
-//            \r
-//        };\r
-//\r
-//        try {\r
-//            cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);\r
-//        } catch (DatabaseException e) {\r
-//            Logger.defaultLogError(e);\r
-//        }\r
-//        return found.get();\r
-//\r
-//    }\r
-\r
-       @Override\r
-    public org.simantics.db.DirectStatements getStatements(final ReadGraphImpl graph, final int subject, final QueryProcessor processor, boolean ignoreVirtual) {\r
-\r
-        assert (subject != 0);\r
-\r
-        final DirectStatementsImpl result = new DirectStatementsImpl(resourceSupport, subject);\r
-\r
-        if (!ignoreVirtual) {\r
-            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-            if (providers != null) {\r
-                for (TransientGraph provider : providers) {\r
-                    for (int p : provider.getPredicates(subject)) {\r
-                        for (int o : provider.getObjects(subject, p)) {\r
-                            result.addStatement(p, o);\r
-                        }\r
-                    }\r
-                }\r
-            }\r
-        }\r
-\r
-        if (subject < 0) {\r
-               return result;\r
-        } else {\r
-            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-            assert (cluster != null);\r
-            doGetStatements(graph, cluster, subject, result);\r
-        }\r
-        \r
-        return result;\r
-\r
-    }\r
-\r
-//    @Override\r
-//    public void getStatements(ReadGraphImpl graph, final int subject, final Procedure<DirectStatements> procedure) {\r
-//     \r
-//             procedure.exception(new DatabaseException("Not supported"));\r
-//             \r
-//    }\r
-\r
-    @Override\r
-    public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) {\r
-\r
-        final TIntHashSet result = new TIntHashSet(16);\r
-\r
-        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);\r
-        \r
-        if (providers != null) {\r
-\r
-            for (VirtualGraph provider : providers) {\r
-\r
-                for (int id : ((VirtualGraphImpl)provider).getPredicates(subject)) {\r
-\r
-                    if (result.add(id)) {\r
-                        procedure.execute(graph, id);\r
-                    }\r
-\r
-                }\r
-\r
-            }\r
-\r
-        }\r
-\r
-        if (subject < 0) {\r
-            procedure.finished(graph);\r
-            return;\r
-        }\r
-\r
-        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);\r
-//        if(!proxy.isLoaded()) {\r
-//             \r
-//             proxy.load(callerThread, session, new Runnable() {\r
-//\r
-//                             @Override\r
-//                             public void run() {\r
-//                                     getPredicates(callerThread, subject, procedure);\r
-//                             }\r
-//                     \r
-//             });\r
-//             return;\r
-//             \r
-//        }\r
-        assert (proxy != null);\r
-\r
-        final DataContainer<Integer> got = new DataContainer<Integer>(0);\r
-        ClusterI.PredicateProcedure<Object> proc = new ClusterI.PredicateProcedure<Object>() {\r
-            @Override\r
-            public boolean execute(Object context, int predicate, int oi) {\r
-                if (result.add(predicate)) {\r
-                    procedure.execute(graph, predicate);\r
-                }\r
-                got.set(got.get() + 1);\r
-                return false; // continue looping\r
-            }\r
-        };\r
-        try {\r
-            proxy.forPredicates(subject, proc, null, clusterSupport);\r
-        } catch (DatabaseException e) {\r
-            Logger.defaultLogError(e);\r
-        }\r
-        procedure.finished(graph);\r
-\r
-    }\r
-    \r
-    \r
-\r
-//    @Override\r
-//    public void getValue(ReadGraphImpl graph, int resource, InternalProcedure<byte[]> procedure) {\r
-//\r
-//     if(resource < 0) {\r
-//     \r
-//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
-//             \r
-//             if (providers != null) {\r
-//     \r
-//                 for (VirtualGraph provider : providers) {\r
-//     \r
-//                     Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
-//                     if (value != null) {\r
-//                         procedure.execute(graph, (byte[])value);\r
-//                         return;\r
-//                     }\r
-//     \r
-//                 }\r
-//     \r
-//             }\r
-//             \r
-//             return;\r
-//        \r
-//     }\r
-//     \r
-//     ClusterI cluster = clusterTable.getClusterByResourceKey(resource);\r
-//        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {\r
-//             \r
-//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
-//             \r
-//             if (providers != null) {\r
-//     \r
-//                 for (VirtualGraph provider : providers) {\r
-//     \r
-//                     Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
-//                     if (value != null) {\r
-//                         procedure.execute(graph, (byte[])value);\r
-//                         return;\r
-//                     }\r
-//     \r
-//                 }\r
-//     \r
-//             }\r
-//             \r
-//             try {\r
-//                     \r
-//                     byte[] data = cluster.getValue(resource, clusterSupport);\r
-//                     if (null == data || 0 == data.length) {\r
-//                         procedure.execute(graph, null);\r
-//                     } else {\r
-//                         procedure.execute(graph, data);\r
-//                     }\r
-//                     \r
-//             } catch (DatabaseException e) {\r
-//                 Logger.defaultLogError(e);\r
-//             }\r
-//             \r
-//        } else {\r
-//\r
-//             try {\r
-//                     \r
-//                     byte[] data = cluster.getValue(resource, clusterSupport);\r
-//                     if (null == data || 0 == data.length) {\r
-//                         procedure.execute(graph, null);\r
-//                     } else {\r
-//                         procedure.execute(graph, data);\r
-//                     }\r
-//                     \r
-//             } catch (DatabaseException e) {\r
-//                 Logger.defaultLogError(e);\r
-//             }\r
-//\r
-//        }\r
-//\r
-//    }\r
-\r
-\r
-    @Override\r
-    public byte[] getValue(ReadGraphImpl graph, int resource) {\r
-\r
-       if(resource < 0) {\r
-       \r
-               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
-               \r
-               if (providers != null) {\r
-       \r
-                   for (VirtualGraph provider : providers) {\r
-       \r
-                       Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
-                       if (value != null) {\r
-                               return (byte[])value;\r
-                       }\r
-       \r
-                   }\r
-       \r
-               }\r
-               \r
-               return null;\r
-        \r
-       }\r
-       \r
-       ClusterI cluster = clusterTable.getClusterByResourceKey(resource);\r
-        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {\r
-               \r
-               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
-               \r
-               if (providers != null) {\r
-       \r
-                   for (VirtualGraph provider : providers) {\r
-       \r
-                       Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
-                       if (value != null) {\r
-                               return (byte[])value;\r
-                       }\r
-       \r
-                   }\r
-       \r
-               }\r
-               \r
-               try {\r
-                       \r
-                       byte[] data = cluster.getValue(resource, clusterSupport);\r
-                       if (null != data && 0 != data.length) {\r
-                               return data;\r
-                       }\r
-                       \r
-               } catch (DatabaseException e) {\r
-                   Logger.defaultLogError(e);\r
-               }\r
-               \r
-               return null;\r
-               \r
-        } else {\r
-\r
-               try {\r
-                       \r
-                       byte[] data = cluster.getValue(resource, clusterSupport);\r
-                       if (null != data && 0 != data.length) {\r
-                               return data;\r
-                       }\r
-                       \r
-               } catch (DatabaseException e) {\r
-                   Logger.defaultLogError(e);\r
-               }\r
-               \r
-               return null;\r
-\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    public InputStream getValueStream(ReadGraphImpl graph, int resource) {\r
-\r
-        if(resource < 0) {\r
-        \r
-            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
-            \r
-            if (providers != null) {\r
-    \r
-                for (VirtualGraph provider : providers) {\r
-    \r
-                    Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
-                    if (value != null) {\r
-                        return new ByteArrayInputStream((byte[])value);\r
-                    }\r
-    \r
-                }\r
-    \r
-            }\r
-            \r
-            return null;\r
-        \r
-        }\r
-        \r
-        ClusterI cluster = clusterTable.getClusterByResourceKey(resource);\r
-        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {\r
-            \r
-            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);\r
-            \r
-            if (providers != null) {\r
-    \r
-                for (VirtualGraph provider : providers) {\r
-    \r
-                    Object value = ((VirtualGraphImpl)provider).getValue(resource);\r
-                    if (value != null) {\r
-                        return new ByteArrayInputStream((byte[])value);\r
-                    }\r
-    \r
-                }\r
-    \r
-            }\r
-            \r
-            try {\r
-                \r
-                return cluster.getValueStream(resource, clusterSupport);\r
-                \r
-            } catch (DatabaseException e) {\r
-                Logger.defaultLogError(e);\r
-            }\r
-            \r
-            return null;\r
-            \r
-        } else {\r
-\r
-            try {\r
-                \r
-                return cluster.getValueStream(resource, clusterSupport);\r
-                \r
-            } catch (DatabaseException e) {\r
-                Logger.defaultLogError(e);\r
-            }\r
-            \r
-            return null;\r
-\r
-        }\r
-\r
-    }\r
-    \r
-    @Override\r
-    public void requestCluster(ReadGraphImpl graph, final long clusterId, final Runnable r) {\r
-\r
-        class CallbackAdapter implements Callback<DatabaseException> {\r
-               final Runnable r;\r
-               CallbackAdapter(final Runnable r) {\r
-                       this.r = r;\r
-               }\r
-               @Override\r
-               public void run(DatabaseException e) {\r
-                       if (null != e)\r
-                               e.printStackTrace();\r
-                       else\r
-                               r.run();\r
-               }\r
-               \r
-        }\r
-       \r
-        double p = clusterTable.getLoadProbability();\r
-// System.out.print("Load cluster " + clusterId + " with probability " + p +\r
-        // " -> ");\r
-        final ClusterI proxy = clusterSupport.getClusterByClusterId(clusterId);\r
-        if (!proxy.isLoaded()) {\r
-               clusterTable.gc();\r
-            if (Math.random() < p) {\r
-                proxy.load(new CallbackAdapter(r));\r
-            } else {\r
-                r.run();\r
-            }\r
-        } else {\r
-            r.run();\r
-        }\r
-\r
-    }\r
-\r
-    @Override\r
-    public int getBuiltin(String uri) {\r
-       return builtinSupport.getBuiltin(uri);\r
-    }\r
-\r
-    @Override\r
-    public void checkTasks() {\r
-        System.out.println(syncThreads.toString());\r
-    }\r
-\r
-//    @Override\r
-//    public void asyncWrite(Write request) {\r
-//        \r
-////           if(plainWrite(writer) && sameProvider(request)) {\r
-////                   writer.writeSupport.pushRequest(request);\r
-////           } else {\r
-//             asyncRequest(request);\r
-////           }\r
-//        \r
-//    }\r
-\r
-    /*\r
-     * Helpers\r
-     * \r
-     * \r
-     */\r
-    \r
-    private void doGetStatements(ReadGraphImpl graph, final ClusterI cluster, final int subject, final DirectStatementsImpl result) {\r
-\r
-        final class Proc implements ClusterI.PredicateProcedure<Object> {\r
-\r
-                       @Override\r
-                       public boolean execute(Object context, final int predicate, final int objectIndex) {\r
-                               \r
-                               doExecute(null, predicate, objectIndex);\r
-                               return false;\r
-                               \r
-                       }\r
-\r
-                       private void doExecute(Object context, final int predicate, final int objectIndex) {\r
-\r
-                               try {\r
-                                       cluster.forObjects(subject, predicate, new ClusterI.ObjectProcedure<Object>() {\r
-\r
-                                               @Override\r
-                                               public boolean execute(Object context, int object) {\r
-                                                       result.addStatement(predicate, object);\r
-                                                       return false;\r
-                                               }\r
-\r
-                                       }, null, clusterSupport);\r
-                               } catch (DatabaseException e) {\r
-                                       e.printStackTrace();\r
-                               }\r
-                               \r
-                       }\r
-               \r
-        }\r
-\r
-        try {\r
-                       cluster.forPredicates(subject, new Proc(), null, clusterSupport);\r
-               } catch (DatabaseException e) {\r
-                       e.printStackTrace();\r
-               }\r
-       \r
-    }\r
-    \r
-//     private void getDirectObjects4(final int callerThread, final ClusterI cluster, final int subject, final int predicate, final QueryProcessor processor, final ReadGraphImpl graph, final ForEachObjectProcedure procedure) {\r
-//\r
-//        if(!cluster.isLoaded()) {\r
-//\r
-//                     requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {\r
-//     \r
-//                             @Override\r
-//                             public void run(Integer i) {\r
-//     \r
-//                                     processor.schedule(i, new SessionTask(callerThread) {\r
-//     \r
-//                                             @Override\r
-//                                             public void run(int thread) {\r
-//                                                     \r
-//                                                     getDirectObjects4(thread, cluster, subject, predicate, processor, graph, procedure);\r
-//                                                     \r
-//                                             }\r
-//     \r
-//                                     });\r
-//     \r
-//                             }\r
-//     \r
-//                     });\r
-//                     \r
-//        } else {\r
-//\r
-//             try {\r
-//                     cluster.forObjects(graph, subject, predicate, procedure);\r
-//             } catch (DatabaseException e) {\r
-//                     e.printStackTrace();\r
-//             }\r
-//             \r
-////                   procedure.finished(graph);\r
-////                   graph.state.barrier.dec();\r
-////                   \r
-////            System.err.println("ai2=" + ai2.decrementAndGet());\r
-//             \r
-//        }\r
-//             \r
-//             \r
-//     }\r
-\r
-//     AtomicInteger ai2  =new AtomicInteger(0);\r
-       \r
-//    private boolean testCluster(int subject, ClusterI proxy) {\r
-//     \r
-//        if (proxy == null)\r
-//            System.out.println("null cluster: " + Integer.toString(subject, 16));\r
-//        \r
-//        return proxy != null;\r
-//     \r
-//    }\r
-\r
-    long getCluster(int id) {\r
-       // Virtual resource\r
-       if(id < 0) return 0;\r
-       ClusterI proxy = clusterTable.getClusterByResourceKey(id);\r
-       if(proxy == null) return 0;\r
-       else return proxy.getClusterId();\r
-    }\r
-\r
-       @Override\r
-       public int getRandomAccessReference(String id) throws ResourceNotFoundException {\r
-               \r
-               try {\r
-                       Resource res = serializationSupport.getResourceSerializer().getResource(id);\r
-                       if(res == null) return 0;\r
-                       else return ((ResourceImpl)res).id;\r
-               } catch (InvalidResourceReferenceException e) {\r
-                       //e.printStackTrace();\r
-               }\r
-               return 0;\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void ensureLoaded(final ReadGraphImpl graph, final int subject, final int predicate) {\r
-               \r
-               if(subject < 0) {\r
-                       \r
-                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
-                               @Override\r
-                               public void run(ReadGraphImpl parameter) {\r
-                               }\r
-                               \r
-                       });\r
-                       \r
-               } else {\r
-                       \r
-               final ClusterI cluster = clusterTable.checkedGetClusterByResourceKey(subject);\r
-\r
-               if(cluster.isLoaded()) {\r
-                       \r
-                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {\r
-\r
-                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
-                                               @Override\r
-                                               public void run(ReadGraphImpl parameter) {\r
-                                               }\r
-                                               \r
-                                       });\r
-                               \r
-                               } else {\r
-                                       \r
-                               }\r
-                       \r
-               } else {\r
-                       \r
-                               new Exception().printStackTrace();\r
-                       \r
-                       cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
-                                       @Override\r
-                                       public void run() {\r
-                                               \r
-                                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {\r
-\r
-                                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {\r
-\r
-                                                               @Override\r
-                                                               public void run(ReadGraphImpl parameter) {\r
-                                                               }\r
-                                                               \r
-                                                       });\r
-                                               \r
-                                               } else {\r
-                                                       \r
-                                               }\r
-                                               \r
-                                       }\r
-                               \r
-                       });\r
-                       \r
-               }\r
-               \r
-               \r
-               }\r
-               \r
-       }\r
-       \r
-       @Override\r
-       public void ensureLoaded(final ReadGraphImpl graph, final int subject) {\r
-               \r
-               if(subject < 0) {\r
-                       \r
-                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
-                               @Override\r
-                               public void run(ReadGraphImpl parameter) {\r
-                               }\r
-                               \r
-                       });\r
-                       \r
-               } else {\r
-                       \r
-               final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-\r
-               if(cluster.isLoaded()) {\r
-                       \r
-                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {\r
-\r
-                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
-                                               @Override\r
-                                               public void run(ReadGraphImpl parameter) {\r
-                                               }\r
-                                               \r
-                                       });\r
-                               \r
-                               } else {\r
-                                       \r
-                               }\r
-                       \r
-               } else {\r
-                       \r
-//                     System.err.println("cluster not loaded " + subject);\r
-                               new Exception().printStackTrace();\r
-                       \r
-                       cluster.load(session.clusterTranslator, new Runnable() {\r
-\r
-                                       @Override\r
-                                       public void run() {\r
-                                               \r
-                                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {\r
-\r
-                                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {\r
-\r
-                                                               @Override\r
-                                                               public void run(ReadGraphImpl parameter) {\r
-                                                               }\r
-                                                               \r
-                                                       });\r
-                                               \r
-                                               } else {\r
-                                                       \r
-                                               }\r
-                                               \r
-                                       }\r
-                               \r
-                       });\r
-                       \r
-               }\r
-               \r
-               \r
-               }\r
-               \r
-       }\r
-\r
-       @Override\r
-       public boolean isLoaded(int subject) {\r
-       ClusterI cluster = clusterTable.getClusterByResourceKey(subject);\r
-       return cluster.isLoaded();\r
-       }\r
-       \r
-       @Override\r
-       public void ceased(int thread) {\r
-               \r
-               session.ceased(thread);\r
-               \r
-       }\r
-\r
-    @Override\r
-    public Object getLock() {\r
-        \r
-        return session.requestManager;\r
-        \r
-    }\r
-\r
-    @Override\r
-    public VirtualGraph getProvider(int subject, int predicate, int object) {\r
-\r
-       if(subject > 0) {\r
-            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
-               // This persistent resource does not have virtual statements => must deny in persistent graph\r
-               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;\r
-       }\r
-       \r
-       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-               for (final int id : g.getObjects(subject, predicate)) {\r
-                       if(object == id) return g;\r
-               }\r
-       }\r
-       \r
-       // Nothing found from virtual graphs\r
-       return null;\r
-               \r
-    }\r
-\r
-    @Override\r
-    public VirtualGraph getProvider(int subject, int predicate) {\r
-\r
-       if(subject > 0) {\r
-            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
-               // This persistent resource does not have virtual statements => must deny in persistent graph\r
-               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;\r
-       }\r
-\r
-       TransientGraph result = null;\r
-       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-               if(g.getObjects(subject, predicate).length > 0) {\r
-                       // Found multiple, return null;\r
-                       if(result != null) return null;\r
-                       else result = g;\r
-               }\r
-       }\r
-       return result;\r
-               \r
-    }\r
-\r
-    @Override\r
-    public VirtualGraph getValueProvider(int subject) {\r
-\r
-       if(subject > 0) {\r
-            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);\r
-               // This persistent resource does not have virtual statements => must deny in persistent graph\r
-               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;\r
-       }\r
-\r
-       TransientGraph result = null;\r
-       for(TransientGraph g : virtualGraphServerSupport.providers) {\r
-               if(g.getValue(subject) != null) {\r
-                       if(result != null) return null;\r
-                       else result = g;\r
-               }\r
-       }\r
-       return result;\r
-               \r
-    }\r
-    \r
-    @Override\r
-    public void exit(Throwable t) {\r
-       state.close();\r
-    }\r
-    \r
-    private void analyseProblem(ClusterI cluster) {\r
-       \r
-       if(cluster instanceof ClusterSmall)\r
-                       try {\r
-                               ((ClusterSmall)cluster).check();\r
-                       } catch (DatabaseException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-       \r
-    }\r
-    \r
-}\r
+package fi.vtt.simantics.procore.internal;
+
+import gnu.trove.set.hash.TIntHashSet;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Collection;
+
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.StandardStatement;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.InvalidResourceReferenceException;
+import org.simantics.db.exception.ResourceNotFoundException;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.ClusterSupport;
+import org.simantics.db.impl.ForEachObjectContextProcedure;
+import org.simantics.db.impl.ForEachObjectProcedure;
+import org.simantics.db.impl.ResourceImpl;
+import org.simantics.db.impl.TransientGraph;
+import org.simantics.db.impl.VirtualGraphImpl;
+import org.simantics.db.impl.graph.ReadGraphImpl;
+import org.simantics.db.impl.query.IntProcedure;
+import org.simantics.db.impl.query.QueryProcessor;
+import org.simantics.db.impl.query.QuerySupport;
+import org.simantics.db.impl.support.BuiltinSupport;
+import org.simantics.db.impl.support.ResourceSupport;
+import org.simantics.db.procore.cluster.ClusterImpl;
+import org.simantics.db.procore.cluster.ClusterSmall;
+import org.simantics.db.service.SerialisationSupport;
+import org.simantics.utils.DataContainer;
+import org.simantics.utils.datastructures.Callback;
+
+public class QuerySupportImpl implements QuerySupport {
+       
+       final SessionImplSocket session;
+       final State state;
+       final ClusterTable clusterTable;
+       final BuiltinSupport builtinSupport;
+       final ClusterSupport clusterSupport;
+       final ResourceSupport resourceSupport;
+       final SerialisationSupport serializationSupport;
+       final VirtualGraphServerSupportImpl virtualGraphServerSupport;
+       final GraphSession graphSession;
+       final SessionRequestManager syncThreads;
+       final int root;
+
+    private boolean pendingPrimitives = false;
+       
+       QuerySupportImpl(SessionImplSocket session, ClusterSupport clusterSupport, SerialisationSupport serializationSupport, SessionRequestManager syncThreads) {
+               this.session = session;
+               this.state = session.state;
+               this.clusterTable = session.clusterTable;
+               this.resourceSupport = session.resourceSupport;
+               this.virtualGraphServerSupport = session.virtualGraphServerSupport;
+               this.graphSession = session.graphSession;
+               this.builtinSupport = session.builtinSupport;
+               this.clusterSupport = clusterSupport;
+               this.serializationSupport = serializationSupport;
+               this.syncThreads = syncThreads;
+               this.root = getBuiltin("http:/");
+               assert(this.session != null);
+               assert(this.state != null);
+               assert(this.clusterTable != null);
+               assert(this.resourceSupport != null);
+               assert(this.virtualGraphServerSupport != null);
+               assert(this.graphSession != null);
+               assert(this.builtinSupport != null);
+               assert(this.clusterSupport != null);
+               assert(this.serializationSupport != null);
+               assert(this.syncThreads != null);
+       }
+
+       @Override
+       public ResourceSupport getSupport() {
+               return resourceSupport;
+       }
+       
+    @Override
+    public Statement getStatement(int s, int p, int o) {
+        return getStatement(null, s, p, o);
+    }
+
+    @Override
+    public Statement getStatement(ReadGraphImpl graph, int s, int p, int o) {
+        Resource sr = getResource(s);
+        Resource pr = getResource(p);
+        Resource or = getResource(o);
+        return new StandardStatement(sr, pr, or);
+    }
+
+       @Override
+       public Session getSession() {
+               return session;
+       }
+
+    @Override
+    public long getClusterId(int id) {
+       ClusterI cluster = clusterTable.getClusterByResourceKey(id);
+       if(cluster == null) return 0;
+       return cluster.getClusterId();
+    }
+    
+    @Override
+    public boolean isImmutable(int id) {
+       // Virtuals are mutable
+       if(id < 0) return false;
+       // Root library is mutable
+       if(root == id) return false;
+       // Anything goes in service mode
+       if(session.serviceMode > 0) return false;
+       return clusterTable.isImmutable(id);
+    }
+
+    @Override
+    public int getId(Resource resource) {
+        if (resource instanceof ResourceImpl)
+            return ((ResourceImpl)resource).id;
+        return 0;
+    }
+
+       @Override
+       public Resource getResource(int id) {
+               try {
+                       return serializationSupport.getResource(id);
+               } catch (DatabaseException e) {
+                       e.printStackTrace();
+               }
+               return null;
+       }
+
+       @Override
+    public boolean resume(ReadGraphImpl graph) {
+               
+               return syncThreads.session.queryProvider2.resume(graph);
+               
+    }
+
+//    @Override
+//    final public void sync(int resumeThread, final SessionRunnable runnable) {
+//     
+//     syncThreads.session.queryProvider2.schedule(Integer.MIN_VALUE, new SessionTask(resumeThread) {
+//
+//                     @Override
+//                     public void run(int thread) {
+//                             runnable.run(thread);
+//                     }
+//             
+//     });
+//     
+//    }
+
+//    @Override
+//    final public int nextSyncThread() {
+//     throw new Error();
+////        return syncThreads.nextThread();
+//    }
+
+       @Override
+    public void dirtyPrimitives() {
+        session.dirtyPrimitives = true;
+        if(state.getWriteCount() == 0 && !pendingPrimitives) {
+            pendingPrimitives = true;
+            session.asyncRequest(new WriteRequest() {
+
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    pendingPrimitives = false;
+                }
+                
+            });
+        }
+    }
+
+    @Override
+    @Deprecated
+    final public void aboutToRead() {
+    }
+
+//    @Override
+//    public void increaseReferenceCount(int callerThread, int subject) {
+//        if (subject < 0)
+//            return;
+//        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);
+//        if (null == proxy)
+//            return;
+//        proxy.increaseReferenceCount(callerThread, 1);
+//    }
+//
+//    @Override
+//    public void decreaseReferenceCount(int callerThread, int subject) {
+//        if (subject < 0)
+//            return;
+//        ClusterProxy proxy = clusterTable.getClusterByResourceKey(subject);
+//        if (null == proxy)
+//            return;
+//        proxy.decreaseReferenceCount(callerThread, 1);
+//    }
+
+//     @Override
+       public void getObjects4(final ReadGraphImpl graph, final int subject, final ForEachObjectProcedure procedure) {
+               
+               if(subject < 0) {
+                       
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {
+
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);
+//                    if(graph.callerThread == suggestSchedule) {
+                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));
+//                    } else {
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
+//             
+//                             @Override
+//                             public void run(int thread) {
+//                             procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));
+//                             }
+//             
+//                     });
+//                    }
+                       
+                }
+                       }
+                       procedure.finished(graph);
+//             graph.dec();
+               return;
+               
+               } 
+               
+        final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
+        if(!cluster.isLoaded()) {
+               cluster.load(session.clusterTranslator, new Runnable() {
+
+                               @Override
+                               public void run() {
+                                       getObjects4(graph, subject, procedure);
+                               }
+                       
+               });
+               return;
+        }
+               
+               if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
+                       
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);
+//                    if(graph.callerThread == suggestSchedule) {
+                       procedure.execute(graph, new ResourceImpl(resourceSupport, id));
+//                    } else {
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
+//             
+//                             @Override
+//                             public void run(int thread) {
+//                             procedure.execute(graph.newAsync(thread), new ResourceImpl(resourceSupport, id));
+//                             }
+//             
+//                     });
+//                    }
+                }
+                       }
+                       
+                       try {
+                               cluster.forObjects(graph, subject, procedure);
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       }
+                       
+               } else {
+                       
+                       try {
+                               cluster.forObjects(graph, subject, procedure);
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       }
+                       
+               }
+               
+       }
+
+       public <C> void getObjects4(final ReadGraphImpl graph, final int subject, final C context, final ForEachObjectContextProcedure<C> procedure) {
+               
+               if(subject < 0) {
+                       
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {
+
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);
+//                    if(graph.callerThread == suggestSchedule) {
+                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
+//                    } else {
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
+//             
+//                             @Override
+//                             public void run(int thread) {
+//                             procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));
+//                             }
+//             
+//                     });
+//                    }
+                       
+                }
+                       }
+                       procedure.finished(graph, context);
+//             graph.dec();
+               return;
+               
+               } 
+               
+        final ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
+        if(!cluster.isLoaded()) {
+               cluster.load(session.clusterTranslator, new Runnable() {
+
+                               @Override
+                               public void run() {
+                                       getObjects4(graph, subject, context, procedure);
+                               }
+                       
+               });
+               return;
+        }
+               
+               if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
+                       
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {
+                for (final int id : g.getObjects(subject, procedure.predicateKey)) {
+//                    int suggestSchedule = graph.processor.processor.resourceThread(id);
+//                    if(graph.callerThread == suggestSchedule) {
+                       procedure.execute(graph, context, new ResourceImpl(resourceSupport, id));
+//                    } else {
+//                     graph.processor.processor.schedule(graph.callerThread, new SessionTask(suggestSchedule) {
+//             
+//                             @Override
+//                             public void run(int thread) {
+//                             procedure.execute(graph.newAsync(thread), context, new ResourceImpl(resourceSupport, id));
+//                             }
+//             
+//                     });
+//                    }
+                }
+                       }
+                       
+                       try {
+                               cluster.forObjects(graph, subject, context, procedure);
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       }
+                       
+               } else {
+                       
+                       try {
+                               cluster.forObjects(graph, subject, context, procedure);
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       }
+                       
+               }
+               
+       }
+       
+       @Override
+    public int getSingleInstance(final int subject) {
+       
+       // Do not process this information for virtual resources
+       if(subject < 0) return 0;
+       
+        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+        if (cluster == null)
+            System.out.println("null cluster: " + Integer.toString(subject, 16));
+        assert (cluster != null);
+
+        try {
+        
+               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);
+               if(ClusterI.CompleteTypeEnum.InstanceOf == type) {
+                       int result = cluster.getCompleteObjectKey(subject, clusterSupport);
+                       assert(result > 0);
+                       return result;
+               } else {
+                       return 0;
+               }
+        
+        } catch (DatabaseException e) {
+               
+               Logger.defaultLogError(e);
+               return 0;
+               
+        }
+        // This happens is the resource is bogus
+        catch (Throwable t) {
+               
+               analyseProblem(cluster);
+               
+               Logger.defaultLogError(t);
+               
+               return 0;
+               
+        }
+       
+    }
+
+       @Override
+    public int getSingleSuperrelation(final int subject) {
+       
+       // Do not process this information for virtual resources
+       if(subject < 0) return 0;
+
+       final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+        if (cluster == null)
+            System.out.println("null cluster: " + Integer.toString(subject, 16));
+        assert (cluster != null);
+
+        try {
+        
+               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(subject, clusterSupport);
+               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
+                       int result = cluster.getCompleteObjectKey(subject, clusterSupport);
+                       assert(result > 0);
+                       return result;
+               } else {
+                       return 0;
+               }
+        
+        } catch (DatabaseException e) {
+               
+               Logger.defaultLogError(e);
+               return 0;
+               
+        }
+       
+    }
+
+//     @Override
+//    public void getSingleSuperrelation(ReadGraphImpl graph, final int subject, final AsyncProcedure<Resource> procedure) {
+//     
+//     // Do not process this information for virtual resources
+//     if(subject < 0) {
+//             procedure.execute(graph, null);
+//                     graph.state.barrier.dec();
+//             return;
+//     }
+//
+//     final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+//        if (cluster == null)
+//            System.out.println("null cluster: " + Integer.toString(subject, 16));
+//        
+//        assert (cluster != null);
+//
+//        if(!cluster.isLoaded()) {
+//            
+//             procedure.execute(graph, null);
+//                     graph.state.barrier.dec();
+//             return;
+//
+////           queryProvider2.requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {
+////   
+////                           @Override
+////                           public void run(Integer i) {
+////   
+////                                   queryProvider2.schedule(i, callerThread, new Runnable() {
+////   
+////                                           @Override
+////                                           public void run() {
+////                                                   
+////                                                   try  {
+////                                                   
+////                                               ClusterI.CompleteTypeEnum type = cluster.getCompleteType(callerThread, subject, SessionImplSocket.this);
+////                                               if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
+////                                                   int result = cluster.getCompleteObjectKey(callerThread, subject, SessionImplSocket.this);
+////                                                   assert(result > 0);
+////                                                   procedure.execute(graph, getResourceByKey(result));
+////                                               } else {
+////                                                   procedure.execute(graph, null);
+////                                               }
+////                                                           graph.state.barrier.dec();
+////                                                           
+////                                                   } catch (DatabaseException e) {
+////                                                           e.printStackTrace();
+////                                                   }
+////                                                   
+////                                           }
+////   
+////                                   });
+////   
+////                           }
+////   
+////                   });
+//                     
+//        } else {
+//
+//             try {
+//
+//                     ClusterI.CompleteTypeEnum type = cluster.getCompleteType(graph.callerThread, subject, clusterSupport);
+//                     if(ClusterI.CompleteTypeEnum.SubrelationOf == type) {
+//                             int result = cluster.getCompleteObjectKey(graph.callerThread, subject, clusterSupport);
+//                             assert(result > 0);
+//                             procedure.execute(graph, new ResourceImpl(resourceSupport, result));
+//                     } else {
+//                             procedure.execute(graph, null);
+//                     }
+//                     graph.state.barrier.dec();
+//
+//             } catch (DatabaseException e) {
+//                     e.printStackTrace();
+//             }
+//                     
+//        }
+//        
+//        
+//    }
+
+//     @Override
+//    public void getObjects2(final int callerThread, final int subject, final int predicate, final IntProcedure procedure) {
+//             ensureLoaded(callerThread, subject, predicate, new Runnable() {
+//
+//                     @Override
+//                     public void run() {
+//                             safeGetObjects2(callerThread, subject, predicate, procedure);
+//                     }
+//                     
+//             });
+//     }
+
+//    public void safeGetObjects2(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {
+//
+//        assert (subject != 0);
+//        assert (predicate != 0);
+////        System.out.println("getObjects2: s=" + subject + "p=" + predicate);
+//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+//        if (providers != null) {
+//
+//            final TIntHashSet result = new TIntHashSet(16);
+//
+//            for (VirtualGraph provider : providers) {
+//
+//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
+//
+//                    if (result.add(id)) {
+//                     procedure.execute(graph, id);
+//                    }
+//
+//                }
+//
+//            }
+//
+//            if (subject < 0)
+//                return;
+//
+//            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+//
+//            assert (testCluster(subject, cluster));
+//            
+//            // wheels within wheels
+//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
+//
+//                @Override
+//                public boolean execute(int callerThread, Object context, int object) {
+//
+//                    if (result.add(object)) {
+//                     procedure.execute(graph.newAsync(callerThread), object);
+//                    }
+//
+//                    return false; // continue looping
+//
+//                }
+//                
+//                             @Override
+//                             public boolean found() {
+//                                     throw new UnsupportedOperationException();
+//                             }
+//                
+//            };
+//
+//            try {
+//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
+//            } catch (DatabaseException e) {
+//                Logger.defaultLogError(e);
+//            } catch (Throwable t) {
+//                Logger.defaultLogError(t);
+//             t.printStackTrace();
+//            }
+//            return;
+//            
+//        }
+//        
+//        assert(subject > 0);
+//
+//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+//
+//        assert (testCluster(subject, cluster));
+//        
+//        try {
+//            cluster.forObjects(graph.callerThread, subject, predicate, new Wheels(procedure), null, clusterSupport);
+//        } catch (DatabaseException e) {
+//            Logger.defaultLogError(e);
+//        } catch (Throwable t) {
+//             t.printStackTrace();
+//            Logger.defaultLogError(t);
+//        }
+//        
+//    }
+
+       @Override
+    public boolean getObjects(final ReadGraphImpl graph, final int subject, final int predicate, final IntProcedure procedure) {
+               
+               assert (subject != 0);
+               assert (predicate != 0);
+
+               if(subject < 0) {
+
+                       boolean found = false;
+                       
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {
+                               for (final int id : g.getObjects(subject, predicate)) {
+                                       found = true;
+                                       procedure.execute(graph, id);
+                               }
+                       }
+                       
+                       return found;
+
+               }
+
+               final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+               assert(cluster.isLoaded());
+        
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
+               
+               final DataContainer<Boolean> found = new DataContainer<Boolean>(Boolean.FALSE);
+               final TIntHashSet result = new TIntHashSet(5);
+               
+                       for(TransientGraph g : virtualGraphServerSupport.providers) {
+                               for (final int id : g.getObjects(subject, predicate)) {
+
+                                       found.set(true);
+                                       if (result.add(id)) {
+                                               procedure.execute(graph, id);
+                                       }
+
+                               }
+                       }
+                       
+                       // Virtual predicates are not found from persistent clusters
+                       if(predicate < 0) return found.get();
+
+               // wheels within wheels
+               final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
+
+                       @Override
+                       public boolean execute(Object context, int object) {
+
+                               found.set(true);
+                               if (result.add(object)) {
+                                       procedure.execute(graph, object);
+                               }
+
+                               return false; // continue looping
+
+                       }
+
+               };
+                       
+                       try {
+                cluster.forObjects(subject, predicate, proc, null, clusterSupport);
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       }
+                       
+                       return found.get();
+                       
+               } else {
+                       
+                       // Virtual predicates are not found from persistent clusters
+                       if(predicate < 0) return false;
+                       
+                       class A implements ClusterI.ObjectProcedure<Object> {
+
+                       boolean found = false;
+
+                       @Override
+                       public boolean execute(Object context, int object) {
+
+                               found = true;
+                               procedure.execute(graph, object);
+
+                               return false; // continue looping
+
+                       }
+
+                               public boolean found() {
+                                       return found;
+                               }
+
+                       }
+                       
+               // wheels within wheels
+               final A proc = new A();
+               
+                       try {
+                cluster.forObjects(subject, predicate, proc, null, clusterSupport);
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       } 
+                       // This happens if resource is bogus
+                       catch (Throwable t) {
+                               
+                       analyseProblem(cluster);
+                       
+                       Logger.defaultLogError(t);
+                               
+                       }
+               
+               return proc.found();
+                       
+               }
+        
+    }
+
+//     @Override
+//    public boolean getFunctionalObject(final ReadGraphImpl graph, final int subject, final int predicate,
+//            final IntProcedure procedure) {
+//
+//        assert (subject != 0);
+//        assert (predicate != 0);
+//
+//        if(subject < 0) {
+//
+//             boolean found = false;
+//
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+//             if (providers != null) {
+//
+//                     for (VirtualGraph provider : providers) {
+//
+//                             for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
+//                                     found = true;
+//                     procedure.execute(graph, id);
+//                    }
+//
+//                }
+//
+//            }
+//             
+//             return found;
+//             
+//        }
+//        
+//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+//        
+//        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
+//        
+//             final DataContainer<Boolean> found = new DataContainer<Boolean>(false);
+//             final TIntHashSet result = new TIntHashSet(5);
+//
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+//             if (providers != null) {
+//
+//                     for (VirtualGraph provider : providers) {
+//
+//                             for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
+//                                     found.set(true);
+//                     procedure.execute(graph, id);
+//                    }
+//
+//                }
+//
+//            }
+//             
+//            // wheels within wheels
+//            final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
+//
+//                @Override
+//                public boolean execute(int callerThread, Object context, int object) {
+//
+//                    found.set(true);
+//                    System.out.println("-found object " + object);
+//                    if (result.add(object)) {
+//                     procedure.execute(graph.newAsync(callerThread), object);
+//                    }
+//
+//                    return false; // continue looping
+//
+//                }
+//                
+//                             @Override
+//                             public boolean found() {
+//                                     throw new UnsupportedOperationException();
+//                             }
+//                
+//            };
+//            
+//            try {
+//                cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
+//            } catch (DatabaseException e) {
+//                Logger.defaultLogError(e);
+//                return false;
+//            } catch (Throwable t) {
+//                Logger.defaultLogError(t);
+//             t.printStackTrace();
+//            }
+//            
+//            return found.get();
+//            
+//        } else {
+//
+//             // wheels within wheels
+//             final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
+//                 
+//                     boolean found = false;
+//                     
+//                 @Override
+//                 public boolean execute(int callerThread, Object context, int object) {
+//     
+//                     found = true;
+//                     procedure.execute(graph.newAsync(callerThread), object);
+//                     return false; // continue looping
+//                     
+//                 }
+//                 
+//                             @Override
+//                             public boolean found() {
+//                                     return found;
+//                             }
+//                 
+//                 @Override
+//                 public String toString() {
+//                     return "Wheels for " + procedure;
+//                 }
+//                 
+//             };
+//             
+//             try {
+//                 cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
+//             } catch (DatabaseException e) {
+//                 Logger.defaultLogError(e);
+//                 return false;
+//             } catch (Throwable t) {
+//                     t.printStackTrace();
+//                 Logger.defaultLogError(t);
+//                 return false;
+//             }
+//             
+//             return proc.found();
+//        
+//        }
+//        
+//    }
+       
+       @Override
+    public int getFunctionalObject(final int subject, final int predicate) {
+
+        assert (subject != 0);
+        assert (predicate != 0);
+
+        if(subject < 0) {
+
+               int found = 0;
+
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+               if (providers != null) {
+
+                       for (VirtualGraph provider : providers) {
+
+                               for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
+                                       if(found == 0) found = id;
+                                       else found = -1;
+                    }
+
+                }
+
+            }
+               
+               return found;
+//             if(found == -1) return 0;
+//             else return found;
+               
+        }
+        
+        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+        
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject)) {
+
+               int result = 0;
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+               if (providers != null) {
+
+                       for (VirtualGraph provider : providers) {
+
+                               for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
+                                       if(result == 0) result = id;
+                                       else result = -1;
+                    }
+
+                }
+
+            }
+               
+               if(result != 0) return result; 
+            
+               try {
+                               return cluster.getSingleObject(subject, predicate, clusterSupport);
+                       } catch (DatabaseException e) {
+                               return -1;
+                       }
+            
+        } else {
+
+               try {
+                               return cluster.getSingleObject(subject, predicate, clusterSupport);
+                       } catch (DatabaseException e) {
+                               return -1;
+                       }
+               // This comes if the resource is bogus
+               catch (Throwable t) {
+                       
+               analyseProblem(cluster);
+               
+               Logger.defaultLogError(t);
+                       
+                               return -1;
+                               
+                       }
+        
+        }
+        
+    }
+
+//     @Override
+//    public boolean getStatements(final ReadGraphImpl graph, final int subject, final int predicate,
+//            final TripleIntProcedure procedure, final Statements entry) {
+//
+//        assert (subject != 0);
+//        assert (predicate != 0);
+//
+//        final TIntHashSet result = new TIntHashSet(16);
+//        final DataContainer<Boolean> found = new DataContainer<Boolean>(false);
+//
+//        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+//        
+//        if (providers != null) {
+//
+//            for (VirtualGraph provider : providers) {
+//
+//                for (int id : ((VirtualGraphImpl)provider).getObjects(subject, predicate)) {
+//
+//                    found.set(true);
+//
+//                    if (result.add(id)) {
+//                        if (null != entry) {
+//                            entry.addOrSet(subject, predicate, id);
+//                            procedure.execute(graph, subject, predicate, id);
+//                            return true; // break;
+//                        } else {
+//                            procedure.execute(graph, subject, predicate, id);
+//                        }
+//                    }
+//
+//                }
+//
+//            }
+//
+//        }
+//
+//        if (subject < 0)
+//            return found.get();
+//
+//        final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+//        assert (cluster != null);
+//
+//        // wheels within wheels
+//        final ClusterI.ObjectProcedure<Object> proc = new ClusterI.ObjectProcedure<Object>() {
+//            @Override
+//            public boolean execute(int callerThread, Object context, int object) {
+//
+//                found.set(true);
+//
+//                if (result.add(object)) {
+//                    if (null != entry) {
+//                        entry.addOrSet(subject, predicate, object);
+//                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);
+//                        return true; // break;
+//                    } else {
+//                        procedure.execute(graph.newAsync(callerThread), subject, predicate, object);
+//                    }
+//                }
+//
+//                return false; // continue looping
+//
+//            }
+//            
+//                     @Override
+//                     public boolean found() {
+//                             throw new UnsupportedOperationException();
+//                     }
+//            
+//        };
+//
+//        try {
+//            cluster.forObjects(graph.callerThread, subject, predicate, proc, null, clusterSupport);
+//        } catch (DatabaseException e) {
+//            Logger.defaultLogError(e);
+//        }
+//        return found.get();
+//
+//    }
+
+       @Override
+    public org.simantics.db.DirectStatements getStatements(final ReadGraphImpl graph, final int subject, final QueryProcessor processor, boolean ignoreVirtual) {
+
+        assert (subject != 0);
+
+        final DirectStatementsImpl result = new DirectStatementsImpl(resourceSupport, subject);
+
+        if (!ignoreVirtual) {
+            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+            if (providers != null) {
+                for (TransientGraph provider : providers) {
+                    for (int p : provider.getPredicates(subject)) {
+                        for (int o : provider.getObjects(subject, p)) {
+                            result.addStatement(p, o);
+                        }
+                    }
+                }
+            }
+        }
+
+        if (subject < 0) {
+               return result;
+        } else {
+            final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+            assert (cluster != null);
+            doGetStatements(graph, cluster, subject, result);
+        }
+        
+        return result;
+
+    }
+
+//    @Override
+//    public void getStatements(ReadGraphImpl graph, final int subject, final Procedure<DirectStatements> procedure) {
+//     
+//             procedure.exception(new DatabaseException("Not supported"));
+//             
+//    }
+
+    @Override
+    public void getPredicates(final ReadGraphImpl graph, final int subject, final IntProcedure procedure) {
+
+        final TIntHashSet result = new TIntHashSet(16);
+
+        Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(subject);
+        
+        if (providers != null) {
+
+            for (VirtualGraph provider : providers) {
+
+                for (int id : ((VirtualGraphImpl)provider).getPredicates(subject)) {
+
+                    if (result.add(id)) {
+                        procedure.execute(graph, id);
+                    }
+
+                }
+
+            }
+
+        }
+
+        if (subject < 0) {
+            procedure.finished(graph);
+            return;
+        }
+
+        ClusterI proxy = clusterTable.getClusterByResourceKey(subject);
+//        if(!proxy.isLoaded()) {
+//             
+//             proxy.load(callerThread, session, new Runnable() {
+//
+//                             @Override
+//                             public void run() {
+//                                     getPredicates(callerThread, subject, procedure);
+//                             }
+//                     
+//             });
+//             return;
+//             
+//        }
+        assert (proxy != null);
+
+        final DataContainer<Integer> got = new DataContainer<Integer>(0);
+        ClusterI.PredicateProcedure<Object> proc = new ClusterI.PredicateProcedure<Object>() {
+            @Override
+            public boolean execute(Object context, int predicate, int oi) {
+                if (result.add(predicate)) {
+                    procedure.execute(graph, predicate);
+                }
+                got.set(got.get() + 1);
+                return false; // continue looping
+            }
+        };
+        try {
+            proxy.forPredicates(subject, proc, null, clusterSupport);
+        } catch (DatabaseException e) {
+            Logger.defaultLogError(e);
+        }
+        procedure.finished(graph);
+
+    }
+    
+    
+
+//    @Override
+//    public void getValue(ReadGraphImpl graph, int resource, InternalProcedure<byte[]> procedure) {
+//
+//     if(resource < 0) {
+//     
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
+//             
+//             if (providers != null) {
+//     
+//                 for (VirtualGraph provider : providers) {
+//     
+//                     Object value = ((VirtualGraphImpl)provider).getValue(resource);
+//                     if (value != null) {
+//                         procedure.execute(graph, (byte[])value);
+//                         return;
+//                     }
+//     
+//                 }
+//     
+//             }
+//             
+//             return;
+//        
+//     }
+//     
+//     ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
+//        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
+//             
+//             Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
+//             
+//             if (providers != null) {
+//     
+//                 for (VirtualGraph provider : providers) {
+//     
+//                     Object value = ((VirtualGraphImpl)provider).getValue(resource);
+//                     if (value != null) {
+//                         procedure.execute(graph, (byte[])value);
+//                         return;
+//                     }
+//     
+//                 }
+//     
+//             }
+//             
+//             try {
+//                     
+//                     byte[] data = cluster.getValue(resource, clusterSupport);
+//                     if (null == data || 0 == data.length) {
+//                         procedure.execute(graph, null);
+//                     } else {
+//                         procedure.execute(graph, data);
+//                     }
+//                     
+//             } catch (DatabaseException e) {
+//                 Logger.defaultLogError(e);
+//             }
+//             
+//        } else {
+//
+//             try {
+//                     
+//                     byte[] data = cluster.getValue(resource, clusterSupport);
+//                     if (null == data || 0 == data.length) {
+//                         procedure.execute(graph, null);
+//                     } else {
+//                         procedure.execute(graph, data);
+//                     }
+//                     
+//             } catch (DatabaseException e) {
+//                 Logger.defaultLogError(e);
+//             }
+//
+//        }
+//
+//    }
+
+
+    @Override
+    public byte[] getValue(ReadGraphImpl graph, int resource) {
+
+       if(resource < 0) {
+       
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
+               
+               if (providers != null) {
+       
+                   for (VirtualGraph provider : providers) {
+       
+                       Object value = ((VirtualGraphImpl)provider).getValue(resource);
+                       if (value != null) {
+                               return (byte[])value;
+                       }
+       
+                   }
+       
+               }
+               
+               return null;
+        
+       }
+       
+       ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
+               
+               Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
+               
+               if (providers != null) {
+       
+                   for (VirtualGraph provider : providers) {
+       
+                       Object value = ((VirtualGraphImpl)provider).getValue(resource);
+                       if (value != null) {
+                               return (byte[])value;
+                       }
+       
+                   }
+       
+               }
+               
+               try {
+                       
+                       byte[] data = cluster.getValue(resource, clusterSupport);
+                       if (null != data && 0 != data.length) {
+                               return data;
+                       }
+                       
+               } catch (DatabaseException e) {
+                   Logger.defaultLogError(e);
+               }
+               
+               return null;
+               
+        } else {
+
+               try {
+                       
+                       byte[] data = cluster.getValue(resource, clusterSupport);
+                       if (null != data && 0 != data.length) {
+                               return data;
+                       }
+                       
+               } catch (DatabaseException e) {
+                   Logger.defaultLogError(e);
+               }
+               
+               return null;
+
+        }
+
+    }
+
+    @Override
+    public InputStream getValueStream(ReadGraphImpl graph, int resource) {
+
+        if(resource < 0) {
+        
+            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
+            
+            if (providers != null) {
+    
+                for (VirtualGraph provider : providers) {
+    
+                    Object value = ((VirtualGraphImpl)provider).getValue(resource);
+                    if (value != null) {
+                        return new ByteArrayInputStream((byte[])value);
+                    }
+    
+                }
+    
+            }
+            
+            return null;
+        
+        }
+        
+        ClusterI cluster = clusterTable.getClusterByResourceKey(resource);
+        if (cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(resource)) {
+            
+            Collection<TransientGraph> providers = virtualGraphServerSupport.getVirtualGraphs(resource);
+            
+            if (providers != null) {
+    
+                for (VirtualGraph provider : providers) {
+    
+                    Object value = ((VirtualGraphImpl)provider).getValue(resource);
+                    if (value != null) {
+                        return new ByteArrayInputStream((byte[])value);
+                    }
+    
+                }
+    
+            }
+            
+            try {
+                
+                return cluster.getValueStream(resource, clusterSupport);
+                
+            } catch (DatabaseException e) {
+                Logger.defaultLogError(e);
+            }
+            
+            return null;
+            
+        } else {
+
+            try {
+                
+                return cluster.getValueStream(resource, clusterSupport);
+                
+            } catch (DatabaseException e) {
+                Logger.defaultLogError(e);
+            }
+            
+            return null;
+
+        }
+
+    }
+    
+    @Override
+    public void requestCluster(ReadGraphImpl graph, final long clusterId, final Runnable r) {
+
+        class CallbackAdapter implements Callback<DatabaseException> {
+               final Runnable r;
+               CallbackAdapter(final Runnable r) {
+                       this.r = r;
+               }
+               @Override
+               public void run(DatabaseException e) {
+                       if (null != e)
+                               e.printStackTrace();
+                       else
+                               r.run();
+               }
+               
+        }
+       
+        double p = clusterTable.getLoadProbability();
+// System.out.print("Load cluster " + clusterId + " with probability " + p +
+        // " -> ");
+        final ClusterI proxy = clusterSupport.getClusterByClusterId(clusterId);
+        if (!proxy.isLoaded()) {
+               clusterTable.gc();
+            if (Math.random() < p) {
+                proxy.load(new CallbackAdapter(r));
+            } else {
+                r.run();
+            }
+        } else {
+            r.run();
+        }
+
+    }
+
+    @Override
+    public int getBuiltin(String uri) {
+       return builtinSupport.getBuiltin(uri);
+    }
+
+    @Override
+    public void checkTasks() {
+        System.out.println(syncThreads.toString());
+    }
+
+//    @Override
+//    public void asyncWrite(Write request) {
+//        
+////           if(plainWrite(writer) && sameProvider(request)) {
+////                   writer.writeSupport.pushRequest(request);
+////           } else {
+//             asyncRequest(request);
+////           }
+//        
+//    }
+
+    /*
+     * Helpers
+     * 
+     * 
+     */
+    
+    private void doGetStatements(ReadGraphImpl graph, final ClusterI cluster, final int subject, final DirectStatementsImpl result) {
+
+        final class Proc implements ClusterI.PredicateProcedure<Object> {
+
+                       @Override
+                       public boolean execute(Object context, final int predicate, final int objectIndex) {
+                               
+                               doExecute(null, predicate, objectIndex);
+                               return false;
+                               
+                       }
+
+                       private void doExecute(Object context, final int predicate, final int objectIndex) {
+
+                               try {
+                                       cluster.forObjects(subject, predicate, new ClusterI.ObjectProcedure<Object>() {
+
+                                               @Override
+                                               public boolean execute(Object context, int object) {
+                                                       result.addStatement(predicate, object);
+                                                       return false;
+                                               }
+
+                                       }, null, clusterSupport);
+                               } catch (DatabaseException e) {
+                                       e.printStackTrace();
+                               }
+                               
+                       }
+               
+        }
+
+        try {
+                       cluster.forPredicates(subject, new Proc(), null, clusterSupport);
+               } catch (DatabaseException e) {
+                       e.printStackTrace();
+               }
+       
+    }
+    
+//     private void getDirectObjects4(final int callerThread, final ClusterI cluster, final int subject, final int predicate, final QueryProcessor processor, final ReadGraphImpl graph, final ForEachObjectProcedure procedure) {
+//
+//        if(!cluster.isLoaded()) {
+//
+//                     requestCluster(callerThread, cluster.getClusterId(), new Callback<Integer>() {
+//     
+//                             @Override
+//                             public void run(Integer i) {
+//     
+//                                     processor.schedule(i, new SessionTask(callerThread) {
+//     
+//                                             @Override
+//                                             public void run(int thread) {
+//                                                     
+//                                                     getDirectObjects4(thread, cluster, subject, predicate, processor, graph, procedure);
+//                                                     
+//                                             }
+//     
+//                                     });
+//     
+//                             }
+//     
+//                     });
+//                     
+//        } else {
+//
+//             try {
+//                     cluster.forObjects(graph, subject, predicate, procedure);
+//             } catch (DatabaseException e) {
+//                     e.printStackTrace();
+//             }
+//             
+////                   procedure.finished(graph);
+////                   graph.state.barrier.dec();
+////                   
+////            System.err.println("ai2=" + ai2.decrementAndGet());
+//             
+//        }
+//             
+//             
+//     }
+
+//     AtomicInteger ai2  =new AtomicInteger(0);
+       
+//    private boolean testCluster(int subject, ClusterI proxy) {
+//     
+//        if (proxy == null)
+//            System.out.println("null cluster: " + Integer.toString(subject, 16));
+//        
+//        return proxy != null;
+//     
+//    }
+
+    long getCluster(int id) {
+       // Virtual resource
+       if(id < 0) return 0;
+       ClusterI proxy = clusterTable.getClusterByResourceKey(id);
+       if(proxy == null) return 0;
+       else return proxy.getClusterId();
+    }
+
+       @Override
+       public int getRandomAccessReference(String id) throws ResourceNotFoundException {
+               
+               try {
+                       Resource res = serializationSupport.getResourceSerializer().getResource(id);
+                       if(res == null) return 0;
+                       else return ((ResourceImpl)res).id;
+               } catch (InvalidResourceReferenceException e) {
+                       //e.printStackTrace();
+               }
+               return 0;
+               
+       }
+       
+       @Override
+       public void ensureLoaded(final ReadGraphImpl graph, final int subject, final int predicate) {
+               
+               if(subject < 0) {
+                       
+                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {
+
+                               @Override
+                               public void run(ReadGraphImpl parameter) {
+                               }
+                               
+                       });
+                       
+               } else {
+                       
+               final ClusterI cluster = clusterTable.checkedGetClusterByResourceKey(subject);
+
+               if(cluster.isLoaded()) {
+                       
+                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {
+
+                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {
+
+                                               @Override
+                                               public void run(ReadGraphImpl parameter) {
+                                               }
+                                               
+                                       });
+                               
+                               } else {
+                                       
+                               }
+                       
+               } else {
+                       
+                               new Exception().printStackTrace();
+                       
+                       cluster.load(session.clusterTranslator, new Runnable() {
+
+                                       @Override
+                                       public void run() {
+                                               
+                                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject, predicate)) {
+
+                                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, predicate, new Callback<ReadGraphImpl>() {
+
+                                                               @Override
+                                                               public void run(ReadGraphImpl parameter) {
+                                                               }
+                                                               
+                                                       });
+                                               
+                                               } else {
+                                                       
+                                               }
+                                               
+                                       }
+                               
+                       });
+                       
+               }
+               
+               
+               }
+               
+       }
+       
+       @Override
+       public void ensureLoaded(final ReadGraphImpl graph, final int subject) {
+               
+               if(subject < 0) {
+                       
+                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {
+
+                               @Override
+                               public void run(ReadGraphImpl parameter) {
+                               }
+                               
+                       });
+                       
+               } else {
+                       
+               final ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+
+               if(cluster.isLoaded()) {
+                       
+                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {
+
+                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {
+
+                                               @Override
+                                               public void run(ReadGraphImpl parameter) {
+                                               }
+                                               
+                                       });
+                               
+                               } else {
+                                       
+                               }
+                       
+               } else {
+                       
+//                     System.err.println("cluster not loaded " + subject);
+                               new Exception().printStackTrace();
+                       
+                       cluster.load(session.clusterTranslator, new Runnable() {
+
+                                       @Override
+                                       public void run() {
+                                               
+                                       if(cluster.hasVirtual() && virtualGraphServerSupport.virtuals.contains(subject) && !SessionImplSocket.areVirtualStatementsLoaded(virtualGraphServerSupport, subject)) {
+
+                                                       SessionImplSocket.loadVirtualStatements(virtualGraphServerSupport, graph, subject, new Callback<ReadGraphImpl>() {
+
+                                                               @Override
+                                                               public void run(ReadGraphImpl parameter) {
+                                                               }
+                                                               
+                                                       });
+                                               
+                                               } else {
+                                                       
+                                               }
+                                               
+                                       }
+                               
+                       });
+                       
+               }
+               
+               
+               }
+               
+       }
+
+       @Override
+       public boolean isLoaded(int subject) {
+       ClusterI cluster = clusterTable.getClusterByResourceKey(subject);
+       return cluster.isLoaded();
+       }
+       
+       @Override
+       public void ceased(int thread) {
+               
+               session.ceased(thread);
+               
+       }
+
+    @Override
+    public Object getLock() {
+        
+        return session.requestManager;
+        
+    }
+
+    @Override
+    public VirtualGraph getProvider(int subject, int predicate, int object) {
+
+       if(subject > 0) {
+            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
+               // This persistent resource does not have virtual statements => must deny in persistent graph
+               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
+       }
+       
+       for(TransientGraph g : virtualGraphServerSupport.providers) {
+               for (final int id : g.getObjects(subject, predicate)) {
+                       if(object == id) return g;
+               }
+       }
+       
+       // Nothing found from virtual graphs
+       return null;
+               
+    }
+
+    @Override
+    public VirtualGraph getProvider(int subject, int predicate) {
+
+       if(subject > 0) {
+            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
+               // This persistent resource does not have virtual statements => must deny in persistent graph
+               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
+       }
+
+       TransientGraph result = null;
+       for(TransientGraph g : virtualGraphServerSupport.providers) {
+               if(g.getObjects(subject, predicate).length > 0) {
+                       // Found multiple, return null;
+                       if(result != null) return null;
+                       else result = g;
+               }
+       }
+       return result;
+               
+    }
+
+    @Override
+    public VirtualGraph getValueProvider(int subject) {
+
+       if(subject > 0) {
+            ClusterImpl cluster = (ClusterImpl)clusterTable.getClusterByResourceKey(subject);
+               // This persistent resource does not have virtual statements => must deny in persistent graph
+               if(!cluster.hasVirtual() || !virtualGraphServerSupport.virtuals.contains(subject)) return null;
+       }
+
+       TransientGraph result = null;
+       for(TransientGraph g : virtualGraphServerSupport.providers) {
+               if(g.getValue(subject) != null) {
+                       if(result != null) return null;
+                       else result = g;
+               }
+       }
+       return result;
+               
+    }
+    
+    @Override
+    public void exit(Throwable t) {
+       state.close();
+    }
+    
+    private void analyseProblem(ClusterI cluster) {
+       
+       if(cluster instanceof ClusterSmall)
+                       try {
+                               ((ClusterSmall)cluster).check();
+                       } catch (DatabaseException e) {
+                               e.printStackTrace();
+                       }
+       
+    }
+    
+}