]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/ModelTransferableGraphSourceRequest.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / ModelTransferableGraphSourceRequest.java
index d7fe5c690ddb64760b4f351ec9917e9bb028991f..5760f1a026cfa7ab2a5a054c27e6311b13cfe6e1 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in 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.BufferedOutputStream;\r
-import java.io.DataOutput;\r
-import java.io.DataOutputStream;\r
-import java.io.File;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileOutputStream;\r
-import java.io.IOException;\r
-import java.lang.management.ManagementFactory;\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.lang.reflect.Method;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.List;\r
-import java.util.UUID;\r
-\r
-import org.apache.commons.io.output.DeferredFileOutputStream;\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.OperationCanceledException;\r
-import org.eclipse.core.runtime.SubMonitor;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.Datatypes;\r
-import org.simantics.databoard.accessor.error.AccessorException;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.error.BindingException;\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.databoard.parser.repository.DataTypeSyntaxError;\r
-import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.util.binary.BinaryFile;\r
-import org.simantics.databoard.util.binary.BinaryMemory;\r
-import org.simantics.databoard.util.binary.DeferredBinaryFile;\r
-import org.simantics.databoard.util.binary.NullRandomAccessBinary;\r
-import org.simantics.databoard.util.binary.RandomAccessBinary;\r
-import org.simantics.db.DirectStatements;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.RequestProcessor;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.Statement;\r
-import org.simantics.db.common.request.UniqueRead;\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.ValidationException;\r
-import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;\r
-import org.simantics.db.layer0.internal.SimanticsInternal;\r
-import org.simantics.db.service.ClusterControl;\r
-import org.simantics.db.service.ClusterControl.ClusterState;\r
-import org.simantics.db.service.ClusteringSupport;\r
-import org.simantics.db.service.CollectionSupport;\r
-import org.simantics.db.service.DirectQuerySupport;\r
-import org.simantics.db.service.SerialisationSupport;\r
-import org.simantics.graph.representation.Extensions;\r
-import org.simantics.graph.utils.TGResourceUtil;\r
-import org.simantics.graph.utils.TGResourceUtil.LongAdapter;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.utils.threads.logger.ITask;\r
-import org.simantics.utils.threads.logger.ThreadLogger;\r
-\r
-import gnu.trove.list.array.TIntArrayList;\r
-import gnu.trove.map.hash.TIntIntHashMap;\r
-import gnu.trove.map.hash.TLongObjectHashMap;\r
-import gnu.trove.procedure.TIntProcedure;\r
-import gnu.trove.procedure.TLongObjectProcedure;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-public class ModelTransferableGraphSourceRequest extends UniqueRead<ModelTransferableGraphSource> {\r
-\r
-       public static String LOG_FILE = "transferableGraph.log";\r
-       final static boolean LOG = false;\r
-       final static private boolean DEBUG = false;\r
-       final static boolean PROFILE = false;\r
-       \r
-       private TransferableGraphConfiguration2 configuration;\r
-       private SubMonitor monitor;\r
-       \r
-       static DataOutput log;\r
-\r
-       static {\r
-\r
-               if (LOG) {\r
-                       try {\r
-                               FileOutputStream stream = new FileOutputStream(LOG_FILE);\r
-                               log = new DataOutputStream(stream);\r
-                       } catch (FileNotFoundException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-               }\r
-\r
-       }\r
-       \r
-       static void log(String line) {\r
-               if (LOG) {\r
-                       try {\r
-                               log.writeUTF(line + "\n");\r
-                       } catch (IOException e) {\r
-                               e.printStackTrace();\r
-                       }\r
-               }\r
-       }\r
-\r
-    public ModelTransferableGraphSourceRequest(TransferableGraphConfiguration2 conf) {\r
-        this(null, conf);\r
-    }\r
-\r
-    public ModelTransferableGraphSourceRequest(IProgressMonitor monitor, TransferableGraphConfiguration2 conf) {\r
-        this.monitor = SubMonitor.convert(monitor);\r
-        this.configuration = conf;\r
-    }\r
-\r
-       Layer0 L0;\r
-       \r
-       int statements[];\r
-       int statementIndex = 0;\r
-       TIntIntHashMap ids;\r
-       TIntArrayList externalParents = new TIntArrayList();\r
-       ArrayList<String> externalNames = new ArrayList<String>();\r
-       \r
-       int id = 0;\r
-       int indent = 0;\r
-\r
-       private SerialisationSupport support;\r
-\r
-       private Resource getResource(int r) throws DatabaseException {\r
-               return support.getResource(r);\r
-       }\r
-       \r
-       public int getInternalId(int r) {\r
-               return ids.get(r);\r
-       }\r
-       \r
-       public boolean validateExternal(Resource ext) {\r
-               ExtentStatus status = configuration.preStatus.get(ext);\r
-               if(status != null) {\r
-                       if(ExtentStatus.INTERNAL.equals(status)) return false;\r
-                       else if(ExtentStatus.EXCLUDED.equals(status)) return false;\r
-               }\r
-               return true;\r
-       }\r
-       \r
-       /*\r
-        * \r
-        * @return -2 if r is not really external and the statement should be excluded\r
-        * \r
-        */\r
-       public int getId(ReadGraph graph, int r) throws DatabaseException {\r
-               if(ids.containsKey(r)) {\r
-                   int ret = ids.get(r);\r
-                   if(ret == -1) {\r
-                       for(int i=0;i<=indent;++i)\r
-                           System.out.print("  ");\r
-                       System.out.println("Cycle!!!"); // with " + GraphUtils.getReadableName(g, r));\r
-                   }\r
-                       return ret;\r
-               }\r
-               else {\r
-            if(!validateExternal(getResource(r))) return -2;\r
-                       Collection<Resource> parents = graph.getObjects(getResource(r), L0.PartOf);                     \r
-                       if(parents.size() != 1) {\r
-                               throw new ValidationException("Reference to external resource " \r
-                                               + NameUtils.getSafeName(graph, getResource(r), true) + " without unique uri (" + parents.size() + " parents).");\r
-                       }\r
-                       for(Resource p : parents) {\r
-                           ++indent;\r
-                           int pid = getId(graph, support.getTransientId(p));\r
-                           if(pid == -2) return -2;\r
-                               externalParents.add(pid);\r
-                               --indent;\r
-                       }\r
-            externalNames.add((String)graph.getRelatedValue(getResource(r), L0.HasName));\r
-                       ids.put(r, id);\r
-                       return id++;\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public ModelTransferableGraphSource perform(ReadGraph graph) throws DatabaseException {\r
-\r
-               support = graph.getService(SerialisationSupport.class);\r
-\r
-               this.L0 = Layer0.getInstance(graph);\r
-\r
-               long total = System.nanoTime();\r
-       long startupTime = System.nanoTime();\r
-       long startupTimeEnd = System.nanoTime();\r
-               long domainTime = System.nanoTime();\r
-               \r
-               String otherStatements = "other" + UUID.randomUUID().toString();\r
-               String valueFileName = "value" + UUID.randomUUID().toString();\r
-               \r
-               File base_ = SimanticsInternal.getTemporaryDirectory();\r
-        File base = new File(base_, "exports");\r
-        base.mkdirs();\r
-               \r
-        File otherStatementsFile = new File(base, otherStatements);\r
-        File valueFile = new File(base, valueFileName);\r
-        \r
-//        System.err.println("f: " + otherStatementsFile.getAbsolutePath());\r
-        \r
-        try {\r
-               DeferredFileOutputStream otherStatementsStream = new DeferredFileOutputStream(1024*1024, otherStatementsFile);\r
-\r
-               DataOutputStream otherStatementsOutput = new DataOutputStream(new BufferedOutputStream(otherStatementsStream, 1024*1024));\r
-               DeferredBinaryFile valueOutput = new DeferredBinaryFile(valueFile, 1024*1024, 128*1024);\r
-\r
-               ClusterControl cc = graph.getService(ClusterControl.class);\r
-               ClusterState clusterState = cc.getClusterState();\r
-\r
-               TIntHashSet excludedShared = new TIntHashSet();\r
-\r
-               ids = new TIntIntHashMap(1000, 0.75f);\r
-\r
-               DomainProcessorState state = new DomainProcessorState();\r
-               state.extensions.putAll(configuration.baseExtensions);\r
-               state.ids = ids;\r
-               state.statementsOutput = otherStatementsOutput;\r
-               state.valueOutput = valueOutput;\r
-               state.valueCount = 0;\r
-               state.excludedShared = excludedShared;\r
-            state.monitor = monitor;\r
-            state.valueModifier = composeTGValueModifier(configuration.valueModifiers);\r
-\r
-               getDomain2(graph, configuration, state, configuration.ignoreVirtualResources);\r
-\r
-               id = ids.size();\r
-\r
-               cc.restoreClusterState(clusterState);\r
-\r
-               otherStatementsOutput.flush();\r
-               otherStatementsOutput.close();\r
-\r
-               // Do not close valueOutput, just flush it and reuse it in\r
-               // ModelTransferableGraphSource for reading.\r
-               valueOutput.flush();\r
-\r
-               long domainDuration = System.nanoTime() - domainTime;\r
-\r
-               state.id = id;\r
-            state.otherStatementsInput = toRandomAccessBinary(otherStatementsStream, 128*1024);\r
-            state.valueInput = toRandomAccessBinary(valueOutput);\r
-            state.statementsOutput = null;\r
-            state.valueOutput = null;\r
-\r
-               long totalEnd = System.nanoTime();\r
-\r
-               if(PROFILE) {   \r
-                       System.out.println("startup in " + 1e-9*(startupTimeEnd - startupTime) + "s.");\r
-                       System.out.println("domain was found in " + 1e-9*(domainDuration) + "s.");\r
-                       System.out.println("total time for building subgraph was " + 1e-9*(totalEnd-total) + "s.");\r
-               }\r
-               \r
-               return getSource(graph, configuration, state, otherStatementsFile, valueFile);\r
-               \r
-        } catch (DatabaseException e) {\r
-               throw e;\r
-        } catch (IOException e) {\r
-               throw new DatabaseException(e.getMessage(), e);\r
-        } catch (Throwable e) {\r
-               dumpHeap("crash.hprof");\r
-               throw new DatabaseException(e.getMessage(), e);\r
-        }\r
-               \r
-       }\r
-       \r
-       protected ModelTransferableGraphSource getSource(ReadGraph graph, TransferableGraphConfiguration2 configuration, DomainProcessorState state, File otherStatementsFile, File valueFile) throws DatabaseException {\r
-       return new ModelTransferableGraphSource(graph, configuration, state, otherStatementsFile, valueFile);\r
-       }\r
-\r
-       private TGValueModifier composeTGValueModifier(Collection<TGValueModifier> configuredModifiers) {\r
-               List<TGValueModifier> valueModifiers = configuredModifiers == null ? new ArrayList<>(2) : new ArrayList<>(configuredModifiers.size() + 2);\r
-               valueModifiers.add(new ResourceTGValueModifier(support));\r
-               valueModifiers.add(RevisionTGValueModifier.INSTANCE);\r
-               return new ComposedTGValueModifier(valueModifiers.toArray(new TGValueModifier[valueModifiers.size()]));\r
-       }\r
-\r
-    private static RandomAccessBinary toRandomAccessBinary(DeferredFileOutputStream stream, int bufferSize) throws IOException {\r
-        if (stream.isInMemory())\r
-            return new BinaryMemory(stream.getData());\r
-        return new BinaryFile(stream.getFile(), bufferSize);\r
-    }\r
-\r
-    private static RandomAccessBinary toRandomAccessBinary(DeferredBinaryFile file) throws IOException {\r
-        RandomAccessBinary b = file.getBackend();\r
-        long size = b.position();\r
-        b.position(0);\r
-        if (b instanceof BinaryMemory) {\r
-            b.setLength(size);\r
-        }\r
-        return b;\r
-    }\r
-\r
-       public static DomainOnlyProcessor getDomainOnly(RequestProcessor processor, IProgressMonitor monitor, final Resource resource) throws DatabaseException {\r
-               return getDomainOnly(processor, monitor, Collections.singletonList(resource));\r
-       }\r
-\r
-       public static DomainOnlyProcessor getDomainOnly(RequestProcessor processor, final IProgressMonitor monitor, final Collection<Resource> resources) throws DatabaseException {\r
-\r
-               return processor.syncRequest(new UniqueRead<DomainOnlyProcessor>() {\r
-\r
-                       @Override\r
-                       public DomainOnlyProcessor perform(ReadGraph graph) throws DatabaseException {\r
-\r
-                               try {\r
-\r
-                                       TransferableGraphConfiguration2 conf = TransferableGraphConfiguration2.createWithResources(graph, resources, Collections.<Resource>emptyList()); \r
-\r
-                                       DomainProcessorState state = new DomainProcessorState();\r
-                                       state.extensions.putAll(conf.baseExtensions);\r
-                                       state.ids = new TIntIntHashMap(1000, 0.75f);\r
-                                       state.statementsOutput = new DataOutputStream(new NullOutputStream());\r
-                                       state.valueOutput = new NullRandomAccessBinary();\r
-                                       state.valueCount = 0;\r
-                                       state.excludedShared = new TIntHashSet();\r
-                                       state.monitor = SubMonitor.convert(monitor);\r
-\r
-                                       return getDomainOnly(graph, conf, state, conf.ignoreVirtualResources);\r
-\r
-                               } catch (OperationCanceledException e) {\r
-                                       \r
-                                       return null;\r
-\r
-                               }\r
-\r
-                       }\r
-\r
-               });\r
-\r
-       }\r
-    \r
-    public static class DomainOnlyProcessor extends DomainProcessor3 {\r
-\r
-       final Resource instanceOf;\r
-       final public List<Resource> internals;\r
-       final public List<Resource> internalTypes;\r
-       \r
-       private int counter = 0;\r
-       \r
-               public DomainOnlyProcessor(ReadGraph graph, TransferableGraphConfiguration2 conf, DomainProcessorState state, boolean ignoreVirtual) throws DatabaseException {\r
-                       super(graph, conf, state, ignoreVirtual);\r
-                       CollectionSupport cs = graph.getService(CollectionSupport.class);\r
-                       internals = cs.createList();\r
-                       internalTypes = cs.createList();\r
-                       instanceOf = Layer0.getInstance(graph).InstanceOf;\r
-               }\r
-               \r
-               @Override\r
-               final public void addToStream(Resource predicate, Resource object) throws DatabaseException {\r
-               }\r
-               \r
-               @Override\r
-               public void flushStatementStream(int sId, DomainProcessorState state) throws IOException {\r
-               }\r
-               \r
-               @Override\r
-               public void processValue(ReadGraph graph, Resource subject, int sId, DomainProcessorState state) throws DatabaseException, IOException {\r
-               }\r
-               \r
-               @Override\r
-               public void processInternal(ReadGraph graph, Resource subject, DirectStatements stms, DomainProcessorState state) throws DatabaseException, IOException {\r
-                       \r
-                       if((counter++ & 1023) == 0)\r
-                               if(state.monitor != null)\r
-                                       if(state.monitor.isCanceled())\r
-                                               throw new CancelTransactionException();\r
-                       \r
-                       super.processInternal(graph, subject, stms, state);\r
-                       \r
-                       internals.add(subject);\r
-                       \r
-                       Resource singleType = null;\r
-                       for(Statement s : stms) {\r
-                               if(instanceOf.equals(s.getPredicate())) {\r
-                                       if(singleType != null) {\r
-                                               internalTypes.add(null);\r
-                                               return;\r
-                                       } else {\r
-                                               singleType = s.getObject();\r
-                                       }\r
-                               }\r
-                       }\r
-                       \r
-                       internalTypes.add(singleType);\r
-                       \r
-               }\r
-               \r
-       \r
-    }\r
-       \r
-       public static DomainOnlyProcessor getDomainOnly(final ReadGraph graph , final TransferableGraphConfiguration2 conf, DomainProcessorState state, boolean ignoreVirtual) throws DatabaseException {\r
-\r
-               final DomainOnlyProcessor processor = new DomainOnlyProcessor(graph, conf, state, ignoreVirtual);\r
-               getDomain2(graph, state, processor);\r
-               return processor;\r
-               \r
-       }\r
-\r
-    public static DomainProcessor3 getDomain2(final ReadGraph graph , final TransferableGraphConfiguration2 conf, DomainProcessorState state, boolean ignoreVirtual) throws DatabaseException {\r
-\r
-               ITask task = ThreadLogger.getInstance().begin("getDomain2");\r
-\r
-               final DomainProcessor3 processor = new DomainProcessor3(graph, conf, state, ignoreVirtual);\r
-               \r
-               getDomain2(graph, state, processor);\r
-               \r
-               final SerialisationSupport support = graph.getService(SerialisationSupport.class);\r
-               final ClusteringSupport cls = graph.getService(ClusteringSupport.class);\r
-               final Resource indexRoot = processor.conf.indexRoot;\r
-\r
-               if (state.monitor.isCanceled())\r
-                       throw new CancelTransactionException();\r
-\r
-               TLongObjectHashMap<TIntArrayList> clusterMap = new TLongObjectHashMap<TIntArrayList>();\r
-               for(Resource r : processor.status.keySet()) {\r
-                       ExtentStatus status = processor.status.get(r);\r
-                       int transientId = support.getTransientId(r);\r
-                       if(ExtentStatus.INTERNAL == status) {\r
-                               long cluster = cls.getCluster(r);\r
-                               TIntArrayList list = clusterMap.get(cluster);\r
-                               if(list == null) {\r
-                                       list = new TIntArrayList();\r
-                                       clusterMap.put(cluster, list);\r
-                               }\r
-                               list.add(transientId);\r
-                       } else if(ExtentStatus.EXTERNAL == status) {\r
-                               state.externals.add(transientId);\r
-                       } else if(ExtentStatus.PENDING == status) {\r
-                               String uri = graph.getPossibleURI(r);\r
-                               if(uri != null)\r
-                                       state.externals.add(transientId);\r
-                               else {\r
-                                       state.pending.add(transientId);\r
-                                       System.err.println("Pending status in export: " + NameUtils.getSafeName(graph, r, true) + " (" + graph.getPossibleURI(r) + ")");\r
-                               }\r
-                       }\r
-               }\r
-\r
-               if (state.monitor.isCanceled())\r
-                       throw new CancelTransactionException();\r
-\r
-               final TIntArrayList clustering = new TIntArrayList();\r
-               clusterMap.forEachEntry(new TLongObjectProcedure<TIntArrayList>() {\r
-                       \r
-                       @Override\r
-                       public boolean execute(long cluster, TIntArrayList b) {\r
-                               clustering.add(b.size());\r
-                               b.forEach(new TIntProcedure() {\r
-                                       \r
-                                       @Override\r
-                                       public boolean execute(int rId) {\r
-                                               processor.ids.put(rId, processor.id++);\r
-                                               return true;\r
-                                       }\r
-                                       \r
-                               });\r
-                               return true;\r
-                       }\r
-                       \r
-               });\r
-\r
-               if (state.monitor.isCanceled())\r
-                       throw new CancelTransactionException();\r
-\r
-               final TIntArrayList clusterSets = new TIntArrayList();\r
-               clusterMap.forEachEntry(new TLongObjectProcedure<TIntArrayList>() {\r
-                       \r
-                       @Override\r
-                       public boolean execute(long cluster, TIntArrayList b) {\r
-                               try {\r
-                                       Resource clusterSet = cls.getClusterSetOfCluster(cluster);\r
-                                       if(clusterSet != null) {\r
-                                               int transientId = support.getTransientId(clusterSet);\r
-                                               if(processor.ids.containsKey(transientId)) {\r
-                                                       clusterSets.add(processor.ids.get(transientId));\r
-                                                       return true;\r
-                                               } else {\r
-                                                       if(graph.getRootLibrary().equals(clusterSet)) {\r
-                                                               clusterSets.add(Extensions.ROOT_LIBRARY_CLUSTER_SET);\r
-                                                               return true;\r
-                                                       } else if (clusterSet.equals(indexRoot)) {\r
-                                                               clusterSets.add(Extensions.INDEX_ROOT_CLUSTER_SET);\r
-                                                               return true;\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                               } catch (DatabaseException e) {\r
-                               }\r
-                               clusterSets.add(Extensions.NO_CLUSTER_SET);\r
-                               return true;\r
-                               \r
-                       }\r
-                       \r
-               });\r
-               \r
-               state.extensions.put(Extensions.CLUSTERING, new Variant(Bindings.INT_ARRAY, clustering.toArray()));\r
-               state.extensions.put(Extensions.CLUSTER_SETS, new Variant(Bindings.INT_ARRAY, clusterSets.toArray()));\r
-               \r
-               long total = processor.startupTime + processor.expandTime\r
-                               + processor.classifyPredicateTime\r
-                               + processor.processFringeTime + processor.extentSeedTime\r
-                               + processor.fullResolveTime + processor.fastResolveTime + \r
-                               + processor.parentResolveTime + processor.otherStatementTime;\r
-\r
-               if (PROFILE) {\r
-                       System.out.println("startup took " + 1e-9 * processor.startupTime + "s.");\r
-                       System.out.println("expand took " + 1e-9 * processor.expandTime + "s.");\r
-                       System.out.println("classifyPredicates took " + 1e-9 * processor.classifyPredicateTime + "s.");\r
-                       System.out.println("processFringe took " + 1e-9 * processor.processFringeTime + "s.");\r
-                       System.out.println("extentSeeding took " + 1e-9 * processor.extentSeedTime + "s.");\r
-                       System.out.println("fullResolve took " + 1e-9 * processor.fullResolveTime + "s.");\r
-                       System.out.println("fastResolve took " + 1e-9 * processor.fastResolveTime + "s.");\r
-                       System.out.println("parentResolve took " + 1e-9 * processor.parentResolveTime + "s.");\r
-                       System.out.println("otherStatements took " + 1e-9 * processor.otherStatementTime + "s.");\r
-                       System.out.println("value output took " + 1e-9 * processor.valueOutputTime + "s.");\r
-                       System.out.println("statement output took " + 1e-9 * processor.statementOutputTime + "s.");\r
-                       System.out.println("total " + 1e-9 * total + "s.");\r
-               }\r
-\r
-               task.finish();\r
-\r
-               return processor;\r
-\r
-       }\r
-\r
-       public static DomainProcessor3 getDomain2(final ReadGraph graph , DomainProcessorState state, final DomainProcessor3 processor) throws DatabaseException {\r
-               processor.process(graph, state);\r
-               return processor;\r
-       }\r
-       \r
-       static class Expansion3 extends UniqueRead<Collection<DirectStatements>> {\r
-\r
-               final private Collection<Resource> roots;\r
-               final boolean ignoreVirtual;\r
-\r
-               public Expansion3(Collection<Resource> roots, boolean ignoreVirtual) {\r
-                       this.roots = roots;\r
-                       this.ignoreVirtual = ignoreVirtual;\r
-               }\r
-\r
-               @Override\r
-               public Collection<DirectStatements> perform(ReadGraph graph) {\r
-                       \r
-                       ArrayList<DirectStatements> result = new ArrayList<DirectStatements>();\r
-\r
-                       final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);\r
-\r
-                       final DomainStatementProcedure3 proc = new DomainStatementProcedure3(result);\r
-\r
-                       if (ignoreVirtual) {\r
-                               for(Resource r : roots) {\r
-                                       dqs.forEachDirectPersistentStatement(graph, r, proc);\r
-                               }\r
-                       } else {\r
-                               for(Resource r : roots) {\r
-                                       dqs.forEachDirectStatement(graph, r, proc);\r
-                               }\r
-                       }\r
-                       \r
-                       return result;\r
-\r
-               }\r
-\r
-       }       \r
-       private static void dumpHeap(String path) {\r
-               \r
-        try {\r
-            Object bean = getBean();\r
-            if (bean == null)\r
-                return;\r
-\r
-            Method m = bean.getClass().getMethod("dumpHeap", String.class, boolean.class);\r
-            m.invoke(bean, path, true);\r
-            \r
-        } catch (IllegalArgumentException e) {\r
-        } catch (IllegalAccessException e) {\r
-        } catch (SecurityException e) {\r
-        } catch (NoSuchMethodException e) {\r
-        } catch (InvocationTargetException e) {\r
-               } finally {\r
-        }\r
-               \r
-       }\r
-       \r
-    private static Object getBean() {\r
-        Class<?> beanClass = getBeanClass();\r
-        if (beanClass == null)\r
-            return null;\r
-        try {\r
-            Object bean = ManagementFactory.newPlatformMXBeanProxy(\r
-                    ManagementFactory.getPlatformMBeanServer(),\r
-                    "com.sun.management:type=HotSpotDiagnostic",\r
-                    beanClass);\r
-            return bean;\r
-        } catch (IOException e) {\r
-            return null;\r
-        }\r
-    }\r
-    \r
-    private static Class<?> getBeanClass() {\r
-        try {\r
-            Class<?> clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");\r
-            return clazz;\r
-        } catch (ClassNotFoundException e) {\r
-            return null;\r
-        }\r
-    }\r
-\r
-    public static void main(String[] args) {\r
-               \r
-       try {\r
-               \r
-                       Datatype dt = Datatypes.translate("{ parts : ( | ResourceRVIPart { role : |CHILD|PROPERTY, resource : Long(unit=\"resource\") } | StringRVIPart { role : |CHILD|PROPERTY, string : String } ) [] }");\r
-                       Binding b = Bindings.getBinding(dt);\r
-                       Object value = b.createDefault();\r
-                       Variant variant = new Variant(b, value);\r
-                       TGResourceUtil util = new TGResourceUtil();\r
-                       LongAdapter la = new LongAdapter() {\r
-                               @Override\r
-                               public long adapt(long in) {\r
-                                       return in;\r
-                               }                       \r
-                       };\r
-                       util.adaptValue( variant.getBinding(), variant.getValue(), la );\r
-                       \r
-               } catch (DataTypeSyntaxError e) {\r
-                       e.printStackTrace();\r
-               } catch (BindingException e) {\r
-                       e.printStackTrace();\r
-               } catch (RuntimeSerializerConstructionException e) {\r
-                       e.printStackTrace();\r
-               } catch (AccessorException e) {\r
-                       e.printStackTrace();\r
-               }\r
-       \r
-       }\r
-    \r
-       \r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 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.BufferedOutputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.management.ManagementFactory;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
+
+import org.apache.commons.io.output.DeferredFileOutputStream;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.SubMonitor;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.Datatypes;
+import org.simantics.databoard.accessor.error.AccessorException;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.error.BindingException;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.parser.repository.DataTypeSyntaxError;
+import org.simantics.databoard.serialization.RuntimeSerializerConstructionException;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.util.binary.BinaryFile;
+import org.simantics.databoard.util.binary.BinaryMemory;
+import org.simantics.databoard.util.binary.DeferredBinaryFile;
+import org.simantics.databoard.util.binary.NullRandomAccessBinary;
+import org.simantics.databoard.util.binary.RandomAccessBinary;
+import org.simantics.db.DirectStatements;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Statement;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.exception.CancelTransactionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.exception.ValidationException;
+import org.simantics.db.layer0.adapter.SubgraphExtent.ExtentStatus;
+import org.simantics.db.layer0.internal.SimanticsInternal;
+import org.simantics.db.service.ClusterControl;
+import org.simantics.db.service.ClusterControl.ClusterState;
+import org.simantics.db.service.ClusteringSupport;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.db.service.DirectQuerySupport;
+import org.simantics.db.service.SerialisationSupport;
+import org.simantics.graph.representation.Extensions;
+import org.simantics.graph.utils.TGResourceUtil;
+import org.simantics.graph.utils.TGResourceUtil.LongAdapter;
+import org.simantics.layer0.Layer0;
+import org.simantics.utils.threads.logger.ITask;
+import org.simantics.utils.threads.logger.ThreadLogger;
+
+import gnu.trove.list.array.TIntArrayList;
+import gnu.trove.map.hash.TIntIntHashMap;
+import gnu.trove.map.hash.TLongObjectHashMap;
+import gnu.trove.procedure.TIntProcedure;
+import gnu.trove.procedure.TLongObjectProcedure;
+import gnu.trove.set.hash.TIntHashSet;
+
+public class ModelTransferableGraphSourceRequest extends UniqueRead<ModelTransferableGraphSource> {
+
+       public static String LOG_FILE = "transferableGraph.log";
+       final static boolean LOG = false;
+       final static private boolean DEBUG = false;
+       final static boolean PROFILE = false;
+       
+       private TransferableGraphConfiguration2 configuration;
+       private SubMonitor monitor;
+       
+       static DataOutput log;
+
+       static {
+
+               if (LOG) {
+                       try {
+                               FileOutputStream stream = new FileOutputStream(LOG_FILE);
+                               log = new DataOutputStream(stream);
+                       } catch (FileNotFoundException e) {
+                               e.printStackTrace();
+                       }
+               }
+
+       }
+       
+       static void log(String line) {
+               if (LOG) {
+                       try {
+                               log.writeUTF(line + "\n");
+                       } catch (IOException e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+    public ModelTransferableGraphSourceRequest(TransferableGraphConfiguration2 conf) {
+        this(null, conf);
+    }
+
+    public ModelTransferableGraphSourceRequest(IProgressMonitor monitor, TransferableGraphConfiguration2 conf) {
+        this.monitor = SubMonitor.convert(monitor);
+        this.configuration = conf;
+    }
+
+       Layer0 L0;
+       
+       int statements[];
+       int statementIndex = 0;
+       TIntIntHashMap ids;
+       TIntArrayList externalParents = new TIntArrayList();
+       ArrayList<String> externalNames = new ArrayList<String>();
+       
+       int id = 0;
+       int indent = 0;
+
+       private SerialisationSupport support;
+
+       private Resource getResource(int r) throws DatabaseException {
+               return support.getResource(r);
+       }
+       
+       public int getInternalId(int r) {
+               return ids.get(r);
+       }
+       
+       public boolean validateExternal(Resource ext) {
+               ExtentStatus status = configuration.preStatus.get(ext);
+               if(status != null) {
+                       if(ExtentStatus.INTERNAL.equals(status)) return false;
+                       else if(ExtentStatus.EXCLUDED.equals(status)) return false;
+               }
+               return true;
+       }
+       
+       /*
+        * 
+        * @return -2 if r is not really external and the statement should be excluded
+        * 
+        */
+       public int getId(ReadGraph graph, int r) throws DatabaseException {
+               if(ids.containsKey(r)) {
+                   int ret = ids.get(r);
+                   if(ret == -1) {
+                       for(int i=0;i<=indent;++i)
+                           System.out.print("  ");
+                       System.out.println("Cycle!!!"); // with " + GraphUtils.getReadableName(g, r));
+                   }
+                       return ret;
+               }
+               else {
+            if(!validateExternal(getResource(r))) return -2;
+                       Collection<Resource> parents = graph.getObjects(getResource(r), L0.PartOf);                     
+                       if(parents.size() != 1) {
+                               throw new ValidationException("Reference to external resource " 
+                                               + NameUtils.getSafeName(graph, getResource(r), true) + " without unique uri (" + parents.size() + " parents).");
+                       }
+                       for(Resource p : parents) {
+                           ++indent;
+                           int pid = getId(graph, support.getTransientId(p));
+                           if(pid == -2) return -2;
+                               externalParents.add(pid);
+                               --indent;
+                       }
+            externalNames.add((String)graph.getRelatedValue(getResource(r), L0.HasName));
+                       ids.put(r, id);
+                       return id++;
+               }
+       }
+       
+       @Override
+       public ModelTransferableGraphSource perform(ReadGraph graph) throws DatabaseException {
+
+               support = graph.getService(SerialisationSupport.class);
+
+               this.L0 = Layer0.getInstance(graph);
+
+               long total = System.nanoTime();
+       long startupTime = System.nanoTime();
+       long startupTimeEnd = System.nanoTime();
+               long domainTime = System.nanoTime();
+               
+               String otherStatements = "other" + UUID.randomUUID().toString();
+               String valueFileName = "value" + UUID.randomUUID().toString();
+               
+               File base_ = SimanticsInternal.getTemporaryDirectory();
+        File base = new File(base_, "exports");
+        base.mkdirs();
+               
+        File otherStatementsFile = new File(base, otherStatements);
+        File valueFile = new File(base, valueFileName);
+        
+//        System.err.println("f: " + otherStatementsFile.getAbsolutePath());
+        
+        try {
+               DeferredFileOutputStream otherStatementsStream = new DeferredFileOutputStream(1024*1024, otherStatementsFile);
+
+               DataOutputStream otherStatementsOutput = new DataOutputStream(new BufferedOutputStream(otherStatementsStream, 1024*1024));
+               DeferredBinaryFile valueOutput = new DeferredBinaryFile(valueFile, 1024*1024, 128*1024);
+
+               ClusterControl cc = graph.getService(ClusterControl.class);
+               ClusterState clusterState = cc.getClusterState();
+
+               TIntHashSet excludedShared = new TIntHashSet();
+
+               ids = new TIntIntHashMap(1000, 0.75f);
+
+               DomainProcessorState state = new DomainProcessorState();
+               state.extensions.putAll(configuration.baseExtensions);
+               state.ids = ids;
+               state.statementsOutput = otherStatementsOutput;
+               state.valueOutput = valueOutput;
+               state.valueCount = 0;
+               state.excludedShared = excludedShared;
+            state.monitor = monitor;
+            state.valueModifier = composeTGValueModifier(configuration.valueModifiers);
+
+               getDomain2(graph, configuration, state, configuration.ignoreVirtualResources);
+
+               id = ids.size();
+
+               cc.restoreClusterState(clusterState);
+
+               otherStatementsOutput.flush();
+               otherStatementsOutput.close();
+
+               // Do not close valueOutput, just flush it and reuse it in
+               // ModelTransferableGraphSource for reading.
+               valueOutput.flush();
+
+               long domainDuration = System.nanoTime() - domainTime;
+
+               state.id = id;
+            state.otherStatementsInput = toRandomAccessBinary(otherStatementsStream, 128*1024);
+            state.valueInput = toRandomAccessBinary(valueOutput);
+            state.statementsOutput = null;
+            state.valueOutput = null;
+
+               long totalEnd = System.nanoTime();
+
+               if(PROFILE) {   
+                       System.out.println("startup in " + 1e-9*(startupTimeEnd - startupTime) + "s.");
+                       System.out.println("domain was found in " + 1e-9*(domainDuration) + "s.");
+                       System.out.println("total time for building subgraph was " + 1e-9*(totalEnd-total) + "s.");
+               }
+               
+               return getSource(graph, configuration, state, otherStatementsFile, valueFile);
+               
+        } catch (DatabaseException e) {
+               throw e;
+        } catch (IOException e) {
+               throw new DatabaseException(e.getMessage(), e);
+        } catch (Throwable e) {
+               dumpHeap("crash.hprof");
+               throw new DatabaseException(e.getMessage(), e);
+        }
+               
+       }
+       
+       protected ModelTransferableGraphSource getSource(ReadGraph graph, TransferableGraphConfiguration2 configuration, DomainProcessorState state, File otherStatementsFile, File valueFile) throws DatabaseException {
+       return new ModelTransferableGraphSource(graph, configuration, state, otherStatementsFile, valueFile);
+       }
+
+       private TGValueModifier composeTGValueModifier(Collection<TGValueModifier> configuredModifiers) {
+               List<TGValueModifier> valueModifiers = configuredModifiers == null ? new ArrayList<>(2) : new ArrayList<>(configuredModifiers.size() + 2);
+               valueModifiers.add(new ResourceTGValueModifier(support));
+               valueModifiers.add(RevisionTGValueModifier.INSTANCE);
+               return new ComposedTGValueModifier(valueModifiers.toArray(new TGValueModifier[valueModifiers.size()]));
+       }
+
+    private static RandomAccessBinary toRandomAccessBinary(DeferredFileOutputStream stream, int bufferSize) throws IOException {
+        if (stream.isInMemory())
+            return new BinaryMemory(stream.getData());
+        return new BinaryFile(stream.getFile(), bufferSize);
+    }
+
+    private static RandomAccessBinary toRandomAccessBinary(DeferredBinaryFile file) throws IOException {
+        RandomAccessBinary b = file.getBackend();
+        long size = b.position();
+        b.position(0);
+        if (b instanceof BinaryMemory) {
+            b.setLength(size);
+        }
+        return b;
+    }
+
+       public static DomainOnlyProcessor getDomainOnly(RequestProcessor processor, IProgressMonitor monitor, final Resource resource) throws DatabaseException {
+               return getDomainOnly(processor, monitor, Collections.singletonList(resource));
+       }
+
+       public static DomainOnlyProcessor getDomainOnly(RequestProcessor processor, final IProgressMonitor monitor, final Collection<Resource> resources) throws DatabaseException {
+
+               return processor.syncRequest(new UniqueRead<DomainOnlyProcessor>() {
+
+                       @Override
+                       public DomainOnlyProcessor perform(ReadGraph graph) throws DatabaseException {
+
+                               try {
+
+                                       TransferableGraphConfiguration2 conf = TransferableGraphConfiguration2.createWithResources(graph, resources, Collections.<Resource>emptyList()); 
+
+                                       DomainProcessorState state = new DomainProcessorState();
+                                       state.extensions.putAll(conf.baseExtensions);
+                                       state.ids = new TIntIntHashMap(1000, 0.75f);
+                                       state.statementsOutput = new DataOutputStream(new NullOutputStream());
+                                       state.valueOutput = new NullRandomAccessBinary();
+                                       state.valueCount = 0;
+                                       state.excludedShared = new TIntHashSet();
+                                       state.monitor = SubMonitor.convert(monitor);
+
+                                       return getDomainOnly(graph, conf, state, conf.ignoreVirtualResources);
+
+                               } catch (OperationCanceledException e) {
+                                       
+                                       return null;
+
+                               }
+
+                       }
+
+               });
+
+       }
+    
+    public static class DomainOnlyProcessor extends DomainProcessor3 {
+
+       final Resource instanceOf;
+       final public List<Resource> internals;
+       final public List<Resource> internalTypes;
+       
+       private int counter = 0;
+       
+               public DomainOnlyProcessor(ReadGraph graph, TransferableGraphConfiguration2 conf, DomainProcessorState state, boolean ignoreVirtual) throws DatabaseException {
+                       super(graph, conf, state, ignoreVirtual);
+                       CollectionSupport cs = graph.getService(CollectionSupport.class);
+                       internals = cs.createList();
+                       internalTypes = cs.createList();
+                       instanceOf = Layer0.getInstance(graph).InstanceOf;
+               }
+               
+               @Override
+               final public void addToStream(Resource predicate, Resource object) throws DatabaseException {
+               }
+               
+               @Override
+               public void flushStatementStream(int sId, DomainProcessorState state) throws IOException {
+               }
+               
+               @Override
+               public void processValue(ReadGraph graph, Resource subject, int sId, DomainProcessorState state) throws DatabaseException, IOException {
+               }
+               
+               @Override
+               public void processInternal(ReadGraph graph, Resource subject, DirectStatements stms, DomainProcessorState state) throws DatabaseException, IOException {
+                       
+                       if((counter++ & 1023) == 0)
+                               if(state.monitor != null)
+                                       if(state.monitor.isCanceled())
+                                               throw new CancelTransactionException();
+                       
+                       super.processInternal(graph, subject, stms, state);
+                       
+                       internals.add(subject);
+                       
+                       Resource singleType = null;
+                       for(Statement s : stms) {
+                               if(instanceOf.equals(s.getPredicate())) {
+                                       if(singleType != null) {
+                                               internalTypes.add(null);
+                                               return;
+                                       } else {
+                                               singleType = s.getObject();
+                                       }
+                               }
+                       }
+                       
+                       internalTypes.add(singleType);
+                       
+               }
+               
+       
+    }
+       
+       public static DomainOnlyProcessor getDomainOnly(final ReadGraph graph , final TransferableGraphConfiguration2 conf, DomainProcessorState state, boolean ignoreVirtual) throws DatabaseException {
+
+               final DomainOnlyProcessor processor = new DomainOnlyProcessor(graph, conf, state, ignoreVirtual);
+               getDomain2(graph, state, processor);
+               return processor;
+               
+       }
+
+    public static DomainProcessor3 getDomain2(final ReadGraph graph , final TransferableGraphConfiguration2 conf, DomainProcessorState state, boolean ignoreVirtual) throws DatabaseException {
+
+               ITask task = ThreadLogger.getInstance().begin("getDomain2");
+
+               final DomainProcessor3 processor = new DomainProcessor3(graph, conf, state, ignoreVirtual);
+               
+               getDomain2(graph, state, processor);
+               
+               final SerialisationSupport support = graph.getService(SerialisationSupport.class);
+               final ClusteringSupport cls = graph.getService(ClusteringSupport.class);
+               final Resource indexRoot = processor.conf.indexRoot;
+
+               if (state.monitor.isCanceled())
+                       throw new CancelTransactionException();
+
+               TLongObjectHashMap<TIntArrayList> clusterMap = new TLongObjectHashMap<TIntArrayList>();
+               for(Resource r : processor.status.keySet()) {
+                       ExtentStatus status = processor.status.get(r);
+                       int transientId = support.getTransientId(r);
+                       if(ExtentStatus.INTERNAL == status) {
+                               long cluster = cls.getCluster(r);
+                               TIntArrayList list = clusterMap.get(cluster);
+                               if(list == null) {
+                                       list = new TIntArrayList();
+                                       clusterMap.put(cluster, list);
+                               }
+                               list.add(transientId);
+                       } else if(ExtentStatus.EXTERNAL == status) {
+                               state.externals.add(transientId);
+                       } else if(ExtentStatus.PENDING == status) {
+                               String uri = graph.getPossibleURI(r);
+                               if(uri != null)
+                                       state.externals.add(transientId);
+                               else {
+                                       state.pending.add(transientId);
+                                       System.err.println("Pending status in export: " + NameUtils.getSafeName(graph, r, true) + " (" + graph.getPossibleURI(r) + ")");
+                               }
+                       }
+               }
+
+               if (state.monitor.isCanceled())
+                       throw new CancelTransactionException();
+
+               final TIntArrayList clustering = new TIntArrayList();
+               clusterMap.forEachEntry(new TLongObjectProcedure<TIntArrayList>() {
+                       
+                       @Override
+                       public boolean execute(long cluster, TIntArrayList b) {
+                               clustering.add(b.size());
+                               b.forEach(new TIntProcedure() {
+                                       
+                                       @Override
+                                       public boolean execute(int rId) {
+                                               processor.ids.put(rId, processor.id++);
+                                               return true;
+                                       }
+                                       
+                               });
+                               return true;
+                       }
+                       
+               });
+
+               if (state.monitor.isCanceled())
+                       throw new CancelTransactionException();
+
+               final TIntArrayList clusterSets = new TIntArrayList();
+               clusterMap.forEachEntry(new TLongObjectProcedure<TIntArrayList>() {
+                       
+                       @Override
+                       public boolean execute(long cluster, TIntArrayList b) {
+                               try {
+                                       Resource clusterSet = cls.getClusterSetOfCluster(cluster);
+                                       if(clusterSet != null) {
+                                               int transientId = support.getTransientId(clusterSet);
+                                               if(processor.ids.containsKey(transientId)) {
+                                                       clusterSets.add(processor.ids.get(transientId));
+                                                       return true;
+                                               } else {
+                                                       if(graph.getRootLibrary().equals(clusterSet)) {
+                                                               clusterSets.add(Extensions.ROOT_LIBRARY_CLUSTER_SET);
+                                                               return true;
+                                                       } else if (clusterSet.equals(indexRoot)) {
+                                                               clusterSets.add(Extensions.INDEX_ROOT_CLUSTER_SET);
+                                                               return true;
+                                                       }
+                                               }
+                                       }
+                               } catch (DatabaseException e) {
+                               }
+                               clusterSets.add(Extensions.NO_CLUSTER_SET);
+                               return true;
+                               
+                       }
+                       
+               });
+               
+               state.extensions.put(Extensions.CLUSTERING, new Variant(Bindings.INT_ARRAY, clustering.toArray()));
+               state.extensions.put(Extensions.CLUSTER_SETS, new Variant(Bindings.INT_ARRAY, clusterSets.toArray()));
+               
+               long total = processor.startupTime + processor.expandTime
+                               + processor.classifyPredicateTime
+                               + processor.processFringeTime + processor.extentSeedTime
+                               + processor.fullResolveTime + processor.fastResolveTime + 
+                               + processor.parentResolveTime + processor.otherStatementTime;
+
+               if (PROFILE) {
+                       System.out.println("startup took " + 1e-9 * processor.startupTime + "s.");
+                       System.out.println("expand took " + 1e-9 * processor.expandTime + "s.");
+                       System.out.println("classifyPredicates took " + 1e-9 * processor.classifyPredicateTime + "s.");
+                       System.out.println("processFringe took " + 1e-9 * processor.processFringeTime + "s.");
+                       System.out.println("extentSeeding took " + 1e-9 * processor.extentSeedTime + "s.");
+                       System.out.println("fullResolve took " + 1e-9 * processor.fullResolveTime + "s.");
+                       System.out.println("fastResolve took " + 1e-9 * processor.fastResolveTime + "s.");
+                       System.out.println("parentResolve took " + 1e-9 * processor.parentResolveTime + "s.");
+                       System.out.println("otherStatements took " + 1e-9 * processor.otherStatementTime + "s.");
+                       System.out.println("value output took " + 1e-9 * processor.valueOutputTime + "s.");
+                       System.out.println("statement output took " + 1e-9 * processor.statementOutputTime + "s.");
+                       System.out.println("total " + 1e-9 * total + "s.");
+               }
+
+               task.finish();
+
+               return processor;
+
+       }
+
+       public static DomainProcessor3 getDomain2(final ReadGraph graph , DomainProcessorState state, final DomainProcessor3 processor) throws DatabaseException {
+               processor.process(graph, state);
+               return processor;
+       }
+       
+       static class Expansion3 extends UniqueRead<Collection<DirectStatements>> {
+
+               final private Collection<Resource> roots;
+               final boolean ignoreVirtual;
+
+               public Expansion3(Collection<Resource> roots, boolean ignoreVirtual) {
+                       this.roots = roots;
+                       this.ignoreVirtual = ignoreVirtual;
+               }
+
+               @Override
+               public Collection<DirectStatements> perform(ReadGraph graph) {
+                       
+                       ArrayList<DirectStatements> result = new ArrayList<DirectStatements>();
+
+                       final DirectQuerySupport dqs = graph.getService(DirectQuerySupport.class);
+
+                       final DomainStatementProcedure3 proc = new DomainStatementProcedure3(result);
+
+                       if (ignoreVirtual) {
+                               for(Resource r : roots) {
+                                       dqs.forEachDirectPersistentStatement(graph, r, proc);
+                               }
+                       } else {
+                               for(Resource r : roots) {
+                                       dqs.forEachDirectStatement(graph, r, proc);
+                               }
+                       }
+                       
+                       return result;
+
+               }
+
+       }       
+       private static void dumpHeap(String path) {
+               
+        try {
+            Object bean = getBean();
+            if (bean == null)
+                return;
+
+            Method m = bean.getClass().getMethod("dumpHeap", String.class, boolean.class);
+            m.invoke(bean, path, true);
+            
+        } catch (IllegalArgumentException e) {
+        } catch (IllegalAccessException e) {
+        } catch (SecurityException e) {
+        } catch (NoSuchMethodException e) {
+        } catch (InvocationTargetException e) {
+               } finally {
+        }
+               
+       }
+       
+    private static Object getBean() {
+        Class<?> beanClass = getBeanClass();
+        if (beanClass == null)
+            return null;
+        try {
+            Object bean = ManagementFactory.newPlatformMXBeanProxy(
+                    ManagementFactory.getPlatformMBeanServer(),
+                    "com.sun.management:type=HotSpotDiagnostic",
+                    beanClass);
+            return bean;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+    
+    private static Class<?> getBeanClass() {
+        try {
+            Class<?> clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean");
+            return clazz;
+        } catch (ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    public static void main(String[] args) {
+               
+       try {
+               
+                       Datatype dt = Datatypes.translate("{ parts : ( | ResourceRVIPart { role : |CHILD|PROPERTY, resource : Long(unit=\"resource\") } | StringRVIPart { role : |CHILD|PROPERTY, string : String } ) [] }");
+                       Binding b = Bindings.getBinding(dt);
+                       Object value = b.createDefault();
+                       Variant variant = new Variant(b, value);
+                       TGResourceUtil util = new TGResourceUtil();
+                       LongAdapter la = new LongAdapter() {
+                               @Override
+                               public long adapt(long in) {
+                                       return in;
+                               }                       
+                       };
+                       util.adaptValue( variant.getBinding(), variant.getValue(), la );
+                       
+               } catch (DataTypeSyntaxError e) {
+                       e.printStackTrace();
+               } catch (BindingException e) {
+                       e.printStackTrace();
+               } catch (RuntimeSerializerConstructionException e) {
+                       e.printStackTrace();
+               } catch (AccessorException e) {
+                       e.printStackTrace();
+               }
+       
+       }
+    
+       
+}