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