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