]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.db.impl/src/org/simantics/db/impl/graph/ReadGraphImpl.java
Attempt to fix regressions in new code base
[simantics/platform.git] / bundles / org.simantics.db.impl / src / org / simantics / db / impl / graph / ReadGraphImpl.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2018 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.db.impl.graph;
13
14 import java.io.BufferedOutputStream;
15 import java.io.File;
16 import java.io.FileOutputStream;
17 import java.io.IOException;
18 import java.io.PrintStream;
19 import java.lang.reflect.Array;
20 import java.lang.reflect.InvocationTargetException;
21 import java.nio.BufferUnderflowException;
22 import java.util.ArrayList;
23 import java.util.Collection;
24 import java.util.Collections;
25 import java.util.HashSet;
26 import java.util.IdentityHashMap;
27 import java.util.Iterator;
28 import java.util.List;
29 import java.util.ListIterator;
30 import java.util.Map;
31 import java.util.Set;
32 import java.util.function.Consumer;
33
34 import org.eclipse.core.runtime.Platform;
35 import org.simantics.databoard.Accessors;
36 import org.simantics.databoard.Bindings;
37 import org.simantics.databoard.accessor.Accessor;
38 import org.simantics.databoard.accessor.error.AccessorConstructionException;
39 import org.simantics.databoard.adapter.AdaptException;
40 import org.simantics.databoard.binding.Binding;
41 import org.simantics.databoard.binding.error.RuntimeBindingConstructionException;
42 import org.simantics.databoard.binding.impl.ObjectVariantBinding;
43 import org.simantics.databoard.binding.mutable.Variant;
44 import org.simantics.databoard.serialization.Serializer;
45 import org.simantics.databoard.type.Datatype;
46 import org.simantics.databoard.util.binary.BinaryFile;
47 import org.simantics.databoard.util.binary.RandomAccessBinary;
48 import org.simantics.db.AsyncReadGraph;
49 import org.simantics.db.DevelopmentKeys;
50 import org.simantics.db.ExternalValueSupport;
51 import org.simantics.db.ReadGraph;
52 import org.simantics.db.RelationContext;
53 import org.simantics.db.Resource;
54 import org.simantics.db.Session;
55 import org.simantics.db.Statement;
56 import org.simantics.db.adaption.AdaptionService;
57 import org.simantics.db.common.primitiverequest.Adapter;
58 import org.simantics.db.common.primitiverequest.Builtin;
59 import org.simantics.db.common.primitiverequest.DatatypeBinding;
60 import org.simantics.db.common.primitiverequest.ForEachAssertedObject;
61 import org.simantics.db.common.primitiverequest.ForEachAssertedStatement;
62 import org.simantics.db.common.primitiverequest.HasStatement;
63 import org.simantics.db.common.primitiverequest.HasStatementSubject;
64 import org.simantics.db.common.primitiverequest.HasStatementSubjectObject;
65 import org.simantics.db.common.primitiverequest.HasValue;
66 import org.simantics.db.common.primitiverequest.Inverse;
67 import org.simantics.db.common.primitiverequest.IsInheritedFrom;
68 import org.simantics.db.common.primitiverequest.IsInstanceOf;
69 import org.simantics.db.common.primitiverequest.IsSubrelationOf;
70 import org.simantics.db.common.primitiverequest.OrderedSet;
71 import org.simantics.db.common.primitiverequest.PossibleAdapter;
72 import org.simantics.db.common.primitiverequest.PossibleInverse;
73 import org.simantics.db.common.primitiverequest.PossibleObject;
74 import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
75 import org.simantics.db.common.primitiverequest.PossibleRelatedValueImplied;
76 import org.simantics.db.common.primitiverequest.PossibleStatement;
77 import org.simantics.db.common.primitiverequest.PossibleType;
78 import org.simantics.db.common.primitiverequest.PossibleUniqueAdapter;
79 import org.simantics.db.common.primitiverequest.PossibleValue;
80 import org.simantics.db.common.primitiverequest.PossibleValueImplied;
81 import org.simantics.db.common.primitiverequest.RelatedValue;
82 import org.simantics.db.common.primitiverequest.RelatedValueImplied;
83 import org.simantics.db.common.primitiverequest.SingleObject;
84 import org.simantics.db.common.primitiverequest.SingleStatement;
85 import org.simantics.db.common.primitiverequest.SingleType;
86 import org.simantics.db.common.primitiverequest.SingleTypeAny;
87 import org.simantics.db.common.primitiverequest.Types;
88 import org.simantics.db.common.primitiverequest.UniqueAdapter;
89 import org.simantics.db.common.primitiverequest.Value;
90 import org.simantics.db.common.primitiverequest.ValueImplied;
91 import org.simantics.db.common.primitiverequest.VariantValueImplied;
92 import org.simantics.db.common.procedure.adapter.AsyncMultiProcedureAdapter;
93 import org.simantics.db.common.procedure.adapter.AsyncProcedureAdapter;
94 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
95 import org.simantics.db.common.procedure.adapter.SyncMultiProcedureAdapter;
96 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
97 import org.simantics.db.common.procedure.adapter.TransientCacheListener;
98 import org.simantics.db.common.procedure.single.SyncReadProcedure;
99 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrErrorProcedure;
100 import org.simantics.db.common.procedure.single.wrapper.DeepSingleOrNullProcedure;
101 import org.simantics.db.common.procedure.single.wrapper.ExceptionToNullProcedure;
102 import org.simantics.db.common.procedure.single.wrapper.NullSingleOrNullProcedure;
103 import org.simantics.db.common.procedure.single.wrapper.SingleFunctionalOrNullProcedure;
104 import org.simantics.db.common.procedure.single.wrapper.SingleOrErrorProcedure;
105 import org.simantics.db.common.procedure.single.wrapper.SingleOrNullProcedure;
106 import org.simantics.db.common.procedure.wrapper.NoneToAsyncListener;
107 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiListener;
108 import org.simantics.db.common.procedure.wrapper.NoneToAsyncMultiProcedure;
109 import org.simantics.db.common.procedure.wrapper.NoneToAsyncProcedure;
110 import org.simantics.db.common.procedure.wrapper.NoneToAsyncSetProcedure;
111 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiListener;
112 import org.simantics.db.common.procedure.wrapper.NoneToSyncMultiProcedure;
113 import org.simantics.db.common.procedure.wrapper.SyncToAsyncListener;
114 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiListener;
115 import org.simantics.db.common.procedure.wrapper.SyncToAsyncMultiProcedure;
116 import org.simantics.db.common.procedure.wrapper.SyncToAsyncProcedure;
117 import org.simantics.db.common.procedure.wrapper.SyncToAsyncSetProcedure;
118 import org.simantics.db.common.request.AdaptValue;
119 import org.simantics.db.common.request.ResourceRead;
120 import org.simantics.db.common.utils.Logger;
121 import org.simantics.db.common.utils.NameUtils;
122 import org.simantics.db.common.validation.L0Validations;
123 import org.simantics.db.exception.AdaptionException;
124 import org.simantics.db.exception.ArgumentException;
125 import org.simantics.db.exception.AssumptionException;
126 import org.simantics.db.exception.BindingException;
127 import org.simantics.db.exception.DatabaseException;
128 import org.simantics.db.exception.DoesNotContainValueException;
129 import org.simantics.db.exception.EmptyResourceException;
130 import org.simantics.db.exception.InternalException;
131 import org.simantics.db.exception.InvalidLiteralException;
132 import org.simantics.db.exception.ManyObjectsForFunctionalRelationException;
133 import org.simantics.db.exception.NoInverseException;
134 import org.simantics.db.exception.NoSingleResultException;
135 import org.simantics.db.exception.ResourceNotFoundException;
136 import org.simantics.db.exception.ServiceException;
137 import org.simantics.db.exception.ValidationException;
138 import org.simantics.db.impl.BlockingAsyncProcedure;
139 import org.simantics.db.impl.RelationContextImpl;
140 import org.simantics.db.impl.ResourceImpl;
141 import org.simantics.db.impl.internal.RandomAccessValueSupport;
142 import org.simantics.db.impl.internal.ResourceData;
143 import org.simantics.db.impl.procedure.ResultCallWrappedSyncQueryProcedure;
144 import org.simantics.db.impl.query.CacheEntry;
145 import org.simantics.db.impl.query.QueryCache;
146 import org.simantics.db.impl.query.QueryCacheBase;
147 import org.simantics.db.impl.query.QueryProcessor;
148 import org.simantics.db.impl.query.QueryProcessor.SessionTask;
149 import org.simantics.db.impl.query.QuerySupport;
150 import org.simantics.db.impl.query.TripleIntProcedure;
151 import org.simantics.db.impl.support.ResourceSupport;
152 import org.simantics.db.procedure.AsyncListener;
153 import org.simantics.db.procedure.AsyncMultiListener;
154 import org.simantics.db.procedure.AsyncMultiProcedure;
155 import org.simantics.db.procedure.AsyncProcedure;
156 import org.simantics.db.procedure.AsyncSetListener;
157 import org.simantics.db.procedure.Listener;
158 import org.simantics.db.procedure.ListenerBase;
159 import org.simantics.db.procedure.MultiListener;
160 import org.simantics.db.procedure.MultiProcedure;
161 import org.simantics.db.procedure.Procedure;
162 import org.simantics.db.procedure.SetListener;
163 import org.simantics.db.procedure.StatementProcedure;
164 import org.simantics.db.procedure.SyncListener;
165 import org.simantics.db.procedure.SyncMultiListener;
166 import org.simantics.db.procedure.SyncMultiProcedure;
167 import org.simantics.db.procedure.SyncProcedure;
168 import org.simantics.db.procedure.SyncSetListener;
169 import org.simantics.db.request.AsyncMultiRead;
170 import org.simantics.db.request.AsyncRead;
171 import org.simantics.db.request.DelayedWrite;
172 import org.simantics.db.request.DelayedWriteResult;
173 import org.simantics.db.request.ExternalRead;
174 import org.simantics.db.request.MultiRead;
175 import org.simantics.db.request.Read;
176 import org.simantics.db.request.ReadInterface;
177 import org.simantics.db.request.Write;
178 import org.simantics.db.request.WriteInterface;
179 import org.simantics.db.request.WriteOnly;
180 import org.simantics.db.request.WriteOnlyResult;
181 import org.simantics.db.request.WriteResult;
182 import org.simantics.layer0.Layer0;
183 import org.simantics.scl.compiler.types.Type;
184 import org.simantics.scl.compiler.types.exceptions.SCLTypeParseException;
185 import org.simantics.scl.reflection.ReflectionUtils;
186 import org.simantics.scl.reflection.ValueNotFoundException;
187 import org.simantics.scl.runtime.function.Function3;
188 import org.simantics.utils.DataContainer;
189 import org.simantics.utils.Development;
190 import org.simantics.utils.datastructures.Pair;
191 import org.simantics.utils.datastructures.collections.CollectionUtils;
192 import org.slf4j.LoggerFactory;
193
194 import gnu.trove.map.hash.TObjectIntHashMap;
195
196 public class ReadGraphImpl implements AsyncReadGraph {
197
198     private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(ReadGraphImpl.class);
199
200     final static boolean EMPTY_RESOURCE_CHECK = false;
201     
202         final public CacheEntry parent;
203         public final ReadGraphImpl parentGraph;
204         final public QueryProcessor processor;
205         
206         public final AsyncBarrierImpl asyncBarrier;
207         
208         final static Binding DATA_TYPE_BINDING_INTERNAL = Bindings.getBindingUnchecked(Datatype.class);
209         final static Serializer DATA_TYPE_SERIALIZER = Bindings.getSerializerUnchecked(DATA_TYPE_BINDING_INTERNAL);
210
211         final public static TObjectIntHashMap<String> counters = new TObjectIntHashMap<String>(); 
212         
213         public static void resetCounters() {
214                 counters.clear();
215         }
216         
217         public static String listCounters(File file) throws IOException {
218                 
219                 PrintStream b = new PrintStream(new BufferedOutputStream(new FileOutputStream(file)));
220
221                 for(Pair<String,Integer> p : CollectionUtils.valueSortedEntries(counters)) {
222                         b.print(-p.second + " " + p.first + "\n");
223                 }
224
225                 b.close();
226
227                 return "Dumped " + counters.size() + " queries.";
228                 
229         }
230         
231         /*
232          * Implementation of the interface ReadGraph
233          */
234         final public String getURI(final Resource resource)     throws AssumptionException, ValidationException, ServiceException {
235                 
236                 assert (resource != null);
237
238                 try {
239
240                         return syncRequest(new org.simantics.db.common.uri.ResourceToURI(resource));
241
242                 } catch (AssumptionException e) {
243
244                         throw new AssumptionException(e);
245
246                 } catch (ValidationException e) {
247
248                         throw new ValidationException(e);
249
250                 } catch (ServiceException e) {
251
252                         throw new ServiceException(e);
253
254                 } catch (DatabaseException e) {
255
256                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
257
258                 }
259
260         }
261         
262         final public String getPossibleURI(final Resource resource)     throws ValidationException,     ServiceException {
263
264                 assert (resource != null);
265
266                 try {
267
268                         return syncRequest(new org.simantics.db.common.uri.ResourceToPossibleURI(resource));
269
270                 } catch (ValidationException e) {
271
272                         throw new ValidationException(e);
273
274                 } catch (ServiceException e) {
275
276                         throw new ServiceException(e);
277
278                 } catch (DatabaseException e) {
279
280                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
281
282                 }
283
284         }
285
286         final public Resource getResource(final String id)
287                         throws ResourceNotFoundException, ValidationException,
288                         ServiceException {
289
290                 assert (id != null);
291
292                 try {
293
294                         Integer rid = QueryCache.resultURIToResource(this, id, parent, null);
295                         // FIXME: stupid to throw this here and catch and wrap it right away
296                         if(rid == 0) throw new ResourceNotFoundException(id);
297                         return processor.querySupport.getResource(rid);
298
299                 } catch (ResourceNotFoundException e) {
300
301                         throw new ResourceNotFoundException(id, e);
302
303                 } catch (ValidationException e) {
304
305                         throw new ValidationException(e);
306
307                 } catch (ServiceException e) {
308
309                         throw new ServiceException(e);
310
311                 } catch (DatabaseException e) {
312
313                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
314
315                 }
316
317         }
318
319         final public Resource getPossibleResource(final String id)
320         throws ResourceNotFoundException, ValidationException,
321         ServiceException {
322
323                 assert (id != null);
324
325                 try {
326
327                         return getResource(id);
328
329                 } catch (ResourceNotFoundException e) {
330                         
331                         return null;
332
333                 } catch (ValidationException e) {
334
335                         throw new ValidationException(e);
336
337                 } catch (ServiceException e) {
338
339                         throw new ServiceException(e);
340
341                 } catch (DatabaseException e) {
342
343                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
344
345                 }
346
347         }
348         
349         @Override
350         public Map<String, Resource> getChildren(Resource resource) throws ValidationException, ServiceException {
351                 
352                 assert (resource != null);
353
354                 try {
355
356                         int rId = processor.querySupport.getId(resource);
357                         return QueryCache.resultChildMap(this, rId, parent, null);
358
359                 } catch (ValidationException e) {
360
361                         throw new ValidationException(e);
362
363                 } catch (ServiceException e) {
364
365                         throw new ServiceException(e);
366
367                 } catch (DatabaseException e) {
368
369                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
370
371                 }
372                 
373         }
374
375         final public Resource getRootLibrary() {
376                 return processor.getRootLibraryResource();
377         }
378         
379         final public Resource getBuiltin(final String id)
380                         throws ResourceNotFoundException, ServiceException {
381
382                 assert (id != null);
383
384                 try {
385
386                         return syncRequest(new Builtin(id));
387
388                 } catch (ResourceNotFoundException e) {
389
390                         throw new ResourceNotFoundException(id, e);
391
392                 } catch (ServiceException e) {
393
394                         throw new ServiceException(e);
395
396                 } catch (DatabaseException e) {
397
398                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
399
400                 }
401
402         }
403
404         static class StatementReadProcedure extends TIntArrayListInternal implements StatementProcedure {
405
406                 private static Throwable DONE = new Throwable();
407                 
408                 Throwable exception = null;
409                 
410                 final ResourceSupport support;
411                 
412                 public StatementReadProcedure(ResourceSupport support) {
413                         this.support = support;
414                 }
415                 
416                 @Override
417                 public synchronized void execute(AsyncReadGraph graph, int s, int p, int o) {
418                         add(s);
419                         add(p);
420                         add(o);
421                 }
422                 
423                 @Override
424                 public void finished(AsyncReadGraph graph) {
425                         exception = DONE;
426                 }
427
428                 @Override
429                 public void exception(AsyncReadGraph graph, Throwable t) {
430                         exception = t;
431                 }
432                 
433                 public void checkAndThrow() throws DatabaseException {
434                         if(exception != DONE) {
435                                 if (exception instanceof DatabaseException)
436                                         throw (DatabaseException) exception;
437                                 else
438                                         throw new DatabaseException(
439                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
440                                                         exception);
441                         }
442                 }
443                 
444                 public boolean done() {
445                         return exception != null;
446                 }
447
448                 @Override
449                 public boolean contains(Object obj) {
450                     if(!(obj instanceof InternalStatement))
451                         return false;
452                     InternalStatement statement = (InternalStatement)obj;
453                     int s = statement.s;
454                     int p = statement.p;
455                     int o = statement.o;
456                     for(int i=0;i<sizeInternal();i+=3)
457                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
458                     return true;
459                     return false;
460                 }
461
462                 @SuppressWarnings("unchecked")
463         @Override
464                 public <T> T[] toArray(T[] a) {
465                     int length = sizeInternal() / 3;
466                     if(length > a.length) {
467                         Class<?> arrayType = a.getClass();
468                         a = (arrayType == Object[].class) 
469                                 ? (T[]) new Object[length]
470                                 : (T[]) Array.newInstance(arrayType.getComponentType(), length);
471                     }
472                     else {
473                         for(int i=length;i<a.length;++i)
474                             a[i] = null;
475                     }
476             for(int i=0,j=0;i<sizeInternal();i+=3,++j)
477                 a[j] = (T)new InternalStatement(support, getQuick(i), getQuick(i+1), getQuick(i+2));
478             return a;
479                 }
480
481                 @Override
482                 public boolean add(Statement e) {
483                         throw new UnsupportedOperationException();
484                 }
485
486                 @Override
487                 public boolean remove(Object o) {
488                         throw new UnsupportedOperationException();
489                 }
490
491                 @Override
492                 public boolean addAll(Collection<? extends Statement> c) {
493                         throw new UnsupportedOperationException();
494                 }
495
496                 class IteratorImpl implements ListIterator<Statement> {
497             
498             int index;
499             
500             public IteratorImpl(int index) {
501                 this.index = index;
502             }
503
504             @Override
505             public boolean hasNext() {
506                 return index < sizeInternal(); 
507             }
508
509             @Override
510             public Statement next() {
511                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
512                 index += 3;
513                 return result;
514             }
515
516             @Override
517             public void remove() {
518                 throw new Error("Not supported");
519             }
520
521             @Override
522             public boolean hasPrevious() {
523                 return index > 0;
524             }
525
526             @Override
527             public Statement previous() {
528                 index -= 3;
529                 Statement result = new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2)); 
530                 return result;
531             }
532
533             @Override
534             public int nextIndex() {
535                 return index/3;
536             }
537
538             @Override
539             public int previousIndex() {
540                 return index/3-1;
541             }
542
543             @Override
544             public void set(Statement e) {
545                 throw new UnsupportedOperationException();
546             }
547
548             @Override
549             public void add(Statement e) {
550                 throw new UnsupportedOperationException();
551             }
552             
553         };
554         
555                 @Override
556                 public Iterator<Statement> iterator() {
557                         return new IteratorImpl(0);
558                 }
559                 
560                 @Override
561                 public int size() {
562                         return sizeInternal() / 3;
563                 }
564
565                 @Override
566                 public Object[] toArray() {
567                     Object[] result = new Object[sizeInternal() / 3];
568                     for(int i=0,j=0;j<sizeInternal();i++,j+=3)
569                         result[i] = new InternalStatement(support, getQuick(j), getQuick(j+1), getQuick(j+2));
570                         return result;
571                 }
572
573         @Override
574         public boolean addAll(int index, Collection<? extends Statement> c) {
575             throw new UnsupportedOperationException();
576         }
577
578         @Override
579         public Statement get(int index) {
580             index += 3;
581             if(index < 0 || index >= sizeInternal())
582                 throw new IndexOutOfBoundsException();
583             return new InternalStatement(support, getQuick(index), getQuick(index+1), getQuick(index+2));
584         }
585
586         @Override
587         public Statement set(int index, Statement element) {
588             throw new UnsupportedOperationException();
589         }
590
591         @Override
592         public void add(int index, Statement element) {
593             throw new UnsupportedOperationException();
594         }
595
596         @Override
597         public Statement remove(int index) {
598             throw new UnsupportedOperationException();
599         }
600
601         @Override
602         public int indexOf(Object obj) {
603             if(!(obj instanceof InternalStatement))
604                 return -1;
605             InternalStatement statement = (InternalStatement)obj;
606             int s = statement.s;
607             int p = statement.p;
608             int o = statement.o;
609             for(int i=0;i<sizeInternal();i+=3)
610                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
611                     return i/3;
612             return -1;
613         }
614
615         @Override
616         public int lastIndexOf(Object obj) {
617             if(!(obj instanceof InternalStatement))
618                 return -1;
619             InternalStatement statement = (InternalStatement)obj;
620             int s = statement.s;
621             int p = statement.p;
622             int o = statement.o;
623             for(int i=sizeInternal()-3;i>=0;i-=3)
624                 if(s==getQuick(i) && p==getQuick(i+1) && o==getQuick(i+2))
625                     return i/3;
626             return -1;
627         }
628
629         @Override
630         public ListIterator<Statement> listIterator() {
631             return new IteratorImpl(0);
632         }
633
634         @Override
635         public ListIterator<Statement> listIterator(int index) {
636             return new IteratorImpl(index*3);
637         }
638
639         @Override
640         public List<Statement> subList(int fromIndex, int toIndex) {
641             if(fromIndex < 0 || toIndex*3 >= sizeInternal() || fromIndex > toIndex)
642                 throw new IndexOutOfBoundsException();
643             return new RandomAccessSubList<Statement>(this, fromIndex, toIndex-fromIndex);
644         }
645         }
646         
647         @Override
648         final public Collection<Statement> getStatements(final Resource subject,
649                         final Resource relation)
650                         throws ManyObjectsForFunctionalRelationException, ServiceException {
651
652                 assert (subject != null);
653                 assert (relation != null);
654
655                 try {
656
657                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
658                         processor.forEachStatement(this, subject, relation, procedure);
659                         procedure.checkAndThrow();
660                         return procedure;
661                         
662                 } catch (DatabaseException e) {
663
664                         System.err.println(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation);
665
666                         StatementReadProcedure procedure = new StatementReadProcedure(getResourceSupport());
667                         processor.forEachStatement(this, subject, relation, procedure);
668                         
669                         return Collections.emptyList();
670                 
671 //                      throw new ServiceException(INTERNAL_ERROR_STRING + " getStatements " + subject + " " + relation, e);
672
673                 }
674
675         }
676
677         @Override
678         final public Collection<Statement> getAssertedStatements(final Resource subject, final Resource relation)
679                         throws ManyObjectsForFunctionalRelationException, ServiceException {
680
681                 assert (subject != null);
682                 assert (relation != null);
683
684                 try {
685
686                         return syncRequest(new ForEachAssertedStatement(subject, relation));
687
688                 } catch (ManyObjectsForFunctionalRelationException e) {
689
690                         throw new ManyObjectsForFunctionalRelationException(e);
691
692                 } catch (ServiceException e) {
693
694                         throw new ServiceException(e);
695
696                 } catch (DatabaseException e) {
697
698                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
699
700                 }
701
702         }
703
704         @Override
705         final public Collection<Resource> getPredicates(final Resource subject) throws ServiceException {
706
707                 assert (subject != null);
708
709                 try {
710
711                         return processor.getPredicates(this, subject);
712
713 //                      AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
714 //                      processor.forEachPredicate(this, subject, procedure);
715 //                      procedure.checkAndThrow();
716 //                      return procedure;
717
718                 } catch (ServiceException e) {
719
720                         throw new ServiceException(e);
721
722                 } catch (DatabaseException e) {
723
724                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
725
726                 }  catch (Throwable e) {
727
728             throw new ServiceException(e);
729
730                 }
731
732         }
733
734         @Override
735         final public Collection<Resource> getPrincipalTypes(final Resource subject)
736                         throws ServiceException {
737
738                 assert (subject != null);
739
740                 try {
741
742                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
743                         processor.forEachPrincipalType(this, subject, procedure);
744                         procedure.checkAndThrow();
745                         return procedure;
746                         
747                 } catch (ServiceException e) {
748
749                         throw new ServiceException(e);
750
751                 } catch (DatabaseException e) {
752
753                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
754
755                 }
756
757         }
758
759         @Override
760         final public Set<Resource> getTypes(final Resource subject) throws ServiceException {
761
762                 assert (subject != null);
763
764                 try {
765                         
766                         return processor.getTypes(this, subject);
767                         
768                 } catch (ServiceException e) {
769
770                         throw new ServiceException(e);
771                         
772                 } catch (DatabaseException e) {
773
774                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
775
776         } catch (Throwable e) {
777
778             throw new ServiceException(e);
779
780                 }
781
782         }
783
784         @Override
785         final public Set<Resource> getSupertypes(final Resource subject)
786                         throws ServiceException {
787
788                 assert (subject != null);
789
790                 try {
791
792                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
793                         processor.forSupertypes(this, subject, procedure);
794                         procedure.checkAndThrow();
795                         return procedure.result;
796
797                 } catch (ServiceException e) {
798
799                         throw new ServiceException(e);
800
801                 } catch (DatabaseException e) {
802
803                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
804
805                 }
806
807         }
808
809         @Override
810         final public Set<Resource> getSuperrelations(final Resource subject)
811                         throws ServiceException {
812
813                 assert (subject != null);
814
815                 try {
816
817                         SyncReadProcedure<Set<Resource>> procedure = new SyncReadProcedure<Set<Resource>>();
818                         processor.forSuperrelations(this, subject, procedure);
819                         procedure.checkAndThrow();
820                         return procedure.result;
821
822                 } catch (ServiceException e) {
823
824                         throw new ServiceException(e);
825
826                 } catch (DatabaseException e) {
827
828                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
829
830                 }
831
832         }
833         
834         @Override
835         public Resource getPossibleSuperrelation(Resource subject) throws ServiceException {
836                 
837                 try {
838
839                         SyncReadProcedure<Resource> procedure = new SyncReadProcedure<Resource>();
840                         processor.forPossibleSuperrelation(this, subject, procedure);
841                         procedure.checkAndThrow();
842                         return procedure.result;
843
844                 } catch (ServiceException e) {
845
846                         throw new ServiceException(e);
847
848                 } catch (DatabaseException e) {
849
850                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
851
852                 }
853
854         }
855
856         @Override
857         final public Collection<Resource> getObjects(final Resource subject, final Resource relation)
858                         throws ServiceException {
859
860                 assert (subject != null);
861                 assert (relation != null);
862
863                 if(Development.DEVELOPMENT) {
864             if(Development.isTrue(DevelopmentKeys.READGRAPH_COUNT)) {
865                 counters.adjustOrPutValue("objects $" + subject.getResourceId() + " $" + relation.getResourceId(), 1, 1);
866             }
867             //if(subject.getResourceId()==xx && relation.getResourceId()==xx) new Exception().printStackTrace();
868                 }
869                 
870                 try {
871
872                         AsyncMultiReadProcedure<Resource> procedure = new AsyncMultiReadProcedure<Resource>();
873                         processor.forEachObject(this, subject, relation, procedure);
874                         procedure.checkAndThrow();
875                         return procedure;
876                         
877                 } catch (DatabaseException e) {
878
879                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
880
881                 }
882
883         }
884
885         @Override
886         final public Collection<Resource> getAssertedObjects(
887                         final Resource subject, final Resource relation)
888                         throws ManyObjectsForFunctionalRelationException, ServiceException {
889
890         if (subject == null)
891             throw new ArgumentException("Subject must not be null.");
892         if (relation == null)
893             throw new ArgumentException("Relation must not be null. Subject=" + subject);
894
895                 try {
896
897                         return syncRequest(new ForEachAssertedObject(subject, relation));
898
899                 } catch (ManyObjectsForFunctionalRelationException e) {
900
901                         throw new ManyObjectsForFunctionalRelationException(e);
902
903                 } catch (ServiceException e) {
904
905                         throw new ServiceException(e);
906
907                 } catch (DatabaseException e) {
908
909                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
910
911                 }
912
913         }
914
915         @Override
916         final public Resource getInverse(final Resource relation) throws NoInverseException, ServiceException {
917
918                 assert (relation != null);
919
920                 try {
921
922                         return getSingleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
923
924                 } catch (NoSingleResultException e) {
925
926                         throw new NoInverseException(e);
927
928                 } catch (ServiceException e) {
929
930                         throw new ServiceException(e);
931
932                 }
933
934         }
935
936         @Override
937         final public Resource getSingleObject(final Resource subject, final Resource relation) throws NoSingleResultException, ServiceException {
938
939                 if( subject == null) throw new IllegalArgumentException("subject can not be null");
940                 if( relation == null) throw new IllegalArgumentException("relation can not be null");
941
942                 try {
943                         int single = processor.getSingleObject(this, subject, relation);
944                         if (single == 0) {
945                                 if (EMPTY_RESOURCE_CHECK) {
946                                         if (!hasStatement(subject)) {
947                                                 throw new EmptyResourceException("Resource " + debugString(subject));
948                                         }
949                                 }
950                                 throw new NoSingleResultException("No single object for subject " + debugString(subject)
951                                                 + " and relation " + debugString(relation), single);
952                         }
953                         return processor.querySupport.getResource(single);
954                 } catch (NoSingleResultException e) {
955                         throw e;
956                 } catch (DatabaseException e) {
957                         throw new ServiceException(e);
958                 } 
959         }
960
961         @Override
962         final public Statement getSingleStatement(final Resource subject, final Resource relation) throws NoSingleResultException, ManyObjectsForFunctionalRelationException, ServiceException {
963                 assert (subject != null);
964                 assert (relation != null);
965                 try {
966                         Collection<Statement> statements = getStatements(subject, relation);
967                         if (statements.size() == 1) {
968                                 return statements.iterator().next();
969                         } else {
970                                 if (EMPTY_RESOURCE_CHECK)
971                                         if (!hasStatement(subject))
972                                                 throw new EmptyResourceException("Resource " + debugString(subject));
973                                 throw new NoSingleResultException("No single statement for subject " + debugString(subject)
974                                                 + " and relation " + debugString(relation), statements.size());
975                         }
976                 } catch (ServiceException e) {
977                         throw new ServiceException(e);
978                 } 
979         }
980
981         @Override
982         final public Resource getSingleType(final Resource subject) throws NoSingleResultException, ServiceException {
983                 assert (subject != null);
984                 try {
985                         ArrayList<Resource> principalTypes = (ArrayList<Resource>)getPrincipalTypes(subject);
986                         if (principalTypes.size() == 1) {
987                             return principalTypes.get(0);
988                         } else {
989                             throw new NoSingleResultException("No single type for subject " + debugString(subject), principalTypes.size());
990                         }
991                 } catch (ServiceException e) {
992                         throw new ServiceException(e);
993                 } 
994         }
995
996         @Override
997         final public Resource getSingleType(final Resource subject,
998                         final Resource baseType) throws NoSingleResultException,
999                         ServiceException {
1000
1001                 assert (subject != null);
1002                 assert (baseType != null);
1003
1004                 try {
1005                         return syncRequest(new SingleType(subject, baseType));
1006                 } catch (DatabaseException e) {
1007                     throw new NoSingleResultException("subject=" + subject + ", baseType=" + baseType, 0, e);
1008                 }
1009         }
1010
1011         @Override
1012         final public <T> T getValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1013
1014                 assert (subject != null);
1015
1016                 try {
1017
1018                         Layer0 L0 = processor.getL0(this);
1019             int object = processor.getSingleObject(this, subject, L0.HasDataType);
1020             if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1021             
1022             if(processor.isImmutable(object)) {
1023                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1024                         return getValue(subject, binding);
1025             } else {
1026                     byte[] dt = processor.getValue(this, object);
1027                     if(dt == null) throw new ServiceException("No data type for " + subject);
1028                     Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1029                     Binding binding = Bindings.getBinding(datatype);
1030                     return getValue(subject, binding);
1031             }
1032                         
1033         } catch (IOException e) {
1034
1035             throw new ServiceException(e);
1036
1037                 } catch (DoesNotContainValueException e) {
1038
1039                         throw new DoesNotContainValueException(e, subject);
1040
1041                 } catch (ServiceException e) {
1042
1043                         throw new ServiceException(e);
1044
1045                 } catch (DatabaseException e) {
1046
1047                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1048
1049         }
1050
1051         }
1052
1053     @Override
1054     final public Variant getVariantValue(final Resource subject) throws DoesNotContainValueException, ServiceException {
1055
1056         assert (subject != null);
1057
1058         try {
1059
1060             Layer0 L0 = processor.getL0(this);
1061             int object = processor.getSingleObject(this, subject, L0.HasDataType);
1062             if(object == 0) throw new DoesNotContainValueException("No data type for " + subject);
1063             
1064             if(processor.isImmutable(object)) {
1065                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1066                 return new Variant(binding, getValue(subject, binding));
1067             } else {
1068                 byte[] dt = processor.getValue(this, object);
1069                 if(dt == null) throw new ServiceException("No data type for " + subject);
1070                 Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1071                 Binding binding = Bindings.getBinding(datatype);
1072                 return new Variant(binding, getValue(subject, binding));
1073             }
1074             
1075         } catch (IOException e) {
1076
1077             throw new ServiceException(e);
1078
1079         } catch (DoesNotContainValueException e) {
1080
1081             throw new DoesNotContainValueException(e, subject);
1082
1083         } catch (ServiceException e) {
1084
1085             throw new ServiceException(e);
1086
1087         } catch (DatabaseException e) {
1088
1089             throw new ServiceException(INTERNAL_ERROR_STRING, e);
1090
1091         }               
1092         }
1093
1094         static final IdentityHashMap<Binding,Serializer> serializers = new IdentityHashMap<Binding,Serializer>();
1095         
1096         static {
1097                 serializers.put(Bindings.STRING, Bindings.STRING.serializer());
1098         }
1099         
1100         final protected Serializer getSerializer(Binding binding) {
1101             return binding.serializer();
1102         }
1103         
1104         @Override
1105         final public <T> T getValue(final Resource subject, final Binding binding) throws DoesNotContainValueException, BindingException,
1106                         ServiceException {
1107
1108                 assert (subject != null);
1109
1110                 try {
1111                         
1112                         byte[] bytes = processor.getValue(this, subject);
1113                         if (bytes == null) throw new DoesNotContainValueException("No value for resource " + subject);
1114
1115                         Serializer serializer = getSerializer(binding);
1116                         return (T)serializer.deserialize(bytes);
1117
1118                 } catch (DoesNotContainValueException e) {
1119
1120                         throw new DoesNotContainValueException(e);
1121
1122                 } catch (IOException e) {
1123
1124                         throw new ServiceException(e);
1125
1126                 } catch (DatabaseException e) {
1127                     
1128             throw new ServiceException(e);
1129             
1130         } catch (BufferUnderflowException e) {
1131             // This is sometimes thrown when deserialize fails because wrong format.
1132             // For callers of this method this is just an service exception.
1133             throw new ServiceException(e);
1134         }
1135
1136         }
1137
1138         @Override
1139         final public <T> T getRelatedValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1140                         DoesNotContainValueException, ServiceException {
1141
1142                 assert (subject != null);
1143                 assert (relation != null);
1144
1145                 try {
1146                         Resource object = getSingleObject(subject, relation);
1147                         return getValue(object);
1148                 } catch (NoSingleResultException e) {
1149                         throw new NoSingleResultException("No single value found for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1150                 } catch (DoesNotContainValueException e) {
1151                         try {
1152                                 Layer0 L0 = processor.getL0(this);
1153                                 Resource object = getPossibleObject(subject, relation);
1154                                 if(isInstanceOf(object, L0.Value)) {
1155                                         if(isInstanceOf(object, L0.Literal)) {
1156                                                 throw new DoesNotContainValueException(e);
1157                                         } else {
1158                                                 throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1159                                         }
1160                                 } else {
1161                                         throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1162                                 }
1163                         } catch (DoesNotContainValueException e2) {
1164                                 throw e2;
1165                         } catch (DatabaseException e2) {
1166                                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1167                         }
1168                 } catch (ServiceException e) {
1169                         throw new ServiceException(e);
1170                 }
1171         }
1172
1173     @Override
1174     final public Variant getRelatedVariantValue(final Resource subject, final Resource relation) throws NoSingleResultException,
1175             DoesNotContainValueException, ServiceException {
1176
1177         assert (subject != null);
1178         assert (relation != null);
1179
1180         try {
1181             Resource object = getSingleObject(subject, relation);
1182             return getVariantValue(object);
1183         } catch (NoSingleResultException e) {
1184             throw new NoSingleResultException("No single object for subject " + debugString(subject) + " and relation " + debugString(relation), e.getResultCount(), e);
1185         } catch (DoesNotContainValueException e) {
1186             try {
1187                 Layer0 L0 = processor.getL0(this);
1188                 Resource object = getPossibleObject(subject, relation);
1189                 if(isInstanceOf(object, L0.Value)) {
1190                     if(isInstanceOf(object, L0.Literal)) {
1191                         throw new DoesNotContainValueException(e);
1192                     } else {
1193                         throw new InvalidLiteralException("The object " + object + " is not an instance of L0.Literal (use getRelatedValue2 instead)", e);
1194                     }
1195                 } else {
1196                     throw new DoesNotContainValueException("The object " + object + " is not an instance of L0.Value", e);
1197                 }
1198             } catch (DoesNotContainValueException e2) {
1199                 throw e2;
1200             } catch (DatabaseException e2) {
1201                 throw new InternalException("The client failed to analyse the cause of the following exception", e);
1202             }
1203         } catch (ServiceException e) {
1204             throw new ServiceException(e);
1205         } 
1206     }
1207     
1208         @Override
1209         final public <T> T getRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1210                         throws NoSingleResultException, DoesNotContainValueException, BindingException, ServiceException {
1211
1212                 assert (subject != null);
1213                 assert (relation != null);
1214
1215                 try {
1216                         Resource object = getSingleObject(subject, relation);
1217                         return getValue(object, binding);
1218                 } catch (NoSingleResultException e) {
1219                     String message = "";
1220                     try {
1221                     String subjectName = NameUtils.getSafeName(this, subject, true);
1222                     String relationName = NameUtils.getSafeName(this, relation, true);
1223                     message = "Subject: " + subjectName + ", Relation: " + relationName;
1224                     } catch (DatabaseException e2) {
1225                         
1226                     }
1227             throw new NoSingleResultException(message, e.getResultCount(), e);
1228                 } catch (DoesNotContainValueException e) {
1229                         throw new DoesNotContainValueException(e);
1230                 } catch (ServiceException e) {
1231                         throw new ServiceException(e);
1232                 }
1233         }
1234
1235         @Override
1236         final public <T> T adapt(final Resource resource, final Class<T> clazz)
1237                         throws AdaptionException, ValidationException, ServiceException {
1238
1239                 assert (resource != null);
1240                 assert (clazz != null);
1241
1242                 try {
1243
1244                         return syncRequest(new Adapter<T>(resource, clazz));
1245
1246                 } catch (AdaptionException e) {
1247
1248                         throw new AdaptionException(e);
1249
1250                 } catch (ValidationException e) {
1251
1252                         throw new ValidationException(e);
1253
1254                 } catch (ServiceException e) {
1255
1256                         throw new ServiceException(e);
1257
1258                 } catch (DatabaseException e) {
1259
1260                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1261
1262                 }
1263
1264         }
1265
1266         @Override
1267         final public <T,C> T adaptContextual(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1268                         throws AdaptionException, ValidationException, ServiceException {
1269
1270                 assert (resource != null);
1271                 assert (context != null);
1272
1273                 class ContextualAdapter implements AsyncRead<T> {
1274
1275                         final private Resource resource;
1276                         final private C context;
1277                     final private Class<T> clazz;
1278                     
1279                     @Override
1280                     public int hashCode() {
1281                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1282                     }
1283                     
1284                     @Override
1285                     final public int threadHash() {
1286                         return resource.getThreadHash();
1287                     }
1288                     
1289                     @Override
1290                     public boolean equals(Object object) {
1291                         if (this == object)
1292                             return true;
1293                         else if (object == null)
1294                             return false;
1295                         else if (getClass() != object.getClass())
1296                             return false;
1297                         ContextualAdapter r = (ContextualAdapter)object;
1298                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1299                     }
1300
1301                     @Override
1302                     public int getFlags() {
1303                         return 0;
1304                     }
1305                     
1306                     public ContextualAdapter(Resource resource, C context, Class<T> clazz) {
1307                         this.resource = resource;
1308                         this.context = context;
1309                         this.clazz = clazz;
1310                     }
1311
1312                     @Override
1313                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1314                         
1315                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1316                                 if (service == null)
1317                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1318                                 else
1319                                         service.adapt(graph, resource, context, contextClass, clazz, false, procedure); 
1320                         
1321                     }
1322
1323                     @Override
1324                     public String toString() {
1325                         return "Adapter for (" + resource + "," + context + ") as " + clazz.getName();
1326                     }
1327                     
1328                 }
1329                 
1330                 try {
1331
1332                         return syncRequest(new ContextualAdapter(resource, context, clazz));
1333
1334                 } catch (AdaptionException e) {
1335
1336                         throw new AdaptionException(e);
1337
1338                 } catch (ValidationException e) {
1339
1340                         throw new ValidationException(e);
1341
1342                 } catch (ServiceException e) {
1343
1344                         throw new ServiceException(e);
1345
1346                 } catch (DatabaseException e) {
1347
1348                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1349
1350                 }
1351
1352         }
1353         
1354         @Override
1355         final public <T> T adaptRelated(final Resource resource, final Resource relation, final Class<T> clazz)
1356                         throws AdaptionException, NoSingleResultException, ValidationException, ServiceException {
1357
1358                 assert (resource != null);
1359                 assert (clazz != null);
1360
1361                 Statement stm = getSingleStatement(resource, relation);
1362                 
1363                 return adaptContextual(stm.getObject(), new RelationContextImpl(resource, stm), RelationContext.class, clazz);
1364                 
1365         }
1366
1367         @Override
1368         final public <T> T getPossibleRelatedAdapter(final Resource resource, final Resource relation, final Class<T> clazz)
1369                         throws ValidationException, ServiceException {
1370
1371                 try {
1372                         return adaptRelated(resource, relation, clazz);
1373                 } catch (DatabaseException e) {
1374                         return null;
1375                 }
1376                 
1377         }
1378
1379         @Override
1380         final public <T,C> T getPossibleContextualAdapter(final Resource resource, final C context, final Class<C> contextClass, final Class<T> clazz)
1381                         throws ValidationException, ServiceException {
1382
1383                 assert (resource != null);
1384                 assert (context != null);
1385
1386                 class PossibleContextualAdapter implements AsyncRead<T> {
1387
1388                         final private Resource resource;
1389                         final private C context;
1390                     final private Class<T> clazz;
1391                     
1392                     @Override
1393                     public int hashCode() {
1394                         return resource.hashCode() + 31 * (clazz.hashCode() + 41 * context.hashCode());
1395                     }
1396                     
1397                     @Override
1398                     final public int threadHash() {
1399                         return resource.getThreadHash();
1400                     }
1401                     
1402                     @Override
1403                     public boolean equals(Object object) {
1404                         if (this == object)
1405                             return true;
1406                         else if (object == null)
1407                             return false;
1408                         else if (getClass() != object.getClass())
1409                             return false;
1410                         PossibleContextualAdapter r = (PossibleContextualAdapter)object;
1411                         return resource.equals(r.resource) && context.equals(r.context) && clazz.equals(r.clazz);
1412                     }
1413
1414                     @Override
1415                     public int getFlags() {
1416                         return 0;
1417                     }
1418                     
1419                     public PossibleContextualAdapter(Resource resource, C context, Class<T> clazz) {
1420                         this.resource = resource;
1421                         this.context = context;
1422                         this.clazz = clazz;
1423                     }
1424
1425                     @Override
1426                     public void perform(AsyncReadGraph graph, AsyncProcedure<T> procedure) {
1427                         
1428                                 final AdaptionService service = getSession().peekService(AdaptionService.class);
1429                                 if (service == null)
1430                                         procedure.exception(graph, new ServiceException("No AdaptionService available")); 
1431                                 else
1432                                         service.adapt(graph, resource, context, contextClass, clazz, true, procedure); 
1433                         
1434                     }
1435
1436                     @Override
1437                     public String toString() {
1438                         return "Possible adapter for (" + resource + "," + context + ") as " + clazz.getName();
1439                     }
1440                     
1441                 }
1442                 
1443                 try {
1444
1445                         return syncRequest(new PossibleContextualAdapter(resource, context, clazz));
1446
1447                 } catch (ValidationException e) {
1448
1449                         throw new ValidationException(e);
1450
1451                 } catch (ServiceException e) {
1452
1453                         throw new ServiceException(e);
1454
1455                 } catch (DatabaseException e) {
1456
1457                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1458
1459                 }
1460                 
1461         }
1462
1463         @Override
1464         final public <T> T adaptUnique(final Resource resource, final Class<T> clazz)
1465                         throws AdaptionException, ValidationException, ServiceException {
1466
1467                 assert (resource != null);
1468                 assert (clazz != null);
1469
1470                 try {
1471
1472                         return syncRequest(new UniqueAdapter<T>(resource, clazz));
1473
1474                 } catch (AdaptionException e) {
1475
1476                         throw new AdaptionException(e);
1477
1478                 } catch (ValidationException e) {
1479
1480                         throw new ValidationException(e);
1481
1482                 } catch (ServiceException e) {
1483
1484                         throw new ServiceException(e);
1485
1486                 } catch (DatabaseException e) {
1487
1488                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1489
1490                 }
1491
1492         }
1493
1494         @Override
1495         final public Resource getPossibleInverse(final Resource relation)
1496                         throws ServiceException {
1497
1498                 assert (relation != null);
1499
1500                 try {
1501
1502                         return getPossibleObject(relation, processor.querySupport.getResource(processor.getInverseOf()));
1503
1504                 } catch (ServiceException e) {
1505
1506                         throw new ServiceException(e);
1507
1508                 } catch (DatabaseException e) {
1509
1510                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1511
1512                 }
1513
1514         }
1515
1516         @Override
1517         public Resource getPossibleObject(final Resource subject, final Resource relation)
1518                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1519
1520                 assert (subject != null);
1521                 assert (relation != null);
1522
1523                 try {
1524
1525                     int result = processor.getSingleObject(this, subject, relation);
1526                     if(result == 0) return null;
1527                     
1528                     return processor.querySupport.getResource(result);
1529
1530              } catch (ManyObjectsForFunctionalRelationException e) {
1531
1532                  throw new ManyObjectsForFunctionalRelationException("subject=" + subject + ", relation=" + relation, e);
1533                  
1534                 } catch (DatabaseException e) {
1535
1536                         throw new ServiceException(e);
1537
1538                 }
1539                 
1540         }
1541
1542         @Override
1543         final public Statement getPossibleStatement(final Resource subject, final Resource relation)
1544                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1545
1546                 assert (subject != null);
1547                 assert (relation != null);
1548
1549                 try {
1550
1551                         Collection<Statement> statements = getStatements(subject, relation);
1552                         if(statements.size() == 1) return statements.iterator().next();
1553                         else return null;
1554
1555                 } catch (ManyObjectsForFunctionalRelationException e) {
1556
1557                         throw new ManyObjectsForFunctionalRelationException("Many objects in " + subject + " for functional relation " + relation);
1558
1559                 } catch (ServiceException e) {
1560
1561                         throw new ServiceException(e);
1562
1563                 } 
1564
1565         }
1566
1567         @Override
1568         final public Resource getPossibleType(final Resource subject, final Resource baseType) throws ServiceException {
1569
1570                 assert (subject != null);
1571                 assert (baseType != null);
1572
1573                 try {
1574
1575                         AsyncReadProcedure<Resource> procedure = new AsyncReadProcedure<Resource>();
1576                         forPossibleType(subject, baseType, procedure);
1577                         procedure.checkAndThrow();
1578                         return procedure.result;                        
1579
1580                 } catch (ServiceException e) {
1581
1582                         throw new ServiceException(e);
1583
1584                 } catch (DatabaseException e) {
1585
1586                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1587
1588                 }
1589
1590         }
1591
1592         @Override
1593         final public <T> T getPossibleValue(final Resource subject) throws ServiceException {
1594
1595                 assert (subject != null);
1596
1597                 try {
1598                     
1599                     int object = processor.getSingleObject(this, subject, processor.getL0(this).HasDataType);
1600                     if(object == 0) return null;
1601                     
1602             if(processor.isImmutable(object)) {
1603                 Binding binding = syncRequest(new DatatypeBinding(processor.querySupport.getResource(object)), TransientCacheListener.<Binding>instance()); 
1604                         return getPossibleValue(subject, binding);
1605             } else {
1606                     byte[] dt = processor.getValue(this, object);
1607                     if(dt == null) return null;
1608                     Datatype datatype = (Datatype)DATA_TYPE_SERIALIZER.deserialize(dt);
1609                     Binding binding = Bindings.getBinding(datatype);
1610                     return getPossibleValue(subject, binding);
1611             }
1612                     
1613         } catch (IOException e) {
1614             
1615             throw new ServiceException(e);
1616             
1617                 } catch (ServiceException e) {
1618
1619                         throw new ServiceException(e);
1620
1621                 } catch (DatabaseException e) {
1622
1623                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1624
1625         }
1626
1627         }
1628
1629         @Override
1630         final public <T> T getPossibleValue(final Resource subject, final Binding binding) throws BindingException, ServiceException {
1631
1632                 assert (subject != null);
1633                 assert (binding != null);
1634
1635                 try {
1636
1637             byte[] dt = processor.getValue(this, subject);
1638             if(dt == null) return null;
1639                         Serializer serializer = getSerializer(binding);
1640             return (T)serializer.deserialize(dt);
1641
1642         } catch (IOException e) {
1643
1644             throw new ServiceException(e);
1645             
1646                 } catch (BindingException e) {
1647
1648                         throw new BindingException(e);
1649
1650                 } catch (ServiceException e) {
1651
1652                         throw new ServiceException(e);
1653
1654                 } catch (DatabaseException e) {
1655                         e.printStackTrace();
1656                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1657         }
1658
1659         }
1660
1661         @Override
1662         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation)
1663                         throws ManyObjectsForFunctionalRelationException, ServiceException {
1664
1665                 assert (subject != null);
1666                 assert (relation != null);
1667
1668                 try {
1669
1670                         Resource object = getPossibleObject(subject, relation);
1671                         if(object == null) return null;
1672                         else return getPossibleValue(object);
1673
1674                 } catch (ManyObjectsForFunctionalRelationException e) {
1675
1676                         throw new ManyObjectsForFunctionalRelationException(e);
1677
1678                 } catch (ServiceException e) {
1679
1680                         throw new ServiceException(e);
1681
1682                 } 
1683
1684         }
1685
1686         @Override
1687         public <T> T getPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding)
1688                         throws ManyObjectsForFunctionalRelationException, BindingException, ServiceException {
1689
1690                 assert (subject != null);
1691                 assert (relation != null);
1692                 assert (binding != null);
1693
1694                 try {
1695
1696                         Resource object = getPossibleObject(subject, relation);
1697                         if(object == null) return null;
1698                         else return getPossibleValue(object, binding);
1699
1700                 } catch (ManyObjectsForFunctionalRelationException e) {
1701
1702                         throw new ManyObjectsForFunctionalRelationException(e);
1703
1704                 } catch (BindingException e) {
1705
1706                         throw new BindingException(e);
1707
1708                 } catch (ServiceException e) {
1709
1710                         throw new ServiceException(e);
1711
1712                 }
1713
1714         }
1715
1716         @Override
1717         public <T> T getPossibleAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1718
1719                 assert (resource != null);
1720                 assert (clazz != null);
1721
1722                 try {
1723
1724                         return syncRequest(new PossibleAdapter<T>(resource, clazz));
1725
1726                 } catch (ValidationException e) {
1727
1728                         throw new ValidationException(e);
1729
1730                 } catch (AdaptionException e) {
1731
1732                         return null;
1733
1734                 } catch (DatabaseException e) {
1735
1736                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1737
1738                 }
1739         }
1740
1741         @Override
1742         public <T> T getPossibleUniqueAdapter(Resource resource, Class<T> clazz) throws ValidationException, ServiceException {
1743
1744                 assert (resource != null);
1745                 assert (clazz != null);
1746
1747                 try {
1748
1749                         return syncRequest(new PossibleUniqueAdapter<T>(resource, clazz));
1750
1751                 } catch (AdaptionException e) {
1752
1753                         return null;
1754
1755                 } catch (ValidationException e) {
1756
1757                         throw new ValidationException(e);
1758
1759                 } catch (DatabaseException e) {
1760
1761                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1762
1763                 }
1764
1765         }
1766
1767     @Override
1768     final public boolean isInstanceOf(final Resource resource, final Resource type) throws ServiceException {
1769
1770         assert (resource != null);
1771         assert (type != null);
1772
1773         Set<Resource> resources = getTypes(resource);
1774         // This check was necessary because some of the callers of this method got stuck when the NPE was thrown from here.
1775         if (null == resources)
1776             return false;
1777         
1778         if(EMPTY_RESOURCE_CHECK) {
1779             if (resources.isEmpty()) {
1780                 if(!hasStatement(resource)) throw new EmptyResourceException("Resource " + debugString(resource));
1781             }
1782         }
1783         
1784         return resources.contains(type);
1785
1786     }
1787
1788         @Override
1789         final public boolean isInheritedFrom(final Resource resource, final Resource type) throws ServiceException {
1790
1791                 assert (resource != null);
1792                 assert (type != null);
1793
1794                 try {
1795
1796                         if(resource.equals(type)) return true;
1797                         
1798                         return getSupertypes(resource).contains(type);
1799
1800                 } catch (ServiceException e) {
1801
1802                         throw new ServiceException(e);
1803
1804                 } 
1805                 
1806         }
1807
1808         @Override
1809         final public boolean isSubrelationOf(final Resource resource, final Resource type) throws ServiceException {
1810
1811                 assert (resource != null);
1812                 assert (type != null);
1813
1814                 try {
1815
1816                         if(resource.equals(type)) return true;
1817                         
1818                         return getSuperrelations(resource).contains(type);
1819
1820                 } catch (ServiceException e) {
1821
1822                         throw new ServiceException(e);
1823
1824                 } 
1825
1826         }
1827
1828         @Override
1829         final public boolean hasStatement(final Resource subject) throws ServiceException {
1830
1831                 assert (subject != null);
1832
1833                 try {
1834
1835                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1836                         processor.forHasStatement(this, subject, procedure);
1837                         procedure.checkAndThrow();
1838                         return procedure.result;
1839
1840                 } catch (ServiceException e) {
1841
1842                         throw new ServiceException(e);
1843
1844                 } catch (DatabaseException e) {
1845
1846                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1847
1848                 }
1849
1850         }
1851
1852         @Override
1853         final public boolean hasStatement(final Resource subject, final Resource relation) throws ServiceException {
1854
1855                 assert (subject != null);
1856                 assert (relation != null);
1857
1858                 try {
1859
1860                         Collection<Resource> objects = getObjects(subject, relation);
1861                         return !objects.isEmpty();
1862
1863                 } catch (ServiceException e) {
1864
1865                         throw new ServiceException(e);
1866
1867                 } 
1868                 
1869         }
1870
1871         @Override
1872         final public boolean hasStatement(final Resource subject, final Resource relation, final Resource object) throws ServiceException {
1873
1874                 assert (subject != null);
1875                 assert (relation != null);
1876                 assert (object != null);
1877
1878                 try {
1879
1880                         for(Resource o : getObjects(subject, relation)) {
1881                                 if(object.equals(o)) return true;
1882                         }
1883                         
1884                         return false;
1885
1886                 } catch (ServiceException e) {
1887
1888                         throw new ServiceException(e);
1889
1890                 }
1891
1892         }
1893
1894         @Override
1895         final public boolean hasValue(final Resource subject) throws ServiceException {
1896
1897                 assert (subject != null);
1898
1899                 try {
1900
1901                         SyncReadProcedure<Boolean> procedure = new SyncReadProcedure<Boolean>();
1902                         processor.forHasValue(this, subject, procedure);
1903                         procedure.checkAndThrow();
1904                         return procedure.result;
1905
1906                 } catch (ServiceException e) {
1907
1908                         throw new ServiceException(e);
1909
1910                 } catch (DatabaseException e) {
1911
1912                         throw new ServiceException(INTERNAL_ERROR_STRING, e);
1913
1914                 }
1915
1916         }
1917
1918         final AsyncProcedure<?> NONE = new AsyncProcedure<Object>() {
1919
1920                 @Override
1921                 public void execute(AsyncReadGraph graph, Object result) {
1922                 }
1923
1924                 @Override
1925                 public void exception(AsyncReadGraph graph, Throwable throwable) {
1926                 }
1927                 
1928         };
1929         
1930         /*
1931          * Implementation of the interface RequestProcessor
1932          */
1933
1934         @Override
1935         public <T> T syncRequest(final Read<T> request) throws DatabaseException {
1936                 assert (request != null);
1937                 return (T)QueryCache.runnerReadEntry(this, request, parent, null, null, true);
1938         }
1939
1940         @Override
1941         public <T> T syncRequest(Read<T> request, SyncListener<T> procedure)
1942                         throws DatabaseException {
1943                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
1944         }
1945
1946         @Override
1947         public <T> T syncRequest(Read<T> request, final Listener<T> procedure)
1948                         throws DatabaseException {
1949                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
1950         }
1951
1952         @Override
1953         public <T> T syncRequest(final Read<T> request, final AsyncProcedure<T> procedure) throws DatabaseException {
1954
1955                 assert (request != null);
1956
1957                 ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
1958
1959                 return QueryCache.resultReadEntry(this, request, parent, listener, procedure);
1960
1961         }
1962
1963         @Override
1964         public <T> T syncRequest(final Read<T> request,
1965                         final SyncProcedure<T> procedure) throws DatabaseException {
1966                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
1967         }
1968
1969         @Override
1970         public <T> T syncRequest(Read<T> request, Procedure<T> procedure)
1971                         throws DatabaseException {
1972                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
1973         }
1974
1975         static class AsyncReadProcedure<T> implements AsyncProcedure<T> {
1976
1977                 private static Throwable DONE = new Throwable();
1978                 
1979                 T result = null;
1980                 Throwable exception = null;
1981                 
1982                 @Override
1983                 public void execute(AsyncReadGraph graph, T t) {
1984                         result = t;
1985                         exception = DONE;
1986                 }
1987
1988                 @Override
1989                 public void exception(AsyncReadGraph graph, Throwable t) {
1990                         exception = t;
1991                 }
1992                 
1993                 public void checkAndThrow() throws DatabaseException {
1994                         if(exception != DONE) {
1995                                 if (exception instanceof DatabaseException)
1996                                         throw (DatabaseException) exception;
1997                                 else
1998                                         throw new DatabaseException(
1999                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncRead)",
2000                                                         exception);
2001                         }
2002                 }
2003                 
2004                 public boolean done() {
2005                         return exception != null;
2006                 }
2007                 
2008         }
2009         
2010         @Override
2011         public <T> T syncRequest(final AsyncRead<T> request)
2012                         throws DatabaseException {
2013
2014                 assert (request != null);
2015                 return syncRequest(request, new AsyncProcedureAdapter<>() );
2016
2017         }
2018
2019         @Override
2020         public <T> T syncRequest(AsyncRead<T> request, AsyncListener<T> procedure)
2021                         throws DatabaseException {
2022                 return syncRequest(request, (AsyncProcedure<T>) procedure);
2023         }
2024
2025         @Override
2026         public <T> T syncRequest(AsyncRead<T> request, SyncListener<T> procedure)
2027                         throws DatabaseException {
2028                 return syncRequest(request, new SyncToAsyncListener<T>(procedure));
2029         }
2030
2031         @Override
2032         public <T> T syncRequest(AsyncRead<T> request, Listener<T> procedure)
2033                         throws DatabaseException {
2034                 return syncRequest(request, new NoneToAsyncListener<T>(procedure));
2035         }
2036
2037         @Override
2038         final public <T> T syncRequest(final AsyncRead<T> request,
2039                         final AsyncProcedure<T> procedure) throws DatabaseException {
2040
2041                 assert (request != null);
2042
2043                 ListenerBase listener = getListenerBase(procedure);
2044
2045 //              BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2046                 return (T)QueryCache.runnerAsyncReadEntry(this, request, parent, listener, procedure, true);
2047 //              return ap.get();
2048
2049         }
2050
2051         final private <T> void syncRequest(final AsyncRead<T> request, final AsyncReadProcedure<T> procedure) throws DatabaseException {
2052
2053                 assert (request != null);
2054
2055                 ListenerBase listener = getListenerBase(procedure);
2056                 assert(listener == null);
2057
2058                 BlockingAsyncProcedure<T> ap = new BlockingAsyncProcedure<>(this, procedure, request);
2059
2060                 QueryCache.runnerAsyncReadEntry(this, request, parent, listener, ap, true);
2061
2062                 ap.get();
2063
2064         }
2065
2066         @Override
2067         public <T> T syncRequest(AsyncRead<T> request,
2068                         final SyncProcedure<T> procedure) throws DatabaseException {
2069                 return syncRequest(request, new SyncToAsyncProcedure<T>(procedure));
2070         }
2071
2072         @Override
2073         final public <T> T syncRequest(final AsyncRead<T> request,
2074                         final Procedure<T> procedure) throws DatabaseException {
2075                 return syncRequest(request, new NoneToAsyncProcedure<T>(procedure));
2076         }
2077
2078         @Override
2079         public <T> Collection<T> syncRequest(final MultiRead<T> request)
2080                         throws DatabaseException {
2081
2082                 assert (request != null);
2083
2084                 final ArrayList<T> result = new ArrayList<T>();
2085                 final DataContainer<Throwable> exception = new DataContainer<Throwable>();
2086
2087                 syncRequest(request, new SyncMultiProcedure<T>() {
2088
2089                         @Override
2090                         public void execute(ReadGraph graph, T t) {
2091                                 synchronized (result) {
2092                                         result.add(t);
2093                                 }
2094                         }
2095
2096                         @Override
2097                         public void finished(ReadGraph graph) {
2098                         }
2099
2100                         @Override
2101                         public void exception(ReadGraph graph, Throwable t) {
2102                                 exception.set(t);
2103                         }
2104
2105                         @Override
2106                         public String toString() {
2107                                 return "syncRequest(MultiRead) -> " + request;
2108                         }
2109
2110                 });
2111
2112                 Throwable t = exception.get();
2113                 if (t != null) {
2114                         if (t instanceof DatabaseException)
2115                                 throw (DatabaseException) t;
2116                         else
2117                                 throw new DatabaseException(
2118                                                 "Unexpected exception in ReadGraph.syncRequest(Read)",
2119                                                 t);
2120                 }
2121
2122                 return result;
2123
2124         }
2125
2126         @Override
2127         public <T> Collection<T> syncRequest(MultiRead<T> request,
2128                         SyncMultiListener<T> procedure) {
2129                 return syncRequest(request, (SyncMultiProcedure<T>)procedure);
2130         }
2131
2132         @Override
2133         public <T> Collection<T> syncRequest(MultiRead<T> request,
2134                         MultiListener<T> procedure) {
2135                 return syncRequest(request, new NoneToSyncMultiListener<T>(procedure));
2136         }
2137
2138         @Override
2139         public <T> Collection<T> syncRequest(MultiRead<T> request,
2140                         SyncMultiProcedure<T> procedure) {
2141
2142                 assert (request != null);
2143
2144                 ListenerBase listener = getListenerBase(procedure);
2145
2146                 final ResultCallWrappedSyncQueryProcedure<T> wrapper = new ResultCallWrappedSyncQueryProcedure<T>(procedure);
2147
2148                 if (parent != null || listener != null) {
2149
2150 //                      Object syncParent = request;
2151
2152 //                      final ReadGraphImpl newGraph = newSync();
2153
2154                         processor.query(this, request, parent, wrapper, listener);
2155
2156 //                      newGraph.waitAsync(syncParent);
2157
2158                 } else {
2159
2160 //                      Object syncParent = request;
2161
2162 //                      final ReadGraphImpl newGraph = newSync();
2163
2164                         try {
2165                                 request.perform(this, wrapper);
2166                         } catch (Throwable t) {
2167                                 wrapper.exception(this, t);
2168                         }
2169
2170                 }
2171
2172                 return wrapper.get();
2173
2174         }
2175
2176         @Override
2177         public <T> Collection<T> syncRequest(MultiRead<T> request,
2178                         MultiProcedure<T> procedure) {
2179                 return syncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
2180         }
2181
2182         static class AsyncMultiReadProcedure<T> extends ArrayList<T> implements AsyncMultiProcedure<T> {
2183
2184                 private static Throwable DONE = new Throwable();
2185                 
2186                 private static final long serialVersionUID = -6494230465108115812L;
2187                 
2188                 Throwable exception = null;
2189                 
2190                 @Override
2191                 public synchronized void execute(AsyncReadGraph graph, T t) {
2192                         add(t);
2193                 }
2194
2195                 @Override
2196                 public void finished(AsyncReadGraph graph) {
2197                         exception = DONE;
2198                 }
2199
2200                 @Override
2201                 public void exception(AsyncReadGraph graph, Throwable t) {
2202                         exception = t;
2203                 }
2204                 
2205                 public void checkAndThrow() throws DatabaseException {
2206                         if(exception != DONE) {
2207                                 if (exception instanceof DatabaseException)
2208                                         throw (DatabaseException) exception;
2209                                 else
2210                                         throw new DatabaseException(
2211                                                         "Unexpected exception in ReadGraph.syncRequest(AsyncMultiRead)",
2212                                                         exception);
2213                         }
2214                 }
2215                 
2216                 public boolean done() {
2217                         return exception != null;
2218                 }
2219                 
2220         }
2221
2222         @Override
2223         final public <T> Collection<T> syncRequest(AsyncMultiRead<T> request)
2224                         throws DatabaseException {
2225
2226                 assert (request != null);
2227
2228                 final AsyncMultiReadProcedure<T> procedure = new AsyncMultiReadProcedure<T>();
2229                 
2230                 syncRequest(request, procedure);
2231                 
2232                 procedure.checkAndThrow();
2233                 return procedure;
2234
2235         }
2236
2237         @Override
2238         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2239                         AsyncMultiListener<T> procedure) {
2240                 return syncRequest(request, (AsyncMultiProcedure<T>) procedure);
2241         }
2242
2243         @Override
2244         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2245                         SyncMultiListener<T> procedure) {
2246                 return syncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
2247         }
2248
2249         @Override
2250         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2251                         MultiListener<T> procedure) {
2252                 return syncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
2253         }
2254
2255         final private <T> void syncRequest(final AsyncMultiRead<T> request,
2256                         final AsyncMultiReadProcedure<T> procedure) {
2257
2258                 assert (request != null);
2259                 assert (procedure != null);
2260
2261                 ListenerBase listener = getListenerBase(procedure);
2262
2263                 if (parent != null || listener != null) {
2264
2265 //                      Object syncParent = request;
2266
2267 //                      final ReadGraphImpl newGraph = newSync();
2268
2269                         processor.query(this, request, parent, procedure, listener);
2270
2271 //                      newGraph.waitAsync(syncParent);
2272                         waitAsyncProcedure(procedure);
2273
2274                 } else {
2275
2276 //                      Object syncParent = callerThread == Integer.MIN_VALUE ? null
2277 //                                      : request;
2278 //
2279 //                      final ReadGraphImpl newGraph = newSyncAsync(syncParent);
2280
2281                         try {
2282
2283 //                              inc();
2284 //                              ReadGraphImpl sync = newSync();
2285                                 request.perform(this, procedure);
2286 //                              sync.waitAsync(null);
2287                                 waitAsyncProcedure(procedure);
2288 //                              dec();
2289
2290                         } catch (Throwable t) {
2291
2292                                 waitAsyncProcedure(procedure);
2293 //                              dec();
2294
2295                         }
2296
2297                 }
2298
2299         }
2300         
2301         
2302         @Override
2303         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2304                         final AsyncMultiProcedure<T> procedure) {
2305
2306                 assert (request != null);
2307                 assert (procedure != null);
2308
2309                 ListenerBase listener = getListenerBase(procedure);
2310
2311                 if (parent != null || listener != null) {
2312
2313 //                      Object syncParent = request;
2314
2315 //                      final ReadGraphImpl newGraph = newSync();
2316
2317                         processor.query(this, request, parent, procedure, listener);
2318
2319 //                      newGraph.waitAsync(syncParent);
2320
2321                 } else {
2322
2323 //                      Object syncParent = request;
2324
2325 //                      final ReadGraphImpl newGraph = newSync();
2326
2327                         try {
2328
2329                                 request.perform(this, new AsyncMultiProcedure<T>() {
2330
2331                                         @Override
2332                                         public void execute(AsyncReadGraph graph, T result) {
2333                                                 procedure.execute(graph, result);
2334                                         }
2335
2336                                         @Override
2337                                         public void finished(AsyncReadGraph graph) {
2338                                                 procedure.finished(graph);
2339                                         }
2340
2341                                         @Override
2342                                         public void exception(AsyncReadGraph graph, Throwable t) {
2343                                                 procedure.exception(graph, t);
2344                                         }
2345
2346                                         @Override
2347                                         public String toString() {
2348                                                 return "syncRequest(AsyncMultiRead) -> " + procedure;
2349                                         }
2350
2351                                 });
2352
2353                         } catch (Throwable t) {
2354
2355                         }
2356
2357                 }
2358
2359                 // TODO!!
2360                 return null;
2361
2362         }
2363
2364         @Override
2365         public <T> Collection<T> syncRequest(AsyncMultiRead<T> request,
2366                         final SyncMultiProcedure<T> procedure) {
2367                 return syncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
2368         }
2369
2370         @Override
2371         final public <T> Collection<T> syncRequest(final AsyncMultiRead<T> request,
2372                         final MultiProcedure<T> procedure) {
2373                 return syncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
2374         }
2375
2376         @Override
2377         public <T> T syncRequest(final ExternalRead<T> request)
2378                         throws DatabaseException {
2379
2380                 assert (request != null);
2381
2382                 return syncRequest(request, new Procedure<T>() {
2383
2384                         @Override
2385                         public void execute(T t) {
2386                         }
2387
2388                         @Override
2389                         public void exception(Throwable t) {
2390                         }
2391
2392                         @Override
2393                         public String toString() {
2394                                 return "syncRequest(AsyncRead) -> " + request;
2395                         }
2396
2397                 });
2398
2399         }
2400
2401         @Override
2402         public <T> T syncRequest(ExternalRead<T> request, Listener<T> procedure) throws DatabaseException {
2403                 return syncRequest(request, (Procedure<T>) procedure);
2404         }
2405
2406         @Override
2407         final public <T> T syncRequest(final ExternalRead<T> request,
2408                         final Procedure<T> procedure) throws DatabaseException {
2409
2410         assert (request != null);
2411
2412         ListenerBase listener = procedure != null ? getListenerBase(procedure) : null;
2413         return QueryCache.resultExternalReadEntry(this, request, parent, listener, procedure);
2414
2415         }
2416
2417         @Override
2418         public void syncRequest(final Write request) throws DatabaseException {
2419
2420                 assert (request != null);
2421
2422                 throw new DatabaseException(
2423                                 "Write operations are not supported during read transactions!");
2424
2425         }
2426
2427         @Override
2428         public <T> T syncRequest(final WriteResult<T> request) throws DatabaseException {
2429
2430                 assert (request != null);
2431
2432                 throw new DatabaseException(
2433                                 "Write operations are not supported during read transactions!");
2434
2435         }
2436
2437         @Override
2438         public void syncRequest(final DelayedWrite request)
2439                         throws DatabaseException {
2440
2441                 assert (request != null);
2442
2443                 throw new DatabaseException(
2444                                 "Write operations are not supported during read transactions!");
2445
2446         }
2447
2448         @Override
2449         public <T> T syncRequest(final DelayedWriteResult<T> request) throws DatabaseException {
2450
2451                 assert (request != null);
2452
2453                 throw new DatabaseException(
2454                                 "Write operations are not supported during read transactions!");
2455
2456         }
2457         
2458         @Override
2459         public void syncRequest(final WriteOnly request) throws DatabaseException {
2460
2461                 assert (request != null);
2462
2463                 throw new DatabaseException(
2464                                 "Write operations are not supported during read transactions!");
2465
2466         }
2467
2468         @Override
2469         public <T> T syncRequest(final WriteOnlyResult<T> request) throws DatabaseException {
2470
2471                 assert (request != null);
2472
2473                 throw new DatabaseException(
2474                                 "Write operations are not supported during read transactions!");
2475
2476         }
2477         
2478         @Override
2479         public <T> void async(ReadInterface<T> r, AsyncProcedure<T> procedure) {
2480                 r.request(this, procedure);
2481         }
2482         
2483         @Override
2484         public <T> void async(ReadInterface<T> r, Procedure<T> procedure) {
2485                 r.request(this, procedure);
2486         }
2487         
2488         @Override
2489         public <T> void async(ReadInterface<T> r, SyncProcedure<T> procedure) {
2490                 r.request(this, procedure);
2491         }
2492         
2493         @Override
2494         public <T> void async(ReadInterface<T> r, AsyncListener<T> procedure) {
2495                 r.request(this, procedure);
2496         }
2497         
2498         @Override
2499         public <T> void async(ReadInterface<T> r, Listener<T> procedure) {
2500                 r.request(this, procedure);
2501         }
2502         
2503         @Override
2504         public <T> void async(ReadInterface<T> r, SyncListener<T> procedure) {
2505                 r.request(this, procedure);
2506         }
2507
2508         @Override
2509         public <T> T sync(ReadInterface<T> r) throws DatabaseException {
2510                 return r.request(this);
2511         }
2512         
2513         @Override
2514         public <T> T sync(WriteInterface<T> r) throws DatabaseException {
2515                 return r.request(this);
2516         }
2517         
2518         @Override
2519         public <T> void async(WriteInterface<T> r, Procedure<T> procedure) {
2520                 r.request(this, procedure);
2521         }
2522
2523         @Override
2524         public <T> void async(WriteInterface<T> r) {
2525                 r.request(this, new ProcedureAdapter<T>());
2526         }
2527
2528         /*
2529          * Implementation of the interface AsyncReadGraph
2530          */
2531
2532         @Override
2533         public void forURI(Resource resource, AsyncListener<String> listener) {
2534                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2535                                 listener);
2536         }
2537
2538         @Override
2539         public void forURI(Resource resource, SyncListener<String> listener) {
2540                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2541                                 listener);
2542         }
2543
2544         @Override
2545         public void forURI(Resource resource, Listener<String> listener) {
2546                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2547                                 listener);
2548         }
2549
2550         @Override
2551         final public void forURI(final Resource resource,
2552                         final AsyncProcedure<String> procedure) {
2553
2554                 assert (resource != null);
2555                 assert (procedure != null);
2556
2557                 asyncRequest(new org.simantics.db.common.uri.ResourceToURI(resource),
2558                                 procedure);
2559
2560         }
2561
2562         @Override
2563         public void forURI(Resource resource, SyncProcedure<String> procedure) {
2564                 forURI(resource, new SyncToAsyncProcedure<String>(procedure));
2565         }
2566
2567         @Override
2568         public void forURI(Resource resource, Procedure<String> procedure) {
2569                 forURI(resource, new NoneToAsyncProcedure<String>(procedure));
2570         }
2571         
2572         @Override
2573         public void forResource(String id, AsyncListener<Resource> listener) {
2574                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2575                                 listener);
2576         }
2577
2578         @Override
2579         public void forResource(String id, SyncListener<Resource> listener) {
2580                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2581                                 listener);
2582         }
2583
2584         @Override
2585         public void forResource(String id, Listener<Resource> listener) {
2586                 asyncRequest(new org.simantics.db.common.primitiverequest.Resource(id),
2587                                 listener);
2588         }
2589
2590         @Override
2591         final public void forResource(final String id,
2592                         final AsyncProcedure<Resource> procedure) {
2593
2594                 assert (id != null);
2595                 assert (procedure != null);
2596
2597                 processor.forResource(this, id, procedure);
2598
2599         }
2600
2601         @Override
2602         public void forResource(String id, SyncProcedure<Resource> procedure) {
2603                 forResource(id, new SyncToAsyncProcedure<Resource>(procedure));
2604         }
2605
2606         @Override
2607         public void forResource(String id, Procedure<Resource> procedure) {
2608                 forResource(id, new NoneToAsyncProcedure<Resource>(procedure));
2609         }
2610
2611         @Override
2612         public void forBuiltin(String id, AsyncListener<Resource> listener) {
2613                 asyncRequest(new Builtin(id), listener);
2614         }
2615
2616         @Override
2617         public void forBuiltin(String id, SyncListener<Resource> listener) {
2618                 asyncRequest(new Builtin(id), listener);
2619         }
2620
2621         @Override
2622         public void forBuiltin(String id, Listener<Resource> listener) {
2623                 asyncRequest(new Builtin(id), listener);
2624         }
2625
2626         @Override
2627         final public void forBuiltin(final String id,
2628                         final AsyncProcedure<Resource> procedure) {
2629
2630                 assert (id != null);
2631                 assert (procedure != null);
2632
2633                 processor.forBuiltin(this, id, procedure);
2634
2635         }
2636
2637         @Override
2638         public void forBuiltin(String id, SyncProcedure<Resource> procedure) {
2639                 forBuiltin(id, new SyncToAsyncProcedure<Resource>(procedure));
2640         }
2641
2642         @Override
2643         public void forBuiltin(String id, Procedure<Resource> procedure) {
2644                 forBuiltin(id, new NoneToAsyncProcedure<Resource>(procedure));
2645         }
2646
2647         @Override
2648         final public void forEachStatement(Resource subject, Resource relation,
2649                         AsyncMultiProcedure<Statement> procedure) {
2650
2651                 assert (subject != null);
2652                 assert (relation != null);
2653                 assert (procedure != null);
2654
2655                 processor.forEachStatement(this, subject, relation, procedure);
2656
2657         }
2658
2659         @Override
2660         public void forEachStatement(Resource subject, Resource relation,
2661                         SyncMultiProcedure<Statement> procedure) {
2662                 forEachStatement(subject, relation,
2663                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2664         }
2665
2666         @Override
2667         final public void forEachStatement(Resource subject, Resource relation,
2668                         MultiProcedure<Statement> procedure) {
2669
2670                 assert (subject != null);
2671                 assert (relation != null);
2672                 assert (procedure != null);
2673
2674                 processor.forEachStatement(this, subject, relation, procedure);
2675
2676         }
2677
2678         @Override
2679         final public void forStatementSet(Resource subject, Resource relation,
2680                         AsyncSetListener<Statement> procedure) {
2681
2682                 assert (subject != null);
2683                 assert (relation != null);
2684                 assert (procedure != null);
2685
2686                 processor.forStatementSet(this, subject, relation, procedure);
2687
2688         }
2689
2690         @Override
2691         final public void forStatementSet(Resource subject, Resource relation,
2692                         SyncSetListener<Statement> procedure) {
2693                 forStatementSet(subject, relation,
2694                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2695         }
2696
2697         @Override
2698         public void forStatementSet(Resource subject, Resource relation,
2699                         SetListener<Statement> listener) {
2700                 forStatementSet(subject, relation,
2701                                 new NoneToAsyncSetProcedure<Statement>(listener));
2702         }
2703
2704         @Override
2705         final public void forEachAssertedStatement(final Resource subject,
2706                         final Resource relation,
2707                         final AsyncMultiProcedure<Statement> procedure) {
2708
2709                 assert (subject != null);
2710                 assert (relation != null);
2711                 assert (procedure != null);
2712
2713                 processor.forEachAssertedStatement(this, subject, relation, procedure);
2714
2715         }
2716
2717         @Override
2718         public void forEachAssertedStatement(Resource subject, Resource relation,
2719                         SyncMultiProcedure<Statement> procedure) {
2720                 forEachAssertedStatement(subject, relation,
2721                                 new SyncToAsyncMultiProcedure<Statement>(procedure));
2722         }
2723
2724         @Override
2725         public void forEachAssertedStatement(Resource subject, Resource relation,
2726                         MultiProcedure<Statement> procedure) {
2727                 forEachAssertedStatement(subject, relation,
2728                                 new NoneToAsyncMultiProcedure<Statement>(procedure));
2729         }
2730
2731         @Override
2732         public void forAssertedStatementSet(Resource subject, Resource relation,
2733                         AsyncSetListener<Statement> procedure) {
2734
2735                 assert (subject != null);
2736                 assert (relation != null);
2737                 assert (procedure != null);
2738
2739                 processor.forAssertedStatementSet(this, subject, relation, procedure);
2740
2741         }
2742
2743         @Override
2744         public void forAssertedStatementSet(Resource subject, Resource relation,
2745                         SyncSetListener<Statement> procedure) {
2746
2747                 assert (subject != null);
2748                 assert (relation != null);
2749                 assert (procedure != null);
2750
2751                 forAssertedStatementSet(subject, relation,
2752                                 new SyncToAsyncSetProcedure<Statement>(procedure));
2753
2754         }
2755
2756         @Override
2757         public void forAssertedStatementSet(Resource subject, Resource relation,
2758                         SetListener<Statement> procedure) {
2759
2760                 assert (subject != null);
2761                 assert (relation != null);
2762                 assert (procedure != null);
2763
2764                 forAssertedStatementSet(subject, relation,
2765                                 new NoneToAsyncSetProcedure<Statement>(procedure));
2766
2767         }
2768
2769         @Override
2770         final public void forEachPredicate(final Resource subject,
2771                         final AsyncMultiProcedure<Resource> procedure) {
2772
2773                 assert (subject != null);
2774                 assert (procedure != null);
2775
2776                 processor.forEachPredicate(this, subject, procedure);
2777
2778         }
2779
2780         @Override
2781         public void forEachPredicate(Resource subject,
2782                         SyncMultiProcedure<Resource> procedure) {
2783                 forEachPredicate(subject, new SyncToAsyncMultiProcedure<Resource>(
2784                                 procedure));
2785         }
2786
2787         @Override
2788         final public void forEachPredicate(final Resource subject,
2789                         final MultiProcedure<Resource> procedure) {
2790
2791                 assert (subject != null);
2792                 assert (procedure != null);
2793
2794                 processor.forEachPredicate(this, subject, procedure);
2795
2796         }
2797
2798         @Override
2799         final public void forPredicateSet(final Resource subject,
2800                         final AsyncSetListener<Resource> procedure) {
2801
2802                 assert (subject != null);
2803                 assert (procedure != null);
2804
2805                 processor.forPredicateSet(this, subject, procedure);
2806
2807         }
2808
2809         @Override
2810         final public void forPredicateSet(final Resource subject,
2811                         final SyncSetListener<Resource> procedure) {
2812
2813                 assert (subject != null);
2814                 assert (procedure != null);
2815
2816                 forPredicateSet(subject, new SyncToAsyncSetProcedure<Resource>(
2817                                 procedure));
2818
2819         }
2820
2821         @Override
2822         final public void forPredicateSet(final Resource subject,
2823                         final SetListener<Resource> procedure) {
2824
2825                 assert (subject != null);
2826                 assert (procedure != null);
2827
2828                 forPredicateSet(subject, new NoneToAsyncSetProcedure<Resource>(
2829                                 procedure));
2830
2831         }
2832
2833         @Override
2834         final public void forEachPrincipalType(final Resource subject,
2835                         final AsyncMultiProcedure<Resource> procedure) {
2836
2837                 assert (subject != null);
2838                 assert (procedure != null);
2839
2840                 processor.forEachPrincipalType(this, subject, procedure);
2841
2842         }
2843
2844         @Override
2845         public void forEachPrincipalType(Resource subject,
2846                         SyncMultiProcedure<Resource> procedure) {
2847                 forEachPrincipalType(subject, new SyncToAsyncMultiProcedure<Resource>(
2848                                 procedure));
2849         }
2850
2851         @Override
2852         final public void forEachPrincipalType(final Resource subject,
2853                         final MultiProcedure<Resource> procedure) {
2854
2855                 assert (subject != null);
2856                 assert (procedure != null);
2857
2858                 processor.forEachPrincipalType(this, subject, procedure);
2859
2860         }
2861
2862         @Override
2863         final public void forPrincipalTypeSet(final Resource subject,
2864                         final AsyncSetListener<Resource> procedure) {
2865
2866                 assert (subject != null);
2867                 assert (procedure != null);
2868
2869                 processor.forPrincipalTypeSet(this, subject, procedure);
2870
2871         }
2872
2873         @Override
2874         final public void forPrincipalTypeSet(final Resource subject,
2875                         final SyncSetListener<Resource> procedure) {
2876
2877                 assert (subject != null);
2878                 assert (procedure != null);
2879
2880                 forPrincipalTypeSet(subject, new SyncToAsyncSetProcedure<Resource>(
2881                                 procedure));
2882
2883         }
2884
2885         @Override
2886         final public void forPrincipalTypeSet(final Resource subject,
2887                         final SetListener<Resource> procedure) {
2888
2889                 assert (subject != null);
2890                 assert (procedure != null);
2891
2892                 forPrincipalTypeSet(subject, new NoneToAsyncSetProcedure<Resource>(
2893                                 procedure));
2894
2895         }
2896
2897         @Override
2898         public void forTypes(Resource subject, AsyncListener<Set<Resource>> listener) {
2899                 asyncRequest(new Types(subject), listener);
2900         }
2901
2902         @Override
2903         public void forTypes(Resource subject, SyncListener<Set<Resource>> listener) {
2904                 asyncRequest(new Types(subject), listener);
2905         }
2906
2907         @Override
2908         public void forTypes(Resource subject, Listener<Set<Resource>> listener) {
2909                 asyncRequest(new Types(subject), listener);
2910         }
2911
2912         @Override
2913         final public void forTypes(final Resource subject,
2914                         final AsyncProcedure<Set<Resource>> procedure) {
2915
2916                 assert (subject != null);
2917                 assert (procedure != null);
2918
2919                 processor.forTypes(this, subject, procedure);
2920
2921         }
2922
2923         @Override
2924         public void forTypes(Resource subject,
2925                         SyncProcedure<Set<Resource>> procedure) {
2926                 forTypes(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
2927         }
2928
2929         @Override
2930         public void forTypes(Resource subject, Procedure<Set<Resource>> procedure) {
2931                 forTypes(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
2932         }
2933
2934         @Override
2935         public void forSupertypes(Resource subject,
2936                         AsyncListener<Set<Resource>> listener) {
2937                 asyncRequest(new Types(subject), listener);
2938         }
2939
2940         @Override
2941         public void forSupertypes(Resource subject,
2942                         SyncListener<Set<Resource>> listener) {
2943                 asyncRequest(new Types(subject), listener);
2944         }
2945
2946         @Override
2947         public void forSupertypes(Resource subject, Listener<Set<Resource>> listener) {
2948                 asyncRequest(new Types(subject), listener);
2949         }
2950
2951         @Override
2952         final public void forSupertypes(final Resource subject,
2953                         final AsyncProcedure<Set<Resource>> procedure) {
2954
2955                 assert (subject != null);
2956                 assert (procedure != null);
2957
2958                 processor.forSupertypes(this, subject, procedure);
2959
2960         }
2961
2962         @Override
2963         public void forSupertypes(Resource subject,
2964                         SyncProcedure<Set<Resource>> procedure) {
2965                 forSupertypes(subject, new SyncToAsyncProcedure<Set<Resource>>(
2966                                 procedure));
2967         }
2968
2969         @Override
2970         public void forSupertypes(Resource subject,
2971                         Procedure<Set<Resource>> procedure) {
2972                 forSupertypes(subject, new NoneToAsyncProcedure<Set<Resource>>(
2973                                 procedure));
2974         }
2975
2976         @Override
2977         public void forDirectSuperrelations(Resource subject,
2978                         AsyncMultiProcedure<Resource> procedure) {
2979                 
2980                 assert (subject != null);
2981                 assert (procedure != null);
2982
2983                 processor.forDirectSuperrelations(this, subject, procedure);
2984                 
2985         }
2986
2987         @Override
2988         public void forPossibleSuperrelation(Resource subject, AsyncProcedure<Resource> procedure) {
2989                 
2990                 assert (subject != null);
2991                 assert (procedure != null);
2992
2993                 processor.forPossibleSuperrelation(this, subject, procedure);
2994                 
2995         }
2996
2997         @Override
2998         public void forSuperrelations(Resource subject,
2999                         AsyncListener<Set<Resource>> listener) {
3000                 asyncRequest(new Types(subject), listener);
3001         }
3002
3003         @Override
3004         public void forSuperrelations(Resource subject,
3005                         SyncListener<Set<Resource>> listener) {
3006                 asyncRequest(new Types(subject), listener);
3007         }
3008
3009         @Override
3010         public void forSuperrelations(Resource subject,
3011                         Listener<Set<Resource>> listener) {
3012                 asyncRequest(new Types(subject), listener);
3013         }
3014
3015         @Override
3016         final public void forSuperrelations(final Resource subject,
3017                         final AsyncProcedure<Set<Resource>> procedure) {
3018
3019                 assert (subject != null);
3020                 assert (procedure != null);
3021
3022                 processor.forSuperrelations(this, subject, procedure);
3023
3024         }
3025
3026         @Override
3027         public void forSuperrelations(Resource subject,
3028                         SyncProcedure<Set<Resource>> procedure) {
3029                 forSuperrelations(subject, new SyncToAsyncProcedure<Set<Resource>>(
3030                                 procedure));
3031         }
3032
3033         @Override
3034         public void forSuperrelations(Resource subject,
3035                         Procedure<Set<Resource>> procedure) {
3036                 forSuperrelations(subject, new NoneToAsyncProcedure<Set<Resource>>(
3037                                 procedure));
3038         }
3039
3040         @Override
3041         final public void forEachObject(final Resource subject, final Resource relation, final AsyncMultiProcedure<Resource> procedure) {
3042                 processor.forEachObject(this, subject, relation, procedure);
3043         }
3044
3045         @Override
3046         public void forEachObject(Resource subject, Resource relation,
3047                         SyncMultiProcedure<Resource> procedure) {
3048                 forEachObject(subject, relation,
3049                                 new SyncToAsyncMultiProcedure<Resource>(procedure));
3050         }
3051
3052         @Override
3053         public void forEachObject(Resource subject, Resource relation,
3054                         MultiProcedure<Resource> procedure) {
3055
3056                 processor.forEachObject(this, subject, relation, procedure);
3057
3058         }
3059
3060         @Override
3061         final public void forEachDirectPredicate(final Resource subject, final AsyncProcedure<Set<Resource>> procedure) {
3062                 processor.forEachDirectPredicate(this, subject, procedure);
3063         }
3064
3065         @Override
3066         final public void forEachDirectPredicate(final Resource subject, final SyncProcedure<Set<Resource>> procedure) {
3067                 forEachDirectPredicate(subject, new SyncToAsyncProcedure<Set<Resource>>(procedure));
3068         }
3069
3070         @Override
3071         public void forEachDirectPredicate(Resource subject, Procedure<Set<Resource>> procedure) {
3072                 forEachDirectPredicate(subject, new NoneToAsyncProcedure<Set<Resource>>(procedure));
3073         }
3074
3075         @Override
3076         final public void forObjectSet(final Resource subject,
3077                         final Resource relation, final AsyncSetListener<Resource> procedure) {
3078
3079                 assert (subject != null);
3080                 assert (relation != null);
3081                 assert (procedure != null);
3082
3083                 processor.forObjectSet(this, subject, relation, procedure);
3084
3085         }
3086
3087         @Override
3088         final public void forObjectSet(final Resource subject,
3089                         final Resource relation, final SyncSetListener<Resource> procedure) {
3090
3091                 assert (subject != null);
3092                 assert (relation != null);
3093                 assert (procedure != null);
3094
3095                 forObjectSet(subject, relation, new SyncToAsyncSetProcedure<Resource>(
3096                                 procedure));
3097
3098         }
3099
3100         @Override
3101         final public void forObjectSet(final Resource subject,
3102                         final Resource relation, final SetListener<Resource> procedure) {
3103
3104                 assert (subject != null);
3105                 assert (relation != null);
3106                 assert (procedure != null);
3107
3108                 forObjectSet(subject, relation, new NoneToAsyncSetProcedure<Resource>(
3109                                 procedure));
3110
3111         }
3112
3113         @Override
3114         final public void forEachAssertedObject(final Resource subject,
3115                         final Resource relation,
3116                         final AsyncMultiProcedure<Resource> procedure) {
3117
3118                 assert (subject != null);
3119                 assert (relation != null);
3120                 assert (procedure != null);
3121
3122                 processor.forEachAssertedObject(this, subject, relation, procedure);
3123
3124         }
3125
3126         @Override
3127         public void forEachAssertedObject(Resource subject, Resource relation,
3128                         SyncMultiProcedure<Resource> procedure) {
3129
3130                 assert (subject != null);
3131                 assert (relation != null);
3132                 assert (procedure != null);
3133
3134                 forEachAssertedObject(subject, relation,
3135                                 new SyncToAsyncMultiProcedure<Resource>(procedure));
3136
3137         }
3138
3139         @Override
3140         public void forEachAssertedObject(Resource subject, Resource relation,
3141                         MultiProcedure<Resource> procedure) {
3142
3143                 assert (subject != null);
3144                 assert (relation != null);
3145                 assert (procedure != null);
3146
3147                 forEachAssertedObject(subject, relation,
3148                                 new NoneToAsyncMultiProcedure<Resource>(procedure));
3149
3150         }
3151
3152         @Override
3153         public void forAssertedObjectSet(Resource subject, Resource relation,
3154                         AsyncSetListener<Resource> procedure) {
3155
3156                 assert (subject != null);
3157                 assert (relation != null);
3158                 assert (procedure != null);
3159
3160                 processor.forAssertedObjectSet(this, subject, relation, procedure);
3161
3162         }
3163
3164         @Override
3165         public void forAssertedObjectSet(Resource subject, Resource relation,
3166                         SyncSetListener<Resource> procedure) {
3167
3168                 assert (subject != null);
3169                 assert (relation != null);
3170                 assert (procedure != null);
3171
3172                 forAssertedObjectSet(subject, relation,
3173                                 new SyncToAsyncSetProcedure<Resource>(procedure));
3174
3175         }
3176
3177         @Override
3178         public void forAssertedObjectSet(Resource subject, Resource relation,
3179                         SetListener<Resource> procedure) {
3180
3181                 assert (subject != null);
3182                 assert (relation != null);
3183                 assert (procedure != null);
3184
3185                 forAssertedObjectSet(subject, relation,
3186                                 new NoneToAsyncSetProcedure<Resource>(procedure));
3187
3188         }
3189
3190         @Override
3191         public void forInverse(Resource relation, AsyncListener<Resource> listener) {
3192                 asyncRequest(new Inverse(relation), listener);
3193         }
3194
3195         @Override
3196         public void forInverse(Resource relation, SyncListener<Resource> listener) {
3197                 asyncRequest(new Inverse(relation), listener);
3198         }
3199
3200         @Override
3201         public void forInverse(Resource relation, Listener<Resource> listener) {
3202                 asyncRequest(new Inverse(relation), listener);
3203         }
3204
3205         @Override
3206         final public void forInverse(final Resource relation,
3207                         final AsyncProcedure<Resource> procedure) {
3208
3209                 assert (relation != null);
3210                 assert (procedure != null);
3211
3212                 processor.forInverse(this, relation, new AsyncProcedure<Resource>() {
3213
3214                         @Override
3215                         public void execute(AsyncReadGraph graph, Resource result) {
3216                                 if (result != null)
3217                                         procedure.execute(graph, result);
3218                                 else {
3219                                         procedure.exception(graph, new NoInverseException(relation
3220                                                         .toString()));
3221                                 }
3222                         }
3223
3224                         @Override
3225                         public void exception(AsyncReadGraph graph, Throwable throwable) {
3226                                 procedure.exception(graph, throwable);
3227                         }
3228
3229                         @Override
3230                         public String toString() {
3231                                 return "forInverse -> " + procedure;
3232                         }
3233
3234                 });
3235
3236         }
3237
3238         @Override
3239         public void forInverse(Resource relation, SyncProcedure<Resource> procedure) {
3240                 forInverse(relation, new SyncToAsyncProcedure<Resource>(procedure));
3241         }
3242
3243         @Override
3244         public void forInverse(Resource relation, Procedure<Resource> procedure) {
3245                 forInverse(relation, new NoneToAsyncProcedure<Resource>(procedure));
3246         }
3247
3248         @Override
3249         public void forSingleObject(Resource subject, Resource relation,
3250                         AsyncListener<Resource> listener) {
3251                 asyncRequest(new SingleObject(subject, relation), listener);
3252         }
3253
3254         @Override
3255         public void forSingleObject(Resource subject, Resource relation,
3256                         SyncListener<Resource> listener) {
3257                 asyncRequest(new SingleObject(subject, relation), listener);
3258         }
3259
3260         @Override
3261         public void forSingleObject(Resource subject, Resource relation,
3262                         Listener<Resource> listener) {
3263                 asyncRequest(new SingleObject(subject, relation), listener);
3264         }
3265
3266         @Override
3267         final public void forSingleObject(final Resource subject,
3268                         final Resource relation, final AsyncProcedure<Resource> procedure) {
3269
3270                 assert (subject != null);
3271                 assert (relation != null);
3272                 assert (procedure != null);
3273
3274                 processor.forEachObject(this, subject, relation,
3275                                 new SingleOrErrorProcedure<Resource>(procedure));
3276
3277         }
3278
3279         @Override
3280         public void forSingleObject(Resource subject, Resource relation,
3281                         SyncProcedure<Resource> procedure) {
3282                 forSingleObject(subject, relation, new SyncToAsyncProcedure<Resource>(
3283                                 procedure));
3284         }
3285
3286         @Override
3287         public void forSingleObject(Resource subject, Resource relation,
3288                         Procedure<Resource> procedure) {
3289                 forSingleObject(subject, relation, new NoneToAsyncProcedure<Resource>(
3290                                 procedure));
3291         }
3292
3293         @Override
3294         public void forSingleStatement(Resource subject, Resource relation,
3295                         AsyncListener<Statement> listener) {
3296                 asyncRequest(new SingleStatement(subject, relation), listener);
3297         }
3298
3299         @Override
3300         public void forSingleStatement(Resource subject, Resource relation,
3301                         SyncListener<Statement> listener) {
3302                 asyncRequest(new SingleStatement(subject, relation), listener);
3303         }
3304
3305         @Override
3306         public void forSingleStatement(Resource subject, Resource relation,
3307                         Listener<Statement> listener) {
3308                 asyncRequest(new SingleStatement(subject, relation), listener);
3309         }
3310
3311         @Override
3312         final public void forSingleStatement(final Resource subject,
3313                         final Resource relation, final AsyncProcedure<Statement> procedure) {
3314
3315                 assert (subject != null);
3316                 assert (relation != null);
3317                 assert (procedure != null);
3318
3319                 processor.forEachStatement(this, subject, relation,
3320                                 new SingleOrErrorProcedure<Statement>(procedure));
3321
3322         }
3323
3324         @Override
3325         public void forSingleStatement(Resource subject, Resource relation,
3326                         SyncProcedure<Statement> procedure) {
3327                 forSingleStatement(subject, relation,
3328                                 new SyncToAsyncProcedure<Statement>(procedure));
3329         }
3330
3331         @Override
3332         public void forSingleStatement(Resource subject, Resource relation,
3333                         Procedure<Statement> procedure) {
3334                 forSingleStatement(subject, relation,
3335                                 new NoneToAsyncProcedure<Statement>(procedure));
3336         }
3337
3338         @Override
3339         public void forSingleType(Resource subject,
3340                         AsyncListener<Resource> listener) {
3341                 asyncRequest(new SingleTypeAny(subject), listener);
3342         }
3343
3344         @Override
3345         public void forSingleType(Resource subject,
3346                         SyncListener<Resource> listener) {
3347                 asyncRequest(new SingleTypeAny(subject), listener);
3348         }
3349
3350         @Override
3351         public void forSingleType(Resource subject,
3352                         Listener<Resource> listener) {
3353                 asyncRequest(new SingleTypeAny(subject), listener);
3354         }
3355
3356         @Override
3357         final public void forSingleType(final Resource subject, final AsyncProcedure<Resource> procedure) {
3358
3359                 assert (subject != null);
3360                 assert (procedure != null);
3361
3362                 final DeepSingleOrErrorProcedure<Resource> checkedProcedure = new DeepSingleOrErrorProcedure<Resource>(procedure);
3363
3364                 processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter<Resource>() {
3365
3366                         @Override
3367                         public void execute(AsyncReadGraph graph, final Resource principalType) {
3368                                 checkedProcedure.offer(graph, principalType);
3369                         }
3370
3371                         @Override
3372                         public void finished(AsyncReadGraph graph) {
3373                                 checkedProcedure.dec(graph);
3374                         }
3375
3376                         @Override
3377                         public void exception(AsyncReadGraph graph, Throwable t) {
3378                                 checkedProcedure.exception(graph, t);
3379                         }
3380
3381                         @Override
3382                         public String toString() {
3383                                 return "forSingleType -> " + procedure;
3384                         }
3385
3386                 });
3387
3388         }
3389
3390         @Override
3391         public void forSingleType(Resource subject, SyncProcedure<Resource> procedure) {
3392                 forSingleType(subject, new SyncToAsyncProcedure<Resource>(
3393                                 procedure));
3394         }
3395
3396         @Override
3397         public void forSingleType(Resource subject, Procedure<Resource> procedure) {
3398                 forSingleType(subject, new NoneToAsyncProcedure<Resource>(
3399                                 procedure));
3400         }
3401
3402         @Override
3403         public void forSingleType(Resource subject, Resource relation,
3404                         AsyncListener<Resource> listener) {
3405                 asyncRequest(new SingleType(subject, relation), listener);
3406         }
3407
3408         @Override
3409         public void forSingleType(Resource subject, Resource relation,
3410                         SyncListener<Resource> listener) {
3411                 asyncRequest(new SingleType(subject, relation), listener);
3412         }
3413
3414         @Override
3415         public void forSingleType(Resource subject, Resource relation,
3416                         Listener<Resource> listener) {
3417                 asyncRequest(new SingleType(subject, relation), listener);
3418         }
3419
3420         @Override
3421         final public void forSingleType(final Resource subject,
3422                         final Resource baseType, final AsyncProcedure<Resource> procedure) {
3423
3424                 assert (subject != null);
3425                 assert (procedure != null);
3426
3427                 final DeepSingleOrErrorProcedure<Resource> checkedProcedure = new DeepSingleOrErrorProcedure<Resource>(procedure);
3428
3429                 processor.forEachPrincipalType(this, subject,
3430                                 new AsyncMultiProcedureAdapter<Resource>() {
3431
3432                                         @Override
3433                                         public void execute(AsyncReadGraph graph,
3434                                                         final Resource principalType) {
3435
3436                                                 checkedProcedure.inc();
3437
3438                                                 if(baseType == null) {
3439
3440                                                         checkedProcedure.offer(graph, principalType);
3441                                                         checkedProcedure.dec(graph);
3442
3443                                                 } else if(principalType.equals(baseType)) {
3444
3445                                                         checkedProcedure.offer(graph, principalType);
3446                                                         checkedProcedure.dec(graph);
3447
3448                                                 } else {
3449
3450                                                         processor.forSupertypes((ReadGraphImpl)graph, principalType,
3451                                                                         new AsyncProcedure<Set<Resource>>() {
3452
3453                                                                                 @Override
3454                                                                                 public void execute(
3455                                                                                                 AsyncReadGraph graph,
3456                                                                                                 Set<Resource> result) {
3457
3458                                                                                         if (result.contains(baseType))
3459                                                                                                 checkedProcedure.offer(graph,
3460                                                                                                                 principalType);
3461                                                                                         checkedProcedure.dec(graph);
3462
3463                                                                                 }
3464
3465                                                                                 @Override
3466                                                                                 public void exception(
3467                                                                                                 AsyncReadGraph graph,
3468                                                                                                 Throwable t) {
3469                                                                                         checkedProcedure
3470                                                                                                         .exception(graph, t);
3471                                                                                 }
3472
3473                                                                         });
3474
3475                                                 }
3476
3477                                         }
3478
3479                                         @Override
3480                                         public void finished(AsyncReadGraph graph) {
3481                                                 checkedProcedure.dec(graph);
3482                                         }
3483
3484                                         @Override
3485                                         public void exception(AsyncReadGraph graph, Throwable t) {
3486                                                 checkedProcedure.exception(graph, t);
3487                                         }
3488
3489                                         @Override
3490                                         public String toString() {
3491                                                 return "forSingleType -> " + procedure;
3492                                         }
3493
3494                                 });
3495
3496         }
3497
3498         @Override
3499         public void forSingleType(Resource subject, Resource relation,
3500                         SyncProcedure<Resource> procedure) {
3501                 forSingleType(subject, relation, new SyncToAsyncProcedure<Resource>(
3502                                 procedure));
3503         }
3504
3505         @Override
3506         public void forSingleType(Resource subject, Resource relation,
3507                         Procedure<Resource> procedure) {
3508                 forSingleType(subject, relation, new NoneToAsyncProcedure<Resource>(
3509                                 procedure));
3510         }
3511
3512         @Override
3513         public <T> void forValue(Resource subject, Binding binding,
3514                         AsyncListener<T> listener) {
3515                 asyncRequest(new Value<T>(subject, binding), listener);
3516         }
3517
3518         @Override
3519         public <T> void forValue(Resource subject, Binding binding,
3520                         SyncListener<T> listener) {
3521                 asyncRequest(new Value<T>(subject, binding), listener);
3522         }
3523
3524         @Override
3525         public <T> void forValue(Resource subject, Binding binding,
3526                         Listener<T> listener) {
3527                 asyncRequest(new Value<T>(subject, binding), listener);
3528         }
3529
3530         @Override
3531         public <T> void forValue(final Resource resource, final Binding binding,
3532                         final AsyncProcedure<T> procedure) {
3533
3534                 assert (resource != null);
3535                 assert (binding != null);
3536                 assert (procedure != null);
3537                 
3538                 processor.forValue(this, resource, new AsyncProcedure<byte[]>() {
3539
3540                         @Override
3541                         public void execute(AsyncReadGraph graph, byte[] result) {
3542                                 
3543                                 try {
3544
3545                                         if (result == null) {
3546                                                 procedure.exception(graph,
3547                                                                 new DoesNotContainValueException(
3548                                                                                 "No value for resource " + resource));
3549                                                 return;
3550                                         }
3551
3552                                         Serializer serializer = binding.serializer();
3553 //                                      Serializer serializer = Bindings.getSerializer( binding );
3554                                         Object obj = serializer.deserialize(result);
3555 //                                      if (!binding.isInstance(obj))
3556 //                                              procedure.exception(graph, new ClassCastException(
3557 //                                                              "Cannot get value " + obj + " with binding "
3558 //                                                                              + binding));
3559 //                                      else
3560                                                 procedure.execute(graph, (T) obj);
3561
3562                                 } catch (IOException e) {
3563                                         procedure.exception(graph, e);
3564                                 } catch (BufferUnderflowException e) {
3565                                         procedure.exception(graph, e);
3566                                 } catch (Throwable t) {
3567                                         procedure.exception(graph, t);
3568                                 }
3569
3570                         }
3571
3572                         @Override
3573                         public void exception(AsyncReadGraph graph, Throwable t) {
3574                                 try {
3575                                         procedure.exception(graph, t);
3576                                 } catch (Throwable t2) {
3577                                 Logger.defaultLogError(t2);
3578                                 }
3579                         }
3580
3581                         @Override
3582                         public String toString() {
3583                                 return "forValue -> " + procedure;
3584                         }
3585
3586                 });
3587
3588         }
3589
3590         @Override
3591         public <T> void forValue(Resource subject, Binding binding,
3592                         SyncProcedure<T> procedure) {
3593                 forValue(subject, binding, new SyncToAsyncProcedure<T>(procedure));
3594         }
3595
3596         @Override
3597         public <T> void forValue(Resource subject, Binding binding,
3598                         Procedure<T> procedure) {
3599                 forValue(subject, binding, new NoneToAsyncProcedure<T>(procedure));
3600         }
3601
3602         @Override
3603         public <T> void forValue(Resource subject, AsyncListener<T> listener) {
3604                 asyncRequest(new ValueImplied<T>(subject), listener);
3605         }
3606
3607         @Override
3608         public <T> void forValue(Resource subject, SyncListener<T> listener) {
3609                 asyncRequest(new ValueImplied<T>(subject), listener);
3610         }
3611
3612         @Override
3613         public <T> void forValue(Resource subject, Listener<T> listener) {
3614                 asyncRequest(new ValueImplied<T>(subject), listener);
3615         }
3616
3617         @Override
3618         final public <T> void forValue(final Resource subject, final AsyncProcedure<T> procedure) {
3619
3620                 assert (subject != null);
3621                 assert (procedure != null);
3622                 
3623                 forRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure<Datatype>() {
3624
3625                         @Override
3626                         public void execute(AsyncReadGraph graph, Datatype type) {
3627                                 // TODO: consider trying Bindings.getBeanBinding(type);
3628                                 Binding binding = Bindings.getBinding(type);
3629                                 graph.forValue(subject, binding, procedure);
3630                         }
3631
3632                         @Override
3633                         public void exception(AsyncReadGraph graph, Throwable throwable) {
3634                                 procedure.exception(graph, new DoesNotContainValueException("Invalid data type", throwable));
3635                         }
3636                         
3637                 });
3638
3639         }
3640
3641         @Override
3642         public <T> void forValue(Resource subject, SyncProcedure<T> procedure) {
3643                 forValue(subject, new SyncToAsyncProcedure<T>(procedure));
3644         }
3645
3646         @Override
3647         public <T> void forValue(Resource subject, Procedure<T> procedure) {
3648                 forValue(subject, new NoneToAsyncProcedure<T>(procedure));
3649         }
3650
3651         @Override
3652         public <T> void forRelatedValue(Resource subject, Resource relation,
3653                         AsyncListener<T> listener) {
3654                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3655         }
3656
3657         @Override
3658         public <T> void forRelatedValue(Resource subject, Resource relation,
3659                         SyncListener<T> listener) {
3660                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3661         }
3662
3663         @Override
3664         public <T> void forRelatedValue(Resource subject, Resource relation,
3665                         Listener<T> listener) {
3666                 asyncRequest(new RelatedValueImplied<T>(subject, relation), listener);
3667         }
3668
3669         @Override
3670         final public <T> void forRelatedValue(final Resource subject,
3671                         final Resource relation, final AsyncProcedure<T> procedure) {
3672
3673                 assert (subject != null);
3674                 assert (relation != null);
3675                 assert (procedure != null);
3676
3677                 final DeepSingleOrErrorProcedure<T> checkedProcedure = new DeepSingleOrErrorProcedure<T>(procedure);
3678
3679                 processor.forEachObject(this, subject, relation,
3680                                 new AsyncMultiProcedureAdapter<Resource>() {
3681
3682                                         @Override
3683                                         public void execute(AsyncReadGraph graph,
3684                                                         final Resource object) {
3685
3686                                                 checkedProcedure.inc();
3687
3688                                                 graph.forValue(object, new AsyncProcedure<Object>() {
3689
3690                                                         @Override
3691                                                         public void execute(AsyncReadGraph graph,
3692                                                                         Object result) {
3693                                                                 checkedProcedure.offer(graph, (T) result);
3694                                                                 checkedProcedure.dec(graph);
3695                                                         }
3696
3697                                                         @Override
3698                                                         public void exception(AsyncReadGraph graph,
3699                                                                         Throwable t) {
3700                                                                 checkedProcedure.exception(graph, t);
3701                                                         }
3702
3703                                                         @Override
3704                                                         public String toString() {
3705                                                                 return "forRelatedValue -> " + procedure;
3706                                                         }
3707
3708                                                 });
3709
3710                                         }
3711
3712                                         @Override
3713                                         public void finished(AsyncReadGraph graph) {
3714                                                 checkedProcedure.dec(graph);
3715                                         }
3716
3717                                         @Override
3718                                         public void exception(AsyncReadGraph graph, Throwable t) {
3719                                                 checkedProcedure.exception(graph, t);
3720                                         }
3721
3722                                 });
3723
3724         }
3725
3726         @Override
3727         public <T> void forRelatedValue(Resource subject, Resource relation,
3728                         SyncProcedure<T> procedure) {
3729                 forRelatedValue(subject, relation, new SyncToAsyncProcedure<T>(
3730                                 procedure));
3731         }
3732
3733         @Override
3734         public <T> void forRelatedValue(Resource subject, Resource relation,
3735                         Procedure<T> procedure) {
3736                 forRelatedValue(subject, relation, new NoneToAsyncProcedure<T>(
3737                                 procedure));
3738         }
3739
3740         @Override
3741         public <T> void forRelatedValue(Resource subject, Resource relation,
3742                         Binding binding, AsyncListener<T> listener) {
3743                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3744         }
3745
3746         @Override
3747         public <T> void forRelatedValue(Resource subject, Resource relation,
3748                         Binding binding, SyncListener<T> listener) {
3749                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3750         }
3751
3752         @Override
3753         public <T> void forRelatedValue(Resource subject, Resource relation,
3754                         Binding binding, Listener<T> listener) {
3755                 asyncRequest(new RelatedValue<T>(subject, relation, binding), listener);
3756         }
3757
3758         @Override
3759         final public <T> void forRelatedValue(final Resource subject,
3760                         final Resource relation, final Binding binding,
3761                         final AsyncProcedure<T> procedure) {
3762
3763                 assert (subject != null);
3764                 assert (relation != null);
3765                 assert (binding != null);
3766                 assert (procedure != null);
3767
3768                 final DeepSingleOrErrorProcedure<T> checkedProcedure = new DeepSingleOrErrorProcedure<T>(procedure);
3769                 
3770                 processor.forEachObject(this, subject, relation,
3771                                 new AsyncMultiProcedureAdapter<Resource>() {
3772
3773                                         @Override
3774                                         public void execute(AsyncReadGraph graph,
3775                                                         final Resource object) {
3776
3777                                                 checkedProcedure.inc();
3778
3779                                                 graph.forValue(object, binding, new AsyncProcedure<Object>() {
3780
3781                                                                         @Override
3782                                                                         public void execute(AsyncReadGraph graph,
3783                                                                                         Object result) {
3784                                                                                 
3785                                                                                 checkedProcedure.offer(graph,
3786                                                                                                 (T) result);
3787                                                                                 checkedProcedure.dec(graph);
3788                                                                         }
3789
3790                                                                         @Override
3791                                                                         public void exception(AsyncReadGraph graph,
3792                                                                                         Throwable t) {
3793                                                                                 checkedProcedure.exception(graph, t);
3794                                                                         }
3795
3796                                                                         @Override
3797                                                                         public String toString() {
3798                                                                                 return "forRelatedValue -> "
3799                                                                                                 + procedure;
3800                                                                         }
3801
3802                                                                 });
3803
3804                                         }
3805
3806                                         @Override
3807                                         public void finished(AsyncReadGraph graph) {
3808                                                 checkedProcedure.dec(graph);
3809                                         }
3810
3811                                         @Override
3812                                         public void exception(AsyncReadGraph graph, Throwable t) {
3813                                                 checkedProcedure.exception(graph, t);
3814                                         }
3815
3816                                 });
3817
3818         }
3819
3820         @Override
3821         public <T> void forRelatedValue(Resource subject, Resource relation,
3822                         Binding binding, SyncProcedure<T> procedure) {
3823                 forRelatedValue(subject, relation, binding,
3824                                 new SyncToAsyncProcedure<T>(procedure));
3825         }
3826
3827         @Override
3828         public <T> void forRelatedValue(Resource subject, Resource relation,
3829                         Binding binding, Procedure<T> procedure) {
3830                 forRelatedValue(subject, relation, binding,
3831                                 new NoneToAsyncProcedure<T>(procedure));
3832         }
3833
3834         @Override
3835         public <T> void forAdapted(Resource resource, Class<T> clazz,
3836                         AsyncListener<T> listener) {
3837                 asyncRequest(new Adapter<T>(resource, clazz), listener);
3838         }
3839
3840         @Override
3841         public <T> void forAdapted(Resource resource, Class<T> clazz,
3842                         SyncListener<T> listener) {
3843                 asyncRequest(new Adapter<T>(resource, clazz), listener);
3844         }
3845
3846         @Override
3847         public <T> void forAdapted(Resource resource, Class<T> clazz,
3848                         Listener<T> listener) {
3849                 asyncRequest(new Adapter<T>(resource, clazz), listener);
3850         }
3851
3852         @Override
3853         final public <T> void forAdapted(final Resource resource,
3854                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
3855
3856                 assert (resource != null);
3857                 assert (clazz != null);
3858                 assert (procedure != null);
3859
3860                 final AdaptionService service = getSession().peekService(AdaptionService.class);
3861                 if (service == null)
3862                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
3863                 else
3864                         service.adapt(this, resource, resource, Resource.class, clazz, false, procedure); 
3865
3866         }
3867
3868         @Override
3869         public <T> void forAdapted(Resource resource, Class<T> clazz,
3870                         SyncProcedure<T> procedure) {
3871                 forAdapted(resource, clazz, new SyncToAsyncProcedure<T>(procedure));
3872         }
3873
3874         @Override
3875         public <T> void forAdapted(Resource resource, Class<T> clazz,
3876                         Procedure<T> procedure) {
3877                 forAdapted(resource, clazz, new NoneToAsyncProcedure<T>(procedure));
3878         }
3879
3880         @Override
3881         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3882                         AsyncListener<T> listener) {
3883                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
3884         }
3885
3886         @Override
3887         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3888                         SyncListener<T> listener) {
3889                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
3890         }
3891
3892         @Override
3893         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3894                         Listener<T> listener) {
3895                 asyncRequest(new UniqueAdapter<T>(resource, clazz), listener);
3896         }
3897
3898         @Override
3899         final public <T> void forUniqueAdapted(final Resource resource,
3900                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
3901
3902                 assert (resource != null);
3903                 assert (clazz != null);
3904                 assert (procedure != null);
3905
3906                 final AdaptionService service = getSession().peekService(AdaptionService.class);
3907                 if (service == null)
3908                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
3909                 else
3910                         service.adaptNew(this, resource, clazz, false, procedure);
3911
3912         }
3913
3914         @Override
3915         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3916                         SyncProcedure<T> procedure) {
3917                 forUniqueAdapted(resource, clazz,
3918                                 new SyncToAsyncProcedure<T>(procedure));
3919         }
3920
3921         @Override
3922         public <T> void forUniqueAdapted(Resource resource, Class<T> clazz,
3923                         Procedure<T> procedure) {
3924                 forUniqueAdapted(resource, clazz,
3925                                 new NoneToAsyncProcedure<T>(procedure));
3926         }
3927
3928         @Override
3929         public void forPossibleInverse(Resource subject,
3930                         AsyncListener<Resource> listener) {
3931                 asyncRequest(new PossibleInverse(subject), listener);
3932         }
3933
3934         @Override
3935         public void forPossibleInverse(Resource subject,
3936                         SyncListener<Resource> listener) {
3937                 asyncRequest(new PossibleInverse(subject), listener);
3938         }
3939
3940         @Override
3941         public void forPossibleInverse(Resource subject, Listener<Resource> listener) {
3942                 asyncRequest(new PossibleInverse(subject), listener);
3943         }
3944
3945         @Override
3946         final public void forPossibleInverse(final Resource relation,
3947                         final AsyncProcedure<Resource> procedure) {
3948
3949                 assert (relation != null);
3950                 assert (procedure != null);
3951
3952                 processor.forInverse(this, relation, new ExceptionToNullProcedure<Resource>(procedure));
3953
3954         }
3955
3956         @Override
3957         public void forPossibleInverse(Resource subject,
3958                         SyncProcedure<Resource> procedure) {
3959                 forPossibleInverse(subject, new SyncToAsyncProcedure<Resource>(
3960                                 procedure));
3961         }
3962
3963         @Override
3964         public void forPossibleInverse(Resource subject,
3965                         Procedure<Resource> procedure) {
3966                 forPossibleInverse(subject, new NoneToAsyncProcedure<Resource>(
3967                                 procedure));
3968         }
3969
3970         @Override
3971         public void forPossibleObject(Resource subject, Resource relation,
3972                         AsyncListener<Resource> listener) {
3973                 asyncRequest(new PossibleObject(subject, relation), listener);
3974         }
3975
3976         @Override
3977         public void forPossibleObject(Resource subject, Resource relation,
3978                         SyncListener<Resource> listener) {
3979                 asyncRequest(new PossibleObject(subject, relation), listener);
3980         }
3981
3982         @Override
3983         public void forPossibleObject(Resource subject, Resource relation,
3984                         Listener<Resource> listener) {
3985                 asyncRequest(new PossibleObject(subject, relation), listener);
3986         }
3987
3988         @Override
3989         final public void forPossibleObject(final Resource subject,
3990                         final Resource relation, final AsyncProcedure<Resource> procedure) {
3991
3992                 assert (subject != null);
3993                 assert (relation != null);
3994                 assert (procedure != null);
3995
3996                 processor.forEachObject(this, subject, relation,
3997                                 new SingleOrNullProcedure<Resource>(procedure));
3998
3999         }
4000
4001         @Override
4002         public void forPossibleObject(Resource subject, Resource relation,
4003                         SyncProcedure<Resource> procedure) {
4004                 forPossibleObject(subject, relation,
4005                                 new SyncToAsyncProcedure<Resource>(procedure));
4006         }
4007
4008         @Override
4009         public void forPossibleObject(Resource subject, Resource relation,
4010                         Procedure<Resource> procedure) {
4011                 forPossibleObject(subject, relation,
4012                                 new NoneToAsyncProcedure<Resource>(procedure));
4013         }
4014
4015         @Override
4016         public void forPossibleStatement(Resource subject, Resource relation,
4017                         AsyncListener<Statement> listener) {
4018                 asyncRequest(new PossibleStatement(subject, relation), listener);
4019         }
4020
4021         @Override
4022         public void forPossibleStatement(Resource subject, Resource relation,
4023                         SyncListener<Statement> listener) {
4024                 asyncRequest(new PossibleStatement(subject, relation), listener);
4025         }
4026
4027         @Override
4028         public void forPossibleStatement(Resource subject, Resource relation,
4029                         Listener<Statement> listener) {
4030                 asyncRequest(new PossibleStatement(subject, relation), listener);
4031         }
4032
4033         @Override
4034         final public void forPossibleStatement(final Resource subject,
4035                         final Resource relation, final AsyncProcedure<Statement> procedure) {
4036
4037                 assert (subject != null);
4038                 assert (relation != null);
4039                 assert (procedure != null);
4040
4041                 processor.forEachStatement(this, subject, relation,
4042                                 new SingleFunctionalOrNullProcedure<Statement>(
4043                                                 "forPossibleStatement", procedure));
4044
4045         }
4046
4047         @Override
4048         public void forPossibleStatement(Resource subject, Resource relation,
4049                         SyncProcedure<Statement> procedure) {
4050                 forPossibleStatement(subject, relation,
4051                                 new SyncToAsyncProcedure<Statement>(procedure));
4052         }
4053
4054         @Override
4055         public void forPossibleStatement(Resource subject, Resource relation,
4056                         Procedure<Statement> procedure) {
4057                 forPossibleStatement(subject, relation,
4058                                 new NoneToAsyncProcedure<Statement>(procedure));
4059         }
4060
4061         @Override
4062         public void forPossibleType(Resource subject, Resource relation,
4063                         AsyncListener<Resource> listener) {
4064                 asyncRequest(new PossibleType(subject, relation), listener);
4065         }
4066
4067         @Override
4068         public void forPossibleType(Resource subject, Resource relation,
4069                         SyncListener<Resource> listener) {
4070                 asyncRequest(new PossibleType(subject, relation), listener);
4071         }
4072
4073         @Override
4074         public void forPossibleType(Resource subject, Resource relation,
4075                         Listener<Resource> listener) {
4076                 asyncRequest(new PossibleType(subject, relation), listener);
4077         }
4078
4079         @Override
4080         final public void forPossibleType(final Resource subject,
4081                         final Resource baseType, final AsyncProcedure<Resource> procedure) {
4082
4083                 assert (subject != null);
4084                 assert (procedure != null);
4085
4086                 final NullSingleOrNullProcedure<Resource> checkedProcedure = new NullSingleOrNullProcedure<Resource>(procedure);
4087
4088                 processor.forEachPrincipalType(this, subject, new AsyncMultiProcedureAdapter<Resource>() {
4089
4090                                         @Override
4091                                         public void execute(AsyncReadGraph graph,
4092                                                         final Resource principalType) {
4093
4094                                                 if (baseType == null) {
4095
4096                                                         checkedProcedure.offer(graph, principalType);
4097
4098                                                 } else if (principalType.equals(baseType)) {
4099
4100                                                         checkedProcedure.offer(graph, principalType);
4101
4102                                                 } else {
4103
4104                                                         checkedProcedure.inc();
4105
4106                                                         processor.forSupertypes((ReadGraphImpl)graph, principalType,
4107                                                                         new AsyncProcedure<Set<Resource>>() {
4108
4109                                                                                 @Override
4110                                                                                 public void execute(
4111                                                                                                 AsyncReadGraph graph,
4112                                                                                                 Set<Resource> result) {
4113
4114                                                                                         if (result.contains(baseType)) {
4115                                                                                                 checkedProcedure.offer(graph,
4116                                                                                                                 principalType);
4117                                                                                         }
4118
4119                                                                                         checkedProcedure.dec(graph);
4120
4121                                                                                 }
4122
4123                                                                                 @Override
4124                                                                                 public void exception(
4125                                                                                                 AsyncReadGraph graph,
4126                                                                                                 Throwable t) {
4127                                                                                         checkedProcedure.exception(graph, t);
4128                                                                                         checkedProcedure.dec(graph);
4129                                                                                 }
4130
4131                                                                                 @Override
4132                                                                                 public String toString() {
4133                                                                                         return "forPossibleType -> "
4134                                                                                                         + procedure;
4135                                                                                 }
4136
4137                                                                         });
4138
4139                                                 }
4140
4141                                         }
4142
4143                                         @Override
4144                                         public void finished(AsyncReadGraph graph) {
4145                                                 checkedProcedure.dec(graph);
4146                                         }
4147
4148                                         @Override
4149                                         public void exception(AsyncReadGraph graph, Throwable t) {
4150                                                 checkedProcedure.exception(graph, t);
4151                                                 checkedProcedure.dec(graph);
4152                                         }
4153
4154                                 });
4155
4156         }
4157
4158         @Override
4159         public void forPossibleType(Resource subject, Resource relation,
4160                         SyncProcedure<Resource> procedure) {
4161                 forPossibleType(subject, relation, new SyncToAsyncProcedure<Resource>(
4162                                 procedure));
4163         }
4164
4165         @Override
4166         public void forPossibleType(Resource subject, Resource relation,
4167                         Procedure<Resource> procedure) {
4168                 forPossibleType(subject, relation, new NoneToAsyncProcedure<Resource>(
4169                                 procedure));
4170         }
4171
4172         @Override
4173         public <T> void forPossibleValue(Resource subject, AsyncListener<T> listener) {
4174                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4175         }
4176
4177         @Override
4178         public <T> void forPossibleValue(Resource subject, SyncListener<T> listener) {
4179                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4180         }
4181
4182         @Override
4183         public <T> void forPossibleValue(Resource subject, Listener<T> listener) {
4184                 asyncRequest(new PossibleValueImplied<T>(subject), listener);
4185         }
4186
4187         @Override
4188         final public <T> void forPossibleValue(final Resource subject,
4189                         final AsyncProcedure<T> procedure) {
4190
4191                 assert (subject != null);
4192                 assert (procedure != null);
4193                 
4194                 forPossibleRelatedValue(subject, processor.getL0(this).HasDataType, DATA_TYPE_BINDING_INTERNAL, new AsyncProcedure<Datatype>() {
4195
4196                         @Override
4197                         public void execute(AsyncReadGraph graph, final Datatype type) {
4198                                 if (type == null) {
4199                                         procedure.execute(graph, null);
4200                                 } else {
4201                                         try {
4202                                                 // TODO: consider trying Bindings.getBeanBinding(type);
4203                                                 Binding binding = Bindings.getBinding(type);
4204                                                 graph.forPossibleValue(subject, binding, procedure);
4205                                         } catch (RuntimeBindingConstructionException e) {
4206                                                 procedure.exception(graph, e);
4207                                         }
4208                                 }
4209                         }
4210
4211                         @Override
4212                         public void exception(AsyncReadGraph graph, Throwable t) {
4213                                 procedure.exception(graph, t);
4214                         }
4215
4216                         @Override
4217                         public String toString() {
4218                                 return "forPossibleValue -> " + procedure;
4219                         }
4220
4221                 });
4222
4223         }
4224
4225         @Override
4226         public <T> void forPossibleValue(Resource subject,
4227                         SyncProcedure<T> procedure) {
4228                 forPossibleValue(subject, new SyncToAsyncProcedure<T>(procedure));
4229         }
4230
4231         @Override
4232         public <T> void forPossibleValue(Resource subject, Procedure<T> procedure) {
4233                 forPossibleValue(subject, new NoneToAsyncProcedure<T>(procedure));
4234         }
4235
4236         @Override
4237         public <T> void forPossibleValue(Resource subject, Binding binding,
4238                         AsyncListener<T> listener) {
4239                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4240         }
4241
4242         @Override
4243         public <T> void forPossibleValue(Resource subject, Binding binding,
4244                         SyncListener<T> listener) {
4245                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4246         }
4247
4248         @Override
4249         public <T> void forPossibleValue(Resource subject, Binding binding,
4250                         Listener<T> listener) {
4251                 asyncRequest(new PossibleValue<T>(subject, binding), listener);
4252         }
4253
4254         @Override
4255         final public <T> void forPossibleValue(final Resource resource,
4256                         final Binding binding, final AsyncProcedure<T> procedure) {
4257
4258                 assert (resource != null);
4259                 assert (binding != null);
4260                 assert (procedure != null);
4261
4262                 processor.forValue(this, resource, new AsyncProcedure<byte[]>() {
4263
4264                         @Override
4265                         public void execute(AsyncReadGraph graph, byte[] result) {
4266
4267                                 try {
4268
4269                                         if (result == null) {
4270                                                 procedure.execute(graph, null);
4271                                                 return;
4272                                         }
4273
4274                                         Serializer serializer = Bindings.getSerializer( binding );
4275                                         Object obj = serializer.deserialize(result);
4276                                         if (!binding.isInstance(obj))
4277                                                 procedure.exception(graph, new ClassCastException(
4278                                                                 "Cannot get value " + obj + " with binding "
4279                                                                                 + binding));
4280                                         else
4281                                                 procedure.execute(graph, (T) obj);
4282
4283                                 } catch (IOException e) {
4284                                         procedure.exception(graph, e);
4285                                 } catch (BufferUnderflowException e) {
4286                                         procedure.exception(graph, e);
4287                                 } catch (Throwable t) {
4288                                         procedure.exception(graph, t);
4289                                 }
4290
4291                         }
4292
4293                         @Override
4294                         public void exception(AsyncReadGraph graph, Throwable t) {
4295                                 try {
4296                                         procedure.exception(graph, t);
4297                                 } catch (Throwable t2) {
4298                                 Logger.defaultLogError(t2);
4299                                 }
4300                         }
4301
4302                         @Override
4303                         public String toString() {
4304                                 return "forPossibleValue -> " + procedure;
4305                         }
4306
4307                 });
4308
4309         }
4310
4311         @Override
4312         public <T> void forPossibleValue(Resource subject, Binding binding,
4313                         SyncProcedure<T> procedure) {
4314                 forPossibleValue(subject, binding, new SyncToAsyncProcedure<T>(
4315                                 procedure));
4316         }
4317
4318         @Override
4319         public <T> void forPossibleValue(Resource subject, Binding binding,
4320                         Procedure<T> procedure) {
4321                 forPossibleValue(subject, binding, new NoneToAsyncProcedure<T>(
4322                                 procedure));
4323         }
4324
4325         @Override
4326         public <T> void forPossibleRelatedValue(Resource subject,
4327                         Resource relation, AsyncListener<T> listener) {
4328                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4329                                 listener);
4330         }
4331
4332         @Override
4333         public <T> void forPossibleRelatedValue(Resource subject,
4334                         Resource relation, SyncListener<T> listener) {
4335                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4336                                 listener);
4337         }
4338
4339         @Override
4340         public <T> void forPossibleRelatedValue(Resource subject,
4341                         Resource relation, Listener<T> listener) {
4342                 asyncRequest(new PossibleRelatedValueImplied<T>(subject, relation),
4343                                 listener);
4344         }
4345
4346         @Override
4347         final public <T> void forPossibleRelatedValue(final Resource subject,
4348                         final Resource relation, final AsyncProcedure<T> procedure) {
4349
4350                 assert (subject != null);
4351                 assert (relation != null);
4352                 assert (procedure != null);
4353
4354                 final DeepSingleOrNullProcedure<T> checkedProcedure = new DeepSingleOrNullProcedure<T>(procedure);
4355                 
4356                 processor.forEachObject(this, subject, relation,
4357                                 new AsyncMultiProcedureAdapter<Resource>() {
4358
4359                                         @Override
4360                                         public void execute(AsyncReadGraph graph,
4361                                                         final Resource object) {
4362
4363                                                 checkedProcedure.inc();
4364
4365                                                 graph.forValue(object, new AsyncProcedure<Object>() {
4366
4367                                                         @Override
4368                                                         public void execute(AsyncReadGraph graph,
4369                                                                         Object result) {
4370                                                                 checkedProcedure.offer(graph, (T) result);
4371                                                                 checkedProcedure.dec(graph);
4372                                                         }
4373
4374                                                         @Override
4375                                                         public void exception(AsyncReadGraph graph,
4376                                                                         Throwable t) {
4377                                                                 checkedProcedure.exception(graph, t);
4378                                                                 checkedProcedure.dec(graph);
4379                                                         }
4380
4381                                                 });
4382
4383                                         }
4384
4385                                         @Override
4386                                         public void finished(AsyncReadGraph graph) {
4387
4388                                                 checkedProcedure.dec(graph);
4389                                         }
4390
4391                                         @Override
4392                                         public void exception(AsyncReadGraph graph, Throwable t) {
4393                                                 checkedProcedure.exception(graph, t);
4394                                                 checkedProcedure.dec(graph);
4395                                         }
4396
4397                                         @Override
4398                                         public String toString() {
4399                                                 return "forPossibleRelatedValue -> " + procedure;
4400                                         }
4401                                 });
4402
4403         }
4404
4405         @Override
4406         public <T> void forPossibleRelatedValue(Resource subject,
4407                         Resource relation, SyncProcedure<T> procedure) {
4408                 forPossibleRelatedValue(subject, relation, new SyncToAsyncProcedure<T>(
4409                                 procedure));
4410         }
4411
4412         @Override
4413         public <T> void forPossibleRelatedValue(Resource subject,
4414                         Resource relation, Procedure<T> procedure) {
4415                 forPossibleRelatedValue(subject, relation, new NoneToAsyncProcedure<T>(
4416                                 procedure));
4417         }
4418
4419         @Override
4420         public <T> void forPossibleRelatedValue(Resource subject,
4421                         Resource relation, Binding binding, AsyncListener<T> listener) {
4422                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4423                                 listener);
4424         }
4425
4426         @Override
4427         public <T> void forPossibleRelatedValue(Resource subject,
4428                         Resource relation, Binding binding, SyncListener<T> listener) {
4429                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4430                                 listener);
4431         }
4432
4433         @Override
4434         public <T> void forPossibleRelatedValue(Resource subject,
4435                         Resource relation, Binding binding, Listener<T> listener) {
4436                 asyncRequest(new PossibleRelatedValue<T>(subject, relation, binding),
4437                                 listener);
4438         }
4439
4440         final public <T> void forPossibleRelatedValue(final Resource subject, final Resource relation, final Binding binding,
4441                         final AsyncProcedure<T> procedure) {
4442
4443                 assert (subject != null);
4444                 assert (relation != null);
4445                 assert (procedure != null);
4446
4447                 processor.forPossibleObject(this, subject, relation, new AsyncProcedure<Resource>() {
4448                         
4449                         @Override
4450                         public void execute(AsyncReadGraph graph, Resource object) {
4451                                 
4452                                 if(object == null) {
4453                                         procedure.execute(graph, null);
4454                                         return;
4455                                 }
4456
4457                                 processor.forPossibleValue((ReadGraphImpl)graph, object, new AsyncProcedure<byte[]>() {
4458
4459                                         @Override
4460                                         public void execute(AsyncReadGraph graph, byte[] bytes) {
4461
4462                                                 if(bytes != null) {
4463
4464                                                         try {
4465                                                         
4466                                                                 Serializer serializer = binding.serializer();
4467                                                                 Object obj = serializer.deserialize(bytes);
4468                                                                 if (!binding.isInstance(obj)) {
4469                                                                         procedure.exception(graph, new ClassCastException("Cannot get value " + obj + " with binding " + binding));
4470                                                                 } else {
4471                                                                         procedure.execute(graph, (T) obj);
4472                                                                 }
4473
4474                                                         } catch (Throwable t) {
4475                                                                 
4476                                                                 procedure.exception(graph, t);
4477                                                                 
4478                                                         }
4479                                                         
4480                                                 } else {
4481                                                         
4482                                                         procedure.execute(graph, null);
4483                                                         
4484                                                 }
4485                                                 
4486                                         }
4487
4488                                         @Override
4489                                         public void exception(AsyncReadGraph graph, Throwable t) {
4490                                                 procedure.exception(graph, t);
4491                                         }
4492
4493                                 });
4494                                 
4495                         }
4496                         
4497                         @Override
4498                         public void exception(AsyncReadGraph graph, Throwable throwable) {
4499                                 throwable.printStackTrace();
4500                                 procedure.exception(graph, throwable);
4501                         }
4502                         
4503                 });
4504
4505         }
4506
4507         @Override
4508         public <T> void forPossibleRelatedValue(Resource subject,
4509                         Resource relation, Binding binding, SyncProcedure<T> procedure) {
4510                 forPossibleRelatedValue(subject, relation, binding,
4511                                 new SyncToAsyncProcedure<T>(procedure));
4512         }
4513
4514         @Override
4515         public <T> void forPossibleRelatedValue(Resource subject,
4516                         Resource relation, Binding binding, Procedure<T> procedure) {
4517                 forPossibleRelatedValue(subject, relation, binding,
4518                                 new NoneToAsyncProcedure<T>(procedure));
4519         }
4520
4521         @Override
4522         public void forIsInstanceOf(Resource subject, Resource relation,
4523                         AsyncListener<Boolean> listener) {
4524                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4525         }
4526
4527         @Override
4528         public void forIsInstanceOf(Resource subject, Resource relation,
4529                         SyncListener<Boolean> listener) {
4530                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4531         }
4532
4533         @Override
4534         public void forIsInstanceOf(Resource subject, Resource relation,
4535                         Listener<Boolean> listener) {
4536                 asyncRequest(new IsInstanceOf(subject, relation), listener);
4537         }
4538
4539         @Override
4540         final public void forIsInstanceOf(final Resource resource,
4541                         final Resource type, final AsyncProcedure<Boolean> procedure) {
4542
4543                 assert (resource != null);
4544                 assert (type != null);
4545                 assert (procedure != null);
4546
4547                 forTypes(resource, new AsyncProcedure<Set<Resource>>() {
4548
4549                         @Override
4550                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4551                                 
4552                                 try {
4553                                         if (result.contains(type))
4554                                                 procedure.execute(graph, true);
4555                                         else
4556                                                 procedure.execute(graph, false);
4557                                 } catch (Throwable t) {
4558                                 Logger.defaultLogError(t);
4559                                 }
4560                         }
4561
4562                         @Override
4563                         public void exception(AsyncReadGraph graph, Throwable t) {
4564                                 try {
4565                                         procedure.exception(graph, t);
4566                                 } catch (Throwable t2) {
4567                                 Logger.defaultLogError(t2);
4568                                 }
4569                         }
4570
4571                         @Override
4572                         public String toString() {
4573                                 return "forIsInstanceOf -> " + procedure;
4574                         }
4575
4576                 });
4577
4578         }
4579
4580         @Override
4581         public void forIsInstanceOf(Resource subject, Resource relation,
4582                         SyncProcedure<Boolean> procedure) {
4583                 forIsInstanceOf(subject, relation, new SyncToAsyncProcedure<Boolean>(
4584                                 procedure));
4585         }
4586
4587         @Override
4588         public void forIsInstanceOf(Resource subject, Resource relation,
4589                         Procedure<Boolean> procedure) {
4590                 forIsInstanceOf(subject, relation, new NoneToAsyncProcedure<Boolean>(
4591                                 procedure));
4592         }
4593
4594         @Override
4595         public void forIsInheritedFrom(Resource subject, Resource relation,
4596                         AsyncListener<Boolean> listener) {
4597                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4598         }
4599
4600         @Override
4601         public void forIsInheritedFrom(Resource subject, Resource relation,
4602                         SyncListener<Boolean> listener) {
4603                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4604         }
4605
4606         @Override
4607         public void forIsInheritedFrom(Resource subject, Resource relation,
4608                         Listener<Boolean> listener) {
4609                 asyncRequest(new IsInheritedFrom(subject, relation), listener);
4610         }
4611
4612         @Override
4613         final public void forIsInheritedFrom(final Resource resource,
4614                         final Resource type, final AsyncProcedure<Boolean> procedure) {
4615
4616                 assert (resource != null);
4617                 assert (type != null);
4618                 assert (procedure != null);
4619
4620                 if (resource.equals(type)) {
4621                         try {
4622                                 procedure.execute(this, true);
4623                         } catch (Throwable t) {
4624                         Logger.defaultLogError(t);
4625                         }
4626                         return;
4627                 }
4628
4629                 forSupertypes(resource, new AsyncProcedure<Set<Resource>>() {
4630
4631                         @Override
4632                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4633                                 try {
4634                                         if (result.contains(type))
4635                                                 procedure.execute(graph, true);
4636                                         else
4637                                                 procedure.execute(graph, false);
4638                                 } catch (Throwable t) {
4639                                 Logger.defaultLogError(t);
4640                                 }
4641                         }
4642
4643                         @Override
4644                         public void exception(AsyncReadGraph graph, Throwable t) {
4645                                 try {
4646                                         procedure.exception(graph, t);
4647                                 } catch (Throwable t2) {
4648                                 Logger.defaultLogError(t2);
4649                                 }
4650                         }
4651
4652                         @Override
4653                         public String toString() {
4654                                 return "forIsInheritedFrom -> " + procedure;
4655                         }
4656
4657                 });
4658
4659         }
4660
4661         @Override
4662         public void forIsInheritedFrom(Resource subject, Resource relation,
4663                         SyncProcedure<Boolean> procedure) {
4664                 forIsInheritedFrom(subject, relation,
4665                                 new SyncToAsyncProcedure<Boolean>(procedure));
4666         }
4667
4668         @Override
4669         public void forIsInheritedFrom(Resource subject, Resource relation,
4670                         Procedure<Boolean> procedure) {
4671                 forIsInheritedFrom(subject, relation,
4672                                 new NoneToAsyncProcedure<Boolean>(procedure));
4673         }
4674
4675         @Override
4676         public void forIsSubrelationOf(Resource subject, Resource relation,
4677                         AsyncListener<Boolean> listener) {
4678                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4679         }
4680
4681         @Override
4682         public void forIsSubrelationOf(Resource subject, Resource relation,
4683                         SyncListener<Boolean> listener) {
4684                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4685         }
4686
4687         @Override
4688         public void forIsSubrelationOf(Resource subject, Resource relation,
4689                         Listener<Boolean> listener) {
4690                 asyncRequest(new IsSubrelationOf(subject, relation), listener);
4691         }
4692
4693         @Override
4694         final public void forIsSubrelationOf(final Resource resource,
4695                         final Resource relation, final AsyncProcedure<Boolean> procedure) {
4696
4697                 assert (resource != null);
4698                 assert (relation != null);
4699                 assert (procedure != null);
4700
4701                 if (resource.equals(relation)) {
4702                         procedure.execute(this, true);
4703                         return;
4704                 }
4705
4706                 forSuperrelations(resource, new AsyncProcedure<Set<Resource>>() {
4707
4708                         @Override
4709                         public void execute(AsyncReadGraph graph, Set<Resource> result) {
4710                                 try {
4711                                         if (result.contains(relation))
4712                                                 procedure.execute(graph, true);
4713                                         else
4714                                                 procedure.execute(graph, false);
4715                                 } catch (Throwable t) {
4716                                 Logger.defaultLogError(t);
4717                                 }
4718                         }
4719
4720                         @Override
4721                         public void exception(AsyncReadGraph graph, Throwable t) {
4722                                 try {
4723                                         procedure.exception(graph, t);
4724                                 } catch (Throwable t2) {
4725                                 Logger.defaultLogError(t2);
4726                                 }
4727                         }
4728
4729                         @Override
4730                         public String toString() {
4731                                 return "forIsSubrelationOf -> " + procedure;
4732                         }
4733
4734                 });
4735
4736         }
4737
4738         @Override
4739         public void forIsSubrelationOf(Resource subject, Resource relation,
4740                         SyncProcedure<Boolean> procedure) {
4741                 forIsSubrelationOf(subject, relation,
4742                                 new SyncToAsyncProcedure<Boolean>(procedure));
4743         }
4744
4745         @Override
4746         public void forIsSubrelationOf(Resource subject, Resource relation,
4747                         Procedure<Boolean> procedure) {
4748                 forIsSubrelationOf(subject, relation,
4749                                 new NoneToAsyncProcedure<Boolean>(procedure));
4750         }
4751
4752         @Override
4753         public void forHasStatement(Resource subject,
4754                         AsyncListener<Boolean> listener) {
4755                 asyncRequest(new HasStatementSubject(subject), listener);
4756         }
4757
4758         @Override
4759         public void forHasStatement(Resource subject, SyncListener<Boolean> listener) {
4760                 asyncRequest(new HasStatementSubject(subject), listener);
4761         }
4762
4763         @Override
4764         public void forHasStatement(Resource subject, Listener<Boolean> listener) {
4765                 asyncRequest(new HasStatementSubject(subject), listener);
4766         }
4767
4768         @Override
4769         final public void forHasStatement(final Resource subject,
4770                         final AsyncProcedure<Boolean> procedure) {
4771
4772                 assert (subject != null);
4773                 assert (procedure != null);
4774
4775                 processor.forHasStatement(this, subject, procedure);
4776
4777         }
4778
4779         @Override
4780         public void forHasStatement(Resource subject,
4781                         SyncProcedure<Boolean> procedure) {
4782                 forHasStatement(subject, new SyncToAsyncProcedure<Boolean>(procedure));
4783         }
4784
4785         @Override
4786         public void forHasStatement(Resource subject, Procedure<Boolean> procedure) {
4787                 forHasStatement(subject, new NoneToAsyncProcedure<Boolean>(procedure));
4788         }
4789
4790         @Override
4791         public void forHasStatement(Resource subject, Resource relation,
4792                         AsyncListener<Boolean> listener) {
4793                 asyncRequest(new HasStatement(subject, relation), listener);
4794         }
4795
4796         @Override
4797         public void forHasStatement(Resource subject, Resource relation,
4798                         SyncListener<Boolean> listener) {
4799                 asyncRequest(new HasStatement(subject, relation), listener);
4800         }
4801
4802         @Override
4803         public void forHasStatement(Resource subject, Resource relation,
4804                         Listener<Boolean> listener) {
4805                 asyncRequest(new HasStatement(subject, relation), listener);
4806         }
4807
4808         @Override
4809         final public void forHasStatement(final Resource subject,
4810                         final Resource relation, final AsyncProcedure<Boolean> procedure) {
4811
4812                 assert (subject != null);
4813                 assert (relation != null);
4814                 assert (procedure != null);
4815
4816                 processor.forHasStatement(this, subject, relation, procedure);
4817
4818         }
4819
4820         @Override
4821         public void forHasStatement(Resource subject, Resource relation,
4822                         SyncProcedure<Boolean> procedure) {
4823                 forHasStatement(subject, relation, new SyncToAsyncProcedure<Boolean>(
4824                                 procedure));
4825         }
4826
4827         @Override
4828         public void forHasStatement(Resource subject, Resource relation,
4829                         Procedure<Boolean> procedure) {
4830                 forHasStatement(subject, relation, new NoneToAsyncProcedure<Boolean>(
4831                                 procedure));
4832         }
4833
4834         @Override
4835         public void forHasStatement(Resource subject, Resource relation,
4836                         Resource object, AsyncListener<Boolean> listener) {
4837                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
4838                                 listener);
4839         }
4840
4841         @Override
4842         public void forHasStatement(Resource subject, Resource relation,
4843                         Resource object, SyncListener<Boolean> listener) {
4844                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
4845                                 listener);
4846         }
4847
4848         @Override
4849         public void forHasStatement(Resource subject, Resource relation,
4850                         Resource object, Listener<Boolean> listener) {
4851                 asyncRequest(new HasStatementSubjectObject(subject, relation, object),
4852                                 listener);
4853         }
4854
4855         @Override
4856         final public void forHasStatement(final Resource subject,
4857                         final Resource relation, final Resource object,
4858                         final AsyncProcedure<Boolean> procedure) {
4859
4860                 assert (subject != null);
4861                 assert (relation != null);
4862                 assert (object != null);
4863                 assert (procedure != null);
4864
4865                 processor.forHasStatement(this, subject, relation, object, procedure);
4866
4867         }
4868
4869         @Override
4870         public void forHasStatement(Resource subject, Resource relation,
4871                         Resource object, SyncProcedure<Boolean> procedure) {
4872                 forHasStatement(subject, relation, object,
4873                                 new SyncToAsyncProcedure<Boolean>(procedure));
4874         }
4875
4876         @Override
4877         public void forHasStatement(Resource subject, Resource relation,
4878                         Resource object, Procedure<Boolean> procedure) {
4879                 forHasStatement(subject, relation, object,
4880                                 new NoneToAsyncProcedure<Boolean>(procedure));
4881         }
4882
4883         @Override
4884         public void forHasValue(Resource subject, AsyncListener<Boolean> listener) {
4885                 asyncRequest(new HasValue(subject), listener);
4886         }
4887
4888         @Override
4889         public void forHasValue(Resource subject, SyncListener<Boolean> listener) {
4890                 asyncRequest(new HasValue(subject), listener);
4891         }
4892
4893         @Override
4894         public void forHasValue(Resource subject, Listener<Boolean> listener) {
4895                 asyncRequest(new HasValue(subject), listener);
4896         }
4897
4898         @Override
4899         final public void forHasValue(final Resource subject,
4900                         final AsyncProcedure<Boolean> procedure) {
4901
4902                 assert (subject != null);
4903                 assert (procedure != null);
4904
4905                 processor.forValue(this, subject, new AsyncProcedure<byte[]>() {
4906
4907                         @Override
4908                         public void execute(AsyncReadGraph graph, byte[] result) {
4909                                 try {
4910                                         if (result == null)
4911                                                 procedure.execute(graph, false);
4912                                         else
4913                                                 procedure.execute(graph, true);
4914                                 } catch (Throwable t) {
4915                                 Logger.defaultLogError(t);
4916                                 }
4917                         }
4918
4919                         @Override
4920                         public void exception(AsyncReadGraph graph, Throwable t) {
4921                                 try {
4922                                         procedure.exception(graph, t);
4923                                 } catch (Throwable t2) {
4924                                 Logger.defaultLogError(t2);
4925                                 }
4926                         }
4927
4928                         @Override
4929                         public String toString() {
4930                                 return "forHasValue -> " + procedure;
4931                         }
4932
4933                 });
4934
4935         }
4936
4937         @Override
4938         public void forHasValue(Resource subject, SyncProcedure<Boolean> procedure) {
4939                 forHasValue(subject, new SyncToAsyncProcedure<Boolean>(procedure));
4940         }
4941
4942         @Override
4943         public void forHasValue(Resource subject, Procedure<Boolean> procedure) {
4944                 forHasValue(subject, new NoneToAsyncProcedure<Boolean>(procedure));
4945         }
4946
4947         @Override
4948         public void forOrderedSet(Resource subject,
4949                         AsyncMultiListener<Resource> listener) {
4950                 asyncRequest(new OrderedSet(subject), listener);
4951         }
4952
4953         @Override
4954         public void forOrderedSet(Resource subject,
4955                         SyncMultiListener<Resource> listener) {
4956                 asyncRequest(new OrderedSet(subject), listener);
4957         }
4958
4959         @Override
4960         public void forOrderedSet(Resource subject, MultiListener<Resource> listener) {
4961                 asyncRequest(new OrderedSet(subject), listener);
4962         }
4963
4964         @Override
4965         final public void forOrderedSet(final Resource subject,
4966                         final AsyncMultiProcedure<Resource> procedure) {
4967
4968                 assert (subject != null);
4969                 assert (procedure != null);
4970
4971                 processor.forOrderedSet(this, subject,
4972                                 new AsyncMultiProcedure<Resource>() {
4973
4974                                         @Override
4975                                         public void finished(AsyncReadGraph graph) {
4976                                                 try {
4977                                                         procedure.finished(graph);
4978                                                 } catch (Throwable t) {
4979                                                 Logger.defaultLogError(t);
4980                                                 }
4981                                         }
4982
4983                                         @Override
4984                                         public void execute(AsyncReadGraph graph, Resource result) {
4985                                                 try {
4986                                                         procedure.execute(graph, result);
4987                                                 } catch (Throwable t) {
4988                                                 Logger.defaultLogError(t);
4989                                                 }
4990                                         }
4991
4992                                         @Override
4993                                         public void exception(AsyncReadGraph graph, Throwable t) {
4994                                                 try {
4995                                                         procedure.exception(graph, t);
4996                                                 } catch (Throwable t2) {
4997                                                 Logger.defaultLogError(t2);
4998                                                 }
4999                                         }
5000
5001                                         @Override
5002                                         public String toString() {
5003                                                 return "forOrderedSet -> " + procedure;
5004                                         }
5005
5006                                 });
5007
5008         }
5009
5010         @Override
5011         public void forOrderedSet(Resource subject,
5012                         SyncMultiProcedure<Resource> procedure) {
5013                 forOrderedSet(subject, new SyncToAsyncMultiProcedure<Resource>(
5014                                 procedure));
5015         }
5016
5017         @Override
5018         public void forOrderedSet(Resource subject,
5019                         MultiProcedure<Resource> procedure) {
5020                 forOrderedSet(subject, new NoneToAsyncMultiProcedure<Resource>(
5021                                 procedure));
5022         }
5023
5024         @Override
5025         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5026                         AsyncListener<T> listener) {
5027                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5028         }
5029
5030         @Override
5031         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5032                         SyncListener<T> listener) {
5033                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5034         }
5035
5036         @Override
5037         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5038                         Listener<T> listener) {
5039                 asyncRequest(new PossibleAdapter<T>(resource, clazz), listener);
5040         }
5041
5042         @Override
5043         final public <T> void forPossibleAdapted(final Resource resource,
5044                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
5045
5046                 assert (resource != null);
5047                 assert (clazz != null);
5048                 assert (procedure != null);
5049
5050                 final AdaptionService service = getSession().peekService(AdaptionService.class);
5051                 if (service == null)
5052                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
5053                 else
5054                         service.adapt(this, resource, resource, Resource.class, clazz, true, procedure);
5055         }
5056
5057         @Override
5058         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5059                         SyncProcedure<T> procedure) {
5060                 forPossibleAdapted(resource, clazz, new SyncToAsyncProcedure<T>(
5061                                 procedure));
5062         }
5063
5064         @Override
5065         public <T> void forPossibleAdapted(Resource resource, Class<T> clazz,
5066                         Procedure<T> procedure) {
5067                 forPossibleAdapted(resource, clazz, new NoneToAsyncProcedure<T>(
5068                                 procedure));
5069         }
5070
5071         @Override
5072         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5073                         AsyncListener<T> listener) {
5074                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5075         }
5076
5077         @Override
5078         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5079                         SyncListener<T> listener) {
5080                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5081         }
5082
5083         @Override
5084         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5085                         Listener<T> listener) {
5086                 asyncRequest(new PossibleUniqueAdapter<T>(resource, clazz), listener);
5087         }
5088
5089         @Override
5090         final public <T> void forPossibleUniqueAdapted(final Resource resource,
5091                         final Class<T> clazz, final AsyncProcedure<T> procedure) {
5092
5093                 assert (resource != null);
5094                 assert (clazz != null);
5095                 assert (procedure != null);
5096
5097                 final AdaptionService service = getSession().peekService(AdaptionService.class);
5098                 if (service == null)
5099                         procedure.exception(this, new ServiceException("No AdaptionService available")); 
5100                 else
5101                         service.adaptNew(this, resource, clazz, true, procedure);
5102
5103         }
5104
5105         @Override
5106         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5107                         SyncProcedure<T> procedure) {
5108                 forPossibleUniqueAdapted(resource, clazz, new SyncToAsyncProcedure<T>(
5109                                 procedure));
5110         }
5111
5112         @Override
5113         public <T> void forPossibleUniqueAdapted(Resource resource, Class<T> clazz,
5114                         Procedure<T> procedure) {
5115                 forPossibleUniqueAdapted(resource, clazz, new NoneToAsyncProcedure<T>(
5116                                 procedure));
5117         }
5118
5119         /*
5120          * Implementation of the interface AsyncRequestProcessor
5121          */
5122
5123         @Override
5124         final public Session getSession() {
5125                 return processor.getSession();
5126         }
5127
5128         @Override
5129         public <T> void asyncRequest(final Read<T> request) {
5130
5131                 asyncRequest(request, new AsyncProcedure<T>() {
5132
5133                         @Override
5134                         public void execute(AsyncReadGraph graph, T result) {
5135                         }
5136
5137                         @Override
5138                         public void exception(AsyncReadGraph graph, Throwable t) {
5139                                 Logger.defaultLogError(t);
5140                         }
5141
5142                         @Override
5143                         public String toString() {
5144                                 return "asyncRequest(Read) -> " + request;
5145                         }
5146
5147                 });
5148
5149         }
5150
5151         @Override
5152         public <T> void asyncRequest(Read<T> request, AsyncListener<T> procedure) {
5153                 asyncRequest(request, (AsyncProcedure<T>) procedure);
5154         }
5155
5156         @Override
5157         public <T> void asyncRequest(Read<T> request,
5158                         final SyncListener<T> procedure) {
5159                 asyncRequest(request, new SyncToAsyncListener<T>(procedure));
5160         }
5161
5162         @Override
5163         public <T> void asyncRequest(Read<T> request, final Listener<T> procedure) {
5164                 asyncRequest(request, new NoneToAsyncListener<T>(procedure));
5165         }
5166
5167         @Override
5168         public <T> void asyncRequest(final Read<T> request, final AsyncProcedure<T> procedure) {
5169
5170                 assert (request != null);
5171                 assert (procedure != null);
5172         
5173                 processor.schedule(new SessionTask(this) {
5174
5175                         @Override
5176                         public void run(int thread) {
5177                                 try {
5178                                         final ListenerBase listener = getListenerBase(procedure);
5179                                         QueryCache.runnerReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
5180                                 } catch (DatabaseException e) {
5181                                         Logger.defaultLogError(e);
5182                                 }
5183                         }
5184                         
5185                 });
5186
5187         }
5188
5189     public static ReadGraphImpl createAsync(QueryProcessor support) {
5190         return new ReadGraphImpl(null, null, support);
5191     }
5192
5193         @Override
5194         public <T> void asyncRequest(Read<T> request, SyncProcedure<T> procedure) {
5195                 asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
5196         }
5197
5198         @Override
5199         public <T> void asyncRequest(Read<T> request, final Procedure<T> procedure) {
5200                 asyncRequest(request, new NoneToAsyncProcedure<T>(procedure));
5201         }
5202
5203         @Override
5204         final public <T> void asyncRequest(final AsyncRead<T> request) {
5205
5206                 assert (request != null);
5207
5208                 asyncRequest(request, new AsyncProcedure<T>() {
5209
5210                         @Override
5211                         public void execute(AsyncReadGraph graph, T result) {
5212                         }
5213
5214                         @Override
5215                         public void exception(AsyncReadGraph graph, Throwable t) {
5216                         Logger.defaultLogError(t);
5217                         }
5218
5219                         @Override
5220                         public String toString() {
5221                                 return "asyncRequest(AsyncRead) -> " + request;
5222                         }
5223
5224                 });
5225
5226         }
5227
5228         @Override
5229         public <T> void asyncRequest(AsyncRead<T> request,
5230                         AsyncListener<T> procedure) {
5231                 asyncRequest(request, (AsyncProcedure<T>) procedure);
5232         }
5233
5234         @Override
5235         final public <T> void asyncRequest(AsyncRead<T> request,
5236                         final SyncListener<T> procedure) {
5237                 asyncRequest(request, new SyncToAsyncListener<T>(procedure));
5238         }
5239
5240         @Override
5241         final public <T> void asyncRequest(AsyncRead<T> request,
5242                         final Listener<T> procedure) {
5243                 asyncRequest(request, new NoneToAsyncListener<T>(procedure));
5244         }
5245
5246         @Override
5247         final public <T> void asyncRequest(final AsyncRead<T> request,
5248                         final AsyncProcedure<T> procedure) {
5249
5250                 assert (request != null);
5251                 assert (procedure != null);
5252
5253                 processor.schedule(new SessionTask(this) {
5254
5255                         @Override
5256                         public void run(int thread) {
5257                                 try {
5258                                         final ListenerBase listener = getListenerBase(procedure);
5259                                         QueryCache.runnerAsyncReadEntry(ReadGraphImpl.this, request, parent, listener, procedure, false);
5260                                 } catch (DatabaseException e) {
5261                                         Logger.defaultLogError(e);
5262                                 }
5263                         }
5264                         
5265                 });
5266
5267         }
5268
5269         @Override
5270         public <T> void asyncRequest(AsyncRead<T> request,
5271                         SyncProcedure<T> procedure) {
5272                 asyncRequest(request, new SyncToAsyncProcedure<T>(procedure));
5273         }
5274
5275         @Override
5276         final public <T> void asyncRequest(final AsyncRead<T> request,
5277                         final Procedure<T> procedure) {
5278                 asyncRequest(request, new NoneToAsyncProcedure<T>(procedure));
5279         }
5280
5281         @Override
5282         public <T> void asyncRequest(final MultiRead<T> request) {
5283
5284                 assert (request != null);
5285
5286                 asyncRequest(request, new SyncMultiProcedureAdapter<T>() {
5287                         @Override
5288                         public void exception(ReadGraph graph, Throwable t) {
5289                         Logger.defaultLogError(t);
5290                         }
5291
5292                         @Override
5293                         public String toString() {
5294                                 return "asyncRequest(MultiRead) -> " + request;
5295                         }
5296                 });
5297
5298         }
5299
5300         @Override
5301         public <T> void asyncRequest(MultiRead<T> request,
5302                         SyncMultiListener<T> procedure) {
5303                 asyncRequest(request, (SyncMultiProcedure<T>)procedure);
5304         }
5305
5306         @Override
5307         public <T> void asyncRequest(MultiRead<T> request,
5308                         MultiListener<T> procedure) {
5309                 asyncRequest(request, new NoneToSyncMultiListener<T>(procedure));
5310         }
5311
5312         
5313         @Override
5314         public <T> void asyncRequest(final MultiRead<T> request,
5315                         final SyncMultiProcedure<T> procedure) {
5316
5317                 assert (request != null);
5318                 assert (procedure != null);
5319
5320                 final ListenerBase listener = getListenerBase(procedure);
5321
5322                 if (parent != null || listener != null) {
5323
5324 //                  final ReadGraphImpl newGraph = newSync();
5325                     processor.query(this, request, parent, procedure,listener);
5326
5327                 } else {
5328
5329 //                  final ReadGraphImpl newGraph = newSync();
5330
5331                     try {
5332
5333                         request.perform(this, procedure);
5334
5335                     } catch (Throwable t) {
5336
5337                         try {
5338                                         procedure.exception(this, t);
5339                                 } catch (DatabaseException e) {
5340                                         LOGGER.error("Unexpected exception while handling exception", e);
5341                                 }
5342
5343                     }                           
5344
5345                 }
5346
5347         }
5348
5349         @Override
5350         public <T> void asyncRequest(MultiRead<T> request,
5351                         MultiProcedure<T> procedure) {
5352                 asyncRequest(request, new NoneToSyncMultiProcedure<T>(procedure));
5353         }
5354
5355         @Override
5356         final public <T> void asyncRequest(final AsyncMultiRead<T> request) {
5357
5358                 assert (request != null);
5359
5360                 asyncRequest(request, new AsyncMultiProcedureAdapter<T>() {
5361                         @Override
5362                         public void exception(AsyncReadGraph graph, Throwable t) {
5363                         Logger.defaultLogError(t);
5364                         }
5365
5366                         @Override
5367                         public String toString() {
5368                                 return "asyncRequest(AsyncMultiRead) -> " + request;
5369                         }
5370                 });
5371
5372         }
5373
5374         @Override
5375         public <T> void asyncRequest(AsyncMultiRead<T> request,
5376                         AsyncMultiListener<T> procedure) {
5377                 asyncRequest(request, (AsyncMultiProcedure<T>) procedure);
5378         }
5379
5380         @Override
5381         public <T> void asyncRequest(AsyncMultiRead<T> request,
5382                         SyncMultiListener<T> procedure) {
5383                 asyncRequest(request, new SyncToAsyncMultiListener<T>(procedure));
5384         }
5385
5386         @Override
5387         public <T> void asyncRequest(AsyncMultiRead<T> request,
5388                         MultiListener<T> procedure) {
5389                 asyncRequest(request, new NoneToAsyncMultiListener<T>(procedure));
5390         }
5391
5392         @Override
5393         final public <T> void asyncRequest(AsyncMultiRead<T> request,
5394                         final AsyncMultiProcedure<T> procedure) {
5395
5396                 assert (request != null);
5397                 assert (procedure != null);
5398
5399                 ListenerBase listener = getListenerBase(procedure);
5400
5401                 if (parent != null || listener != null) {
5402
5403                         processor.query(this, request, parent, procedure, listener);
5404
5405                 } else {
5406
5407                         try {
5408
5409                                 request.perform(this, new AsyncMultiProcedure<T>() {
5410
5411                                         @Override
5412                                         public void execute(AsyncReadGraph graph, T result) {
5413                                                 procedure.execute(graph, result);
5414                                         }
5415
5416                                         @Override
5417                                         public void finished(AsyncReadGraph graph) {
5418                                                 procedure.finished(graph);
5419                                         }
5420
5421                                         @Override
5422                                         public void exception(AsyncReadGraph graph, Throwable t) {
5423                                                 procedure.exception(graph, t);
5424                                         }
5425
5426                                         @Override
5427                                         public String toString() {
5428                                                 return "asyncRequest(AsyncMultiRead) -> " + procedure;
5429                                         }
5430
5431                                 });
5432
5433                         } catch (Throwable t) {
5434
5435                                 procedure.exception(this, new DatabaseException(t));
5436
5437                         }
5438                 }
5439
5440         }
5441
5442         @Override
5443         public <T> void asyncRequest(AsyncMultiRead<T> request,
5444                         SyncMultiProcedure<T> procedure) {
5445                 asyncRequest(request, new SyncToAsyncMultiProcedure<T>(procedure));
5446         }
5447
5448         @Override
5449         final public <T> void asyncRequest(AsyncMultiRead<T> request,
5450                         final MultiProcedure<T> procedure) {
5451                 asyncRequest(request, new NoneToAsyncMultiProcedure<T>(procedure));
5452         }
5453
5454         @Override
5455         final public <T> void asyncRequest(final ExternalRead<T> request) {
5456
5457                 assert (request != null);
5458
5459                 asyncRequest(request, new Procedure<T>() {
5460
5461                         @Override
5462                         public void execute(T result) {
5463                         }
5464
5465                         @Override
5466                         public void exception(Throwable t) {
5467                         Logger.defaultLogError(t);
5468                         }
5469
5470                         @Override
5471                         public String toString() {
5472                                 return "asyncRequest(PrimitiveRead) -> " + request;
5473                         }
5474
5475                 });
5476
5477         }
5478
5479         @Override
5480         public <T> void asyncRequest(ExternalRead<T> request,
5481                         final Listener<T> procedure) {
5482                 asyncRequest(request, (Procedure<T>) procedure);
5483         }
5484
5485         @Override
5486         final public <T> void asyncRequest(final ExternalRead<T> request,
5487                         final Procedure<T> procedure) {
5488
5489                 assert (request != null);
5490                 assert (procedure != null);
5491
5492                 final ListenerBase listener = getListenerBase(procedure);
5493
5494                 if (parent != null || listener != null) {
5495
5496                         try {
5497                                 QueryCacheBase.resultExternalReadEntry(this, request, parent, listener, procedure);
5498                         } catch (DatabaseException e) {
5499                                 Logger.defaultLogError(e);
5500                                 // This throwable has already been transferred to procedure at this point - do nothing about it
5501                         }
5502
5503                 } else {
5504
5505                         request.register(this, new Listener<T>() {
5506                                 @Override
5507                                 public void execute(T result) {
5508                                         procedure.execute(result);
5509                                 }
5510
5511                                 @Override
5512                                 public void exception(Throwable t) {
5513                                         procedure.exception(t);
5514                                 }
5515
5516                                 @Override
5517                                 public String toString() {
5518                                         return "asyncRequest(PrimitiveRead) -> " + request;
5519                                 }
5520
5521                                 @Override
5522                                 public boolean isDisposed() {
5523                                         return true;
5524                                 }
5525
5526                         });
5527
5528                 }
5529
5530         }
5531
5532         @Override
5533         public void asyncRequest(final Write request) {
5534
5535                 assert (request != null);
5536                 
5537                 getSession().asyncRequest(request);
5538
5539 //              processor.asyncWrite(request);
5540
5541         }
5542
5543         @Override
5544         public <T> void asyncRequest(final WriteResult<T> request, Procedure<T> procedure) {
5545                 throw new Error("Not implemented.");
5546         }
5547         
5548         @Override
5549         public void asyncRequest(Write request, Consumer<DatabaseException> callback) {
5550                 
5551                 assert (request != null);
5552                 
5553                 getSession().asyncRequest(request, callback);
5554                 
5555         }
5556
5557         @Override
5558         public void asyncRequest(final DelayedWrite request) {
5559
5560                 assert (request != null);
5561
5562                 getSession().asyncRequest(request);
5563
5564         }
5565
5566         @Override
5567         public <T> void asyncRequest(final DelayedWriteResult<T> request, Procedure<T> procedure) {
5568                 throw new Error("Not implemented.");
5569         }
5570         
5571         @Override
5572         public void asyncRequest(DelayedWrite r,
5573                         Consumer<DatabaseException> callback) {
5574                 throw new Error("Not implemented.");
5575         }
5576
5577         @Override
5578         public void asyncRequest(final WriteOnly request) {
5579
5580                 assert (request != null);
5581
5582                 getSession().asyncRequest(request);
5583
5584         }
5585
5586         @Override
5587         public <T> void asyncRequest(final WriteOnlyResult<T> request, Procedure<T> procedure) {
5588                 throw new Error("Not implemented.");
5589         }
5590         
5591         @Override
5592         public void asyncRequest(WriteOnly r, Consumer<DatabaseException> callback) {
5593                 throw new Error("Not implemented.");
5594         }
5595
5596         /*
5597          * Implementation of the interface ServiceLocator
5598          */
5599
5600         @Override
5601         public <T> T getService(Class<T> api) {
5602             if(WriteSupport.class == api) {
5603                 if(this instanceof WriteGraphImpl) {
5604                     WriteGraphImpl impl = (WriteGraphImpl)this;
5605                     return (T)impl.writeSupport;
5606                 }
5607             }
5608                 return getSession().getService(api);
5609         }
5610
5611         @Override
5612         public <T> T peekService(Class<T> api) {
5613                 return getSession().peekService(api);
5614         }
5615
5616         @Override
5617         public boolean hasService(Class<?> api) {
5618                 return getSession().hasService(api);
5619         }
5620
5621         @Override
5622         public <T> void registerService(Class<T> api, T service) {
5623                 getSession().registerService(api, service);
5624         }
5625         
5626         @Override
5627         public boolean isImmutable(Resource resource) throws DatabaseException {
5628                 ResourceImpl impl = (ResourceImpl)resource;
5629                 return processor.isImmutable(impl.id);
5630         }
5631
5632         /*
5633          * Internal routines
5634          */
5635
5636         protected static String INTERNAL_ERROR_STRING = "Transaction aborted due to internal client error.";
5637
5638         /*
5639          * callerThread is the currently running thread state.syncThread is blocking for
5640          * this execution state.syncParent is the blocking request
5641          */
5642
5643         ReadGraphImpl(ReadGraphImpl parentGraph, CacheEntry parent, QueryProcessor support) {
5644                 this.parentGraph = parentGraph;
5645                 this.parent = parent;
5646                 this.processor = support;
5647                 this.asyncBarrier = new AsyncBarrierImpl(parentGraph != null ? parentGraph.asyncBarrier : null);
5648         }
5649
5650         ReadGraphImpl(ReadGraphImpl graph, CacheEntry parent) {
5651                 this(graph, parent, graph.processor);
5652         }
5653
5654         ReadGraphImpl(ReadGraphImpl graph) {
5655                 this(graph, graph.parent);
5656         }
5657
5658         public ReadGraphImpl withParent(CacheEntry parent) {
5659                 return new ReadGraphImpl(this, parent);
5660         }
5661
5662         public ReadGraphImpl forRecompute(CacheEntry parent) {
5663                 return new ReadGraphImpl(null, parent, processor);
5664         }
5665
5666         public static ReadGraphImpl create(QueryProcessor support) {
5667                 return new ReadGraphImpl(null, null, support);
5668         }
5669
5670         public ReadGraphImpl newRestart(ReadGraphImpl impl) {
5671
5672                 WriteGraphImpl write = processor.getSession().getService(
5673                                 WriteGraphImpl.class);
5674
5675                 return write;
5676
5677         }
5678
5679         final private ListenerBase getListenerBase(final Object procedure) {
5680                 if (procedure instanceof ListenerBase)
5681                         return (ListenerBase) procedure;
5682                 else
5683                         return null;
5684         }
5685
5686         public <T> void waitAsyncProcedure(AsyncMultiReadProcedure<T> procedure) {
5687                 
5688                 assert(procedure.done());
5689                 
5690         }
5691
5692         public <T> void waitAsyncProcedure(AsyncReadProcedure<T> procedure) {
5693                 
5694                 assert(procedure.done());
5695                 
5696         }
5697
5698         public boolean resumeTasks() {
5699                 return processor.resumeTasks(this);
5700         }
5701
5702         Class<?> singleClass(Set<Resource> types) {
5703                 Class<?> result = null;
5704                 for (Resource type : types) {
5705                         Class<?> clazz = processor.getBuiltinValue(type);
5706                         if (clazz != null) {
5707                                 if (result != null)
5708                                         return null;
5709                                 else
5710                                         result = clazz;
5711                         }
5712                 }
5713                 return result;
5714         }
5715
5716         private String debugString(Resource r) {
5717                 String name = null;
5718                 try {
5719                         name = getPossibleRelatedValue(r, processor.getL0(this).HasName);
5720                 } catch (ManyObjectsForFunctionalRelationException e) {
5721                 Logger.defaultLogError(e);
5722                 } catch (ServiceException e) {
5723                 Logger.defaultLogError(e);
5724                 }
5725                 return "[" + name + " - " + r + "]";
5726         }
5727
5728         @Override
5729         public String toString() {
5730                 return "ReadGraphImpl[thread=" + Thread.currentThread() + "]";
5731         }
5732
5733         @Override
5734         final public int thread() {
5735                 return 0;
5736         }
5737         
5738     static class MultiTripleIntProcedure implements TripleIntProcedure {
5739
5740         final private AsyncMultiProcedure<Statement> procedure;
5741         final private ReadGraphImpl impl;
5742         final private QuerySupport support;
5743         
5744         public MultiTripleIntProcedure(AsyncMultiProcedure<Statement> procedure, ReadGraphImpl impl, QuerySupport support) {
5745                 this.procedure = procedure;
5746                 this.impl = impl;
5747                 this.support = support;
5748         }
5749         
5750         @Override
5751         public void execute(ReadGraphImpl graph, int s, int p, int o) {
5752                 try {
5753                         procedure.execute(graph, support.getStatement(s, p, o));
5754                 } catch (Throwable t2) {
5755                         Logger.defaultLogError(t2);
5756                 }
5757         }
5758
5759         @Override
5760         public void finished(ReadGraphImpl graph) {
5761                 try {
5762                         procedure.finished(graph);
5763 //                      impl.state.barrier.dec("ReadGraphSupportImpl.516");
5764                 } catch (Throwable t2) {
5765                         Logger.defaultLogError(t2);
5766                 }
5767         }
5768
5769         @Override
5770         public void exception(ReadGraphImpl graph, Throwable t) {
5771                 try {
5772                         procedure.exception(graph, t);
5773                 } catch (Throwable t2) {
5774                         Logger.defaultLogError(t2);
5775                 }
5776 //              impl.state.barrier.dec("ReadGraphSupportImpl.516");
5777         }
5778
5779         @Override
5780         public String toString() {
5781                 return "forEachObject with " + procedure;
5782         }
5783         
5784     }
5785
5786 //    private AsyncMultiProcedure<Resource> cacheKey = null;
5787 //    private MultiIntProcedure cacheResult = null;
5788 //    
5789 //    final IntProcedure forMultiProcedure(final AsyncMultiProcedure<Resource> procedure) {
5790 //      
5791 //      if(procedure == cacheKey) return cacheResult; 
5792 //      
5793 //      cacheResult = new MultiIntProcedure(procedure, this, processor.support);
5794 //      cacheKey = procedure;
5795 //      
5796 //      return cacheResult;
5797 //      
5798 //    }
5799 //
5800 //    private AsyncMultiProcedure<Statement> cacheKey2 = null;
5801 //    private MultiTripleIntProcedure cacheResult2 = null;
5802 //
5803 //    final synchronized TripleIntProcedure forMultiProcedure(final AsyncMultiProcedure<Statement> procedure) {
5804 //      
5805 //      if(procedure == cacheKey2) return cacheResult2; 
5806 //      
5807 //      cacheResult2 = new MultiTripleIntProcedure(procedure, this, processor.support);
5808 //      cacheKey2 = procedure;
5809 //      
5810 //      return cacheResult2;
5811 //      
5812 //    }
5813     
5814     @Override
5815     public Datatype getDataType(Resource subject) throws DatabaseException {
5816         for(Resource dataTypeResource : getObjects(subject, processor.getL0(this).HasDataType))
5817                 return getValue(dataTypeResource, Bindings.getBindingUnchecked(Datatype.class));
5818         throw new DoesNotContainValueException("The literal has no data type.");
5819     }
5820     
5821     protected <T extends Accessor> T getAccessor4File(Resource subject)
5822     throws DatabaseException {
5823         return null;
5824         /*        
5825         byte[]  bytes = processor.support.getValue(g, subject);
5826         if (null == bytes)
5827             return null;
5828         try {
5829             BinaryVariant va = (BinaryVariant) Accessors.getAccessor(bytes, Datatypes.VARIANT);
5830             Accessor ca = va.getContentAccessor();
5831             return (T)ca;
5832         } catch (AccessorConstructionException e) {
5833             throw new DatabaseException(e);
5834         }
5835         */
5836         /*
5837         if (null == bytes)
5838             return null;
5839         Binding datatype_binding = Bindings.getBindingUnchecked(DataType.class);
5840         Serializer datatype_serializer = datatype_binding.serializer();
5841         DataType datatype;
5842         try {
5843             BinaryMemory in = new BinaryMemory(ByteBuffer.wrap(bytes));
5844             datatype = (DataType)datatype_serializer.deserialize(in);
5845             Binding data_binding = Bindings.getBinding(datatype);
5846             Serializer data_serializer = data_binding.serializer(BinarySerializationFormat.INSTANCE);
5847             Object o = data_serializer.deserialize(in);
5848             try {
5849                 return (T)Accessors.getAccessor(data_binding, o);
5850             } catch(AccessorConstructionException e) {
5851                 return null;
5852             }
5853         } catch (Exception e) {
5854             throw new DatabaseException(e);
5855         }*/
5856     }
5857     @SuppressWarnings("unchecked")
5858     @Override
5859     public <T extends Accessor> T getAccessor(Resource subject) throws DatabaseException {
5860         RandomAccessBinary rab = getRandomAccessBinary(subject);
5861         try {
5862             return (T)Accessors.getAccessor(rab, getDataType(subject));
5863         } catch(AccessorConstructionException e) {
5864             throw new DatabaseException(e);
5865         }
5866     }
5867     @SuppressWarnings("unchecked")
5868     protected <T extends Accessor> T createAccessor(Resource resource, Datatype datatype, Object intialValue)
5869     throws DatabaseException {
5870         RandomAccessBinary rab = createRandomAccessBinary(resource, datatype, intialValue);
5871         try {
5872             return (T)Accessors.getAccessor(rab, datatype);
5873         } catch(AccessorConstructionException e) {
5874             throw new DatabaseException(e);
5875         }
5876     }
5877     @Override
5878     public RandomAccessBinary getRandomAccessBinary(Resource subject) throws DatabaseException {
5879         RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class);
5880         ResourceData rd = ravs.get(subject);
5881         if (null != rd)
5882             return rd;
5883         try {
5884             ExternalValueSupport evs = getService(ExternalValueSupport.class);
5885             long size = evs.getValueSize(this, subject); // Throws DatabaseException if no old external value.
5886             try {
5887                 File platform = Platform.getLocation().toFile();
5888                 File tempFiles = new File(platform, "tempFiles");
5889                 File dbDir = new File(tempFiles, "db");
5890                 dbDir.mkdirs();
5891                 File file = new File(dbDir, "ResourceFile" + subject.getResourceId());
5892                 rd = new ResourceData(new BinaryFile(file), true); // Old external value.
5893                 final int N = 1<<20;
5894                 long left = size;
5895                 long offset = 0;
5896                 while (left > 0) {
5897                     int length = N < left ? N : (int)left;
5898                     byte[] bytes = evs.readValue(this, subject, offset, length);
5899                     offset += bytes.length;
5900                     left -= bytes.length;
5901                     rd.binaryFile.write(bytes);
5902                 }
5903                 ravs.put(subject, rd);
5904                 return rd;
5905             } catch (Exception e) {
5906                 throw new DatabaseException("Resource " + subject + " have value but there was problem with accessing value data.", e);
5907             }
5908         } catch (Exception e) {
5909             if(Development.DEVELOPMENT) {
5910                 if(Development.<Boolean>getProperty(DevelopmentKeys.WRITEGRAPH_EXCEPTION_STACKTRACES, Bindings.BOOLEAN)) {
5911                     e.printStackTrace();
5912                 }
5913             }
5914         }
5915         Datatype datatype = getDataType(subject);
5916         Object value = getPossibleValue(subject, Bindings.getBinding(datatype));
5917         return createRandomAccessBinary(subject, datatype, value);
5918     }
5919     public RandomAccessBinary createRandomAccessBinary(Resource resource, Datatype datatype, Object initialValue)
5920     throws DatabaseException {
5921         RandomAccessValueSupport ravs = getSession().getService(RandomAccessValueSupport.class);
5922         try {
5923             File platform = Platform.getLocation().toFile();
5924             File tempFiles = new File(platform, "tempFiles");
5925             File dbDir = new File(tempFiles, "db");
5926             dbDir.mkdirs();
5927             File file = new File(dbDir, "ResourceFile" + resource.getResourceId());
5928             ResourceData rd = new ResourceData(new BinaryFile(file), false);
5929             Binding binding = Bindings.getBinding(datatype);
5930             if (null == initialValue) {
5931                 initialValue = binding.createDefault();
5932             }
5933             Serializer serializer = binding.serializer();
5934             byte[] bytes = serializer.serialize(initialValue);
5935             rd.binaryFile.write(bytes);
5936             ravs.put(resource, rd);
5937             return rd;
5938         } catch (Exception e) {
5939             if (e instanceof DatabaseException)
5940                 throw (DatabaseException)e;
5941             else
5942                 throw new DatabaseException(e);
5943         }
5944     }
5945
5946 //    static class ExternalValueRequest<T> extends ResourceRead<T> {
5947 //
5948 //              public ExternalValueRequest(Resource resource) {
5949 //                      super(resource);
5950 //              }
5951 //
5952 //              @SuppressWarnings("unchecked")
5953 //              @Override
5954 //              public T perform(ReadGraph graph) throws DatabaseException {
5955 //              try {
5956 //                      
5957 //                      String uri = graph.getURI(resource);
5958 //                      if(Layer0.URIs.Functions_functionApplication.equals(uri)) return (T)functionApplication;
5959 //                      
5960 //                      return (T)ReflectionUtils.getValue(uri).getValue();
5961 //                      
5962 //              } catch(ValueNotFoundException e) {
5963 //                      throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e);
5964 //              } catch(ClassCastException e) {
5965 //                      throw new DatabaseException("Couldn't convert to external value (r=" + resource + ")", e);
5966 //              }
5967 //              }
5968 //      
5969 //    }
5970     
5971     @SuppressWarnings("unchecked")
5972     @Override
5973     public <T> T getValue2(Resource r, Object context) throws DatabaseException {
5974         Layer0 L0 = processor.getL0(this);
5975         Set<Resource> types = getTypes(r);
5976         
5977         if(types.contains(L0.Literal)) {
5978                 if(isImmutable(r)) {
5979                         return syncRequest(new ValueImplied<T>(r));
5980                 } else {
5981                         return getValue(r);
5982                 }
5983         }
5984         else if(types.contains(L0.ExternalValue)) {
5985                 return (T)syncRequest(new AdaptValue(r), TransientCacheListener.<Object>instance());
5986         }
5987         else {
5988
5989             Function3<ReadGraph,Resource,Object,T> function = requestValueFunction(r);
5990             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r);
5991             try {
5992                 return function.apply(this, r, context);
5993             } catch(RuntimeException e) {
5994                 DatabaseException dte = findPossibleRootException(e);
5995                 if(dte != null) throw dte;
5996                 else throw new DatabaseException(e);
5997             }
5998                 
5999         }
6000     }
6001
6002     @Override
6003     public Variant getVariantValue2(Resource r, Object context) throws DatabaseException {
6004         Layer0 L0 = processor.getL0(this);
6005         Set<Resource> types = getTypes(r);
6006         
6007         if(types.contains(L0.Literal)) {
6008             if(isImmutable(r)) {
6009                 return syncRequest(new VariantValueImplied(r));
6010             } else {
6011                 return getVariantValue(r);
6012             }
6013         }
6014         else if(types.contains(L0.ExternalValue)) {
6015             Object value = syncRequest(new AdaptValue(r), TransientCacheListener.<Object>instance());
6016             try {
6017                 return new Variant(Bindings.OBJECT.getContentBinding(value), value);
6018             } catch ( org.simantics.databoard.binding.error.BindingException e ) {
6019                 throw new BindingException( "No binding found for class " + value.getClass().getName(), e );
6020             }
6021         }
6022         else {
6023
6024             Function3<ReadGraph,Resource,Object,Object> function = requestValueFunction(r);
6025             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function " + r);
6026             try {
6027                 Object value = function.apply(this, r, context);
6028                 try {
6029                     return new Variant(Bindings.OBJECT.getContentBinding(value), value);
6030                 } catch ( org.simantics.databoard.binding.error.BindingException e ) {
6031                     throw new BindingException( "No binding found for class " + value.getClass().getName(), e );
6032                 }
6033             } catch(RuntimeException e) {
6034                 DatabaseException dte = findPossibleRootException(e);
6035                 if(dte != null) throw dte;
6036                 else throw new DatabaseException(e);
6037             }
6038         }
6039     }
6040     
6041     @Override
6042     public <T> T getPossibleValue2(Resource subject, Object context) throws DatabaseException {
6043         try {
6044                 return getValue2(subject, context);
6045         } catch (DatabaseException e) {
6046                 return null;
6047         }
6048     }
6049
6050     static class PossibleConverterFunction<T> extends ResourceRead<Function3<ReadGraph,Resource,Object,T>> {
6051         
6052         public PossibleConverterFunction(Resource resource) {
6053                         super(resource);
6054                 }
6055
6056         @Override
6057         public Function3<ReadGraph,Resource,Object,T> perform(ReadGraph graph) throws DatabaseException {
6058                 return compute(graph, resource);
6059         }
6060         
6061         @SuppressWarnings("unchecked")
6062                 public static <T> Function3<ReadGraph,Resource,Object,T> compute(ReadGraph graph, Resource resource) throws DatabaseException {
6063             Layer0 L0 = Layer0.getInstance(graph);
6064             for(Resource converter : graph.getObjects(resource, L0.ConvertsToValueWith)) {
6065                 try {
6066                         if(L0.Functions_functionApplication.equals(converter)) {
6067                                 return (Function3<ReadGraph,Resource,Object,T>)graph.syncRequest(new AdaptValue(resource));
6068                         } else {
6069                                 return graph.getValue2(converter, resource);
6070                         }
6071                 } catch(RuntimeException e) {
6072                     DatabaseException dte = findPossibleRootException(e);
6073                     if(dte != null) throw dte;
6074                     else throw new DatabaseException(e);
6075                 }
6076             }
6077             return null;
6078         }
6079         
6080     }
6081     
6082     <T> Function3<ReadGraph,Resource,Object,T> requestValueFunction(Resource r) throws DatabaseException {
6083         if(isImmutable(r))
6084                 return syncRequest(new PossibleConverterFunction<T>(r), TransientCacheAsyncListener.<Function3<ReadGraph,Resource,Object,T>>instance());
6085         else
6086                 return syncRequest(new PossibleConverterFunction<T>(r));
6087     }
6088     
6089     /**
6090      * Get a value associated with a graph {@link Resource}, using a possible context object and
6091      * a desired value binding. The following methods are tried in order to retreive the value:
6092      * <ol>
6093      *   <li>If the given resource is a {@code L0.Literal}, the value of the literal is returned, using the binding specified by {@code binding}.</li>
6094      *   <li>If the resource is a {@code L0.ExternalValue}, the value is acquired using
6095      *       {@link ReflectionUtils#getValue(String)}.</li>
6096      *   <li>If the resource is associated with a suitable value converter with relation {@code L0.ConvertsToValueWith}
6097      *       (see {@link #requestValueFunction(Resource)}), the value function is called with the graph, the resource
6098      *       and the context object.</li>
6099      * </ul>
6100      * 
6101      * @param r  A graph resource with which the value is associated
6102      * @param context  A context object that is used for acquiring the value (only applied in case 3)
6103      * @param binding  A binding for the value type (only applied in case 1)
6104      * @return  The value of the graph node.
6105      * @throws DoesNotContainValueException  No value is associated with the graph node.
6106      * @throws DatabaseException  Other errors, such as an error in casting the value to the return type or
6107      *         a runtime error in the value function.
6108      */
6109     @SuppressWarnings("unchecked")
6110         @Override
6111     public <T> T getValue2(Resource r, Object context, Binding binding) throws DatabaseException {
6112         if (binding instanceof ObjectVariantBinding)
6113                 return getValue2(r, context);
6114         
6115         Layer0 L0 = processor.getL0(this);
6116         Set<Resource> types = getTypes(r);
6117         if(types.contains(L0.Literal)) {
6118                 if(isImmutable(r)) {
6119                         return syncRequest(new Value<T>(r, binding));
6120                 } else {
6121                         return getValue(r, binding);
6122                 }
6123         } else if(types.contains(L0.ExternalValue)) {
6124                 try {
6125                         return (T)ReflectionUtils.getValue(getURI(r)).getValue();
6126                 } catch(ValueNotFoundException e) {
6127                         throw new DatabaseException(e);
6128                 } catch(ClassCastException e) {
6129                         throw new DatabaseException(e);
6130                 }
6131         }
6132         else {
6133             Function3<ReadGraph,Resource,Object,T> function = requestValueFunction(r);
6134             if(function == null) throw new DoesNotContainValueException("Couldn't convert to a value function.");
6135             try {
6136                 Object value = function.apply(this, r, context);
6137                 if(binding.isInstance(value)) return (T)value;
6138                 Binding srcBinding = Bindings.OBJECT.getContentBinding(value);
6139                 return (T)Bindings.adapt(value, srcBinding, binding);
6140             } catch(RuntimeException e) {
6141                 DatabaseException dte = findPossibleRootException(e);
6142                 if(dte != null) throw dte;
6143                 else throw new DatabaseException(e);
6144             } catch (AdaptException e) {
6145                 throw new DatabaseException(e);
6146                         } catch (org.simantics.databoard.binding.error.BindingException e) {
6147                 throw new DatabaseException(e);
6148                         }
6149         }
6150     }
6151     
6152     @Override
6153     public <T> T getPossibleValue2(Resource subject, Object context, Binding binding) throws DatabaseException {
6154         try {
6155                 return getValue2(subject, context, binding);
6156         } catch (DatabaseException e) {
6157                 return null;
6158         }
6159     }
6160     
6161         private static DatabaseException findPossibleRootException(Throwable t) {
6162                 if(t == null) return null;
6163                 if(t instanceof DatabaseException) return (DatabaseException)t;
6164                 if(t instanceof RuntimeException || t instanceof InvocationTargetException) {
6165                         return findPossibleRootException(t.getCause());
6166                 }
6167                 return null;
6168         }
6169     
6170     @Override
6171     public <T> T getRelatedValue2(Resource subject, Resource relation) throws DatabaseException {
6172         return getRelatedValue2(subject, relation, subject);
6173     }
6174     
6175     @Override
6176     public Variant getRelatedVariantValue2(Resource subject, Resource relation) throws DatabaseException {
6177         return getRelatedVariantValue2(subject, relation, subject);
6178     }
6179     
6180     @Override
6181     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation) throws DatabaseException {
6182         try {
6183                 Resource object = getPossibleObject(subject, relation);
6184                 if(object == null) return null;
6185                 else return getValue2(object, subject);
6186         } catch (DatabaseException e) {
6187                 return null;
6188         }
6189     }
6190
6191     @Override
6192     public <T> T getRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6193                 if(Development.DEVELOPMENT) {
6194                         String error = L0Validations.checkValueType(this, subject, relation);
6195                         if(error != null) {
6196                                 Logger.defaultLogError(new ValidationException(error));
6197                                 //throw new ValidationException(error);
6198                                 new ValidationException(error).printStackTrace();
6199                         }
6200                 }
6201         return getValue2(getSingleObject(subject, relation), context);
6202     }
6203     
6204     @Override
6205     public Variant getRelatedVariantValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6206         if(Development.DEVELOPMENT) {
6207             String error = L0Validations.checkValueType(this, subject, relation);
6208             if(error != null) {
6209                 Logger.defaultLogError(new ValidationException(error));
6210                 //throw new ValidationException(error);
6211                 new ValidationException(error).printStackTrace();
6212             }
6213         }
6214         return getVariantValue2(getSingleObject(subject, relation), context);
6215     }
6216     
6217     @Override
6218     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Object context) throws DatabaseException {
6219         try {
6220                 Resource object = getPossibleObject(subject, relation);
6221                 if(object == null) return null;
6222                 else return getValue2(object, context);
6223         } catch (DatabaseException e) {
6224                 return null;
6225         }
6226     }
6227
6228     @Override
6229     public <T> T getRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException {
6230         return getRelatedValue2(subject, relation, subject, binding);
6231     }
6232     
6233     @Override
6234     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Binding binding) throws DatabaseException {
6235         try {
6236                 Resource object = getPossibleObject(subject, relation);
6237                 if(object == null) return null;
6238                 return getValue2(object, subject, binding);
6239         } catch (DatabaseException e) {
6240                 return null;
6241         }
6242     }
6243
6244     @Override
6245     public <T> T getRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException {
6246         return getValue2(getSingleObject(subject, relation), context, binding);
6247     }
6248     
6249     @Override
6250     public <T> T getPossibleRelatedValue2(Resource subject, Resource relation, Object context, Binding binding) throws DatabaseException {
6251         try {
6252                 Resource object = getPossibleObject(subject, relation);
6253                 if(object == null) return null;
6254                 else return getValue2(object, context, binding);
6255         } catch (DatabaseException e) {
6256                 return null;
6257         }
6258     }
6259     
6260     @Override
6261     public Type getRelatedValueType(Resource subject, Resource relation) throws DatabaseException {
6262         Layer0 L0 = processor.getL0(this);
6263         Resource property = getSingleObject(subject, relation);
6264         String typeText = (String)getRelatedValue(property, L0.HasValueType, Bindings.STRING);
6265         try {
6266             return org.simantics.scl.compiler.types.Types.parseType(typeText);
6267         } catch (SCLTypeParseException e) {
6268             throw new DatabaseException(e);
6269         }
6270     }
6271
6272     private static ThreadLocal<Boolean> syncGraph = new ThreadLocal<Boolean>() {
6273         protected Boolean initialValue() {
6274             return true;
6275         }
6276     };
6277
6278     @Override
6279     public boolean setSynchronous(boolean value) {
6280         boolean old = getSynchronous();
6281         syncGraph.set(value);
6282         return old;
6283     }
6284
6285     @Override
6286     public boolean getSynchronous() {
6287         return syncGraph.get();
6288     }
6289     
6290     public void ensureLoaded(int resource) {
6291         processor.querySupport.ensureLoaded(this, resource);
6292     }
6293     
6294     public void ensureLoaded(int resource, int predicate) {
6295         processor.querySupport.ensureLoaded(this, resource, predicate);
6296     }
6297
6298     public byte[] getValue(int resource) {
6299         return processor.querySupport.getValue(this, resource);
6300     }
6301     
6302     public int thread(int resource) {
6303         return (resource >>> 16) & processor.THREAD_MASK;
6304     }
6305
6306     public int thread(Resource resource) {
6307         return (((ResourceImpl)resource).id >>> 16) & processor.THREAD_MASK;
6308     }
6309     
6310     public ResourceSupport getResourceSupport() {
6311         return processor.getResourceSupport();
6312     }
6313     
6314     @Override
6315     public Object getModificationCounter() {
6316         return processor.getSession().getModificationCounter();
6317     }
6318
6319     @Override
6320     public boolean performPending() {
6321         return processor.performPending(this);
6322     }
6323
6324     public Set<ReadGraphImpl> ancestorSet() {
6325         HashSet<ReadGraphImpl> result = new HashSet<>();
6326         ReadGraphImpl g = this;
6327         while(g != null) {
6328             result.add(g);
6329             g = g.parentGraph;
6330         }
6331         return result;
6332     }
6333
6334 }