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