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