]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/Layer0Utils.java
Merge "Default property editing restores assertions"
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / Layer0Utils.java
index c916b36b0ba31967e208a881be95268ad1c17271..5ccfcf325f49df3f919f6ee54f34b3d0f2033960 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2012 Association for Decentralized Information Management in\r
- * Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.layer0.util;\r
-\r
-import java.io.IOException;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.TreeSet;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.SubMonitor;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.adapter.AdaptException;\r
-import org.simantics.databoard.adapter.Adapter;\r
-import org.simantics.databoard.adapter.AdapterConstructionException;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.NumberBinding;\r
-import org.simantics.databoard.binding.StringBinding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.binding.mutable.MutableStringBinding;\r
-import org.simantics.databoard.parser.repository.DataTypeSyntaxError;\r
-import org.simantics.databoard.parser.repository.DataValueRepository;\r
-import org.simantics.databoard.primitives.MutableString;\r
-import org.simantics.databoard.type.ArrayType;\r
-import org.simantics.databoard.type.BooleanType;\r
-import org.simantics.databoard.type.ByteType;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.type.DoubleType;\r
-import org.simantics.databoard.type.FloatType;\r
-import org.simantics.databoard.type.IntegerType;\r
-import org.simantics.databoard.type.LongType;\r
-import org.simantics.databoard.type.MapType;\r
-import org.simantics.databoard.type.NumberType;\r
-import org.simantics.databoard.type.OptionalType;\r
-import org.simantics.databoard.type.RecordType;\r
-import org.simantics.databoard.type.StringType;\r
-import org.simantics.databoard.type.UnionType;\r
-import org.simantics.databoard.type.VariantType;\r
-import org.simantics.databoard.util.ObjectUtils;\r
-import org.simantics.db.ChangeSetIdentifier;\r
-import org.simantics.db.Operation;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.RelationContext;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.WriteOnlyGraph;\r
-import org.simantics.db.common.CommentMetadata;\r
-import org.simantics.db.common.Indexing;\r
-import org.simantics.db.common.StandardStatement;\r
-import org.simantics.db.common.primitiverequest.PossibleRelatedValue;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
-import org.simantics.db.common.request.DelayedWriteRequest;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.request.PossibleChild;\r
-import org.simantics.db.common.request.PossibleIndexRoot;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.exception.CancelTransactionException;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.exception.ServiceException;\r
-import org.simantics.db.layer0.adapter.CopyHandler;\r
-import org.simantics.db.layer0.adapter.CopyHandler2;\r
-import org.simantics.db.layer0.adapter.GenericRelationIndex;\r
-import org.simantics.db.layer0.adapter.PasteHandler;\r
-import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;\r
-import org.simantics.db.layer0.adapter.impl.TGRemover;\r
-import org.simantics.db.layer0.genericrelation.IndexedRelations;\r
-import org.simantics.db.layer0.internal.SimanticsInternal;\r
-import org.simantics.db.layer0.migration.OntologiesFromLibrary;\r
-import org.simantics.db.layer0.property.OrderedResource;\r
-import org.simantics.db.layer0.request.GlobalOntologies;\r
-import org.simantics.db.layer0.request.PossibleVariableIndexRoot;\r
-import org.simantics.db.layer0.request.PropertyInfo;\r
-import org.simantics.db.layer0.request.PropertyInfoRequest;\r
-import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
-import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.db.service.ClusterCollectorPolicy;\r
-import org.simantics.db.service.ClusterControl;\r
-import org.simantics.db.service.ClusteringSupport;\r
-import org.simantics.db.service.CollectionSupport;\r
-import org.simantics.db.service.DebugSupport;\r
-import org.simantics.db.service.ManagementSupport;\r
-import org.simantics.db.service.UndoRedoSupport;\r
-import org.simantics.db.service.XSupport;\r
-import org.simantics.graph.db.TransferableGraphSource;\r
-import org.simantics.graph.db.TransferableGraphs;\r
-import org.simantics.graph.diff.Diff;\r
-import org.simantics.graph.diff.TransferableGraphDelta1;\r
-import org.simantics.graph.refactoring.GraphRefactoringUtils;\r
-import org.simantics.graph.representation.TransferableGraph1;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.operation.Layer0X;\r
-import org.simantics.scl.compiler.environment.Environments;\r
-import org.simantics.scl.compiler.runtime.RuntimeEnvironment;\r
-import org.simantics.scl.compiler.top.SCLExpressionCompilationException;\r
-import org.simantics.scl.compiler.types.Type;\r
-import org.simantics.scl.osgi.SCLOsgi;\r
-import org.simantics.scl.runtime.function.Function;\r
-import org.simantics.scl.runtime.function.Function1;\r
-import org.simantics.scl.runtime.function.FunctionImpl1;\r
-\r
-public class Layer0Utils {\r
-\r
-       @SuppressWarnings("rawtypes")\r
-       public static final ThreadLocal SCL_GRAPH = new ThreadLocal();\r
-\r
-       final public static Binding datatype_binging = Bindings.getBindingUnchecked(Datatype.class);\r
-\r
-       public static Resource literal(WriteGraph g, String value) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               Resource r = g.newResource();\r
-               g.claimValue(r, value, Bindings.STRING);\r
-               g.claim(r, L0.InstanceOf, L0.String);\r
-               return r;\r
-       }\r
-\r
-       public static Resource literal(WriteGraph g, double value) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               Resource r = g.newResource();\r
-               g.claimValue(r, value, Bindings.DOUBLE);\r
-               g.claim(r, L0.InstanceOf, L0.Double);\r
-               return r;\r
-       }\r
-\r
-       public static Resource literal(WriteGraph g, int value) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               Resource r = g.newResource();\r
-               g.claimValue(r, value, Bindings.INTEGER);\r
-               g.claim(r, L0.InstanceOf, L0.Integer);\r
-               return r;\r
-       }\r
-\r
-       public static void assert_(WriteGraph g, Resource type, Resource predicate, Resource object) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               Resource assertion = g.newResource();\r
-               g.claim(type, L0.Asserts, assertion);\r
-               g.claim(assertion, L0.InstanceOf, L0.Assertion);\r
-               g.claim(assertion, L0.HasPredicate, predicate);\r
-               g.claim(assertion, L0.HasObject, object);\r
-       }\r
-\r
-       public static Resource relation(WriteGraph g, Resource parent, String name, Resource superrelation) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(g);\r
-               Resource relation = g.newResource();\r
-               g.claim(relation, L0.SubrelationOf, superrelation);\r
-               g.claim(relation, L0.HasName, literal(g, name));\r
-               g.claim(parent, L0.ConsistsOf, relation);\r
-\r
-               Resource superrelationInverse = g.getInverse(superrelation);\r
-               if(superrelationInverse != null) {\r
-                       Resource inverse = g.newResource();\r
-                       g.claim(inverse, L0.SubrelationOf, superrelationInverse);\r
-                       g.claim(relation, L0.ConsistsOf, inverse);\r
-                       g.claim(inverse, L0.HasName, literal(g, "Inverse"));\r
-               }\r
-               return relation;\r
-       }\r
-\r
-       private static Resource getLiteralType(ReadGraph graph, Datatype type) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               if(type instanceof DoubleType) return L0.Double;\r
-               else if(type instanceof StringType) return L0.String;\r
-               else if(type instanceof IntegerType) return L0.Integer;\r
-               else if(type instanceof LongType) return L0.Long;\r
-               else if(type instanceof FloatType) return L0.Float;\r
-               else if(type instanceof ByteType) return L0.Byte;\r
-               else if(type instanceof BooleanType) return L0.Boolean;\r
-               else if(type instanceof ArrayType) {\r
-                       ArrayType at = (ArrayType)type;\r
-                       if(at.componentType instanceof DoubleType) return L0.DoubleArray;\r
-                       else if(at.componentType instanceof StringType) return L0.StringArray;\r
-                       else if(at.componentType instanceof IntegerType) return L0.IntegerArray;\r
-                       else if(at.componentType instanceof LongType) return L0.LongArray;\r
-                       else if(at.componentType instanceof FloatType) return L0.FloatArray;\r
-                       else if(at.componentType instanceof ByteType) return L0.ByteArray;\r
-                       else if(at.componentType instanceof BooleanType) return L0.BooleanArray;\r
-                       else if(at.componentType instanceof VariantType) return L0.VariantArray;\r
-               }\r
-               throw new DatabaseException("Unidentified literal type for datatype " + type);\r
-       }\r
-\r
-       private static Resource getPossibleLiteralType(ReadGraph graph, String type) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               if("Double".equals(type)) return L0.Double;\r
-               else if("String".equals(type)) return L0.String;\r
-               else if("Integer".equals(type)) return L0.Integer;\r
-               else if("Long".equals(type)) return L0.Long;\r
-               else if("Float".equals(type)) return L0.Float;\r
-               else if("Byte".equals(type)) return L0.Byte;\r
-               else if("Boolean".equals(type)) return L0.Boolean;\r
-               else if("[Double]".equals(type)) return L0.DoubleArray;\r
-               else if("[String]".equals(type)) return L0.StringArray;\r
-               else if("[Integer]".equals(type)) return L0.IntegerArray;\r
-               else if("[Long]".equals(type)) return L0.LongArray;\r
-               else if("[Float]".equals(type)) return L0.FloatArray;\r
-               else if("[Byte]".equals(type)) return L0.ByteArray;\r
-               else if("[Boolean]".equals(type)) return L0.BooleanArray;\r
-               else if("[Variant]".equals(type)) return L0.VariantArray;\r
-               else if("Array Double".equals(type)) return L0.DoubleArray;\r
-               else if("Array String".equals(type)) return L0.StringArray;\r
-               else if("Array Integer".equals(type)) return L0.IntegerArray;\r
-               else if("Array Long".equals(type)) return L0.LongArray;\r
-               else if("Array Float".equals(type)) return L0.FloatArray;\r
-               else if("Array Byte".equals(type)) return L0.ByteArray;\r
-               else if("Array Boolean".equals(type)) return L0.BooleanArray;\r
-               else if("Array Variant".equals(type)) return L0.VariantArray;\r
-               else if("Vector Double".equals(type)) return L0.DoubleArray;\r
-               else if("Vector String".equals(type)) return L0.StringArray;\r
-               else if("Vector Integer".equals(type)) return L0.IntegerArray;\r
-               else if("Vector Long".equals(type)) return L0.LongArray;\r
-               else if("Vector Float".equals(type)) return L0.FloatArray;\r
-               else if("Vector Byte".equals(type)) return L0.ByteArray;\r
-               else if("Vector Boolean".equals(type)) return L0.BooleanArray;\r
-               else if("Vector Variant".equals(type)) return L0.VariantArray;\r
-               else if("Datatype".equals(type)) return L0.DataType;\r
-               else if("Variant".equals(type)) return L0.Variant;\r
-               else return null;\r
-       }\r
-\r
-       public static Resource getPossibleLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {\r
-               Resource predicate = variable.getPossiblePredicateResource(graph);\r
-               if(predicate == null) return null;\r
-               return getPossibleLiteralType(graph, predicate);\r
-       }\r
-\r
-       public static Resource getLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {\r
-               Resource result = getPossibleLiteralType(graph, variable);\r
-               if(result == null) throw new DatabaseException("Unidentified literal type for variable " + variable.getURI(graph));\r
-               return result;\r
-       }\r
-\r
-       public static Resource getLiteralType(ReadGraph graph, Resource property) throws DatabaseException {\r
-               Resource result = getPossibleLiteralType(graph, property);\r
-               if(result == null) throw new DatabaseException("Unidentified literal type for property " + graph.getURI(property));\r
-               return result;\r
-       }\r
-\r
-       public static Resource getPossibleLiteralType(ReadGraph graph, Resource property) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-\r
-               Resource defaultLiteralType = graph.getPossibleObject(property, L0.HasDefaultLiteralType);\r
-               if(defaultLiteralType != null) return defaultLiteralType;\r
-\r
-               Resource range = graph.getPossibleObject(property, L0.HasRange);\r
-               if(range != null && !L0.Value.equals(range)) return range;\r
-\r
-               Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);\r
-               if(requiredDataType != null) return getLiteralType(graph, requiredDataType);\r
-\r
-               String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);\r
-               if(requiredValueType == null) return null;\r
-\r
-               return getPossibleLiteralType(graph, requiredValueType);\r
-\r
-       }\r
-\r
-       /**\r
-        * @param type any data type definition\r
-        * @return SCL type that matches the specified data type on a basic level.\r
-        *         Data type metadata is/cannot be converted into SCL types.\r
-        * @throws IllegalArgumentException\r
-        *             if the input datatype can't be converted into an SCL type\r
-        */\r
-       public static String getSCLType(Datatype type) throws IllegalArgumentException {\r
-               return buildSCLType(type, null).toString();\r
-       }\r
-\r
-       /**\r
-        * Only used internally by {@link #buildSCLType(Datatype, StringBuilder)}\r
-        * @param s\r
-        * @param toBuilder\r
-        * @return\r
-        * @see #buildSCLType(Datatype, StringBuilder)\r
-        */\r
-       private static StringBuilder append(StringBuilder toBuilder, String s) {\r
-               return toBuilder != null ? toBuilder.append(s) : new StringBuilder(s);\r
-       }\r
-\r
-       private static CharSequence append(CharSequence to, String s) {\r
-               if (to instanceof StringBuilder)\r
-                       return ((StringBuilder) to).append(s);\r
-               return new StringBuilder(to.length() + s.length()).append(to).append(s);\r
-       }\r
-\r
-       private static CharSequence stringOrBuilder(StringBuilder toBuilder, String s) {\r
-               return toBuilder != null ? toBuilder.append(s) : s;\r
-       }\r
-\r
-       /**\r
-        * @param type any data type definition\r
-        * @return SCL type that matches the specified data type on a basic level.\r
-        *         Data type metadata is/cannot be converted into SCL types.\r
-        * @throws IllegalArgumentException\r
-        *             if the input datatype can't be converted into an SCL type\r
-        */\r
-       private static CharSequence buildSCLType(Datatype type, StringBuilder result) throws IllegalArgumentException {\r
-               if(type instanceof DoubleType) return stringOrBuilder(result, "Double");\r
-               else if(type instanceof StringType) return stringOrBuilder(result, "String");\r
-               else if(type instanceof IntegerType) return stringOrBuilder(result, "Integer");\r
-               else if(type instanceof FloatType) return stringOrBuilder(result, "Float");\r
-               else if(type instanceof BooleanType) return stringOrBuilder(result, "Boolean");\r
-               else if(type instanceof ByteType) return stringOrBuilder(result, "Byte");\r
-               else if(type instanceof LongType) return stringOrBuilder(result, "Long");\r
-               else if(type instanceof VariantType) return stringOrBuilder(result, "Variant");\r
-               else if(type instanceof ArrayType) {\r
-                       ArrayType at = (ArrayType) type;\r
-                       // Optimization to prevent allocations in the most basic array cases\r
-                       if(at.componentType instanceof DoubleType) return stringOrBuilder(result, "Vector Double");\r
-                       else if(at.componentType instanceof StringType) return stringOrBuilder(result, "Vector String");\r
-                       else if(at.componentType instanceof IntegerType) return stringOrBuilder(result, "Vector Integer");\r
-                       else if(at.componentType instanceof FloatType) return stringOrBuilder(result, "Vector Float");\r
-                       else if(at.componentType instanceof BooleanType) return stringOrBuilder(result, "Vector Boolean");\r
-                       else if(at.componentType instanceof ByteType) return stringOrBuilder(result, "Vector Byte");\r
-                       else if(at.componentType instanceof LongType) return stringOrBuilder(result, "Vector Long");\r
-                       else if(at.componentType instanceof VariantType) return stringOrBuilder(result, "Vector Variant");\r
-                       else return buildSCLType(at.componentType, append(result, "Vector "));\r
-               } else if(type instanceof OptionalType) {\r
-                       OptionalType ot = (OptionalType) type;\r
-                       return append(buildSCLType(ot.componentType, append(result, "Maybe (")), ")");\r
-               } else if (type instanceof RecordType) {\r
-                       throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
-               } else if (type instanceof MapType) {\r
-                       throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
-               } else if (type instanceof UnionType) {\r
-                       throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
-               }\r
-               throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);\r
-       }\r
-\r
-\r
-       public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException {\r
-        try {\r
-                       return Environments.getType(runtimeEnvironment.getEnvironment(), typeText);\r
-               } catch (SCLExpressionCompilationException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-       }\r
-\r
-       public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException {\r
-\r
-               RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(property.getIndexRoot(graph)));\r
-               return getSCLType(graph, runtimeEnvironment, getSCLTypeString(graph, property));\r
-\r
-       }\r
-\r
-               \r
-       public static String getSCLTypeString(ReadGraph graph, Variable context) throws DatabaseException {\r
-               return getSCLTypeString(graph, context.getPossiblePredicateResource(graph), context.getRepresents(graph));\r
-       }\r
-\r
-\r
-       public static String getSCLTypeString(ReadGraph graph, Resource predicate, Resource value) throws DatabaseException {\r
-\r
-               if(predicate != null) {\r
-                   String requiredValueTypes = graph.getPossibleRelatedValue(predicate, Layer0.getInstance(graph).RequiresValueType, Bindings.STRING);\r
-                   if(requiredValueTypes != null)\r
-                       return requiredValueTypes;\r
-               }\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-\r
-               Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, datatype_binging);\r
-               if(literalDatatype != null) return getSCLType(literalDatatype);\r
-\r
-               String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING);\r
-               if(literalValueType != null) return literalValueType;\r
-\r
-               if(predicate != null) {\r
-\r
-                       Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, datatype_binging);\r
-                       if(requiredDataType != null) return getSCLType(requiredDataType);\r
-\r
-                       throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate));\r
-\r
-               }\r
-\r
-               throw new DatabaseException("Unidentified literal data type");\r
-\r
-       }\r
-\r
-       public static Datatype getDatatype(ReadGraph graph, Variable variable) throws DatabaseException {\r
-               Datatype result = getPossibleDatatype(graph, variable);\r
-               if(result != null) return result;\r
-               throw new DatabaseException("Unidentified literal data type for property " + variable.getURI(graph));\r
-       }\r
-\r
-       public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-\r
-               Resource property = variable.getPossiblePredicateResource(graph);\r
-               if(property != null) {\r
-//                     Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);\r
-                       Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue<Datatype>(property, L0X.RequiresDataType, datatype_binging));\r
-                       if(requiredDataType != null) return requiredDataType;\r
-               }\r
-\r
-               Resource literal = variable.getPossibleRepresents(graph);\r
-               if(literal != null) {\r
-                   Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging);\r
-                   if(literalDatatype != null) return literalDatatype;\r
-               }\r
-\r
-               if(property != null) {\r
-\r
-                       String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);\r
-                       if(requiredValueType != null) {\r
-                               Datatype datatype = getPossibleDatatypeForValueType(requiredValueType);\r
-                               if(datatype != null) return datatype;\r
-                       }\r
-\r
-                       Resource subject = variable.getParent(graph).getPossibleRepresents(graph);\r
-                       if(subject != null) {\r
-                               Set<Resource> asses = new HashSet<Resource>();\r
-                               for(Resource type : graph.getTypes(subject)) {\r
-                                       asses.addAll(graph.getAssertedObjects(type, property));\r
-                               }\r
-                               if(asses.size() == 1) {\r
-                                       Resource ass = asses.iterator().next();\r
-                                       Datatype dt = graph.getPossibleRelatedValue(ass, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class));\r
-                                       if(dt != null) return dt;\r
-                               }\r
-                       }\r
-\r
-               }\r
-\r
-               return null;\r
-\r
-       }\r
-\r
-       private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException {\r
-\r
-               String[] split = requiredValueType.split(" ");\r
-               String arrayType = null;\r
-               if(split.length == 2 && "Array".equals(split[0])) {\r
-                       arrayType = split[1];\r
-               } else if(requiredValueType.startsWith("[") && requiredValueType.endsWith("]")) {\r
-                       arrayType = requiredValueType.substring(1, requiredValueType.length()-1);\r
-               }\r
-\r
-               if(arrayType != null) {\r
-                       Datatype arrayDataType = getArrayDataTypeForType(arrayType);\r
-                       if(arrayDataType != null)\r
-                               return arrayDataType;\r
-               }\r
-\r
-               Datatype dt = Datatypes.getDatatype(requiredValueType);\r
-               if(dt != null) return dt;\r
-\r
-               try {\r
-                       return Datatypes.translate(requiredValueType);\r
-               } catch (DataTypeSyntaxError e) {\r
-                       return null;\r
-               }\r
-\r
-\r
-       }\r
-\r
-       private static Datatype getArrayDataTypeForType(String type) {\r
-               if("Double".equals(type)) return Datatypes.DOUBLE_ARRAY;\r
-               else if("String".equals(type)) return Datatypes.STRING_ARRAY;\r
-               else if("Integer".equals(type)) return Datatypes.INTEGER_ARRAY;\r
-               else if("Long".equals(type)) return Datatypes.LONG_ARRAY;\r
-               else if("Float".equals(type)) return Datatypes.FLOAT_ARRAY;\r
-               else if("Byte".equals(type)) return Datatypes.BYTE_ARRAY;\r
-               else if("Boolean".equals(type)) return Datatypes.BOOLEAN_ARRAY;\r
-               else if("Variant".equals(type)) return Datatypes.VARIANT_ARRAY;\r
-               return null;\r
-       }\r
-\r
-       public static Binding getDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {\r
-\r
-               Resource property = variable.getPossiblePredicateResource(graph);\r
-               if(property != null) {\r
-                       PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());\r
-                       if(info.defaultBinding != null) return info.defaultBinding;\r
-               }\r
-\r
-               Datatype type = getDatatype(graph, variable);\r
-               if (type == null)\r
-                       throw new DatabaseException("No datatype available for variable " + variable.getURI(graph));\r
-               return Bindings.getBinding(type);\r
-\r
-       }\r
-\r
-       public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {\r
-\r
-               Resource property = variable.getPossiblePredicateResource(graph);\r
-               if(property != null) {\r
-                       PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());\r
-                       if(info.defaultBinding != null) return info.defaultBinding;\r
-               }\r
-\r
-               Datatype type = getPossibleDatatype(graph, variable);\r
-               if (type == null) return null;\r
-\r
-               return Bindings.getBinding(type);\r
-\r
-       }\r
-\r
-       public static String getPossibleUnit(Datatype dt) {\r
-               if (dt == null)\r
-                       return null;\r
-               else if (dt instanceof NumberType) {\r
-                       return ((NumberType) dt).getUnit();\r
-               } else if (dt instanceof ArrayType) {\r
-                       ArrayType at = (ArrayType) dt;\r
-                       Datatype cdt = at.componentType();\r
-                       if (cdt instanceof NumberType) {\r
-                               return ((NumberType) cdt).getUnit();\r
-                       }\r
-               }\r
-               return null;\r
-\r
-       }\r
-\r
-       public static String getUnit(ReadGraph graph, Variable variable) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-\r
-               Resource literal = variable.getPossibleRepresents(graph);\r
-               if(literal == null)\r
-                   return "";\r
-\r
-               Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging);\r
-               if(literalDatatype != null) {\r
-                       String unit = getPossibleUnit(literalDatatype);\r
-                       if(unit != null) return unit;\r
-               }\r
-\r
-               Resource property = variable.getPossiblePredicateResource(graph);\r
-               if(property != null) {\r
-\r
-                       Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);\r
-                       if(requiredDataType != null) {\r
-                               String unit = getPossibleUnit(requiredDataType);\r
-                               if(unit != null) return unit;\r
-                       }\r
-\r
-               }\r
-\r
-               return "";\r
-\r
-       }\r
-\r
-       public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype datatype) throws DatabaseException {\r
-\r
-               try {\r
-\r
-                       Datatype source = binding.type();\r
-                       if(source.equals(datatype)) {\r
-                               graph.claimValue(objectResource, value, binding);\r
-                       } else {\r
-                               Binding target = Bindings.getBinding(datatype);\r
-                               Adapter adapter = Bindings.getAdapter(binding, target);\r
-                               graph.claimValue(objectResource, adapter.adapt(value), target);\r
-                       }\r
-\r
-               } catch (AdapterConstructionException e) {\r
-                       throw new DatabaseException(e);\r
-               } catch (AdaptException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-\r
-       }\r
-\r
-       public static String toString(Object value, Binding binding) throws DatabaseException {\r
-               try {\r
-                       if(value instanceof String) return (String)value;\r
-                       StringBuilder sb = new StringBuilder();\r
-                       DataValueRepository rep = new DataValueRepository();\r
-                       binding.printValue(value, sb, rep, false);\r
-                       return sb.toString();\r
-               } catch (BindingException e) {\r
-                       throw new DatabaseException(e);\r
-               } catch (IOException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-       }\r
-\r
-       public static Object parseValue(String text, Binding binding) throws DatabaseException {\r
-               try {\r
-                       if(binding.isInstance(text)) return text;\r
-                       DataValueRepository rep = new DataValueRepository();\r
-                       return binding.parseValue(text, rep);\r
-               } catch (BindingException e) {\r
-                       throw new DatabaseException(e);\r
-               } catch (DataTypeSyntaxError e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-       }\r
-\r
-       @SuppressWarnings("unchecked")\r
-       public static <T> T getValueAdaptedToBinding(ReadGraph graph, Resource literal, Binding targetBinding) throws DatabaseException {\r
-               Datatype sourceDatatype = graph.getDataType(literal);\r
-               Datatype targetDatatype = targetBinding.type();\r
-               if (sourceDatatype.equals(targetDatatype))\r
-                       return graph.getValue(literal, targetBinding);\r
-\r
-               Binding sourceBinding = Bindings.getBinding(sourceDatatype);\r
-               try {\r
-                       Adapter adapter = Bindings.adapterFactory.getAdapter(Bindings.getBinding(sourceDatatype), targetBinding, true, false);\r
-                       Object value = graph.getValue(literal, sourceBinding);\r
-                       return (T) adapter.adaptUnchecked(value);\r
-               } catch (AdapterConstructionException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-       }\r
-\r
-       public static Statement getStatementInLocal(Resource subject, Statement statement) {\r
-               if(statement.isAsserted(subject)) return new StandardStatement(subject, statement.getPredicate(), statement.getObject());\r
-               else return statement;\r
-       }\r
-\r
-       public static Resource browsePossible(ReadGraph graph, Resource root, String suffix) throws DatabaseException {\r
-               return graph.getPossibleResource(graph.getURI(root) + suffix);\r
-       }\r
-\r
-       public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException {\r
-               return graph.sync(new PossibleChild(resource, name));\r
-       }\r
-\r
-       public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException {\r
-               Resource child = graph.sync(new PossibleChild(resource, name));\r
-               if(child == null) return null;\r
-               if(!graph.isInstanceOf(child, type)) return null;\r
-               return child;\r
-       }\r
-\r
-       public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {\r
-               Statement stm = graph.getSingleStatement(subject, predicate);\r
-               return new RelationContextImpl(subject, stm);\r
-       }\r
-\r
-       public static RelationContext relationContext(Statement stm) throws DatabaseException {\r
-               return new RelationContextImpl(stm.getSubject(), stm);\r
-       }\r
-\r
-       public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm) throws DatabaseException {\r
-               return graph.getValue2(subject, Layer0Utils.relationContext(stm));\r
-       }\r
-\r
-       public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm, Binding binding) throws DatabaseException {\r
-               return graph.getValue2(subject, Layer0Utils.relationContext(stm), binding);\r
-       }\r
-\r
-       public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {\r
-               Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));\r
-               return valueInRelationContext(graph, stm.getObject(), stm);\r
-       }\r
-\r
-       public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation, Binding binding) throws DatabaseException {\r
-               Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));\r
-               return valueInRelationContext(graph, stm.getObject(), stm, binding);\r
-       }\r
-\r
-       public static Statement possibleObtainedStatementInternal(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {\r
-\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-\r
-               for(Resource ob : graph.getObjects(subject, L0X.DefinesObtainedStatement)) {\r
-                       Resource pred = graph.getSingleObject(ob, L0X.ObtainedStatement_predicate);\r
-                       if(graph.isSubrelationOf(pred, relation)) {\r
-                               Resource object = graph.getSingleObject(ob, L0X.ObtainedStatement_object);\r
-                               return new StandardStatement(subject, pred, object);\r
-                       }\r
-               }\r
-\r
-               ArrayList<OrderedResource> order = new ArrayList<OrderedResource>();\r
-               for(Statement stm : graph.getStatements(subject, L0X.ObtainsProperty)) {\r
-                       Integer position = graph.getRelatedValue(stm.getPredicate(), L0X.NaturalNumberOrderRelation, Bindings.INTEGER);\r
-                       order.add(new OrderedResource(position, stm.getObject()));\r
-               }\r
-\r
-               for(OrderedResource or : order) {\r
-                       Statement stm = possibleObtainedStatementInternal(graph, or.r, relation);\r
-                       if(stm != null) return stm;\r
-               }\r
-\r
-               return null;\r
-\r
-       }\r
-\r
-       public static <T> T possibleObtainedValue(ReadGraph graph, RelationContext ctx, Binding binding) throws DatabaseException {\r
-\r
-               Statement stm = ctx.getStatement();\r
-               Statement obj = Layer0Utils.possibleObtainedStatementInternal(graph, stm.getSubject(), stm.getPredicate());\r
-\r
-               if(obj != null) {\r
-                       return Layer0Utils.valueInRelationContext(graph, obj.getObject(), obj, binding);\r
-               } else {\r
-                       return null;\r
-               }\r
-\r
-       }\r
-\r
-       public static void addObtainedStatement(WriteGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-               Resource ob = graph.newResource();\r
-               graph.claim(ob, L0.InstanceOf, null, L0X.ObtainedStatement);\r
-               graph.claim(ob, L0X.ObtainedStatement_predicate, null, predicate);\r
-               graph.claim(ob, L0X.ObtainedStatement_object, null, object);\r
-               graph.claim(subject, L0X.DefinesObtainedStatement, null, ob);\r
-       }\r
-\r
-       public static void addObtainedValue(WriteGraph graph, Resource subject, Resource predicate, Resource type, Object value, Binding binding) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Resource object = graph.newResource();\r
-               graph.claim(object, L0.InstanceOf, type);\r
-               graph.claimValue(object, value, binding);\r
-               Layer0Utils.addObtainedStatement(graph, subject, predicate, object);\r
-       }\r
-\r
-       //-------------------------------------------------------------------------\r
-       // Indexing state query utilities idle handling utilities\r
-       //-------------------------------------------------------------------------\r
-\r
-       /**\r
-        * This method waits until the indexing engine becomes idle.\r
-        * @since 1.8\r
-        */\r
-       public static void waitIndexPending() {\r
-               Indexing.waitIndexPending();\r
-       }\r
-\r
-       /**\r
-        * @param graph an active database write handle to prove one is in a write\r
-        *        transaction and wants to disable dependencies indexing for this\r
-        *        transaction only.\r
-        * @return previous value\r
-        * @since 1.8\r
-        */\r
-       public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) {\r
-               return Indexing.setDependenciesIndexingDisabled(graph, disabled);\r
-       }\r
-\r
-       public static String undo() throws DatabaseException {\r
-\r
-           Session session = SimanticsInternal.getSession();\r
-\r
-        UndoRedoSupport support = session.getService(UndoRedoSupport.class);\r
-\r
-        List<Operation> ops = support.undoAndReturnOperations(session, 1);\r
-        if(ops.isEmpty())\r
-            return "Undo history is empty.";\r
-\r
-        Operation mainOperation = ops.get(0);\r
-\r
-        long csId = mainOperation.getCSId();\r
-\r
-        ManagementSupport management = session.getService(ManagementSupport.class);\r
-        Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);\r
-\r
-        return "Undo reverted " + ids.size() + " change sets.";\r
-\r
-       }\r
-\r
-       public static String undoOperations(int amountOfOperations) throws DatabaseException {\r
-\r
-           Session session = SimanticsInternal.getSession();\r
-\r
-        UndoRedoSupport support = session.getService(UndoRedoSupport.class);\r
-\r
-        List<Operation> ops = support.undoAndReturnOperations(session, amountOfOperations);\r
-        if(ops.isEmpty())\r
-            return "Undo history is empty.";\r
-\r
-        Operation mainOperation = ops.get(0);\r
-\r
-        long csId = mainOperation.getCSId();\r
-\r
-        ManagementSupport management = session.getService(ManagementSupport.class);\r
-        Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);\r
-\r
-        return "Undo reverted " + ids.size() + " change sets.";\r
-\r
-       }\r
-\r
-       public static String redo() throws DatabaseException {\r
-\r
-           Session session = SimanticsInternal.getSession();\r
-\r
-        UndoRedoSupport support = session.getService(UndoRedoSupport.class);\r
-\r
-        List<Operation> ops = support.redo(session, 1);\r
-        if(ops.isEmpty())\r
-            return "Redo history is empty.";\r
-\r
-        Operation mainOperation = ops.get(0);\r
-\r
-        long csId = mainOperation.getCSId();\r
-\r
-        ManagementSupport management = session.getService(ManagementSupport.class);\r
-        Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);\r
-\r
-        return "Redo redid " + ids.size() + " change sets.";\r
-\r
-       }\r
-\r
-       public static String getComment(Session session, ChangeSetIdentifier id) {\r
-           byte[] data = id.getMetadata().get(CommentMetadata.class.getName());\r
-           if(data == null)\r
-               return "Undescribed operation.";\r
-           String comment = CommentMetadata.deserialise(session, data).toString().trim();\r
-           if(comment.isEmpty())\r
-               return "Undescribed operation.";\r
-           return comment;\r
-       }\r
-\r
-    /**\r
-     * This method adds CommentMetadata for write transaction. CommentMetadata is used e.g. in Undo view.\r
-     * @param graph\r
-     *    graph handle\r
-     * @param string\r
-     *    comment\r
-     * @throws ServiceException\r
-     */\r
-    public static void addCommentMetadata(WriteOnlyGraph graph, String string) throws ServiceException {\r
-        // Add a comment to metadata.\r
-        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-        graph.addMetadata(cm.add(ObjectUtils.toString(string)));\r
-    }\r
-\r
-       //-------------------------------------------------------------------------\r
-\r
-       /**\r
-        * Copy the specified source resource into the specified container using the\r
-        * specified write transaction handle.\r
-        *\r
-        * @param graph write transaction handle\r
-        * @param targetContainer target container resource of the created copy. The\r
-        *        exact logic of how the copy will be contained by the target\r
-        *        container is up to the PasteHandler to decide\r
-        * @param source the source resource to copy\r
-        * @throws DatabaseException\r
-        * @since 1.8\r
-        */\r
-       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source) throws DatabaseException {\r
-               return copyTo(graph, targetContainer, source, null, null, null);\r
-       }\r
-\r
-       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler) throws DatabaseException {\r
-               return copyTo(graph, targetContainer, source, handler, null, null);\r
-       }\r
-\r
-       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {\r
-               if(copyHandler == null) copyHandler = graph.adapt(source, CopyHandler.class);\r
-               return copyTo(graph, targetContainer, handler, copyHandler, pasteHandler);\r
-       }\r
-\r
-       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {\r
-               SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
-               copyHandler.copyToClipboard(graph, clipboard);\r
-               if(targetContainer != null) {\r
-                       if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class);\r
-                       return pasteHandler.pasteFromClipboard(graph, clipboard, handler);\r
-               } else {\r
-                       DefaultPasteHandler ph = new DefaultPasteHandler(null);\r
-                       return ph.pasteFromClipboard(graph, clipboard, handler);\r
-               }\r
-       }\r
-\r
-       public static CopyHandler2 getPossibleCopyHandler(ReadGraph graph, Collection<Resource> rs) throws DatabaseException {\r
-        CopyHandler2 ch = null;\r
-        for(Resource r : rs) {\r
-            if(ch == null) {\r
-                CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);\r
-                if(ch2_ instanceof CopyHandler2) {\r
-                    ch = (CopyHandler2)ch2_;\r
-                }\r
-            } else {\r
-                CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);\r
-                if(ch2_ instanceof CopyHandler2) {\r
-                    CopyHandler2 ch2 = (CopyHandler2)ch2_;\r
-                    ch = ch.combine(ch2);\r
-                }\r
-            }\r
-        }\r
-        return ch;\r
-       }\r
-\r
-       public static ClusterCollectorPolicy setClusterCollectorPolicy(ClusterCollectorPolicy policy) {\r
-               Session session = SimanticsInternal.getSession();\r
-               ClusterControl cc = session.getService(ClusterControl.class);\r
-               return cc.setPolicy(policy);\r
-       }\r
-\r
-       private static String decodeType(ReadGraph graph, Variable variable) throws DatabaseException {\r
-               Datatype dt = getDatatype(graph, variable);\r
-               return dt.toSingleLineString();\r
-       }\r
-\r
-       private static boolean isAsserted(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {\r
-               Statement stm = graph.getPossibleStatement(subject, predicate);\r
-               return stm != null && stm.isAsserted(subject);\r
-       }\r
-\r
-       public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException {\r
-               \r
-               Resource value = context.getRepresents(graph);\r
-               Resource predicateResource = context.getPredicateResource(graph);\r
-               Variable parent = context.getParent(graph);\r
-               Resource parentResource = parent.getRepresents(graph);\r
-               setExpression(graph, parentResource, predicateResource, value, text, expressionValueType);\r
-\r
-       }\r
-\r
-       public static void setExpression(WriteGraph graph, Resource parentResource, Resource predicateResource, Resource value, String text, Resource expressionValueType) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               boolean hasExpression = graph.isInstanceOf(value, expressionValueType);\r
-               String t = getSCLTypeString(graph, predicateResource, value);\r
-               String expression = text.substring(1).trim();\r
-               if(isAsserted(graph, parentResource, predicateResource)) {\r
-                       Resource newValue = graph.newResource();\r
-                       graph.claim(newValue, L0.InstanceOf, expressionValueType);\r
-                       graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);\r
-                       graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);\r
-                       graph.claim(parentResource, predicateResource, newValue);\r
-               } else {\r
-                       if(hasExpression) {\r
-                               graph.claimLiteral(value, L0.SCLValue_expression, expression, Bindings.STRING);\r
-                       } else {\r
-                               Resource newValue = graph.newResource();\r
-                               graph.claim(newValue, L0.InstanceOf, expressionValueType);\r
-                               graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);\r
-                               graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);\r
-                               graph.deny(parentResource, predicateResource);\r
-                               graph.claim(parentResource, predicateResource, newValue);\r
-                       }\r
-               }\r
-\r
-       }\r
-\r
-       public static void clearExpression(WriteGraph graph, Variable property, Resource expressionValueType) throws DatabaseException {\r
-\r
-               Resource object = property.getPossibleRepresents(graph);\r
-               if(object != null) {\r
-                       boolean hasExpression = graph.isInstanceOf(object, expressionValueType);\r
-                       if(hasExpression) {\r
-                               // There was an expression and now we go back to a value\r
-                               Resource subject = property.getParent(graph).getPossibleRepresents(graph);\r
-                               if(subject != null) {\r
-                                       Resource predicate = property.getPossiblePredicateResource(graph);\r
-                                       if(predicate != null) {\r
-                                               graph.deny(subject, predicate, object);\r
-                                               RemoverUtil.remove(graph, object);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-\r
-       }\r
-\r
-       public static boolean setOrClearExpression(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {\r
-\r
-               if(text.startsWith("=")) {\r
-                       setExpression(graph, property, text, expressionValueType);\r
-                       return true;\r
-               }\r
-\r
-               clearExpression(graph, property, expressionValueType);\r
-\r
-               return false;\r
-\r
-       }\r
-\r
-       public static void setValueAsString(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {\r
-\r
-               try {\r
-\r
-                       if (setOrClearExpression(graph, property, text, expressionValueType))\r
-                               return;\r
-\r
-                       Object value = text;\r
-                       Datatype type = property.getPossibleDatatype(graph);\r
-                       if (type != null) {\r
-\r
-                               Binding binding = Bindings.getBinding(type);\r
-\r
-                               if (binding instanceof StringBinding) {\r
-\r
-                                       if (binding instanceof MutableStringBinding)\r
-                                               value = new MutableString(text);\r
-                                       else\r
-                                               value = text;\r
-\r
-                               } else {\r
-\r
-                                       if (binding instanceof NumberBinding) {\r
-                                               text = text.replace(",", ".");\r
-                                       }\r
-\r
-                                       value = binding.parseValue(text, new DataValueRepository());\r
-\r
-                               }\r
-\r
-                               property.setValue(graph, value, binding);\r
-\r
-                       } else {\r
-\r
-                               property.setValue(graph, value);\r
-\r
-                       }\r
-\r
-                       // Add a comment to metadata.\r
-                       CommentMetadata cm = graph.getMetadata(CommentMetadata.class);\r
-                       graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value)));\r
-\r
-               } catch (DataTypeSyntaxError e) {\r
-                       throw new DatabaseException(e);\r
-               } catch (BindingException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-\r
-       }\r
-\r
-\r
-    public static String queryDebugSupport(String query) {\r
-        Session session = SimanticsInternal.getSession();\r
-        DebugSupport ds = session.getService(DebugSupport.class);\r
-        return ds.query(session, "exec " + query);\r
-    }\r
-\r
-    public static String queryListSupport (String query) {\r
-       Session session = SimanticsInternal.getSession();\r
-       DebugSupport ds = session.getService(DebugSupport.class);\r
-       return ds.query(session, "list " + query);\r
-    }\r
-\r
-    final public static Function1<Resource,Resource> resourceCluster = new FunctionImpl1<Resource, Resource>() {\r
-               @Override\r
-               public Resource apply(Resource p0) {\r
-                       return p0;\r
-               }\r
-       };\r
-\r
-       public static void sort(ReadGraph graph, List<Resource> collection) {\r
-       CollectionSupport cos = graph.getService(CollectionSupport.class);\r
-       cos.sort(collection);\r
-       }\r
-\r
-       public static List<Resource> sortByCluster(ReadGraph graph, Collection<Resource> collection) {\r
-       CollectionSupport cos = graph.getService(CollectionSupport.class);\r
-       return cos.asSortedList(collection);\r
-       }\r
-\r
-       public static List<Object> sortByCluster(final ReadGraph graph, List<Object> list, final Function1<Object,Resource> fn) {\r
-       final ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
-       ArrayList<Object> result = new ArrayList<Object>(list);\r
-       Collections.sort(result, new Comparator<Object>() {\r
-\r
-                       @Override\r
-                       public int compare(Object o1, Object o2) {\r
-                               Resource r1 = fn.apply(o1);\r
-                               Resource r2 = fn.apply(o2);\r
-                               long l1 = cs.getCluster(r1);\r
-                               long l2 = cs.getCluster(r2);\r
-                               if(l1 < l2) return -1;\r
-                               else if (l1 > l2) return 1;\r
-                               else return 0;\r
-                       }\r
-\r
-       });\r
-       return result;\r
-    }\r
-\r
-    public static <T> List<T> sortByClusterT(final ReadGraph graph, Collection<T> list, final Function1<T,Resource> fn) {\r
-        final ClusteringSupport cs = graph.getService(ClusteringSupport.class);\r
-        ArrayList<T> result = new ArrayList<T>(list);\r
-        Collections.sort(result, new Comparator<Object>() {\r
-\r
-            @Override\r
-            public int compare(Object o1, Object o2) {\r
-                Resource r1 = fn.apply((T)o1);\r
-                Resource r2 = fn.apply((T)o2);\r
-                long l1 = cs.getCluster(r1);\r
-                long l2 = cs.getCluster(r2);\r
-                if(l1 < l2) return -1;\r
-                else if (l1 > l2) return 1;\r
-                else return 0;\r
-            }\r
-\r
-        });\r
-        return result;\r
-    }\r
-\r
-    public static void makeSynchronous(ReadGraph graph, boolean value) throws DatabaseException {\r
-        graph.setSynchronous(value);\r
-    }\r
-\r
-    public static Set<Resource> listIndexRoots(ReadGraph graph) throws DatabaseException {\r
-       \r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       \r
-               Set<Resource> indexRoots = new TreeSet<Resource>();\r
-               indexRoots.addAll(Layer0Utils.listOntologies(graph));\r
-               indexRoots.addAll(graph.syncRequest(new ObjectsWithType(SimanticsInternal.getProject(), L0.ConsistsOf, L0.IndexRoot)));\r
-               return indexRoots;\r
-\r
-    }\r
-    \r
-    public static List<Resource> listOntologies(ReadGraph graph) throws DatabaseException {\r
-        return graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary()));\r
-    }\r
-\r
-    public static List<Resource> listGlobalOntologies(ReadGraph graph) throws DatabaseException {\r
-        return graph.syncRequest(new GlobalOntologies(graph.getRootLibrary()));\r
-    }\r
-\r
-    public static <T> T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException {\r
-\r
-               try {\r
-                       SCL_GRAPH.set(graph);\r
-                       T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module + "/" + function)).applyArray(args);\r
-                       SCL_GRAPH.set(null);\r
-                       return t;\r
-               } catch (Throwable t) {\r
-                       throw new DatabaseException(t);\r
-               }\r
-\r
-    }\r
-\r
-    public static boolean isContainerPublished(ReadGraph graph, Variable variable) throws DatabaseException {\r
-\r
-        Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable));\r
-        if(indexRoot == null) return false;\r
-        if(variable.equals(indexRoot)) return false;\r
-        return isPublished(graph, indexRoot);\r
-\r
-    }\r
-\r
-    public static boolean isContainerPublished(ReadGraph graph, Resource resource) throws DatabaseException {\r
-\r
-       Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resource));\r
-       if(indexRoot == null) return false;\r
-       if(resource.equals(indexRoot)) return false;\r
-       return isPublished(graph, indexRoot);\r
-\r
-    }\r
-\r
-    public static boolean isPublished(ReadGraph graph, Resource resource) throws DatabaseException {\r
-\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       Boolean value = graph.getPossibleRelatedValue(resource, L0.Entity_published, Bindings.BOOLEAN);\r
-       if(value != null && value) return true;\r
-\r
-       // This is safety - root should not be published it child is not\r
-       Resource root = graph.syncRequest(new PossibleIndexRoot(resource));\r
-       if(root != null) {\r
-               value = graph.getPossibleRelatedValue(root, L0.Entity_published, Bindings.BOOLEAN);\r
-               if(value != null && value) return true;\r
-       }\r
-\r
-       return false;\r
-\r
-    }\r
-\r
-    private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException {\r
-\r
-       SimanticsClipboardImpl cp = new SimanticsClipboardImpl();\r
-       CopyHandler c1 = graph.adapt(r, CopyHandler.class);\r
-       c1.copyToClipboard(graph, cp);\r
-       Collection<Set<Representation>> reps = cp.getContents();\r
-       if(reps.size() != 1) return null;\r
-       return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
-\r
-    }\r
-\r
-    private static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException {\r
-\r
-       SimanticsClipboardImpl cp = new SimanticsClipboardImpl();\r
-       CopyHandler c1 = graph.adapt(r, CopyHandler.class);\r
-       c1.copyToClipboard(graph, cp);\r
-       Collection<Set<Representation>> reps = cp.getContents();\r
-       if(reps.size() != 1) return null;\r
-       return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE);\r
-\r
-    }\r
-\r
-    /*\r
-     * Modifies target to resemble source.\r
-     */\r
-    public static boolean merge(WriteGraph graph, Resource source, Resource target) throws DatabaseException {\r
-\r
-       TransferableGraphSource tgs1 = makeTGSource(graph, target);\r
-       TransferableGraph1 tg1 = TransferableGraphs.create(graph, tgs1);\r
-       TransferableGraph1 tg2 = makeTG(graph, source);\r
-\r
-        GraphRefactoringUtils.fixIncorrectRoot(tg1.identities);\r
-        GraphRefactoringUtils.fixIncorrectRoot(tg2.identities);\r
-\r
-       ModelTransferableGraphSource mtgs = (ModelTransferableGraphSource)tgs1;\r
-\r
-               Diff diff = new Diff(tg1, tg2);\r
-               TransferableGraphDelta1 delta = diff.diff();\r
-\r
-               long[] oldResources = mtgs.getResourceArray(graph);\r
-               if(TransferableGraphs.hasChanges(graph, oldResources, delta)) {\r
-                       TransferableGraphs.applyDelta(graph, mtgs.getResourceArray(graph), delta);\r
-                       return true;\r
-               } else {\r
-                       return false;\r
-               }\r
-\r
-    }\r
-\r
-    public static Resource inferLiteralTypeFromString(ReadGraph graph, String text) {\r
-       return Layer0.getInstance(graph).String;\r
-    }\r
-\r
-    public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException {\r
-        emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject());\r
-    }\r
-\r
-    public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project) throws ServiceException {\r
-        final SubMonitor mon = SubMonitor.convert(monitor, "Emptying Trash Bin...", 10000);\r
-        try {\r
-            session.syncRequest(new DelayedWriteRequest() {\r
-                @Override\r
-                public void perform(WriteGraph graph) throws DatabaseException {\r
-                    Layer0Utils.setDependenciesIndexingDisabled(graph, true);\r
-                    Layer0 L0 = Layer0.getInstance(graph);\r
-                    Layer0X L0X = Layer0X.getInstance(graph);\r
-                    Resource parent = graph.getSingleObject(project, L0.PartOf);\r
-                    Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin");\r
-                    Collection<Resource> trashes = trashBin != null\r
-                            ? graph.getObjects(trashBin, L0.ConsistsOf)\r
-                            : Collections.<Resource>emptyList();\r
-                    if (trashes.isEmpty())\r
-                        throw new CancelTransactionException();\r
-                    mon.setWorkRemaining((2 + trashes.size()) * 1000);\r
-                    for(Resource trash : trashes) {\r
-                        if (mon.isCanceled())\r
-                            throw new CancelTransactionException();\r
-                        mon.subTask(NameUtils.getSafeName(graph, trash));\r
-                        TGRemover remo = new TGRemover(mon.newChild(1000, SubMonitor.SUPPRESS_ALL_LABELS), trash);\r
-                        remo.remove(graph);\r
-                        if(graph.isInstanceOf(trash, L0.IndexRoot)) {\r
-                               // TODO: this should be an utility \r
-                                       GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);\r
-                                       IndexedRelations ir = graph.getService(IndexedRelations.class);\r
-                                       // Deletes index files\r
-                                       ir.reset(null, graph, L0X.DependenciesRelation, trash);\r
-                                       // Notifies DB listeners\r
-                                       index.reset(graph, trash);\r
-                        }\r
-                    }\r
-                    if (mon.isCanceled())\r
-                        throw new CancelTransactionException();\r
-                    mon.subTask("Committing Changes");\r
-                    mon.newChild(1000);\r
-                }\r
-            });\r
-            if (mon.isCanceled())\r
-                return;\r
-            mon.subTask("Purging Database");\r
-            mon.newChild(1000);\r
-            XSupport xs = session.getService(XSupport.class);\r
-            xs.purge();\r
-        } catch (CancelTransactionException e) {\r
-            // Ignore.\r
-        } catch (DatabaseException e) {\r
-            throw new ServiceException(e);\r
-        }\r
-    }\r
-    \r
-    public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException {\r
-       Resource result = null;\r
-       for(Resource candidate : getDomainOf(graph, type).values()) {\r
-               if(graph.isInstanceOf(candidate, target)) {\r
-                       if(result != null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));\r
-                       else result = candidate;\r
-               }\r
-       }\r
-       if(result == null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));\r
-       return result;\r
-    }\r
-\r
-    public static Map<String, Resource> getDomainOf(ReadGraph graph, Resource type) throws DatabaseException {\r
-       CollectionSupport cs = graph.getService(CollectionSupport.class);\r
-       Map<String, Resource> result = cs.createObjectResourceMap(String.class);\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       for(Resource r : graph.getObjects(type, L0.DomainOf)) {\r
-               String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);\r
-               if(name != null) result.put(name, r);\r
-       }\r
-       for(Resource t : graph.getSupertypes(type)) {\r
-               for(Resource r : graph.getObjects(t, L0.DomainOf)) {\r
-                       String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);\r
-                       if(name != null) result.put(name, r);\r
-               }\r
-       }\r
-       return result;\r
-    }\r
-    \r
-    public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {\r
-       for(Resource type : graph.getPrincipalTypes(instance)) {\r
-               Map<String, Resource> domainOf = getDomainOf(graph, type);\r
-               Resource predicate = domainOf.get(predicateName);\r
-               if(predicate != null) return predicate;\r
-       }\r
-       return null;\r
-    }\r
-    \r
-    \r
-    public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException {\r
-\r
-       try {\r
-               PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(property));\r
-               if(pi.literalRange == null) throw new DatabaseException("No suitable literal type defined as range for property.");\r
-               if(pi.defaultBinding == null) throw new DatabaseException("No suitable default binding for property.");\r
-                       Object value = pi.defaultBinding.parseValue(valueText, new DataValueRepository());\r
-                       graph.claimLiteral(container, property, pi.literalRange, value, pi.defaultBinding);\r
-               } catch (DataTypeSyntaxError e) {\r
-                       throw new DatabaseException(e);\r
-               } catch (BindingException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-       \r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2012 Association for Decentralized Information Management in
+ * Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.layer0.util;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.SubMonitor;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.adapter.AdaptException;
+import org.simantics.databoard.adapter.Adapter;
+import org.simantics.databoard.adapter.AdapterConstructionException;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.NumberBinding;
+import org.simantics.databoard.binding.StringBinding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.mutable.MutableStringBinding;
+import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
+import org.simantics.databoard.parser.repository.DataValueRepository;
+import org.simantics.databoard.primitives.MutableString;
+import org.simantics.databoard.type.ArrayType;
+import org.simantics.databoard.type.BooleanType;
+import org.simantics.databoard.type.ByteType;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.type.DoubleType;
+import org.simantics.databoard.type.FloatType;
+import org.simantics.databoard.type.IntegerType;
+import org.simantics.databoard.type.LongType;
+import org.simantics.databoard.type.MapType;
+import org.simantics.databoard.type.NumberType;
+import org.simantics.databoard.type.OptionalType;
+import org.simantics.databoard.type.RecordType;
+import org.simantics.databoard.type.StringType;
+import org.simantics.databoard.type.UnionType;
+import org.simantics.databoard.type.VariantType;
+import org.simantics.databoard.util.ObjectUtils;
+import org.simantics.db.ChangeSetIdentifier;
+import org.simantics.db.Operation;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RelationContext;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.WriteOnlyGraph;
+import org.simantics.db.common.CommentMetadata;
+import org.simantics.db.common.Indexing;
+import org.simantics.db.common.StandardStatement;
+import org.simantics.db.common.primitiverequest.PossibleRelatedValue;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.common.request.DelayedWriteRequest;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.PossibleChild;
+import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.CancelTransactionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ServiceException;
+import org.simantics.db.layer0.adapter.CopyHandler;
+import org.simantics.db.layer0.adapter.CopyHandler2;
+import org.simantics.db.layer0.adapter.GenericRelationIndex;
+import org.simantics.db.layer0.adapter.PasteHandler;
+import org.simantics.db.layer0.adapter.impl.DefaultPasteHandler;
+import org.simantics.db.layer0.adapter.impl.TGRemover;
+import org.simantics.db.layer0.genericrelation.IndexedRelations;
+import org.simantics.db.layer0.internal.SimanticsInternal;
+import org.simantics.db.layer0.migration.OntologiesFromLibrary;
+import org.simantics.db.layer0.property.OrderedResource;
+import org.simantics.db.layer0.request.GlobalOntologies;
+import org.simantics.db.layer0.request.PossibleVariableIndexRoot;
+import org.simantics.db.layer0.request.PropertyInfo;
+import org.simantics.db.layer0.request.PropertyInfoRequest;
+import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
+import org.simantics.db.layer0.variable.StandardGraphPropertyVariable;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.service.ClusterCollectorPolicy;
+import org.simantics.db.service.ClusterControl;
+import org.simantics.db.service.ClusteringSupport;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.db.service.DebugSupport;
+import org.simantics.db.service.ManagementSupport;
+import org.simantics.db.service.UndoRedoSupport;
+import org.simantics.db.service.XSupport;
+import org.simantics.graph.db.TransferableGraphSource;
+import org.simantics.graph.db.TransferableGraphs;
+import org.simantics.graph.diff.Diff;
+import org.simantics.graph.diff.TransferableGraphDelta1;
+import org.simantics.graph.refactoring.GraphRefactoringUtils;
+import org.simantics.graph.representation.PrettyPrintTG;
+import org.simantics.graph.representation.TransferableGraph1;
+import org.simantics.layer0.Layer0;
+import org.simantics.operation.Layer0X;
+import org.simantics.scl.compiler.environment.Environments;
+import org.simantics.scl.compiler.runtime.RuntimeEnvironment;
+import org.simantics.scl.compiler.top.SCLExpressionCompilationException;
+import org.simantics.scl.compiler.types.Type;
+import org.simantics.scl.osgi.SCLOsgi;
+import org.simantics.scl.runtime.function.Function;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.function.FunctionImpl1;
+
+public class Layer0Utils {
+
+       @SuppressWarnings("rawtypes")
+       public static final ThreadLocal SCL_GRAPH = new ThreadLocal();
+
+       final public static Binding datatype_binging = Bindings.getBindingUnchecked(Datatype.class);
+
+       public static Resource literal(WriteGraph g, String value) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(g);
+               Resource r = g.newResource();
+               g.claimValue(r, value, Bindings.STRING);
+               g.claim(r, L0.InstanceOf, L0.String);
+               return r;
+       }
+
+       public static Resource literal(WriteGraph g, double value) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(g);
+               Resource r = g.newResource();
+               g.claimValue(r, value, Bindings.DOUBLE);
+               g.claim(r, L0.InstanceOf, L0.Double);
+               return r;
+       }
+
+       public static Resource literal(WriteGraph g, int value) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(g);
+               Resource r = g.newResource();
+               g.claimValue(r, value, Bindings.INTEGER);
+               g.claim(r, L0.InstanceOf, L0.Integer);
+               return r;
+       }
+
+       public static void assert_(WriteGraph g, Resource type, Resource predicate, Resource object) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(g);
+               Resource assertion = g.newResource();
+               g.claim(type, L0.Asserts, assertion);
+               g.claim(assertion, L0.InstanceOf, L0.Assertion);
+               g.claim(assertion, L0.HasPredicate, predicate);
+               g.claim(assertion, L0.HasObject, object);
+       }
+
+       public static Resource relation(WriteGraph g, Resource parent, String name, Resource superrelation) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(g);
+               Resource relation = g.newResource();
+               g.claim(relation, L0.SubrelationOf, superrelation);
+               g.claim(relation, L0.HasName, literal(g, name));
+               g.claim(parent, L0.ConsistsOf, relation);
+
+               Resource superrelationInverse = g.getInverse(superrelation);
+               if(superrelationInverse != null) {
+                       Resource inverse = g.newResource();
+                       g.claim(inverse, L0.SubrelationOf, superrelationInverse);
+                       g.claim(relation, L0.ConsistsOf, inverse);
+                       g.claim(inverse, L0.HasName, literal(g, "Inverse"));
+               }
+               return relation;
+       }
+
+       private static Resource getLiteralType(ReadGraph graph, Datatype type) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               if(type instanceof DoubleType) return L0.Double;
+               else if(type instanceof StringType) return L0.String;
+               else if(type instanceof IntegerType) return L0.Integer;
+               else if(type instanceof LongType) return L0.Long;
+               else if(type instanceof FloatType) return L0.Float;
+               else if(type instanceof ByteType) return L0.Byte;
+               else if(type instanceof BooleanType) return L0.Boolean;
+               else if(type instanceof ArrayType) {
+                       ArrayType at = (ArrayType)type;
+                       if(at.componentType instanceof DoubleType) return L0.DoubleArray;
+                       else if(at.componentType instanceof StringType) return L0.StringArray;
+                       else if(at.componentType instanceof IntegerType) return L0.IntegerArray;
+                       else if(at.componentType instanceof LongType) return L0.LongArray;
+                       else if(at.componentType instanceof FloatType) return L0.FloatArray;
+                       else if(at.componentType instanceof ByteType) return L0.ByteArray;
+                       else if(at.componentType instanceof BooleanType) return L0.BooleanArray;
+                       else if(at.componentType instanceof VariantType) return L0.VariantArray;
+               }
+               throw new DatabaseException("Unidentified literal type for datatype " + type);
+       }
+
+       private static Resource getPossibleLiteralType(ReadGraph graph, String type) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               if("Double".equals(type)) return L0.Double;
+               else if("String".equals(type)) return L0.String;
+               else if("Integer".equals(type)) return L0.Integer;
+               else if("Long".equals(type)) return L0.Long;
+               else if("Float".equals(type)) return L0.Float;
+               else if("Byte".equals(type)) return L0.Byte;
+               else if("Boolean".equals(type)) return L0.Boolean;
+               else if("[Double]".equals(type)) return L0.DoubleArray;
+               else if("[String]".equals(type)) return L0.StringArray;
+               else if("[Integer]".equals(type)) return L0.IntegerArray;
+               else if("[Long]".equals(type)) return L0.LongArray;
+               else if("[Float]".equals(type)) return L0.FloatArray;
+               else if("[Byte]".equals(type)) return L0.ByteArray;
+               else if("[Boolean]".equals(type)) return L0.BooleanArray;
+               else if("[Variant]".equals(type)) return L0.VariantArray;
+               else if("Array Double".equals(type)) return L0.DoubleArray;
+               else if("Array String".equals(type)) return L0.StringArray;
+               else if("Array Integer".equals(type)) return L0.IntegerArray;
+               else if("Array Long".equals(type)) return L0.LongArray;
+               else if("Array Float".equals(type)) return L0.FloatArray;
+               else if("Array Byte".equals(type)) return L0.ByteArray;
+               else if("Array Boolean".equals(type)) return L0.BooleanArray;
+               else if("Array Variant".equals(type)) return L0.VariantArray;
+               else if("Vector Double".equals(type)) return L0.DoubleArray;
+               else if("Vector String".equals(type)) return L0.StringArray;
+               else if("Vector Integer".equals(type)) return L0.IntegerArray;
+               else if("Vector Long".equals(type)) return L0.LongArray;
+               else if("Vector Float".equals(type)) return L0.FloatArray;
+               else if("Vector Byte".equals(type)) return L0.ByteArray;
+               else if("Vector Boolean".equals(type)) return L0.BooleanArray;
+               else if("Vector Variant".equals(type)) return L0.VariantArray;
+               else if("Datatype".equals(type)) return L0.DataType;
+               else if("Variant".equals(type)) return L0.Variant;
+               else return null;
+       }
+
+       public static Resource getPossibleLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {
+               Resource predicate = variable.getPossiblePredicateResource(graph);
+               if(predicate == null) return null;
+               return getPossibleLiteralType(graph, predicate);
+       }
+
+       public static Resource getLiteralType(ReadGraph graph, Variable variable) throws DatabaseException {
+               Resource result = getPossibleLiteralType(graph, variable);
+               if(result == null) throw new DatabaseException("Unidentified literal type for variable " + variable.getURI(graph));
+               return result;
+       }
+
+       public static Resource getLiteralType(ReadGraph graph, Resource property) throws DatabaseException {
+               Resource result = getPossibleLiteralType(graph, property);
+               if(result == null) throw new DatabaseException("Unidentified literal type for property " + graph.getURI(property));
+               return result;
+       }
+
+       public static Resource getPossibleLiteralType(ReadGraph graph, Resource property) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               Layer0X L0X = Layer0X.getInstance(graph);
+
+               Resource defaultLiteralType = graph.getPossibleObject(property, L0.HasDefaultLiteralType);
+               if(defaultLiteralType != null) return defaultLiteralType;
+
+               Resource range = graph.getPossibleObject(property, L0.HasRange);
+               if(range != null && !L0.Value.equals(range)) return range;
+
+               Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);
+               if(requiredDataType != null) return getLiteralType(graph, requiredDataType);
+
+               String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);
+               if(requiredValueType == null) return null;
+
+               return getPossibleLiteralType(graph, requiredValueType);
+
+       }
+
+       /**
+        * @param type any data type definition
+        * @return SCL type that matches the specified data type on a basic level.
+        *         Data type metadata is/cannot be converted into SCL types.
+        * @throws IllegalArgumentException
+        *             if the input datatype can't be converted into an SCL type
+        */
+       public static String getSCLType(Datatype type) throws IllegalArgumentException {
+               return buildSCLType(type, null).toString();
+       }
+
+       /**
+        * Only used internally by {@link #buildSCLType(Datatype, StringBuilder)}
+        * @param s
+        * @param toBuilder
+        * @return
+        * @see #buildSCLType(Datatype, StringBuilder)
+        */
+       private static StringBuilder append(StringBuilder toBuilder, String s) {
+               return toBuilder != null ? toBuilder.append(s) : new StringBuilder(s);
+       }
+
+       private static CharSequence append(CharSequence to, String s) {
+               if (to instanceof StringBuilder)
+                       return ((StringBuilder) to).append(s);
+               return new StringBuilder(to.length() + s.length()).append(to).append(s);
+       }
+
+       private static CharSequence stringOrBuilder(StringBuilder toBuilder, String s) {
+               return toBuilder != null ? toBuilder.append(s) : s;
+       }
+
+       /**
+        * @param type any data type definition
+        * @return SCL type that matches the specified data type on a basic level.
+        *         Data type metadata is/cannot be converted into SCL types.
+        * @throws IllegalArgumentException
+        *             if the input datatype can't be converted into an SCL type
+        */
+       private static CharSequence buildSCLType(Datatype type, StringBuilder result) throws IllegalArgumentException {
+               if(type instanceof DoubleType) return stringOrBuilder(result, "Double");
+               else if(type instanceof StringType) return stringOrBuilder(result, "String");
+               else if(type instanceof IntegerType) return stringOrBuilder(result, "Integer");
+               else if(type instanceof FloatType) return stringOrBuilder(result, "Float");
+               else if(type instanceof BooleanType) return stringOrBuilder(result, "Boolean");
+               else if(type instanceof ByteType) return stringOrBuilder(result, "Byte");
+               else if(type instanceof LongType) return stringOrBuilder(result, "Long");
+               else if(type instanceof VariantType) return stringOrBuilder(result, "Variant");
+               else if(type instanceof ArrayType) {
+                       ArrayType at = (ArrayType) type;
+                       // Optimization to prevent allocations in the most basic array cases
+                       if(at.componentType instanceof DoubleType) return stringOrBuilder(result, "Vector Double");
+                       else if(at.componentType instanceof StringType) return stringOrBuilder(result, "Vector String");
+                       else if(at.componentType instanceof IntegerType) return stringOrBuilder(result, "Vector Integer");
+                       else if(at.componentType instanceof FloatType) return stringOrBuilder(result, "Vector Float");
+                       else if(at.componentType instanceof BooleanType) return stringOrBuilder(result, "Vector Boolean");
+                       else if(at.componentType instanceof ByteType) return stringOrBuilder(result, "Vector Byte");
+                       else if(at.componentType instanceof LongType) return stringOrBuilder(result, "Vector Long");
+                       else if(at.componentType instanceof VariantType) return stringOrBuilder(result, "Vector Variant");
+                       else return buildSCLType(at.componentType, append(result, "Vector "));
+               } else if(type instanceof OptionalType) {
+                       OptionalType ot = (OptionalType) type;
+                       return append(buildSCLType(ot.componentType, append(result, "Maybe (")), ")");
+               } else if (type instanceof RecordType) {
+                       throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
+               } else if (type instanceof MapType) {
+                       throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
+               } else if (type instanceof UnionType) {
+                       throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
+               }
+               throw new IllegalArgumentException("Unable to convert datatype into SCL type: " + type);
+       }
+
+
+       public static Type getSCLType(ReadGraph graph, RuntimeEnvironment runtimeEnvironment, String typeText) throws DatabaseException {
+        try {
+                       return Environments.getType(runtimeEnvironment.getEnvironment(), typeText);
+               } catch (SCLExpressionCompilationException e) {
+                       throw new DatabaseException(e);
+               }
+       }
+
+       public static Type getSCLType(ReadGraph graph, Variable property) throws DatabaseException {
+
+               RuntimeEnvironment runtimeEnvironment = graph.syncRequest(new RuntimeEnvironmentRequest(property.getIndexRoot(graph)));
+               return getSCLType(graph, runtimeEnvironment, getSCLTypeString(graph, property));
+
+       }
+
+               
+       public static String getSCLTypeString(ReadGraph graph, Variable context) throws DatabaseException {
+               return getSCLTypeString(graph, context.getPossiblePredicateResource(graph), context.getRepresents(graph));
+       }
+
+
+       public static String getSCLTypeString(ReadGraph graph, Resource predicate, Resource value) throws DatabaseException {
+
+               if(predicate != null) {
+                   String requiredValueTypes = graph.getPossibleRelatedValue(predicate, Layer0.getInstance(graph).RequiresValueType, Bindings.STRING);
+                   if(requiredValueTypes != null)
+                       return requiredValueTypes;
+               }
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               Layer0X L0X = Layer0X.getInstance(graph);
+
+               Datatype literalDatatype = graph.getPossibleRelatedValue(value, L0.HasDataType, datatype_binging);
+               if(literalDatatype != null) return getSCLType(literalDatatype);
+
+               String literalValueType = graph.getPossibleRelatedValue(value, L0.HasValueType, Bindings.STRING);
+               if(literalValueType != null) return literalValueType;
+
+               if(predicate != null) {
+
+                       Datatype requiredDataType = graph.getPossibleRelatedValue(predicate, L0X.RequiresDataType, datatype_binging);
+                       if(requiredDataType != null) return getSCLType(requiredDataType);
+
+                       throw new DatabaseException("Unidentified literal data type for property " + NameUtils.getURIOrSafeNameInternal(graph, predicate));
+
+               }
+
+               throw new DatabaseException("Unidentified literal data type");
+
+       }
+
+       public static Datatype getDatatype(ReadGraph graph, Variable variable) throws DatabaseException {
+               Datatype result = getPossibleDatatype(graph, variable);
+               if(result != null) return result;
+               throw new DatabaseException("Unidentified literal data type for property " + variable.getURI(graph));
+       }
+
+       public static Datatype getPossibleDatatype(ReadGraph graph, Variable variable) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               Layer0X L0X = Layer0X.getInstance(graph);
+
+               Resource property = variable.getPossiblePredicateResource(graph);
+               if(property != null) {
+//                     Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);
+                       Datatype requiredDataType = graph.syncRequest(new PossibleRelatedValue<Datatype>(property, L0X.RequiresDataType, datatype_binging));
+                       if(requiredDataType != null) return requiredDataType;
+               }
+
+               Resource literal = variable.getPossibleRepresents(graph);
+               if(literal != null) {
+                   Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging);
+                   if(literalDatatype != null) return literalDatatype;
+               }
+
+               if(property != null) {
+
+                       String requiredValueType = graph.getPossibleRelatedValue(property, L0.RequiresValueType, Bindings.STRING);
+                       if(requiredValueType != null) {
+                               Datatype datatype = getPossibleDatatypeForValueType(requiredValueType);
+                               if(datatype != null) return datatype;
+                       }
+
+                       Resource subject = variable.getParent(graph).getPossibleRepresents(graph);
+                       if(subject != null) {
+                               Set<Resource> asses = new HashSet<Resource>();
+                               for(Resource type : graph.getTypes(subject)) {
+                                       asses.addAll(graph.getAssertedObjects(type, property));
+                               }
+                               if(asses.size() == 1) {
+                                       Resource ass = asses.iterator().next();
+                                       Datatype dt = graph.getPossibleRelatedValue(ass, L0.HasDataType, Bindings.getBindingUnchecked(Datatype.class));
+                                       if(dt != null) return dt;
+                               }
+                       }
+
+               }
+
+               return null;
+
+       }
+
+       private static Datatype getPossibleDatatypeForValueType(String requiredValueType) throws DatabaseException {
+
+               String[] split = requiredValueType.split(" ");
+               String arrayType = null;
+               if(split.length == 2 && "Array".equals(split[0])) {
+                       arrayType = split[1];
+               } else if(requiredValueType.startsWith("[") && requiredValueType.endsWith("]")) {
+                       arrayType = requiredValueType.substring(1, requiredValueType.length()-1);
+               }
+
+               if(arrayType != null) {
+                       Datatype arrayDataType = getArrayDataTypeForType(arrayType);
+                       if(arrayDataType != null)
+                               return arrayDataType;
+               }
+
+               Datatype dt = Datatypes.getDatatype(requiredValueType);
+               if(dt != null) return dt;
+
+               try {
+                       return Datatypes.translate(requiredValueType);
+               } catch (DataTypeSyntaxError e) {
+                       return null;
+               }
+
+
+       }
+
+       private static Datatype getArrayDataTypeForType(String type) {
+               if("Double".equals(type)) return Datatypes.DOUBLE_ARRAY;
+               else if("String".equals(type)) return Datatypes.STRING_ARRAY;
+               else if("Integer".equals(type)) return Datatypes.INTEGER_ARRAY;
+               else if("Long".equals(type)) return Datatypes.LONG_ARRAY;
+               else if("Float".equals(type)) return Datatypes.FLOAT_ARRAY;
+               else if("Byte".equals(type)) return Datatypes.BYTE_ARRAY;
+               else if("Boolean".equals(type)) return Datatypes.BOOLEAN_ARRAY;
+               else if("Variant".equals(type)) return Datatypes.VARIANT_ARRAY;
+               return null;
+       }
+
+       public static Binding getDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {
+
+               Resource property = variable.getPossiblePredicateResource(graph);
+               if(property != null) {
+                       PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());
+                       if(info.defaultBinding != null) return info.defaultBinding;
+               }
+
+               Datatype type = getDatatype(graph, variable);
+               if (type == null)
+                       throw new DatabaseException("No datatype available for variable " + variable.getURI(graph));
+               return Bindings.getBinding(type);
+
+       }
+
+       public static Binding getPossibleDefaultBinding(ReadGraph graph, Variable variable) throws DatabaseException {
+
+               Resource property = variable.getPossiblePredicateResource(graph);
+               if(property != null) {
+                       PropertyInfo info = graph.syncRequest(new PropertyInfoRequest(property), TransientCacheAsyncListener.<PropertyInfo>instance());
+                       if(info.defaultBinding != null) return info.defaultBinding;
+               }
+
+               Datatype type = getPossibleDatatype(graph, variable);
+               if (type == null) return null;
+
+               return Bindings.getBinding(type);
+
+       }
+
+       public static String getPossibleUnit(Datatype dt) {
+               if (dt == null)
+                       return null;
+               else if (dt instanceof NumberType) {
+                       return ((NumberType) dt).getUnit();
+               } else if (dt instanceof ArrayType) {
+                       ArrayType at = (ArrayType) dt;
+                       Datatype cdt = at.componentType();
+                       if (cdt instanceof NumberType) {
+                               return ((NumberType) cdt).getUnit();
+                       }
+               }
+               return null;
+
+       }
+
+       public static String getUnit(ReadGraph graph, Variable variable) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               Layer0X L0X = Layer0X.getInstance(graph);
+
+               Resource literal = variable.getPossibleRepresents(graph);
+               if(literal == null)
+                   return "";
+
+               Datatype literalDatatype = graph.getPossibleRelatedValue2(literal, L0.HasDataType, new StandardGraphPropertyVariable(graph, variable, null, literal, L0.HasDataType), datatype_binging);
+               if(literalDatatype != null) {
+                       String unit = getPossibleUnit(literalDatatype);
+                       if(unit != null) return unit;
+               }
+
+               Resource property = variable.getPossiblePredicateResource(graph);
+               if(property != null) {
+
+                       Datatype requiredDataType = graph.getPossibleRelatedValue(property, L0X.RequiresDataType, datatype_binging);
+                       if(requiredDataType != null) {
+                               String unit = getPossibleUnit(requiredDataType);
+                               if(unit != null) return unit;
+                       }
+
+               }
+
+               return "";
+
+       }
+
+       public static void claimAdaptedValue(WriteGraph graph, Resource objectResource, Object value, Binding binding, Datatype datatype) throws DatabaseException {
+
+               try {
+
+                       Datatype source = binding.type();
+                       if(source.equals(datatype)) {
+                               graph.claimValue(objectResource, value, binding);
+                       } else {
+                               Binding target = Bindings.getBinding(datatype);
+                               Adapter adapter = Bindings.getAdapter(binding, target);
+                               graph.claimValue(objectResource, adapter.adapt(value), target);
+                       }
+
+               } catch (AdapterConstructionException e) {
+                       throw new DatabaseException(e);
+               } catch (AdaptException e) {
+                       throw new DatabaseException(e);
+               }
+
+       }
+
+       public static String toString(Object value, Binding binding) throws DatabaseException {
+               try {
+                       if(value instanceof String) return (String)value;
+                       StringBuilder sb = new StringBuilder();
+                       DataValueRepository rep = new DataValueRepository();
+                       binding.printValue(value, sb, rep, false);
+                       return sb.toString();
+               } catch (BindingException e) {
+                       throw new DatabaseException(e);
+               } catch (IOException e) {
+                       throw new DatabaseException(e);
+               }
+       }
+
+       public static Object parseValue(String text, Binding binding) throws DatabaseException {
+               try {
+                       if(binding.isInstance(text)) return text;
+                       DataValueRepository rep = new DataValueRepository();
+                       return binding.parseValue(text, rep);
+               } catch (BindingException e) {
+                       throw new DatabaseException(e);
+               } catch (DataTypeSyntaxError e) {
+                       throw new DatabaseException(e);
+               }
+       }
+
+       @SuppressWarnings("unchecked")
+       public static <T> T getValueAdaptedToBinding(ReadGraph graph, Resource literal, Binding targetBinding) throws DatabaseException {
+               Datatype sourceDatatype = graph.getDataType(literal);
+               Datatype targetDatatype = targetBinding.type();
+               if (sourceDatatype.equals(targetDatatype))
+                       return graph.getValue(literal, targetBinding);
+
+               Binding sourceBinding = Bindings.getBinding(sourceDatatype);
+               try {
+                       Adapter adapter = Bindings.adapterFactory.getAdapter(Bindings.getBinding(sourceDatatype), targetBinding, true, false);
+                       Object value = graph.getValue(literal, sourceBinding);
+                       return (T) adapter.adaptUnchecked(value);
+               } catch (AdapterConstructionException e) {
+                       throw new DatabaseException(e);
+               }
+       }
+
+       public static Statement getStatementInLocal(Resource subject, Statement statement) {
+               if(statement.isAsserted(subject)) return new StandardStatement(subject, statement.getPredicate(), statement.getObject());
+               else return statement;
+       }
+
+       public static Resource browsePossible(ReadGraph graph, Resource root, String suffix) throws DatabaseException {
+               return graph.getPossibleResource(graph.getURI(root) + suffix);
+       }
+
+       public static Resource getPossibleChild(ReadGraph graph, Resource resource, String name) throws DatabaseException {
+               return graph.sync(new PossibleChild(resource, name));
+       }
+
+       public static Resource getPossibleChild(ReadGraph graph, Resource resource, Resource type, String name) throws DatabaseException {
+               Resource child = graph.sync(new PossibleChild(resource, name));
+               if(child == null) return null;
+               if(!graph.isInstanceOf(child, type)) return null;
+               return child;
+       }
+
+       public static RelationContext relationContext(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {
+               Statement stm = graph.getSingleStatement(subject, predicate);
+               return new RelationContextImpl(subject, stm);
+       }
+
+       public static RelationContext relationContext(Statement stm) throws DatabaseException {
+               return new RelationContextImpl(stm.getSubject(), stm);
+       }
+
+       public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm) throws DatabaseException {
+               return graph.getValue2(subject, Layer0Utils.relationContext(stm));
+       }
+
+       public static <T> T valueInRelationContext(ReadGraph graph, Resource subject, Statement stm, Binding binding) throws DatabaseException {
+               return graph.getValue2(subject, Layer0Utils.relationContext(stm), binding);
+       }
+
+       public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {
+               Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));
+               return valueInRelationContext(graph, stm.getObject(), stm);
+       }
+
+       public static <T> T relatedValueInRelationContext(ReadGraph graph, Resource subject, Resource relation, Binding binding) throws DatabaseException {
+               Statement stm = getStatementInLocal(subject, graph.getSingleStatement(subject, relation));
+               return valueInRelationContext(graph, stm.getObject(), stm, binding);
+       }
+
+       public static Statement possibleObtainedStatementInternal(ReadGraph graph, Resource subject, Resource relation) throws DatabaseException {
+
+               Layer0X L0X = Layer0X.getInstance(graph);
+
+               for(Resource ob : graph.getObjects(subject, L0X.DefinesObtainedStatement)) {
+                       Resource pred = graph.getSingleObject(ob, L0X.ObtainedStatement_predicate);
+                       if(graph.isSubrelationOf(pred, relation)) {
+                               Resource object = graph.getSingleObject(ob, L0X.ObtainedStatement_object);
+                               return new StandardStatement(subject, pred, object);
+                       }
+               }
+
+               ArrayList<OrderedResource> order = new ArrayList<OrderedResource>();
+               for(Statement stm : graph.getStatements(subject, L0X.ObtainsProperty)) {
+                       Integer position = graph.getRelatedValue(stm.getPredicate(), L0X.NaturalNumberOrderRelation, Bindings.INTEGER);
+                       order.add(new OrderedResource(position, stm.getObject()));
+               }
+
+               for(OrderedResource or : order) {
+                       Statement stm = possibleObtainedStatementInternal(graph, or.r, relation);
+                       if(stm != null) return stm;
+               }
+
+               return null;
+
+       }
+
+       public static <T> T possibleObtainedValue(ReadGraph graph, RelationContext ctx, Binding binding) throws DatabaseException {
+
+               Statement stm = ctx.getStatement();
+               Statement obj = Layer0Utils.possibleObtainedStatementInternal(graph, stm.getSubject(), stm.getPredicate());
+
+               if(obj != null) {
+                       return Layer0Utils.valueInRelationContext(graph, obj.getObject(), obj, binding);
+               } else {
+                       return null;
+               }
+
+       }
+
+       public static void addObtainedStatement(WriteGraph graph, Resource subject, Resource predicate, Resource object) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               Layer0X L0X = Layer0X.getInstance(graph);
+               Resource ob = graph.newResource();
+               graph.claim(ob, L0.InstanceOf, null, L0X.ObtainedStatement);
+               graph.claim(ob, L0X.ObtainedStatement_predicate, null, predicate);
+               graph.claim(ob, L0X.ObtainedStatement_object, null, object);
+               graph.claim(subject, L0X.DefinesObtainedStatement, null, ob);
+       }
+
+       public static void addObtainedValue(WriteGraph graph, Resource subject, Resource predicate, Resource type, Object value, Binding binding) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               Resource object = graph.newResource();
+               graph.claim(object, L0.InstanceOf, type);
+               graph.claimValue(object, value, binding);
+               Layer0Utils.addObtainedStatement(graph, subject, predicate, object);
+       }
+
+       //-------------------------------------------------------------------------
+       // Indexing state query utilities idle handling utilities
+       //-------------------------------------------------------------------------
+
+       /**
+        * This method waits until the indexing engine becomes idle.
+        * @since 1.8
+        */
+       public static void waitIndexPending() {
+               Indexing.waitIndexPending();
+       }
+
+       /**
+        * @param graph an active database write handle to prove one is in a write
+        *        transaction and wants to disable dependencies indexing for this
+        *        transaction only.
+        * @return previous value
+        * @since 1.8
+        */
+       public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) {
+               return Indexing.setDependenciesIndexingDisabled(graph, disabled);
+       }
+
+       public static String undo() throws DatabaseException {
+
+           Session session = SimanticsInternal.getSession();
+
+        UndoRedoSupport support = session.getService(UndoRedoSupport.class);
+
+        List<Operation> ops = support.undoAndReturnOperations(session, 1);
+        if(ops.isEmpty())
+            return "Undo history is empty.";
+
+        Operation mainOperation = ops.get(0);
+
+        long csId = mainOperation.getCSId();
+
+        ManagementSupport management = session.getService(ManagementSupport.class);
+        Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);
+
+        return "Undo reverted " + ids.size() + " change sets.";
+
+       }
+
+       public static String undoOperations(int amountOfOperations) throws DatabaseException {
+
+           Session session = SimanticsInternal.getSession();
+
+        UndoRedoSupport support = session.getService(UndoRedoSupport.class);
+
+        List<Operation> ops = support.undoAndReturnOperations(session, amountOfOperations);
+        if(ops.isEmpty())
+            return "Undo history is empty.";
+
+        Operation mainOperation = ops.get(0);
+
+        long csId = mainOperation.getCSId();
+
+        ManagementSupport management = session.getService(ManagementSupport.class);
+        Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);
+
+        return "Undo reverted " + ids.size() + " change sets.";
+
+       }
+
+       public static String redo() throws DatabaseException {
+
+           Session session = SimanticsInternal.getSession();
+
+        UndoRedoSupport support = session.getService(UndoRedoSupport.class);
+
+        List<Operation> ops = support.redo(session, 1);
+        if(ops.isEmpty())
+            return "Redo history is empty.";
+
+        Operation mainOperation = ops.get(0);
+
+        long csId = mainOperation.getCSId();
+
+        ManagementSupport management = session.getService(ManagementSupport.class);
+        Collection<ChangeSetIdentifier> ids = management.getChangeSetIdentifiers(csId, csId);
+
+        return "Redo redid " + ids.size() + " change sets.";
+
+       }
+
+       public static String getComment(Session session, ChangeSetIdentifier id) {
+           byte[] data = id.getMetadata().get(CommentMetadata.class.getName());
+           if(data == null)
+               return "Undescribed operation.";
+           String comment = CommentMetadata.deserialise(session, data).toString().trim();
+           if(comment.isEmpty())
+               return "Undescribed operation.";
+           return comment;
+       }
+
+    /**
+     * This method adds CommentMetadata for write transaction. CommentMetadata is used e.g. in Undo view.
+     * @param graph
+     *    graph handle
+     * @param string
+     *    comment
+     * @throws ServiceException
+     */
+    public static void addCommentMetadata(WriteOnlyGraph graph, String string) throws ServiceException {
+        // Add a comment to metadata.
+        CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+        graph.addMetadata(cm.add(ObjectUtils.toString(string)));
+    }
+
+       //-------------------------------------------------------------------------
+
+       /**
+        * Copy the specified source resource into the specified container using the
+        * specified write transaction handle.
+        *
+        * @param graph write transaction handle
+        * @param targetContainer target container resource of the created copy. The
+        *        exact logic of how the copy will be contained by the target
+        *        container is up to the PasteHandler to decide
+        * @param source the source resource to copy
+        * @throws DatabaseException
+        * @since 1.8
+        */
+       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source) throws DatabaseException {
+               return copyTo(graph, targetContainer, source, null, null, null);
+       }
+
+       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler) throws DatabaseException {
+               return copyTo(graph, targetContainer, source, handler, null, null);
+       }
+
+       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, Resource source, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {
+               if(copyHandler == null) copyHandler = graph.adapt(source, CopyHandler.class);
+               return copyTo(graph, targetContainer, handler, copyHandler, pasteHandler);
+       }
+
+       public static Collection<Resource> copyTo(WriteGraph graph, Resource targetContainer, PasteEventHandler handler, CopyHandler copyHandler, PasteHandler pasteHandler) throws DatabaseException {
+               SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();
+               copyHandler.copyToClipboard(graph, clipboard);
+               if(targetContainer != null) {
+                       if(pasteHandler == null) pasteHandler = graph.adapt(targetContainer, PasteHandler.class);
+                       return pasteHandler.pasteFromClipboard(graph, clipboard, handler);
+               } else {
+                       DefaultPasteHandler ph = new DefaultPasteHandler(null);
+                       return ph.pasteFromClipboard(graph, clipboard, handler);
+               }
+       }
+
+       public static CopyHandler2 getPossibleCopyHandler(ReadGraph graph, Collection<Resource> rs) throws DatabaseException {
+        CopyHandler2 ch = null;
+        for(Resource r : rs) {
+            if(ch == null) {
+                CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);
+                if(ch2_ instanceof CopyHandler2) {
+                    ch = (CopyHandler2)ch2_;
+                }
+            } else {
+                CopyHandler ch2_ = graph.adapt(r, CopyHandler.class);
+                if(ch2_ instanceof CopyHandler2) {
+                    CopyHandler2 ch2 = (CopyHandler2)ch2_;
+                    ch = ch.combine(ch2);
+                }
+            }
+        }
+        return ch;
+       }
+
+       public static ClusterCollectorPolicy setClusterCollectorPolicy(ClusterCollectorPolicy policy) {
+               Session session = SimanticsInternal.getSession();
+               ClusterControl cc = session.getService(ClusterControl.class);
+               return cc.setPolicy(policy);
+       }
+
+       private static String decodeType(ReadGraph graph, Variable variable) throws DatabaseException {
+               Datatype dt = getDatatype(graph, variable);
+               return dt.toSingleLineString();
+       }
+
+       private static boolean isAsserted(ReadGraph graph, Resource subject, Resource predicate) throws DatabaseException {
+               Statement stm = graph.getPossibleStatement(subject, predicate);
+               return stm != null && stm.isAsserted(subject);
+       }
+
+       public static void setExpression(WriteGraph graph, Variable context, String text, Resource expressionValueType) throws DatabaseException {
+               
+               Resource value = context.getRepresents(graph);
+               Resource predicateResource = context.getPredicateResource(graph);
+               Variable parent = context.getParent(graph);
+               Resource parentResource = parent.getRepresents(graph);
+               setExpression(graph, parentResource, predicateResource, value, text, expressionValueType);
+
+       }
+
+       public static void setExpression(WriteGraph graph, Resource parentResource, Resource predicateResource, Resource value, String text, Resource expressionValueType) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               boolean hasExpression = graph.isInstanceOf(value, expressionValueType);
+               String t = getSCLTypeString(graph, predicateResource, value);
+               String expression = text.substring(1).trim();
+               if(isAsserted(graph, parentResource, predicateResource)) {
+                       Resource newValue = graph.newResource();
+                       graph.claim(newValue, L0.InstanceOf, expressionValueType);
+                       graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);
+                       graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);
+                       graph.claim(parentResource, predicateResource, newValue);
+               } else {
+                       if(hasExpression) {
+                               graph.claimLiteral(value, L0.SCLValue_expression, expression, Bindings.STRING);
+                       } else {
+                               Resource newValue = graph.newResource();
+                               graph.claim(newValue, L0.InstanceOf, expressionValueType);
+                               graph.claimLiteral(newValue, L0.HasValueType, t, Bindings.STRING);
+                               graph.claimLiteral(newValue, L0.SCLValue_expression, expression, Bindings.STRING);
+                               graph.deny(parentResource, predicateResource);
+                               graph.claim(parentResource, predicateResource, newValue);
+                       }
+               }
+
+       }
+
+       public static void clearExpression(WriteGraph graph, Variable property, Resource expressionValueType) throws DatabaseException {
+
+               Resource object = property.getPossibleRepresents(graph);
+               if(object != null) {
+                       boolean hasExpression = graph.isInstanceOf(object, expressionValueType);
+                       if(hasExpression) {
+                               // There was an expression and now we go back to a value
+                               Resource subject = property.getParent(graph).getPossibleRepresents(graph);
+                               if(subject != null) {
+                                       Resource predicate = property.getPossiblePredicateResource(graph);
+                                       if(predicate != null) {
+                                               graph.deny(subject, predicate, object);
+                                               RemoverUtil.remove(graph, object);
+                                       }
+                               }
+                       }
+               }
+
+       }
+
+       public static boolean setOrClearExpression(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {
+
+               if(text.startsWith("=")) {
+                       setExpression(graph, property, text, expressionValueType);
+                       return true;
+               }
+
+               clearExpression(graph, property, expressionValueType);
+
+               return false;
+
+       }
+
+       public static void setValueAsString(WriteGraph graph, Variable property, String text, Resource expressionValueType) throws DatabaseException {
+
+               try {
+
+                       if (setOrClearExpression(graph, property, text, expressionValueType))
+                               return;
+
+                       Object value = text;
+                       Datatype type = property.getPossibleDatatype(graph);
+                       if (type != null) {
+
+                               Binding binding = Bindings.getBinding(type);
+
+                               if (binding instanceof StringBinding) {
+
+                                       if (binding instanceof MutableStringBinding)
+                                               value = new MutableString(text);
+                                       else
+                                               value = text;
+
+                               } else {
+
+                                       if (binding instanceof NumberBinding) {
+                                               text = text.replace(",", ".");
+                                       }
+
+                                       value = binding.parseValue(text, new DataValueRepository());
+
+                               }
+
+                               property.setValue(graph, value, binding);
+
+                       } else {
+
+                               property.setValue(graph, value);
+
+                       }
+
+                       // Add a comment to metadata.
+                       CommentMetadata cm = graph.getMetadata(CommentMetadata.class);
+                       graph.addMetadata(cm.add("Set value " + ObjectUtils.toString(value)));
+
+               } catch (DataTypeSyntaxError e) {
+                       throw new DatabaseException(e);
+               } catch (BindingException e) {
+                       throw new DatabaseException(e);
+               }
+
+       }
+
+
+    public static String queryDebugSupport(String query) {
+        Session session = SimanticsInternal.getSession();
+        DebugSupport ds = session.getService(DebugSupport.class);
+        return ds.query(session, "exec " + query);
+    }
+
+    public static String queryListSupport (String query) {
+       Session session = SimanticsInternal.getSession();
+       DebugSupport ds = session.getService(DebugSupport.class);
+       return ds.query(session, "list " + query);
+    }
+
+    final public static Function1<Resource,Resource> resourceCluster = new FunctionImpl1<Resource, Resource>() {
+               @Override
+               public Resource apply(Resource p0) {
+                       return p0;
+               }
+       };
+
+       public static void sort(ReadGraph graph, List<Resource> collection) {
+       CollectionSupport cos = graph.getService(CollectionSupport.class);
+       cos.sort(collection);
+       }
+
+       public static List<Resource> sortByCluster(ReadGraph graph, Collection<Resource> collection) {
+       CollectionSupport cos = graph.getService(CollectionSupport.class);
+       return cos.asSortedList(collection);
+       }
+
+       public static List<Object> sortByCluster(final ReadGraph graph, List<Object> list, final Function1<Object,Resource> fn) {
+       final ClusteringSupport cs = graph.getService(ClusteringSupport.class);
+       ArrayList<Object> result = new ArrayList<Object>(list);
+       Collections.sort(result, new Comparator<Object>() {
+
+                       @Override
+                       public int compare(Object o1, Object o2) {
+                               Resource r1 = fn.apply(o1);
+                               Resource r2 = fn.apply(o2);
+                               long l1 = cs.getCluster(r1);
+                               long l2 = cs.getCluster(r2);
+                               if(l1 < l2) return -1;
+                               else if (l1 > l2) return 1;
+                               else return 0;
+                       }
+
+       });
+       return result;
+    }
+
+    public static <T> List<T> sortByClusterT(final ReadGraph graph, Collection<T> list, final Function1<T,Resource> fn) {
+        final ClusteringSupport cs = graph.getService(ClusteringSupport.class);
+        ArrayList<T> result = new ArrayList<T>(list);
+        Collections.sort(result, new Comparator<Object>() {
+
+            @Override
+            public int compare(Object o1, Object o2) {
+                Resource r1 = fn.apply((T)o1);
+                Resource r2 = fn.apply((T)o2);
+                long l1 = cs.getCluster(r1);
+                long l2 = cs.getCluster(r2);
+                if(l1 < l2) return -1;
+                else if (l1 > l2) return 1;
+                else return 0;
+            }
+
+        });
+        return result;
+    }
+
+    public static void makeSynchronous(ReadGraph graph, boolean value) throws DatabaseException {
+        graph.setSynchronous(value);
+    }
+
+    public static Set<Resource> listIndexRoots(ReadGraph graph) throws DatabaseException {
+       
+       Layer0 L0 = Layer0.getInstance(graph);
+       
+               Set<Resource> indexRoots = new TreeSet<Resource>();
+               indexRoots.addAll(Layer0Utils.listOntologies(graph));
+               indexRoots.addAll(graph.syncRequest(new ObjectsWithType(SimanticsInternal.getProject(), L0.ConsistsOf, L0.IndexRoot)));
+               return indexRoots;
+
+    }
+    
+    public static List<Resource> listOntologies(ReadGraph graph) throws DatabaseException {
+        return graph.syncRequest(new OntologiesFromLibrary(graph.getRootLibrary()));
+    }
+
+    public static List<Resource> listGlobalOntologies(ReadGraph graph) throws DatabaseException {
+        return graph.syncRequest(new GlobalOntologies(graph.getRootLibrary()));
+    }
+
+    public static <T> T applySCL(String module, String function, ReadGraph graph, Object ... args) throws DatabaseException {
+
+               try {
+                       SCL_GRAPH.set(graph);
+                       T t = (T)((Function)SCLOsgi.MODULE_REPOSITORY.getValue(module + "/" + function)).applyArray(args);
+                       SCL_GRAPH.set(null);
+                       return t;
+               } catch (Throwable t) {
+                       throw new DatabaseException(t);
+               }
+
+    }
+
+    public static boolean isContainerPublished(ReadGraph graph, Variable variable) throws DatabaseException {
+
+        Resource indexRoot = graph.syncRequest(new PossibleVariableIndexRoot(variable));
+        if(indexRoot == null) return false;
+        if(variable.equals(indexRoot)) return false;
+        return isPublished(graph, indexRoot);
+
+    }
+
+    public static boolean isContainerPublished(ReadGraph graph, Resource resource) throws DatabaseException {
+
+       Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(resource));
+       if(indexRoot == null) return false;
+       if(resource.equals(indexRoot)) return false;
+       return isPublished(graph, indexRoot);
+
+    }
+
+    public static boolean isPublished(ReadGraph graph, Resource resource) throws DatabaseException {
+
+       Layer0 L0 = Layer0.getInstance(graph);
+       Boolean value = graph.getPossibleRelatedValue(resource, L0.Entity_published, Bindings.BOOLEAN);
+       if(value != null && value) return true;
+
+       // This is safety - root should not be published it child is not
+       Resource root = graph.syncRequest(new PossibleIndexRoot(resource));
+       if(root != null) {
+               value = graph.getPossibleRelatedValue(root, L0.Entity_published, Bindings.BOOLEAN);
+               if(value != null && value) return true;
+       }
+
+       return false;
+
+    }
+
+    private static TransferableGraph1 makeTG(ReadGraph graph, Resource r) throws DatabaseException {
+
+       SimanticsClipboardImpl cp = new SimanticsClipboardImpl();
+       CopyHandler c1 = graph.adapt(r, CopyHandler.class);
+       c1.copyToClipboard(graph, cp);
+       Collection<Set<Representation>> reps = cp.getContents();
+       if(reps.size() != 1) return null;
+       return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
+
+    }
+
+    public static TransferableGraphSource makeTGSource(ReadGraph graph, Resource r) throws DatabaseException {
+
+       SimanticsClipboardImpl cp = new SimanticsClipboardImpl();
+       CopyHandler c1 = graph.adapt(r, CopyHandler.class);
+       c1.copyToClipboard(graph, cp);
+       Collection<Set<Representation>> reps = cp.getContents();
+       if(reps.size() != 1) return null;
+       return ClipboardUtils.accept(graph, reps.iterator().next(), SimanticsKeys.KEY_TRANSFERABLE_GRAPH_SOURCE);
+
+    }
+
+    /*
+     * Modifies target to resemble source.
+     */
+    public static boolean merge(WriteGraph graph, Resource source, Resource target) throws DatabaseException {
+
+       TransferableGraphSource tgs1 = makeTGSource(graph, target);
+       TransferableGraph1 tg1 = TransferableGraphs.create(graph, tgs1);
+       TransferableGraph1 tg2 = makeTG(graph, source);
+
+        GraphRefactoringUtils.fixIncorrectRoot(tg1.identities);
+        GraphRefactoringUtils.fixIncorrectRoot(tg2.identities);
+
+       ModelTransferableGraphSource mtgs = (ModelTransferableGraphSource)tgs1;
+
+               Diff diff = new Diff(tg1, tg2);
+               TransferableGraphDelta1 delta = diff.diff();
+
+               long[] oldResources = mtgs.getResourceArray(graph);
+               if(TransferableGraphs.hasChanges(graph, oldResources, delta)) {
+                       TransferableGraphs.applyDelta(graph, mtgs.getResourceArray(graph), delta);
+                       return true;
+               } else {
+                       return false;
+               }
+
+    }
+
+    public static Resource inferLiteralTypeFromString(ReadGraph graph, String text) {
+       return Layer0.getInstance(graph).String;
+    }
+
+    public static void emptyTrashBin() throws ServiceException {
+        emptyTrashBin(new NullProgressMonitor());
+    }
+
+    public static void emptyTrashBin(IProgressMonitor monitor) throws ServiceException {
+        emptyTrashBin(monitor, SimanticsInternal.getSession(), SimanticsInternal.getProject());
+    }
+
+    public static void emptyTrashBin(final IProgressMonitor monitor, Session session, final Resource project) throws ServiceException {
+        final SubMonitor mon = SubMonitor.convert(monitor, "Emptying Trash Bin...", 10000);
+        try {
+            session.syncRequest(new DelayedWriteRequest() {
+                @Override
+                public void perform(WriteGraph graph) throws DatabaseException {
+                    Layer0Utils.setDependenciesIndexingDisabled(graph, true);
+                    Layer0 L0 = Layer0.getInstance(graph);
+                    Layer0X L0X = Layer0X.getInstance(graph);
+                    Resource parent = graph.getSingleObject(project, L0.PartOf);
+                    Resource trashBin = Layer0Utils.getPossibleChild(graph, parent, "TrashBin");
+                    Collection<Resource> trashes = trashBin != null
+                            ? graph.getObjects(trashBin, L0.ConsistsOf)
+                            : Collections.<Resource>emptyList();
+                    if (trashes.isEmpty())
+                        throw new CancelTransactionException();
+                    mon.setWorkRemaining((2 + trashes.size()) * 1000);
+                    for(Resource trash : trashes) {
+                        if (mon.isCanceled())
+                            throw new CancelTransactionException();
+                        mon.subTask(NameUtils.getSafeName(graph, trash));
+                        TGRemover remo = new TGRemover(mon.newChild(1000, SubMonitor.SUPPRESS_ALL_LABELS), trash);
+                        remo.remove(graph);
+                        if(graph.isInstanceOf(trash, L0.IndexRoot)) {
+                               // TODO: this should be an utility 
+                                       GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);
+                                       IndexedRelations ir = graph.getService(IndexedRelations.class);
+                                       // Deletes index files
+                                       ir.reset(null, graph, L0X.DependenciesRelation, trash);
+                                       // Notifies DB listeners
+                                       index.reset(graph, trash);
+                        }
+                    }
+                    if (mon.isCanceled())
+                        throw new CancelTransactionException();
+                    mon.subTask("Committing Changes");
+                    mon.newChild(1000);
+                }
+            });
+            if (mon.isCanceled())
+                return;
+            mon.subTask("Purging Database");
+            mon.newChild(1000);
+            purgeDatabase(monitor, session);
+        } catch (CancelTransactionException e) {
+            // Ignore.
+        } catch (DatabaseException e) {
+            throw new ServiceException(e);
+        }
+    }
+
+    public static void purgeDatabase() throws ServiceException {
+       purgeDatabase(new NullProgressMonitor());
+    }
+
+    public static void purgeDatabase(final IProgressMonitor monitor) throws ServiceException {
+       purgeDatabase(monitor, SimanticsInternal.getSession());
+    }
+
+    public static void purgeDatabase(final IProgressMonitor monitor, Session session) throws ServiceException {
+       try {
+               XSupport xs = session.getService(XSupport.class);
+               xs.purge();
+       } catch (DatabaseException e) {
+               throw new ServiceException(e);
+       }
+    }
+
+    public static Resource getSingleDomainOf(ReadGraph graph, Resource type, Resource target) throws DatabaseException {
+       Resource result = null;
+       for(Resource candidate : getDomainOf(graph, type).values()) {
+               if(graph.isInstanceOf(candidate, target)) {
+                       if(result != null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));
+                       else result = candidate;
+               }
+       }
+       if(result == null) throw new DatabaseException("Multiple relations found for target " + graph.getURI(target) + " in type " + graph.getURI(type));
+       return result;
+    }
+
+    public static Map<String, Resource> getDomainOf(ReadGraph graph, Resource type) throws DatabaseException {
+       CollectionSupport cs = graph.getService(CollectionSupport.class);
+       Map<String, Resource> result = cs.createObjectResourceMap(String.class);
+       Layer0 L0 = Layer0.getInstance(graph);
+       for(Resource r : graph.getObjects(type, L0.DomainOf)) {
+               String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
+               if(name != null) result.put(name, r);
+       }
+       for(Resource t : graph.getSupertypes(type)) {
+               for(Resource r : graph.getObjects(t, L0.DomainOf)) {
+                       String name = graph.getPossibleRelatedValue(r, L0.HasName, Bindings.STRING);
+                       if(name != null) result.put(name, r);
+               }
+       }
+       return result;
+    }
+    
+    public static Resource getPossiblePredicateByName(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {
+       for(Resource type : graph.getPrincipalTypes(instance)) {
+               Map<String, Resource> domainOf = getDomainOf(graph, type);
+               Resource predicate = domainOf.get(predicateName);
+               if(predicate != null) return predicate;
+       }
+       return null;
+    }
+    
+    public static Resource getPossiblePredicateByLabel(ReadGraph graph, Resource instance, String predicateName) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(graph);
+       for(Resource type : graph.getPrincipalTypes(instance)) {
+               Map<String, Resource> domainOf = getDomainOf(graph, type);
+               for(Resource r : domainOf.values()) {
+                       String label = graph.getPossibleRelatedValue(r, L0.HasLabel, Bindings.STRING);
+                       if(predicateName.equals(label))
+                               return r;
+               }
+       }
+       return null;
+    }
+    
+    public static void claimLiteralDataboard(WriteGraph graph, Resource container, Resource property, String valueText) throws DatabaseException {
+
+       try {
+               PropertyInfo pi = graph.syncRequest(new PropertyInfoRequest(property));
+               if(pi.literalRange == null) throw new DatabaseException("No suitable literal type defined as range for property.");
+               if(pi.defaultBinding == null) throw new DatabaseException("No suitable default binding for property.");
+                       Object value = pi.defaultBinding.parseValue(valueText, new DataValueRepository());
+                       graph.claimLiteral(container, property, pi.literalRange, value, pi.defaultBinding);
+               } catch (DataTypeSyntaxError e) {
+                       throw new DatabaseException(e);
+               } catch (BindingException e) {
+                       throw new DatabaseException(e);
+               }
+       
+    }
+
+    public static String prettyPrintResource(ReadGraph graph, Resource resource, boolean ignoreIdentifiers) throws Exception {
+        TransferableGraphSource source = makeTGSource(graph, resource);
+        TransferableGraph1 tg = TransferableGraphs.create(graph, source);
+        GraphRefactoringUtils.fixOntologyExport(tg);
+        System.out.println("Printing resoure " + graph.getURI(resource));
+        return PrettyPrintTG.print(tg, ignoreIdentifiers);
+    }
+
+    public static Resource getPossibleAssertedObject(ReadGraph graph, Resource resource, Resource predicate) throws DatabaseException {
+       Resource result = null;
+       for(Resource type : graph.getPrincipalTypes(resource)) {
+               Collection<Resource> rs = graph.getAssertedObjects(type, predicate);
+               if(rs.size() > 1) return null;
+               if(rs.size() == 1) {
+                       Resource ass = rs.iterator().next();
+                       if (result != null && !result.equals(ass)) return null;
+                       result = ass;
+               }
+       }
+       return result;
+    }
+    
+}