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