]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling/src/org/simantics/modeling/ModelingUtils.java
Improved shared library structure dump to take more types into account
[simantics/platform.git] / bundles / org.simantics.modeling / src / org / simantics / modeling / ModelingUtils.java
index e1494cf3201f3fd79fefe0efc9956d0c6e4ea5a8..1edf3cd3121a4e4682e5de0012916fcfd0b74ee5 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.modeling;\r
-\r
-import java.io.File;\r
-import java.io.IOException;\r
-import java.text.DateFormat;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Date;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-import java.util.TreeMap;\r
-\r
-import org.eclipse.core.runtime.CoreException;\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.NullProgressMonitor;\r
-import org.eclipse.core.runtime.Path;\r
-import org.eclipse.jface.dialogs.Dialog;\r
-import org.eclipse.jface.dialogs.IDialogConstants;\r
-import org.eclipse.jface.dialogs.MessageDialog;\r
-import org.eclipse.jface.layout.GridDataFactory;\r
-import org.eclipse.jface.layout.GridLayoutFactory;\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.eclipse.jface.window.Window;\r
-import org.eclipse.jface.wizard.WizardDialog;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Display;\r
-import org.eclipse.swt.widgets.FileDialog;\r
-import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.ui.IWorkbenchWizard;\r
-import org.eclipse.ui.PlatformUI;\r
-import org.eclipse.ui.wizards.IWizardDescriptor;\r
-import org.simantics.Simantics;\r
-import org.simantics.annotation.ontology.AnnotationResource;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.binding.Binding;\r
-import org.simantics.databoard.binding.mutable.Variant;\r
-import org.simantics.databoard.container.DataContainer;\r
-import org.simantics.databoard.container.DataContainers;\r
-import org.simantics.databoard.container.DataFormatException;\r
-import org.simantics.databoard.container.FormatHandler;\r
-import org.simantics.databoard.serialization.SerializationException;\r
-import org.simantics.databoard.type.Datatype;\r
-import org.simantics.databoard.util.URIStringUtils;\r
-import org.simantics.datatypes.literal.GUID;\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.WriteGraph;\r
-import org.simantics.db.common.NamedResource;\r
-import org.simantics.db.common.QueryMemoryWatcher;\r
-import org.simantics.db.common.primitiverequest.IsInstanceOf;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;\r
-import org.simantics.db.common.procedure.adapter.TransientCacheListener;\r
-import org.simantics.db.common.request.IndexRoot;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.request.PossibleIndexRoot;\r
-import org.simantics.db.common.request.ReadRequest;\r
-import org.simantics.db.common.request.ResourceRead2;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.request.WriteResultRequest;\r
-import org.simantics.db.common.utils.ListUtils;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.common.utils.NameUtils;\r
-import org.simantics.db.common.utils.OrderedSetUtils;\r
-import org.simantics.db.common.utils.VersionInfo;\r
-import org.simantics.db.common.utils.VersionInfoRequest;\r
-import org.simantics.db.common.utils.Versions;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.layer0.SelectionHints;\r
-import org.simantics.db.layer0.adapter.CopyHandler;\r
-import org.simantics.db.layer0.adapter.GenericRelationIndex;\r
-import org.simantics.db.layer0.adapter.Instances;\r
-import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;\r
-import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory;\r
-import org.simantics.db.layer0.genericrelation.IndexedRelations;\r
-import org.simantics.db.layer0.migration.MigrationUtils;\r
-import org.simantics.db.layer0.request.ActivateModel;\r
-import org.simantics.db.layer0.request.ActiveModels;\r
-import org.simantics.db.layer0.request.Configuration;\r
-import org.simantics.db.layer0.request.IsLinkedTo;\r
-import org.simantics.db.layer0.request.PossibleModel;\r
-import org.simantics.db.layer0.util.ClipboardUtils;\r
-import org.simantics.db.layer0.util.DraftStatusBean;\r
-import org.simantics.db.layer0.util.Layer0Utils;\r
-import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;\r
-import org.simantics.db.layer0.util.PasteEventHandler;\r
-import org.simantics.db.layer0.util.RemoverUtil;\r
-import org.simantics.db.layer0.util.SimanticsClipboard;\r
-import org.simantics.db.layer0.util.SimanticsClipboard.Representation;\r
-import org.simantics.db.layer0.util.SimanticsClipboardImpl;\r
-import org.simantics.db.layer0.util.SimanticsKeys;\r
-import org.simantics.db.layer0.util.TransferableGraphConfiguration2;\r
-import org.simantics.db.layer0.variable.Variable;\r
-import org.simantics.db.layer0.variable.Variables;\r
-import org.simantics.db.request.Read;\r
-import org.simantics.db.service.ClusterControl;\r
-import org.simantics.db.service.CollectionSupport;\r
-import org.simantics.db.service.QueryControl;\r
-import org.simantics.db.service.VirtualGraphSupport;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.diagram.stubs.G2DResource;\r
-import org.simantics.diagram.synchronization.graph.AddElement;\r
-import org.simantics.graph.db.IImportAdvisor2;\r
-import org.simantics.graph.db.ImportAdvisors;\r
-import org.simantics.graph.db.MissingDependencyException;\r
-import org.simantics.graph.db.StreamingTransferableGraphFileReader;\r
-import org.simantics.graph.db.TransferableGraphException;\r
-import org.simantics.graph.db.TransferableGraphSource;\r
-import org.simantics.graph.db.TransferableGraphs;\r
-import org.simantics.graph.representation.Identity;\r
-import org.simantics.graph.representation.Root;\r
-import org.simantics.graph.representation.TransferableGraph1;\r
-import org.simantics.graph.representation.TransferableGraphUtils;\r
-import org.simantics.issues.common.IssueSourceUtils;\r
-import org.simantics.issues.ontology.IssueResource;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.layer0.utils.direct.GraphUtils;\r
-import org.simantics.modeling.adapters.ChangeInformation;\r
-import org.simantics.modeling.template2d.ontology.Template2dResource;\r
-import org.simantics.operation.Layer0X;\r
-import org.simantics.project.ontology.ProjectResource;\r
-import org.simantics.scenegraph.profile.ProfileUtils;\r
-import org.simantics.scl.runtime.function.Function1;\r
-import org.simantics.scl.runtime.tuple.Tuple;\r
-import org.simantics.simulation.ontology.SimulationResource;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.structural2.scl.StructuralComponent;\r
-import org.simantics.structural2.utils.StructuralUtils;\r
-import org.simantics.ui.SimanticsUI;\r
-import org.simantics.utils.ObjectUtils;\r
-import org.simantics.utils.datastructures.Pair;\r
-import org.simantics.utils.datastructures.Triple;\r
-import org.simantics.utils.datastructures.hints.HintContext;\r
-import org.simantics.utils.ui.dialogs.ListDialog;\r
-\r
-/**\r
- * @author Hannu Niemistö\r
- */\r
-public class ModelingUtils {\r
-\r
-       private ReadGraph g;\r
-       private WriteGraph wg;\r
-       public Layer0 b;\r
-       private StructuralResource2 sr;\r
-       private DiagramResource dr;\r
-       public ModelingResources mr;\r
-       public SimulationResource SIMU;\r
-\r
-       public ModelingUtils(WriteGraph g) {\r
-               wg = g;\r
-               this.g = g;\r
-               b = Layer0.getInstance(g);\r
-               sr = StructuralResource2.getInstance(g);\r
-               dr = DiagramResource.getInstance(g);\r
-               mr = ModelingResources.getInstance(g);\r
-               SIMU = SimulationResource.getInstance(g);\r
-       }\r
-\r
-       @Deprecated\r
-       public Resource createSymbol2(String name) throws DatabaseException {\r
-               return createSymbol2(name, dr.Composite);\r
-       }\r
-\r
-       @Deprecated\r
-       public Resource createSymbol2(String name, Resource type) throws DatabaseException {\r
-               G2DResource g2d = G2DResource.getInstance(g);\r
-\r
-//             Resource visibleTag = wg.newResource();\r
-//             wg.claim(visibleTag, b.SubrelationOf, null, dr.IsVisible);\r
-//             Resource focusableTag = wg.newResource();\r
-//             wg.claim(focusableTag, b.SubrelationOf, null, dr.IsFocusable);\r
-\r
-               Double boxDimension = 6.0;\r
-               Collection<Statement> grid = g.getAssertedStatements(type, dr.HasGridSize);\r
-               if(grid.size() == 1) {\r
-                       Double d = g.getPossibleValue(grid.iterator().next().getObject(), Bindings.DOUBLE);\r
-                       if(d != null) boxDimension = 2*d;\r
-               }\r
-\r
-\r
-               Resource element  = GraphUtils.create(wg,\r
-                               b.InstanceOf, dr.SVGElement,\r
-                               g2d.HasSVGDocument,\r
-                               "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +\r
-                                               // REMOVED by Tuukka, because This will cause\r
-                                               // parsers to get on the net and get the doctype\r
-                                               // definitions which can stall the UI for a long time.\r
-                                               // Besides, we're not using the validation for anything\r
-                                               // so it's useless to us.\r
-                                               //"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" +\r
-                                               "<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">" +\r
-                                               "<rect x=\"-" + boxDimension + "\" y=\"-" + boxDimension + "\" width=\"" + (2*boxDimension) + "\" height=\"" + (2*boxDimension) + "\" fill=\"none\" stroke=\"rgb(0,0,0)\" stroke-width=\"0.1\"/>" +\r
-                                               "</svg>"\r
-                               );\r
-\r
-//             wg.claim(element, visibleTag, element);\r
-//             wg.claim(element, focusableTag, element);\r
-\r
-               Resource orderedSet = OrderedSetUtils.create(wg, type, element);\r
-\r
-//             wg.claim(orderedSet, dr.HasLayer, GraphUtils.create2(wg, dr.Layer,\r
-//                             b.HasName, "Default",\r
-//                             dr.IsActive, Boolean.TRUE,\r
-//                             dr.HasVisibleTag, visibleTag,\r
-//                             dr.HasFocusableTag, focusableTag));\r
-\r
-               Resource result = GraphUtils.create(wg,\r
-                               b.HasName, name,\r
-                               b.HasLabel, "",\r
-                               sr.IsDefinedBy, orderedSet);\r
-\r
-               wg.claim(result, b.ConsistsOf, orderedSet);\r
-               wg.claimLiteral(orderedSet, b.HasName, "__DIAGRAM__", Bindings.STRING);\r
-               AddElement.claimFreshElementName(wg, orderedSet, element);\r
-               wg.claim(orderedSet, b.ConsistsOf, element);\r
-\r
-               wg.claim(result, b.Inherits, null, dr.DefinedElement);\r
-               return result;\r
-       }\r
-\r
-       public static Collection<Resource> getElementCorrespondendences(ReadGraph g, Resource element) throws DatabaseException {\r
-               DiagramResource dr = DiagramResource.getInstance(g);\r
-               ModelingResources mr = ModelingResources.getInstance(g);\r
-               if(g.isInstanceOf(element, dr.Connection)) {\r
-                       Resource mappedComponent = g.getPossibleObject(element, mr.ElementToComponent);\r
-                       if(mappedComponent != null) return Collections.singletonList(mappedComponent);\r
-                       Resource mappedConnection = g.getPossibleObject(element, mr.DiagramConnectionToConnection);\r
-                       if(mappedConnection == null)\r
-                               return Collections.emptyList();\r
-                       ArrayList<Resource> result = new ArrayList<Resource>();\r
-                       Collection<Resource> relatedMappedConnections = StructuralUtils.getRelatedConnections(g, mappedConnection);\r
-                       for(Resource relatedMappedConnection : relatedMappedConnections)\r
-                               for(Resource relatedConnection : g.getObjects(relatedMappedConnection, mr.ConnectionToDiagramConnection))\r
-                                       result.addAll(g.getObjects(relatedConnection, mr.ElementToComponent));\r
-                       return result;\r
-               }\r
-               else\r
-                       return g.getObjects(element, mr.ElementToComponent);\r
-       }\r
-\r
-       public static Resource getPossibleElement(ReadGraph g, Resource component) throws DatabaseException {\r
-               ModelingResources mr = ModelingResources.getInstance(g);\r
-               return g.getPossibleObject(component, mr.ComponentToElement);\r
-       }\r
-\r
-       public static Resource getPossibleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {\r
-               Collection<Resource> corrs = getElementCorrespondendences(g, element);\r
-               if(corrs.size() != 1) return null;\r
-               else return corrs.iterator().next();\r
-       }\r
-\r
-       public static Resource getSingleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {\r
-               Collection<Resource> corrs = getElementCorrespondendences(g, element);\r
-               if(corrs.size() != 1) throw new DatabaseException("Expected 1 element correspondence, got " + corrs.size());\r
-               else return corrs.iterator().next();\r
-       }\r
-\r
-       public static Resource createExperiment(WriteGraph graph, Resource model) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-               Resource experiment = graph.newResource();\r
-               graph.claim(experiment, L0.InstanceOf, SIMU.Experiment);\r
-               graph.claimLiteral(experiment, L0.HasName, "Experiment");\r
-               graph.claim(model, L0.ConsistsOf, experiment);\r
-               return experiment;\r
-\r
-       }\r
-\r
-       public static Resource createModel(WriteGraph graph, Resource type) throws DatabaseException {\r
-               return createModel(graph, type, Simantics.getProjectResource(), null);\r
-       }\r
-               \r
-       public static Resource createModel(WriteGraph graph, Resource type, String name) throws DatabaseException {\r
-               return createModel(graph, type, Simantics.getProjectResource(), name);\r
-       }\r
-\r
-       public static Resource createModel(WriteGraph graph, Resource type, final Resource target, String name) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-               StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-               ModelingResources MOD = ModelingResources.getInstance(graph);\r
-\r
-               if(name == null)\r
-                       name = NameUtils.findFreshName(graph, "Model", target, L0.ConsistsOf, "%s%d");\r
-\r
-               final Resource model = graph.newResource();\r
-               graph.newClusterSet(model);\r
-               graph.claim(model, L0.InstanceOf, null, type);\r
-               graph.claimLiteral(model, L0.HasName, name);\r
-\r
-               graph.claim(target, L0.ConsistsOf, model);\r
-\r
-               Resource configurationType = graph.getPossibleObject(model, MOD.StructuralModel_HasConfigurationType);\r
-               if(configurationType == null) configurationType = STR.Composite;\r
-\r
-               Resource configuration = graph.newResource();\r
-               graph.claimLiteral(configuration, L0.HasName, "Configuration", Bindings.STRING);\r
-               graph.claim(configuration, L0.InstanceOf, null, configurationType);\r
-               graph.claim(model, L0.ConsistsOf, configuration);\r
-               graph.claim(model, SIMU.HasConfiguration, configuration);\r
-\r
-               Resource joinClusterSet = graph.newResource();\r
-               graph.newClusterSet(joinClusterSet);\r
-               graph.claim(joinClusterSet, L0.InstanceOf, L0.ClusterSet);\r
-               graph.claim(model, STR.HasJoinClusterSet, joinClusterSet);\r
-\r
-               linkOntologyDependenciesToModel(graph, model, target);\r
-               \r
-               Resource ontology = graph.syncRequest(new PossibleIndexRoot(type));\r
-               if(ontology != null) {\r
-                       graph.claim(model, L0.IsLinkedTo, ontology);\r
-               }\r
-\r
-               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
-               graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("activations")) {\r
-\r
-                       @Override\r
-                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                               Layer0X L0X = Layer0X.getInstance(graph);\r
-                               Collection<Resource> actives = graph.syncRequest(new ActiveModels(target));\r
-                               if(actives.isEmpty()) {\r
-                                       graph.claim(model,  L0X.IsActivatedBy, target);\r
-                               }\r
-                       }\r
-\r
-               });\r
-\r
-               return model;\r
-\r
-       }\r
-       \r
-       public static void linkOntologyDependenciesToModel(WriteGraph graph, Resource model, Resource target) \r
-                       throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               ProjectResource PROJ = ProjectResource.getInstance(graph);\r
-               for(Resource dep : graph.getObjects(target, L0.IsLinkedTo)) {\r
-                       if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {\r
-                               for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {\r
-                                       String uri = graph.getPossibleValue(req, Bindings.STRING);\r
-                                       if(uri != null) {\r
-                                               Resource ns = graph.getResource(uri);\r
-                                               if(ns != null) {\r
-                                                       graph.claim(model, L0.IsLinkedTo, null, ns);\r
-                                               }\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-       \r
-       public static void addSCLMainToModel(WriteGraph graph, Resource model) \r
-                       throws DatabaseException {\r
-               addSCLMainToModel(graph, model, "SCLMain", "include \"Simantics/All\"\n");\r
-       }\r
-       \r
-       public static void addSCLMainToModel(WriteGraph graph, Resource model, String name, String contents) \r
-                       throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-        Resource sclmain = GraphUtils.create2(graph, L0.SCLModule, L0.PartOf, model, L0.HasName, name);\r
-        graph.claimLiteral(sclmain, L0.SCLModule_definition, contents, Bindings.STRING);\r
-       }\r
-\r
-    public static Resource createLocalLibrary(WriteGraph graph, Resource container, String name) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        ModelingResources MOD = ModelingResources.getInstance(graph);\r
-        Resource library = graph.newResource();\r
-        graph.claim(library, L0.InstanceOf, null, L0.Library);\r
-        graph.addLiteral(library, L0.HasName, L0.NameOf, "Library", Bindings.STRING);\r
-        if (container != null) {\r
-            graph.claim(container, L0.ConsistsOf, L0.PartOf, library);\r
-            graph.claim(container, MOD.HasLocalLibrary, MOD.IsLocalLibraryOf, library);\r
-        }\r
-        return library;\r
-    }\r
-\r
-       public static void importModel(String fileName) {\r
-\r
-               Resource project = SimanticsUI.getProject().get();\r
-\r
-               try {\r
-\r
-                       StreamingTransferableGraphFileReader importer = new StreamingTransferableGraphFileReader(new File(fileName));\r
-                       TransferableGraphSource tg = importer.readTG();\r
-\r
-                       final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(project) {\r
-                               @Override\r
-                               public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {\r
-                               }\r
-                               @Override\r
-                               public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {\r
-                                       library = Simantics.getProjectResource();\r
-                                       String newName = newName(graph, library, root.name);\r
-                                       nameMappings.put(root.name, newName);\r
-                                       return null;\r
-                               }\r
-                       };\r
-                       TransferableGraphs.importGraph1(Simantics.getSession(), tg, advisor);\r
-\r
-               } catch (MissingDependencyException e) {\r
-\r
-                       final Set<String> missingURIs = e.getMissingURIs();\r
-\r
-                       class ErrorMessageDialog extends MessageDialog {\r
-\r
-                               public ErrorMessageDialog(Shell shell) {\r
-                                       super(shell, \r
-                                                       "Unsatisfied dependencies", null, \r
-                                                       "The following dependencies were missing. Please import the dependencies and try again.", \r
-                                                       MessageDialog.ERROR, new String[] { "Continue" }, 0);\r
-                               }\r
-\r
-                               @Override\r
-                               protected Control createCustomArea(Composite composite) {\r
-                                       GridLayoutFactory.fillDefaults().applyTo(composite);\r
-                                       \r
-                                       org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);\r
-                                       GridDataFactory.fillDefaults().grab(true, true).applyTo(list);\r
-                                       for(String s : missingURIs) list.add(s);\r
-                                       return composite;\r
-                               }\r
-\r
-                       }\r
-\r
-                       Display display = Display.getCurrent();\r
-                       if(display != null) {\r
-                               ErrorMessageDialog md = new ErrorMessageDialog(display.getActiveShell());\r
-                               md.open();\r
-                       } else {\r
-                               Display.getDefault().asyncExec(new Runnable() {\r
-\r
-                                       @Override\r
-                                       public void run() {\r
-                                               Shell shell = Display.getCurrent().getActiveShell();\r
-                                               ErrorMessageDialog md = new ErrorMessageDialog(shell);\r
-                                               md.open();\r
-                                       }\r
-                                       \r
-                               });\r
-                       }\r
-                       \r
-\r
-               } catch (Exception e) {\r
-                       Logger.defaultLogError(e);\r
-               }\r
-\r
-       }\r
-\r
-       public static void primeVirtualGraphs() {\r
-               VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
-               support.getWorkspacePersistent("activations");\r
-               support.getWorkspacePersistent("experiments");\r
-               support.getWorkspacePersistent("issues");\r
-               support.getWorkspacePersistent("preferences");\r
-       }\r
-\r
-       public static Resource createProfileEntry(WriteGraph graph, String name, Resource style, Resource group) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
-               Resource entry = graph.newResource();\r
-               graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry);\r
-               graph.claimLiteral(entry, L0.HasName, name);\r
-               graph.claimLiteral(entry, L0.HasLabel, name);\r
-               graph.claim(entry, DIA.ProfileEntry_HasStyle, style);\r
-               graph.claim(entry, DIA.ProfileEntry_HasGroup, group);\r
-\r
-               return entry;\r
-\r
-       }\r
-\r
-       public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
-               Resource list = ListUtils.create(graph, DIA.Profile, entries);\r
-\r
-               Resource profile = graph.newResource();\r
-               graph.claim(profile, L0.InstanceOf, null, DIA.Profile);\r
-               graph.claimLiteral(profile, L0.HasName, profileName);\r
-               graph.claim(profile, DIA.HasEntries, null, list);\r
-\r
-               return profile;\r
-\r
-       }\r
-       \r
-       public static Resource createProfile(WriteGraph graph, String profileName, Collection<Resource> entries) throws DatabaseException {\r
-           return createProfile(graph, profileName, entries.toArray(new Resource[entries.size()]));\r
-       }\r
-\r
-       public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Resource ... profiles) throws DatabaseException {\r
-\r
-               Resource work = createProfile(graph, name, profiles);\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               DiagramResource DIA = DiagramResource.getInstance(graph);\r
-\r
-               graph.deny(model, DIA.HasActiveProfile);\r
-               graph.claim(model, DIA.HasActiveProfile, work);\r
-               graph.claim(model, L0.ConsistsOf, L0.PartOf, work);\r
-\r
-               return work;\r
-\r
-       }\r
-       \r
-       public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Collection<Resource> profiles) throws DatabaseException {\r
-           return createToplevelProfile(graph, model, name, profiles.toArray(new Resource[profiles.size()]));\r
-       }\r
-\r
-       public static void activateProfileEntries(WriteGraph graph, final Resource profile, final Resource ... entries) {\r
-\r
-               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);\r
-               graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
-\r
-                       @Override\r
-                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                               SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-                               for(Resource entry : entries)\r
-                                       graph.claim(profile, SIMU.IsActive, entry);\r
-                       }\r
-\r
-               });\r
-\r
-       }\r
-       \r
-       public static void activateProfileEntries(WriteGraph graph, Resource profile, Collection<Resource> entries) {\r
-           activateProfileEntries(graph, profile, entries.toArray(new Resource[entries.size()]));\r
-       }\r
-       \r
-       public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, String groupName, boolean enabled) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               for (Resource group : ProfileUtils.getProfileChildren(graph, runtimeProfile)) {\r
-                       String name = graph.getRelatedValue2(group, L0.HasName);\r
-                       if (name.equals(groupName)) {\r
-                               toggleProfileGroup(graph, runtimeProfile, group, enabled);\r
-                               return;\r
-                       }\r
-               }\r
-       }\r
-       \r
-       public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, Resource group, boolean enabled) throws DatabaseException {\r
-       DiagramResource DIA = DiagramResource.getInstance(graph);\r
-               \r
-       if(graph.isInstanceOf(group, DIA.Profile)) {\r
-               \r
-               for(Resource child : ProfileUtils.getProfileChildren(graph, group)) {\r
-                       toggleProfileGroup(graph, runtimeProfile, child, enabled);\r
-               }\r
-               \r
-       } else if(graph.isInstanceOf(group, DIA.ProfileEntry)) {\r
-\r
-            if(enabled) {\r
-                graph.claim(runtimeProfile, SimulationResource.getInstance(graph).IsActive, null, group);\r
-            } else {\r
-                graph.denyStatement(runtimeProfile, SimulationResource.getInstance(graph).IsActive, group);\r
-            }\r
-\r
-               }\r
-       }\r
-\r
-    public static void untrackDependencies() {\r
-       untrackDependencies(Simantics.getSession());\r
-    }\r
-\r
-       public static void untrackDependencies(RequestProcessor processor) {\r
-        \r
-        try {\r
-            processor.syncRequest(new ReadRequest() {\r
-\r
-                @Override\r
-                public void run(ReadGraph graph) throws DatabaseException {\r
-                    Layer0X L0X = Layer0X.getInstance(graph);\r
-                    GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);\r
-                    index.untrack(graph.getSession(), graph.getRootLibrary());\r
-                }\r
-                \r
-            });\r
-        } catch (DatabaseException e) {\r
-            Logger.defaultLogError(e);\r
-        }\r
-\r
-    }\r
-\r
-    public static void trackDependencies() {\r
-       trackDependencies(Simantics.getSession());\r
-    }\r
-\r
-       public static void trackDependencies(RequestProcessor processor) {\r
-           \r
-           try {\r
-            processor.syncRequest(new ReadRequest() {\r
-\r
-                @Override\r
-                public void run(ReadGraph graph) throws DatabaseException {\r
-                    Layer0X L0X = Layer0X.getInstance(graph);\r
-                    GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);\r
-                    index.trackAndIndex(graph.getSession(), graph.getRootLibrary());\r
-                }\r
-                \r
-            });\r
-        } catch (DatabaseException e) {\r
-            Logger.defaultLogError(e);\r
-        }\r
-\r
-       }\r
-\r
-    public static void removeIndex(WriteGraph graph, Resource model) throws DatabaseException {\r
-        Layer0X L0X = Layer0X.getInstance(graph);\r
-        IndexedRelations ir = graph.getService(IndexedRelations.class);\r
-        // Deletes index files\r
-        ir.reset(null, graph, L0X.DependenciesRelation, model);\r
-    }\r
-    \r
-    public static void resetIssueSources(WriteGraph graph, Resource model) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        IssueResource ISSUE = IssueResource.getInstance(graph);\r
-        for(Resource source : graph.sync(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.ContinuousIssueSource))) {\r
-            IssueSourceUtils.update(graph, source);\r
-        }\r
-    }\r
-    \r
-    public static void copyAnnotationTypes(WriteGraph graph, Resource sourceModel, Resource targetModel) throws DatabaseException {\r
-\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        AnnotationResource ANNO = AnnotationResource.getInstance(graph);\r
-\r
-        Instances query = graph.adapt(ANNO.AnnotationType, Instances.class);\r
-\r
-        Resource library = graph.getPossibleObject(targetModel, ANNO.HasAnnotationTypeRoot);\r
-        // HAXX:\r
-        if(library == null) {\r
-            library = graph.newResource();\r
-            graph.claim(library, L0.InstanceOf, null, ANNO.AnnotationTypeLibrary);\r
-            graph.claimLiteral(library, L0.HasName, L0.NameOf, L0.String, "Annotation types", Bindings.STRING);\r
-            graph.claim(library, L0.PartOf, L0.ConsistsOf, targetModel);\r
-            graph.claim(targetModel, ANNO.HasAnnotationTypeRoot, library);\r
-        }\r
-\r
-        for(Resource type : query.find(graph, sourceModel)) {\r
-            String name = graph.getRelatedValue(type, L0.HasName);\r
-            Resource existing = Layer0Utils.getPossibleChild(graph, library, name);\r
-            if(existing != null) {\r
-                RemoverUtil.remove(graph, existing);\r
-            }\r
-            Layer0Utils.copyTo(graph, library, type);\r
-        }\r
-\r
-    }\r
-    \r
-       public static void deleteIndex(WriteGraph graph, Resource model) throws DatabaseException {\r
-               Layer0X L0X = Layer0X.getInstance(graph);\r
-               IndexedRelations ir = graph.getService(IndexedRelations.class);\r
-               // Deletes index files\r
-               ir.reset(null, graph, L0X.DependenciesRelation, model);\r
-       }\r
-    \r
-       public static void disableDependencies(WriteGraph graph, Resource dummy) {\r
-               Layer0Utils.setDependenciesIndexingDisabled(graph, true);               \r
-       }\r
-\r
-    public static void releaseMemory(WriteGraph graph) {\r
-       \r
-               QueryControl qc = graph.getService(QueryControl.class);\r
-               ClusterControl cc = graph.getService(ClusterControl.class);\r
-               cc.flushClusters();\r
-               qc.flush(graph);\r
-       \r
-    }\r
-\r
-    public static List<Resource> filterByIndexRoot(ReadGraph graph, Resource indexRoot, List<Resource> resources) throws DatabaseException {\r
-        ArrayList<Resource> result =  new ArrayList<Resource>(resources.size());\r
-        for (Resource r : resources) {\r
-            Resource root = graph.syncRequest(new PossibleIndexRoot(r));\r
-            if (indexRoot.equals(root))\r
-                result.add(r);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    public static List<Resource> searchByTypeShallow(ReadGraph graph, Resource model, Resource type) throws DatabaseException {\r
-        return filterByIndexRoot(graph, model, searchByType(graph, model, type));\r
-    }\r
-\r
-    public static List<Resource> searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {\r
-       Instances query = graph.adapt(type, Instances.class);\r
-       return Layer0Utils.sortByCluster(graph, query.find(graph, model));\r
-    }\r
-\r
-    public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, GUID guid) throws DatabaseException {\r
-       return searchByGUID(graph, indexRoot, guid.indexString());\r
-    }\r
-    \r
-    public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, String indexString) throws DatabaseException {\r
-       return searchByQueryShallow(graph, indexRoot, "GUID:" + indexString);\r
-    }\r
-\r
-    public static List<Resource> searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException {\r
-        return filterByIndexRoot(graph, model, searchByQuery(graph, model, query));\r
-    }\r
-\r
-    public static List<Resource> searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException {\r
-        Instances instances = graph.adapt(Layer0.getInstance(graph).Entity, Instances.class);\r
-        Collection<Resource> queryResult = instances.find(graph, model, query);\r
-        return Layer0Utils.sortByCluster(graph, queryResult);\r
-    }\r
-\r
-    public static List<Resource> searchByTypeAndFilter(ReadGraph graph, Resource model, Resource type, Function1<Resource,Boolean> filter) throws DatabaseException {\r
-       Instances query = graph.adapt(type, Instances.class);\r
-       ArrayList<Resource> result =  new ArrayList<Resource>();\r
-       for(Resource r : query.find(graph, model)) {\r
-               if(filter.apply(r))\r
-                       result.add(r);\r
-       }\r
-       return result;\r
-    }\r
-\r
-    public static List<Triple<Resource, Resource, String>> getIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       List<Resource> entries = searchByQuery(graph, model, filter);\r
-       List<Triple<Resource, Resource, String>> listOfTriples = new ArrayList<Triple<Resource,Resource,String>>();\r
-       for (Resource entry : entries) {\r
-               Resource type = graph.getPossibleObject(entry, L0.InstanceOf);\r
-               String name = NameUtils.getSafeName(graph, entry);\r
-               listOfTriples.add(new Triple<Resource, Resource, String>(entry, type, name));\r
-       }\r
-               return listOfTriples;\r
-    }\r
-    \r
-    public static String listIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {\r
-       List<Triple<Resource, Resource, String>> listOfTriples = getIndexEntries(graph, model, filter);\r
-       StringBuilder sb = new StringBuilder();\r
-       sb.append("== LISTING INDEX ENTRIES OF INDEX: " + NameUtils.getSafeName(graph, model) + ". AMOUNT OF ENTRIES: " + listOfTriples.size() + " ==\n");\r
-       for (Triple<Resource, Resource, String> entry : listOfTriples) {\r
-               String instanceOf = NameUtils.getSafeName(graph, entry.second);\r
-               sb.append("Name: " + entry.third + " instanceOf: " + instanceOf + " Resource: " + entry.first.toString() + "\n");\r
-       }\r
-               return sb.toString();\r
-    }\r
-\r
-    public static List<Resource> searchByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {\r
-       Instances query = graph.adapt(type, Instances.class);\r
-       ArrayList<Resource> result =  new ArrayList<Resource>();\r
-       for(Resource r : query.findByName(graph, model, name)) {\r
-               if(graph.isInstanceOf(r, type))\r
-                       result.add(r);\r
-       }\r
-       return result;\r
-    }\r
-\r
-    public static List<Resource> searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {\r
-        return filterByIndexRoot(graph, model, searchByTypeAndName(graph, model, type, name));\r
-    }\r
-\r
-       /**\r
-        * @param graph\r
-        *            database write access\r
-        * @param sourceContainer\r
-        *            the source container to look for annotationProperty from to be\r
-        *            used as the copy source\r
-        * @param targetContainer\r
-        *            the target container for the copied annotationProperty\r
-        *            annotation\r
-        * @param annotationProperty\r
-        *            the annotation property relation\r
-        * @return created copy of the original annotation or <code>null</code> if\r
-        *         there was nothing to copy\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource copyPossibleAnnotation(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty) throws DatabaseException {\r
-               return copyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, null);\r
-       }\r
-\r
-       public static List<String> getPossibleNamePath(ReadGraph graph, Resource resource) throws DatabaseException {\r
-               return getPossibleNamePath(graph, resource, null);\r
-       }\r
-        \r
-       private static List<String> getPossibleNamePath(ReadGraph graph, Resource resource, List<String> result) throws DatabaseException {\r
-               \r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);\r
-               if(name == null) return null;\r
-\r
-               if(result == null) result = new ArrayList<String>();\r
-               \r
-               SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-               if(graph.isInstanceOf(resource, SIMU.Model)) return result;\r
-               \r
-               Resource parent = graph.getPossibleObject(resource, L0.PartOf);\r
-               if(parent != null) {\r
-                       getPossibleNamePath(graph, parent, result);\r
-               } else {\r
-                       return null;\r
-               }\r
-\r
-               result.add(name);\r
-               \r
-               return result;\r
-\r
-       }\r
-       \r
-       public static Resource claimLibraryPath(WriteGraph graph, Resource resource, List<String> path) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               for(int i=0;i<path.size()-1;i++) {\r
-                       String p = path.get(i);\r
-                       Resource child = Layer0Utils.getPossibleChild(graph, resource, p);\r
-                       if(child == null) {\r
-                               child = graph.newResource();\r
-                               graph.claim(child, L0.InstanceOf, L0.Library);\r
-                               graph.addLiteral(child, L0.HasName, L0.NameOf, L0.String, p, Bindings.STRING);\r
-                               graph.claim(resource, L0.ConsistsOf, L0.PartOf, child);\r
-                       }\r
-                       resource = child;\r
-               }\r
-               return resource;\r
-       }\r
-       \r
-       /**\r
-        * @param graph\r
-        *            database write access\r
-        * @param sourceContainer\r
-        *            the source container to look for annotationProperty from to be\r
-        *            used as the copy source\r
-        * @param targetContainer\r
-        *            the target container for the copied annotationProperty\r
-        *            annotation\r
-        * @param annotationProperty\r
-        *            the annotation property relation\r
-        * @param annotationProperty\r
-        *            the 2nd level annotation property relation or\r
-        *            <code>null</code> if no 2nd level annotation exists\r
-        * @return created copy of the original annotation or <code>null</code> if\r
-        *         there was nothing to copy\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource copyPossibleAnnotation2(WriteGraph graph,\r
-                       Resource sourceContainer, Resource targetContainer,\r
-                       Resource annotationProperty, Resource entryType) throws DatabaseException {\r
-\r
-               // Delete existing target value first\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Resource targetValue = graph.getPossibleObject(targetContainer, annotationProperty);\r
-               if (targetValue != null) {\r
-                       if(!graph.hasStatement(targetValue, L0.PartOf))\r
-                               RemoverUtil.remove(graph, targetValue);\r
-                       graph.deny(targetContainer, annotationProperty);\r
-               }\r
-\r
-               Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);\r
-               if (sourceValue == null)\r
-                       return null;\r
-               \r
-               List<String> sourceValuePath = getPossibleNamePath(graph, sourceValue);\r
-               if(sourceValuePath != null) {\r
-                       Resource targetModel = graph.sync(new PossibleModel(targetContainer));\r
-                       if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);\r
-                       Resource library = claimLibraryPath(graph, targetModel, sourceValuePath);\r
-                       Resource existing = Layer0Utils.getPossibleChild(graph, library, sourceValuePath.get(sourceValuePath.size()-1));\r
-                       if(existing == null) {\r
-                               existing = doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);\r
-                               graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);\r
-                       }\r
-                       graph.claim(targetContainer, annotationProperty, existing);\r
-                       return existing;\r
-               } else {\r
-                       return doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);\r
-               }\r
-\r
-       }\r
-\r
-       private static Resource doCopyPossibleAnnotation2(WriteGraph graph,\r
-                       Resource sourceContainer, Resource targetContainer,\r
-                       Resource annotationProperty, Resource entryType) throws DatabaseException {\r
-\r
-               Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);\r
-               if (sourceValue == null)\r
-                       return null;\r
-               \r
-               // Copy 1st level annotation\r
-               Resource targetValue = createAnnotation(graph, targetContainer, annotationProperty, sourceValue);\r
-\r
-               // Copy possible 2nd level annotations and attach to 1st if entry\r
-               // property is defined.\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               if (entryType != null) {\r
-                       \r
-                       AnnotationResource ANNO = AnnotationResource.getInstance(graph);\r
-                       for (Resource entry : graph.getObjects(sourceValue, ANNO.Annotation_HasEntry)) {\r
-\r
-                               String name = graph.getRelatedValue(entry, L0.HasName, Bindings.STRING);\r
-\r
-                               List<String> entryPath = getPossibleNamePath(graph, entry);\r
-                               if(entryPath != null) {\r
-                                       Resource targetModel = graph.sync(new PossibleModel(targetContainer));\r
-                                       if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);\r
-                                       Resource library = claimLibraryPath(graph, targetModel, entryPath);\r
-                                       Resource existing = Layer0Utils.getPossibleChild(graph, library, entryPath.get(entryPath.size()-1));\r
-                                       if(existing == null) {\r
-                                               existing = createTypedAnnotation(graph, null, null, entry, entryType, name);\r
-                                               graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);\r
-                                       }\r
-                                       graph.claim(targetValue, ANNO.Annotation_HasEntry, existing);\r
-                               } else {\r
-                                       Resource result = createTypedAnnotation(graph, null, null, entry, entryType, name);\r
-                                       graph.claim(targetValue, ANNO.Annotation_HasEntry, result);\r
-                               }\r
-                               \r
-                       }\r
-               }\r
-\r
-               return targetValue;\r
-\r
-       }\r
-\r
-       /**\r
-        * @param graph\r
-        *            database write access\r
-        * @param container\r
-        *            the container resource to attach the new annotation to\r
-        * @param property\r
-        *            the annotation property relation. The type of the created\r
-        *            annotation is decided from this property relation's range\r
-        * @param sourceAnnotation\r
-        *            the annotation to copy data from or <code>null</code> if\r
-        *            nothing shall be copied\r
-        * @return the newly created annotation resource or <code>null</code> if the\r
-        *         annotation property relation didn't have a single range type\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation) throws DatabaseException {\r
-               return createAnnotation(graph, container, property, sourceAnnotation, null);\r
-       }\r
-\r
-       /**\r
-        * @param graph\r
-        *            database write access\r
-        * @param container\r
-        *            the container resource to attach the new annotation to\r
-        * @param property\r
-        *            the annotation property relation. The type of the created\r
-        *            annotation is decided from this property relation's range\r
-        * @param sourceAnnotation\r
-        *            the annotation to copy data from or <code>null</code> if\r
-        *            nothing shall be copied\r
-        * @param name\r
-        *            name for newly created annotation or <code>null</code> to copy\r
-        *            name from source if available\r
-        * @return the newly created annotation resource or <code>null</code> if the\r
-        *         annotation property relation didn't have a single range type\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, String name) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Resource annotationType = graph.getSingleObject(property, L0.HasRange);\r
-               if (annotationType == null)\r
-                       return null;\r
-\r
-               return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, name);\r
-\r
-       }\r
-\r
-       /**\r
-        * @param graph\r
-        *            database write access\r
-        * @param container\r
-        *            the container resource to attach the new annotation to\r
-        * @param property\r
-        *            the annotation property relation\r
-        * @param sourceAnnotation\r
-        *            the annotation to copy data from or <code>null</code> if\r
-        *            nothing shall be copied\r
-        * @param annotationType\r
-        *            the type of the new annotation\r
-        * @return the newly created annotation resource\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType) throws DatabaseException {\r
-               return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, null);\r
-       }\r
-\r
-       /**\r
-        * @param graph\r
-        *            database write access\r
-        * @param container\r
-        *            the container resource to attach the new annotation to\r
-        * @param property\r
-        *            the annotation property relation\r
-        * @param sourceAnnotation\r
-        *            the annotation to copy data from or <code>null</code> if\r
-        *            nothing shall be copied\r
-        * @param annotationType\r
-        *            the type of the new annotation\r
-        * @param name\r
-        *            name for newly created annotation or <code>null</code> to copy\r
-        *            name from source if available\r
-        * @return the newly created annotation resource\r
-        * @throws DatabaseException\r
-        */\r
-       public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType, String name) throws DatabaseException {\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-\r
-               Resource anno = graph.newResource();\r
-\r
-               graph.claim(anno, L0.InstanceOf, null, annotationType);\r
-\r
-               if (name != null)\r
-                       graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);\r
-\r
-               if (sourceAnnotation != null) {\r
-\r
-                       if (name == null) {\r
-                               String sourceName = graph.getPossibleRelatedValue(sourceAnnotation, L0.HasName, Bindings.STRING);\r
-                               if(sourceName != null) graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, sourceName, Bindings.STRING);\r
-                       }\r
-\r
-                       Resource sourceType = graph.getSingleType(sourceAnnotation);\r
-                       List<AnnotationMap> am = getAnnotationMap(graph, annotationType, sourceType);\r
-                       for (AnnotationMap a : am) {\r
-                               Resource object = graph.getSingleObject(sourceAnnotation, a.sourcePredicate);\r
-                               Collection<Resource> objectTypes = graph.getTypes(object);\r
-                               if (objectTypes.contains(L0.Literal)) {\r
-                                       Object value = graph.getValue(object, a.defaultValueBinding);\r
-                                       if (!ObjectUtils.objectEquals(value, a.defaultValue)) {\r
-                                               graph.addLiteral(anno, a.annotationPredicate, a.annotationPredicateInverse, a.defaultValueType, value, a.defaultValueBinding);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-\r
-               if (container != null && property != null) {\r
-                       graph.claim(container, property, anno);\r
-               }\r
-\r
-               return anno;\r
-\r
-       }\r
-\r
-       private static class AnnotationMap {\r
-\r
-               final public Resource sourcePredicate;\r
-               final public Resource sourcePredicateInverse;\r
-\r
-               final public Resource annotationPredicate;\r
-               final public Resource annotationPredicateInverse;\r
-\r
-               final public Resource defaultValueType;\r
-               final public Object defaultValue;\r
-               final public Binding defaultValueBinding;\r
-\r
-               public AnnotationMap(Resource sp, Resource spi, Resource tp, Resource tpi, Resource defaultValueType, Object defaultValue, Binding defaultValueBinding) {\r
-                       sourcePredicate = sp;\r
-                       sourcePredicateInverse = spi;\r
-                       annotationPredicate = tp;\r
-                       annotationPredicateInverse = tpi;\r
-                       this.defaultValueType = defaultValueType;\r
-                       this.defaultValue = defaultValue;\r
-                       this.defaultValueBinding = defaultValueBinding;\r
-               }\r
-\r
-       }\r
-\r
-       public static List<AnnotationMap> getAnnotationMap(ReadGraph graph, Resource annotationType, Resource sourceType) throws DatabaseException {\r
-               return graph.syncRequest(new AnnotationMapRequest(annotationType, sourceType), TransientCacheListener.<List<AnnotationMap>>instance());\r
-       }\r
-\r
-       static class AnnotationMapRequest extends ResourceRead2<List<AnnotationMap>> {\r
-\r
-               public AnnotationMapRequest(Resource annotationType, Resource sourceType) {\r
-                       super(annotationType, sourceType);\r
-               }\r
-\r
-               @Override\r
-               public List<AnnotationMap> perform(ReadGraph graph) throws DatabaseException {\r
-\r
-                       Layer0 L0 = Layer0.getInstance(graph);\r
-\r
-                       ArrayList<AnnotationMap> result = new ArrayList<AnnotationMap>(); \r
-\r
-                       Map<String, Resource> annotationPredicates = new HashMap<String, Resource>();\r
-                       for(Resource predicate : graph.getObjects(resource, L0.DomainOf)) {\r
-                               String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);\r
-                               annotationPredicates.put(name, predicate);\r
-                       }\r
-                       Map<String, Resource> sourcePredicates = new HashMap<String, Resource>();\r
-                       for(Resource predicate : graph.getObjects(resource2, L0.DomainOf)) {\r
-                               String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);\r
-                               sourcePredicates.put(name, predicate);\r
-                       }\r
-\r
-                       for(String key : sourcePredicates.keySet()) {\r
-                               Resource sourcePredicate = sourcePredicates.get(key);\r
-                               Resource anno = annotationPredicates.get(key);\r
-                               if(sourcePredicate != null && anno != null) {\r
-                                       Resource defaultValueType = graph.getSingleObject(anno, L0.HasRange);\r
-                                       Binding defaultValueBinding = null;\r
-                                       Object defaultValue = null;\r
-                                       Resource assertion = graph.getPossibleObject(anno, L0.HasPredicateInverse);\r
-                                       if (assertion != null) {\r
-                                               Resource object = graph.getPossibleObject(assertion, L0.HasObject);\r
-                                               if (object != null) {\r
-                                                       if(graph.isInstanceOf(object, L0.Literal)) {\r
-                                                               Datatype dt = graph.getDataType(object);\r
-                                                               defaultValueBinding = Bindings.getBeanBinding(dt);\r
-                                                               defaultValue = graph.getPossibleValue(object);\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                                       result.add(new AnnotationMap(\r
-                                                       sourcePredicate, graph.getInverse(sourcePredicate),\r
-                                                       anno, graph.getInverse(anno),\r
-                                                       defaultValueType, defaultValue, defaultValueBinding));\r
-                               }\r
-                       }\r
-\r
-                       return result;\r
-\r
-               }\r
-\r
-       }\r
-\r
-       public static final String DRAWING_TEMPLATE_FORMAT    = "drawingTemplate";\r
-    public static final String DRAWING_TEMPLATE_FORMAT_V1 = DRAWING_TEMPLATE_FORMAT + ":1";\r
-    public static final String DRAWING_TEMPLATE_FORMAT_V2 = DRAWING_TEMPLATE_FORMAT + ":2";\r
-\r
-    public static Resource importDrawingTemplate(final Resource model, final File file) throws IOException, SerializationException, DatabaseException, TransferableGraphException {\r
-\r
-               try {\r
-\r
-                       final Resource library = Simantics.sync(new WriteResultRequest<Resource>() {\r
-\r
-                               @Override\r
-                               public Resource perform(WriteGraph graph) throws DatabaseException {\r
-                                       \r
-                                       Layer0 L0 = Layer0.getInstance(graph);\r
-                                       Template2dResource TEMPLATE = Template2dResource.getInstance(graph);\r
-                                       Resource root = graph.getPossibleObject(model, TEMPLATE.HasDrawingTemplateRoot);\r
-                                       if(root == null) {\r
-                                               Template2dResource TEMPLATE2D = Template2dResource.getInstance(graph);\r
-                                               root = graph.newResource();\r
-                                               graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibrary);\r
-                                               graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibraryUI);\r
-                                               graph.claimLiteral(root, L0.HasName, L0.NameOf, L0.String, "Diagram Templates", Bindings.STRING);\r
-                                               graph.claim(root, L0.PartOf, L0.ConsistsOf, model);\r
-                                               graph.claim(model, TEMPLATE2D.HasDrawingTemplateRoot, root);\r
-                                       }\r
-                                       \r
-                                       String name = new Path(file.getAbsolutePath()).removeFileExtension().lastSegment();\r
-                                       if(name != null) {\r
-                                               Resource existing = Layer0Utils.getPossibleChild(graph, root, name);\r
-                                               if(existing != null)\r
-                                                       graph.deny(root, L0.ConsistsOf, existing);\r
-                                       }\r
-                                       \r
-                                       return root;\r
-                                       \r
-                               }\r
-\r
-                       });\r
-\r
-                       final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(library);\r
-\r
-                       try {\r
-                               HashMap<String, FormatHandler<Object>> handlers = new HashMap<String, FormatHandler<Object>>();\r
-                               FormatHandler<Object> handler = new FormatHandler<Object>() {\r
-                                       @Override\r
-                                       public Binding getBinding() {\r
-                                               return TransferableGraph1.BINDING;\r
-                                       }\r
-\r
-                                       @Override\r
-                                       public Object process(DataContainer container) throws Exception {\r
-                                               TransferableGraphs.importGraph1(Simantics.getSession(), (TransferableGraph1)container.content.getValue(), \r
-                                                               advisor, null);\r
-                                               return null;\r
-                                       }\r
-                               };\r
-                               handlers.put(DRAWING_TEMPLATE_FORMAT_V1, handler);\r
-                               handlers.put(DRAWING_TEMPLATE_FORMAT_V2, handler);\r
-                               try {\r
-                                       DataContainers.readFile(file, handlers);\r
-                               } catch(DataFormatException e) {\r
-                                       throw new IOException(e);\r
-                               } catch(IOException e) {\r
-                                       throw e;\r
-                               } catch(Exception e) {\r
-                                       if(e instanceof RuntimeException)\r
-                                               throw (RuntimeException)e;\r
-                                       else\r
-                                               throw new RuntimeException(e);\r
-                               }\r
-\r
-                       } catch(IOException e) {\r
-                       }\r
-\r
-                       return advisor.getRoot();\r
-\r
-               } catch (Throwable t) {\r
-                       Logger.defaultLogError("Unexpected exception while importing diagram template.", t);\r
-               } finally {\r
-               }\r
-\r
-               return null;\r
-\r
-       }\r
-    \r
-    public static Collection<Variable> getMappedVariables(ReadGraph graph, Variable source) throws DatabaseException {\r
-       \r
-        ArrayList<Variable> result = new ArrayList<Variable>();\r
-       Resource represents = source.getPossibleRepresents(graph);\r
-       if(represents == null) return Collections.emptyList();\r
-       ModelingResources MOD = ModelingResources.getInstance(graph);\r
-       for(Resource r : getElementCorrespondendences(graph, represents)) {\r
-           result.add(Variables.getVariable(graph, r));\r
-       }\r
-       for(Resource r : graph.getObjects(represents, MOD.ComponentToElement)) {\r
-            result.add(Variables.getVariable(graph, r));\r
-       }\r
-        for(Resource r : graph.getObjects(represents, MOD.DiagramToComposite)) {\r
-            result.add(Variables.getVariable(graph, r));\r
-        }\r
-        for(Resource r : graph.getObjects(represents, MOD.CompositeToDiagram)) {\r
-            result.add(Variables.getVariable(graph, r));\r
-        }\r
-       return result;\r
-       \r
-    }\r
-    \r
-    public static Resource getPossibleModel(ReadGraph graph, Resource resource) throws DatabaseException {\r
-       \r
-       PossibleModel pm = new PossibleModel(resource);\r
-       Resource model = pm.perform(graph);\r
-       return model;\r
-    }\r
-    \r
-    public static Resource possibleIndexRoot(ReadGraph graph, Resource resource) throws DatabaseException {\r
-       return graph.syncRequest(new PossibleIndexRoot(resource));\r
-    }\r
-\r
-    public static Object getMonitorValue(StructuralComponent _variable, ReadGraph graph, String path) throws DatabaseException {\r
-        Variable variable = ((VariableStructuralContext)_variable).variable;\r
-        Variable var = variable.browse(graph, path);\r
-        return var.getValue(graph);\r
-    }\r
-    \r
-    public static void createSharedOntologyWithUI(ReadGraph graph, Variable variable, Resource baseType) throws DatabaseException {\r
-       createSharedOntologyWithUI(graph, baseType);\r
-    }\r
-\r
-    public static void createSharedOntologyWithUI(ReadGraph graph, Resource baseType) throws DatabaseException {\r
-       \r
-//     Resource indexRoot_ = variable.getPossibleRepresents(graph);\r
-//     if(indexRoot_ == null) return;\r
-\r
-           final Map<Resource, Pair<String,ImageDescriptor>> map = new HashMap<Resource, Pair<String,ImageDescriptor>>();\r
-\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-       Instances query = graph.adapt(L0.IndexRootType, Instances.class);\r
-       for(Resource ontology : Layer0Utils.listOntologies(graph)) {\r
-               for(Resource type : query.find(graph, ontology)) {\r
-                       if(graph.isInheritedFrom(type, SIMU.Model)) continue;\r
-                       if(graph.hasStatement(type, L0.Abstract)) continue;\r
-                       if(!graph.isInheritedFrom(type, baseType)) continue;\r
-                       String name = graph.getPossibleRelatedValue(type, L0.HasLabel, Bindings.STRING);\r
-                       if(name == null) name = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);\r
-                       map.put(type, new Pair<String,ImageDescriptor>(name, null));\r
-               }\r
-       }\r
-       \r
-       Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
-                               CreateSharedOntologyDialog page = new CreateSharedOntologyDialog(shell, map, "Select type and name of new shared library");\r
-                               if (page.open() == Window.OK) {\r
-                                       Object[] result = page.getResult();\r
-                                       if (result != null && result.length == 1) {\r
-                                               final Resource res = (Resource)result[0];\r
-                                               final String name = "http://" + page.getName();\r
-                                               Simantics.getSession().asyncRequest(new WriteRequest() {\r
-\r
-                                                       @Override\r
-                                                       public void perform(WriteGraph graph) throws DatabaseException {\r
-                                                               graph.markUndoPoint();\r
-                                                               Resource target = Simantics.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, name+"@A", res);\r
-                                                               \r
-                                                               ProjectResource PROJ = ProjectResource.getInstance(graph);\r
-                                                               Layer0 L0 = Layer0.getInstance(graph);\r
-                                                               for(Resource dep : graph.getObjects(Simantics.getProjectResource(), L0.IsLinkedTo)) {\r
-                                                                       if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {\r
-                                                                               for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {\r
-                                                                                       String uri = graph.getPossibleValue(req, Bindings.STRING);\r
-                                                                                       if(uri != null) {\r
-                                                                                               Resource ns = graph.getResource(uri);\r
-                                                                                               if(ns != null) {\r
-                                                                                                       graph.claim(target, L0.IsLinkedTo, null, ns);\r
-                                                                                               }\r
-                                                                                       }\r
-                                                                               }\r
-                                                                       }\r
-                                                               }\r
-                                                               \r
-                                                       }\r
-                                                       \r
-                                               });\r
-                                       }\r
-                               }\r
-                       }\r
-               });\r
-       \r
-    }\r
-\r
-    public static void unlinkSharedOntologyWithUI(ReadGraph graph, Variable variable, final List<Resource> libraries) throws DatabaseException {\r
-        \r
-       final Resource indexRoot = variable.getPossibleRepresents(graph);\r
-       if(indexRoot == null) return;\r
-       \r
-       StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-\r
-       final List<String> instances = new ArrayList<String>();\r
-       \r
-       DiagramResource DIA = DiagramResource.getInstance(graph);\r
-       \r
-       for(Resource library : libraries) {\r
-               for(Resource type : ModelingUtils.searchByTypeShallow(graph, library, STR.ComponentType)) {\r
-                       for(Resource instance : ModelingUtils.searchByTypeShallow(graph, indexRoot, type)) {\r
-                               // TODO: haxx\r
-                               if(graph.isInstanceOf(instance, DIA.Element)) continue;\r
-                               String name = Versions.getStandardPathNameString(graph, instance);\r
-                               instances.add(name);\r
-                       }\r
-               }\r
-       }\r
-       \r
-       if(instances.isEmpty()) {\r
-               graph.getSession().asyncRequest(new WriteRequest() {\r
-                       \r
-                               @Override\r
-                               public void perform(WriteGraph graph) throws DatabaseException {\r
-                               Layer0 L0 = Layer0.getInstance(graph);\r
-                               for(Resource library : libraries)\r
-                                       graph.deny(indexRoot, L0.IsLinkedTo, library);\r
-                               }\r
-                       \r
-               });\r
-               return;\r
-       }\r
-       \r
-        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-               \r
-                if (!PlatformUI.isWorkbenchRunning())\r
-                    return;\r
-\r
-                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
-                ListDialog<String> dialog = new ListDialog<String>(\r
-                        shell,\r
-                        instances,\r
-                        "Cannot unlink selected libraries",\r
-                        "Libraries cannot be unlinked since the following instances are referring to them.") {\r
-\r
-                       protected void createButtonsForButtonBar(Composite parent) {\r
-                               createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);\r
-                       }\r
-                       \r
-                };\r
-                int result = dialog.open();\r
-                if (result != Dialog.OK)\r
-                    return;\r
-\r
-            }\r
-        });\r
-       \r
-    }\r
-    \r
-    public static void importSharedOntology(String fileName) throws Exception {\r
-       try {\r
-               DataContainer dc = DataContainers.readFile(new File(fileName));\r
-               TransferableGraph1 tg = (TransferableGraph1)dc.content.getValue(TransferableGraph1.BINDING);\r
-               Variant draftStatus = dc.metadata.get(DraftStatusBean.EXTENSION_KEY);\r
-               MigrationUtils.importSharedOntology(Simantics.getSession(), tg, draftStatus == null);\r
-       } catch (Exception e) {\r
-               Logger.defaultLogError(e);\r
-               throw e;\r
-       }\r
-    }\r
-    \r
-    public static void importSharedOntologyWithUI(ReadGraph graph, final Variable variable) throws DatabaseException {\r
-       \r
-       Display.getDefault().asyncExec(new Runnable() {\r
-\r
-                       @Override\r
-                       public void run() {\r
-                               IStructuredSelection sel = new StructuredSelection(variable);\r
-                       openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyImportWizard");\r
-                       }\r
-                       \r
-               });\r
-       \r
-    }\r
-    \r
-       public static class LibraryInfo implements Comparable<LibraryInfo> {\r
-               public NamedResource library;\r
-               public DraftStatusBean draft;\r
-               public LibraryInfo(String name, Resource r, DraftStatusBean draft) {\r
-                       library = new NamedResource(name, r);\r
-                       this.draft = draft;\r
-               }\r
-               @Override\r
-               public int compareTo(LibraryInfo o) {\r
-                       return library.compareTo(o.library);\r
-               }\r
-               @Override\r
-               public int hashCode() {\r
-                       return library.hashCode();\r
-               }\r
-               @Override\r
-               public boolean equals(Object object) {\r
-               if (this == object)\r
-                   return true;\r
-               else if (object == null)\r
-                   return false;\r
-               else if (!(object instanceof LibraryInfo))\r
-                   return false;\r
-               LibraryInfo info = (LibraryInfo)object;\r
-               return info.library.equals(library);\r
-               }\r
-               \r
-       }\r
-       \r
-    public static void exportSharedOntologyWithUI(final Resource sharedOntology) {\r
-\r
-       Display.getDefault().asyncExec(new Runnable() {\r
-\r
-               @Override\r
-               public void run() {\r
-                       HintContext hc = new HintContext();\r
-                       hc.setHint(SelectionHints.KEY_MAIN, sharedOntology);\r
-                       IStructuredSelection sel = new StructuredSelection(hc);\r
-               openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyExportWizard");\r
-               }\r
-               \r
-       });\r
-       \r
-    }\r
-       \r
-    public static void exportSharedOntology(IProgressMonitor monitor, RequestProcessor processor, File location, String format, int version, final LibraryInfo info) throws DatabaseException, IOException {\r
-       \r
-       if(monitor == null) monitor = new NullProgressMonitor();\r
-       \r
-        // TODO: figure out a way to make the TG go directly into a file\r
-        // instead of having it all in memory at once.\r
-\r
-        monitor.beginTask("Exporting shared library...", 100);\r
-       SimanticsClipboard clipboard = processor.syncRequest(new Read<SimanticsClipboard>() {\r
-            @Override\r
-            public SimanticsClipboard perform(ReadGraph graph) throws DatabaseException {\r
-                CopyHandler ch = graph.adapt(info.library.getResource(), CopyHandler.class);\r
-                SimanticsClipboardImpl clipboard = new SimanticsClipboardImpl();\r
-                ch.copyToClipboard(graph, clipboard);\r
-                return clipboard;\r
-            }\r
-        });\r
-       \r
-        TreeMap<String,Variant> metadata = getExportMetadata();\r
-        DraftStatusBean draft = info.draft;\r
-        if(draft != null) {\r
-               metadata.put(DraftStatusBean.EXTENSION_KEY, new Variant(DraftStatusBean.BINDING ,draft));\r
-        }\r
-        \r
-        for (Set<Representation> object : clipboard.getContents()) {\r
-               \r
-            TransferableGraph1 tg = ClipboardUtils.accept(processor, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);\r
-            monitor.worked(95);\r
-\r
-            monitor.setTaskName("Writing transferable graph...");\r
-            DataContainers.writeFile(location, new DataContainer(\r
-                    format, version,\r
-                    metadata, new Variant(TransferableGraph1.BINDING, tg)));\r
-\r
-            monitor.worked(5);\r
-        }\r
-    }\r
-\r
-    public static TreeMap<String, Variant> getExportMetadata() {\r
-\r
-        TreeMap<String,Variant> metadata = new TreeMap<String,Variant>();\r
-        metadata.put("date", Variant.ofInstance(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())));\r
-        metadata.put("author", Variant.ofInstance(System.getProperty("user.name", "")));\r
-\r
-        return metadata;\r
-        \r
-    }\r
-    \r
-    public static void createNewVersionWithoutUI(WriteGraph graph, Resource resource) throws DatabaseException {\r
-        VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));\r
-        int currentVersion = Integer.parseInt(info.version);\r
-        String result = Integer.toString(currentVersion + 1);\r
-        createNewVersion(graph, resource, info, result);\r
-    }\r
-    \r
-    public static void createNewVersionWithUI(ReadGraph graph, final Resource resource) throws DatabaseException {\r
-       \r
-       final VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));\r
-       \r
-       Display.getDefault().asyncExec(new Runnable() {\r
-                       @Override\r
-                       public void run() {\r
-                               Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
-                               CreateVersionDialog dialog = new CreateVersionDialog(shell, info);\r
-                               if (dialog.open() == Window.OK) {\r
-                                       final String result = dialog.getResult();\r
-                                       Simantics.getSession().asyncRequest(new WriteRequest() {\r
-                                               @Override\r
-                                               public void perform(WriteGraph graph) throws DatabaseException {\r
-                                                   createNewVersion(graph, resource, info, result);\r
-                                               }\r
-                                       });\r
-                               }\r
-                       }\r
-               });\r
-       \r
-    }\r
-    \r
-    public static void createNewVersion(WriteGraph graph, Resource resource, final VersionInfo info, final String result) throws DatabaseException {\r
-        graph.markUndoPoint();\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        Resource parent = graph.getPossibleObject(resource, L0.PartOf);\r
-        if(parent == null) return;\r
-        final String parentURI = graph.getPossibleURI(parent);\r
-        if(parentURI == null) return;\r
-        Layer0Utils.copyTo(graph, parent, resource, new PasteEventHandler() {\r
-\r
-            @Override\r
-            public void postProcess(WriteGraph graph, Resource root) throws DatabaseException {\r
-                Layer0 L0 = Layer0.getInstance(graph);\r
-                graph.deny(root, L0.Entity_published);\r
-            }\r
-            \r
-            @Override\r
-            public IImportAdvisor2 createAdvisor(ReadGraph graph, ImportAdvisorFactory factory, Resource target) throws DatabaseException {\r
-                Map<String,Object> context = new HashMap<String,Object>();\r
-                String base = parentURI + "/" + URIStringUtils.escape( info.baseName ) + "@";\r
-                Map<String,String> renameMap = new HashMap<String,String>();\r
-                renameMap.put(base + info.version, base + result);\r
-                renameMap.put(info.baseName + "@" + info.version, info.baseName + "@" + result);\r
-                context.put(ImportAdvisors.RENAME_MAP, renameMap);\r
-                return factory.create(graph, target, context);\r
-            }\r
-            \r
-        });\r
-        Layer0Utils.addCommentMetadata(graph, "Created new version of " + info.baseName);\r
-    }\r
-    \r
-    public static boolean isUserComponent(ReadGraph graph, Resource type) throws DatabaseException {\r
-       StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-       if(graph.isInstanceOf(type, STR.ProceduralComponentType)) return true;\r
-       else if (graph.hasStatement(type, STR.IsDefinedBy)) return true;\r
-       return false;\r
-    }\r
-    \r
-    public static void publishComponentTypeWithUI(WriteGraph graph, final Resource componentType) throws DatabaseException {\r
-\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-       Resource composite = graph.getPossibleObject(componentType, STR.IsDefinedBy);\r
-       final List<String> instances = new ArrayList<String>();\r
-       if(composite != null) {\r
-               for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) {\r
-               Resource type = graph.getPossibleType(component, STR.Component);\r
-                       if(type != null && isUserComponent(graph, type)) {\r
-                               if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, component));\r
-                       }\r
-               }\r
-       }\r
-\r
-       if(instances.isEmpty()) {\r
-               graph.getSession().asyncRequest(new WriteRequest() {\r
-                       \r
-                               @Override\r
-                               public void perform(WriteGraph graph) throws DatabaseException {\r
-                               graph.markUndoPoint();\r
-                               publish(graph, componentType);\r
-                               }\r
-                       \r
-               });\r
-               return;\r
-       }\r
-       \r
-        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-               \r
-                if (!PlatformUI.isWorkbenchRunning())\r
-                    return;\r
-\r
-                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
-                ListDialog<String> dialog = new ListDialog<String>(\r
-                        shell,\r
-                        instances,\r
-                        "Cannot publish user component",\r
-                        "The following instances are referring to unpublished user components.") {\r
-\r
-                       protected void createButtonsForButtonBar(Composite parent) {\r
-                               createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);\r
-                       }\r
-                       \r
-                };\r
-                int result = dialog.open();\r
-                if (result != Dialog.OK)\r
-                    return;\r
-\r
-            }\r
-        });\r
-       \r
-    }\r
-\r
-    public static void publishSharedOntologyWithUI(WriteGraph graph, final Resource sharedOntology) throws DatabaseException {\r
-       \r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       DiagramResource DIA = DiagramResource.getInstance(graph);\r
-       StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-       final List<String> instances = new ArrayList<String>();\r
-       for(Resource type : searchByTypeShallow(graph, sharedOntology, STR.ComponentType)) {\r
-                       // TODO: haxx\r
-                       if(graph.isInheritedFrom(type, DIA.Element)) continue;\r
-               if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, type));\r
-       }\r
-       for(Resource dep : graph.syncRequest(new ObjectsWithType(sharedOntology, L0.IsLinkedTo, L0.SharedOntology))) {\r
-               if(!Layer0Utils.isPublished(graph, dep)) instances.add(Versions.getStandardPathNameString(graph, dep));\r
-       }\r
-       \r
-       if(instances.isEmpty()) {\r
-               graph.getSession().asyncRequest(new WriteRequest() {\r
-                       \r
-                               @Override\r
-                               public void perform(WriteGraph graph) throws DatabaseException {\r
-                               graph.markUndoPoint();\r
-                               publish(graph, sharedOntology);\r
-                               }\r
-                       \r
-               });\r
-               return;\r
-       }\r
-       \r
-        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
-            @Override\r
-            public void run() {\r
-               \r
-                if (!PlatformUI.isWorkbenchRunning())\r
-                    return;\r
-\r
-                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();\r
-                ListDialog<String> dialog = new ListDialog<String>(\r
-                        shell,\r
-                        instances,\r
-                        "Cannot publish shared library",\r
-                        "The following dependencies are unpublished.") {\r
-\r
-                       protected void createButtonsForButtonBar(Composite parent) {\r
-                               createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);\r
-                       }\r
-                       \r
-                };\r
-                int result = dialog.open();\r
-                if (result != Dialog.OK)\r
-                    return;\r
-\r
-            }\r
-        });\r
-       \r
-    }\r
-\r
-    \r
-    public static void createSCLModuleDefault(WriteGraph graph, Resource target) throws DatabaseException {\r
-       String name = NameUtils.findFreshEscapedName(graph, "SCLModule", target);\r
-       createSCLModule(graph, target, name);\r
-    }\r
-\r
-    public static void createSCLModule(WriteGraph graph, Resource target, String name) throws DatabaseException {\r
-        graph.markUndoPoint();\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-        Resource sclModule = GraphUtils.create2(graph, L0.SCLModule,\r
-                L0.HasName, name,\r
-                L0.PartOf, target,\r
-                L0.SCLModule_definition, "");\r
-       Layer0Utils.addCommentMetadata(graph, "Created SCL Module " + name + " " + sclModule.toString());\r
-    }\r
-\r
-    public static void createPGraphDefault(WriteGraph graph, Resource target) throws DatabaseException {\r
-       String name = NameUtils.findFreshEscapedName(graph, "Ontology Definition File", target);\r
-       createPGraph(graph, target, name);\r
-    }\r
-\r
-    public static void createPGraph(WriteGraph graph, Resource target, String name) throws DatabaseException {\r
-        graph.markUndoPoint();\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-        Resource file = GraphUtils.create2(graph, L0.PGraph,\r
-                L0.HasName, name,\r
-                L0.PartOf, target,\r
-                L0.PGraph_definition, "");\r
-       Layer0Utils.addCommentMetadata(graph, "Created Ontology Definition File " + name + " " + file.toString());\r
-    }\r
-    \r
-    public static void publish(WriteGraph graph, Resource target) throws DatabaseException {\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       graph.claimLiteral(target, L0.Entity_published, true, Bindings.BOOLEAN);\r
-       Layer0Utils.addCommentMetadata(graph, "Published " + graph.getPossibleRelatedValue2(target, L0.HasName, Bindings.STRING) + " " + target.toString());\r
-    }\r
-\r
-    public static boolean isLinkedToDeep(ReadGraph graph, Resource r1, Resource r2) throws DatabaseException {\r
-       return graph.syncRequest(new IsLinkedTo(r1, r2));\r
-    }\r
-    \r
-    public static void openWizard(Display display, IStructuredSelection selection, String id) {\r
-       // First see if this is a "new wizard".\r
-       IWizardDescriptor descriptor = PlatformUI.getWorkbench()\r
-                       .getNewWizardRegistry().findWizard(id);\r
-       // If not check if it is an "import wizard".\r
-       if  (descriptor == null) {\r
-               descriptor = PlatformUI.getWorkbench().getImportWizardRegistry()\r
-                               .findWizard(id);\r
-       }\r
-       // Or maybe an export wizard\r
-       if  (descriptor == null) {\r
-               descriptor = PlatformUI.getWorkbench().getExportWizardRegistry()\r
-                               .findWizard(id);\r
-       }\r
-       try  {\r
-               // Then if we have a wizard, open it.\r
-               if  (descriptor != null) {\r
-                       IWorkbenchWizard wizard = descriptor.createWizard();\r
-                       wizard.init(PlatformUI.getWorkbench(), selection);\r
-                       WizardDialog wd = new  WizardDialog(display.getActiveShell(), wizard);\r
-                       wd.setTitle(wizard.getWindowTitle());\r
-                       wd.open();\r
-               }\r
-       } catch  (CoreException e) {\r
-               e.printStackTrace();\r
-       }\r
-    }\r
-    \r
-    public static String withinEpsilon(double value, double reference, double epsilon) {\r
-       if(Math.abs(value-reference) < epsilon) return "True";\r
-       else return "Not within epsilon value=" + value + ", reference=" + reference + " , epsilon=" + epsilon; \r
-    }\r
-    \r
-    public static boolean needsIdentifier(ReadGraph graph, Resource r) throws DatabaseException {\r
-       Layer0 L0 = Layer0.getInstance(graph);\r
-       Collection<Resource> types = graph.getPrincipalTypes(r);\r
-       for(Resource type : types)\r
-               if(graph.syncRequest(new IsInstanceOf(type, L0.TypeWithIdentifier), TransientCacheAsyncListener.<Boolean>instance()))\r
-                               return true;\r
-       return false;\r
-    }\r
-\r
-    public static boolean needsModificationInfo(ReadGraph graph, Resource r) throws DatabaseException {\r
-       ModelingResources MOD = ModelingResources.getInstance(graph);\r
-       Collection<Resource> types = graph.getPrincipalTypes(r);\r
-       for(Resource type : types)\r
-               if(graph.syncRequest(new IsInstanceOf(type, MOD.TypeWithChangeInformation), TransientCacheAsyncListener.<Boolean>instance()))\r
-                               return true;\r
-       return false;\r
-    }\r
-\r
-    public static void attachCreationInformation(IProgressMonitor monitor, WriteGraph graph, Resource model) throws DatabaseException {\r
-       \r
-       if(monitor == null) monitor = new NullProgressMonitor();\r
-       \r
-        final String author = System.getProperty("user.name", "");\r
-        final long time = System.currentTimeMillis();\r
-       \r
-        monitor.setTaskName("Attach creation information");\r
-\r
-       ModelingResources MOD = ModelingResources.getInstance(graph);\r
-       Collection<Resource> rs = ModelingUtils.searchByType(graph, model, MOD.TypeWithChangeInformation);\r
-       Collection<Resource> supers = ModelingUtils.getMostUnspecificTypes(graph, rs);\r
-       \r
-       CollectionSupport cs = graph.getService(CollectionSupport.class);\r
-       Collection<Resource> set = cs.createSet();\r
-        for(Resource type : supers) {\r
-               set.addAll(ModelingUtils.searchByTypeShallow(graph, model, type));\r
-        }\r
-        Collection<Resource> instances = Layer0Utils.sortByCluster(graph, set);\r
-\r
-       int pc = instances.size() / 100;\r
-       int done = 0;\r
-       int stint = pc;\r
-\r
-        for(Resource instance : instances) {\r
-               ChangeInformation info = graph.getPossibleRelatedValue(instance, MOD.changeInformation, ChangeInformation.BINDING);\r
-               if(info == null) {\r
-                       info = new ChangeInformation();\r
-                       info.createdAt = time;\r
-                       info.createdBy = author;\r
-                       info.modifiedAt = time;\r
-                       info.modifiedBy = author;\r
-                       graph.claimLiteral(instance, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING);\r
-               }\r
-               done++;\r
-               stint--;\r
-               if(stint == 0) {\r
-                       Double d = (100.0*done)/instances.size();\r
-                       monitor.setTaskName("Attach creation information " +  d.intValue() + "%");\r
-                       stint = pc;\r
-               }\r
-        }\r
-        \r
-               monitor.setTaskName("Attach creation information - commit");\r
-       \r
-    }\r
-\r
-    public static class DiagramComponentInfo {\r
-\r
-        private static String CHILD_PREFIX             = "child:";\r
-\r
-               final private String compositePathAndName;\r
-               final private String componentName;\r
-               final private GUID guid;\r
-               \r
-               public DiagramComponentInfo(String compositePathAndName, String componentName, GUID guid) {\r
-                       this.compositePathAndName = compositePathAndName;\r
-                       this.componentName = componentName;\r
-                       this.guid = guid;\r
-               }\r
-               \r
-               public static boolean isDiagramComponent(String tgName) {\r
-                       return tgName.startsWith(CHILD_PREFIX);\r
-               }\r
-\r
-               public String getTGName(CompositeInfo info) {\r
-                       return CHILD_PREFIX + info.getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + info.getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedComponentName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();\r
-               }\r
-               \r
-               public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {\r
-                       Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);\r
-                       return !res.isEmpty();\r
-               }\r
-\r
-               public static DiagramComponentInfo fromResource(ReadGraph graph, CompositeInfo info, Resource resource) throws DatabaseException {\r
-                       Layer0 L0 = Layer0.getInstance(graph);\r
-               GUID childId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);\r
-            String childName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);\r
-            return new DiagramComponentInfo(info.getStateKey(), URIStringUtils.escape(childName), childId);\r
-               }\r
-               \r
-               public GUID getGUID() {\r
-                       return guid;\r
-               }\r
-               \r
-               public String getEscapedCompositePathAndName() {\r
-                       return compositePathAndName;\r
-               }\r
-               \r
-               public String getEscapedComponentName() {\r
-                       return componentName;\r
-               }\r
-               \r
-               public String getUnescapedComponentName() {\r
-                       return URIStringUtils.unescape(getEscapedComponentName());\r
-               }\r
-               \r
-               // "child:path#compositeName#componentName#guid"\r
-               public static DiagramComponentInfo parse(String tgName) {\r
-                       \r
-            String name = tgName.substring(CHILD_PREFIX.length());\r
-            String compositePathAndName = "";\r
-            String moduleName = name;\r
-            GUID guid = GUID.invalid();\r
-            int lastHash = name.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);\r
-            if(lastHash >= 0) {\r
-               String first = name.substring(0, lastHash);\r
-               String second = name.substring(lastHash+1);\r
-               lastHash = first.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);\r
-               if(lastHash >= 0) {\r
-                       compositePathAndName = first.substring(0, lastHash);\r
-                       moduleName = first.substring(lastHash+1);\r
-                       guid = GUID.parseIndexString(second);\r
-               } else {\r
-                       compositePathAndName = first;\r
-                       moduleName = second;\r
-               }\r
-            }\r
-            return new DiagramComponentInfo(compositePathAndName, moduleName, guid); \r
-                       \r
-               }\r
-\r
-\r
-       @Override\r
-               public int hashCode() {\r
-                       final int prime = 31;\r
-                       int result = 1;\r
-                       result = prime * result + ((compositePathAndName == null) ? 0 : compositePathAndName.hashCode());\r
-                       result = prime * result + ((componentName == null) ? 0 : componentName.hashCode());\r
-                       return result;\r
-               }\r
-\r
-               @Override\r
-               public boolean equals(Object obj) {\r
-                       if (this == obj)\r
-                               return true;\r
-                       if (obj == null)\r
-                               return false;\r
-                       if (getClass() != obj.getClass())\r
-                               return false;\r
-                       DiagramComponentInfo other = (DiagramComponentInfo) obj;\r
-                       if (compositePathAndName == null) {\r
-                               if (other.compositePathAndName != null)\r
-                                       return false;\r
-                       } else if (!compositePathAndName.equals(other.compositePathAndName))\r
-                               return false;\r
-                       if (componentName == null) {\r
-                               if (other.componentName != null)\r
-                                       return false;\r
-                       } else if (!componentName.equals(other.componentName))\r
-                               return false;\r
-                       return true;\r
-               }\r
-               \r
-    }\r
-    \r
-       public static class CompositeInfo {\r
-\r
-           public static String COMPOSITE_PREFIX         = "composite:";\r
-\r
-               final private boolean useGuids;\r
-               final private boolean applyPaths;\r
-               final private String path;\r
-               final private String name;\r
-               final private GUID guid;\r
-               \r
-               private CompositeInfo(boolean useGuids, boolean applyPaths, String path, String name, GUID guid) {\r
-                       this.useGuids = useGuids;\r
-                       this.applyPaths = applyPaths;\r
-                       this.path = path;\r
-                       this.name = name;\r
-                       this.guid = guid;\r
-               }\r
-\r
-               @Override\r
-               public String toString() {\r
-                       return "CompositeInfo[useGuids=" + useGuids + ", applyPaths=" + applyPaths + ", path=" + path + ", name=" + name + ", guid=" + guid.indexString() + "]";\r
-               }\r
-\r
-               public static boolean isComposite(String tgName) {\r
-                       return tgName.startsWith(COMPOSITE_PREFIX);\r
-               }\r
-\r
-               public String getTGName() {\r
-                       return COMPOSITE_PREFIX + getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();\r
-               }\r
-               \r
-               public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {\r
-                       Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);\r
-                       return !res.isEmpty();\r
-               }\r
-\r
-               public static CompositeInfo fromResource(ReadGraph graph, Resource resource) throws DatabaseException {\r
-                       \r
-                       Layer0 L0 = Layer0.getInstance(graph);\r
-            GUID rootId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);\r
-            String rootName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);\r
-            String escapedRootName = URIStringUtils.escape(rootName);\r
-            String escapedPath = ModelingUtils.getDiagramCompositePath(graph, resource);\r
-            return new CompositeInfo(true, true, escapedPath, escapedRootName, rootId);\r
-                       \r
-               }\r
-\r
-           public static CompositeInfo parse(String tgName) {\r
-               return parse(tgName, true, true);\r
-           }\r
-\r
-           /*\r
-            * Index 0 is root-relative folder path separated with '/' or null if target-relative positioning is used\r
-            * Index 1 is diagram name\r
-            */\r
-           public static CompositeInfo parse(String tgName, boolean applyPaths, boolean useGuids) {\r
-               if(!tgName.startsWith(COMPOSITE_PREFIX)) return null;\r
-               tgName = tgName.substring(COMPOSITE_PREFIX.length());\r
-               if(!tgName.contains(COMPOSITE_SEPARATOR)) {\r
-                       if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");\r
-                       return new CompositeInfo(useGuids, applyPaths, null, tgName, null);\r
-               }\r
-               String[] parts = tgName.split(COMPOSITE_SEPARATOR);\r
-               if(parts.length == 2) {\r
-                       String name = parts[1];\r
-                       String path = applyPaths ? parts[0] : null;\r
-                       if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");\r
-                       return new CompositeInfo(useGuids, applyPaths, path, name, null);\r
-               } else if(parts.length == 3) {\r
-                       String path = parts[0];\r
-                       String name = parts[1];\r
-                       GUID guid = GUID.parseIndexString(parts[2]);\r
-                       return new CompositeInfo(useGuids, applyPaths, path, name, guid);\r
-               } else {\r
-                       return null;\r
-               }\r
-           }\r
-\r
-               public GUID getGUID() {\r
-                       return guid;\r
-               }\r
-\r
-               public String getEscapedName() {\r
-                       return name;\r
-               }\r
-               \r
-               public String getUnescapedName() {\r
-                       return URIStringUtils.unescape(name);\r
-               }\r
-               \r
-               public String getOriginalPath() {\r
-                       return path;\r
-               }\r
-               \r
-               public String getFinalPath() {\r
-                       if(applyPaths) return path;\r
-                       else return null;\r
-               }\r
-               \r
-               public CompositeInfo renamed(String newName) {\r
-                       return new CompositeInfo(useGuids, applyPaths, path, newName, guid);\r
-               }\r
-               \r
-               public String getStateKey() {\r
-                       return path + "#" + getEscapedName();\r
-               }\r
-               \r
-               private Resource getFromFolder(ReadGraph graph, Resource target) throws DatabaseException {\r
-            Resource diagram = Layer0Utils.getPossibleChild(graph, target, URIStringUtils.unescape(name));\r
-            if(diagram == null) return null;\r
-            StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-            return graph.isInstanceOf(diagram, STR.Composite) ? diagram : null;\r
-               }\r
-               \r
-               public Resource resolve(ReadGraph graph, Resource target) throws DatabaseException {\r
-\r
-                       if(useGuids && guid != null) {\r
-                               Resource indexRoot = graph.syncRequest(new IndexRoot(target));\r
-                               Collection<Resource> queryResult = searchByGUID(graph, indexRoot, guid);\r
-                               if(queryResult.size() == 1) {\r
-                                       Resource composite = queryResult.iterator().next(); \r
-                           StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-                           if(!graph.isInstanceOf(composite, STR.Composite)) return null;\r
-                           return composite;\r
-                               }\r
-                       }\r
-                       \r
-                       if(applyPaths) {\r
-                               Resource folder = resolveFolder(graph, target);\r
-                               if(folder == null) return null;\r
-                       return getFromFolder(graph, folder);\r
-                       } else {\r
-                       return getFromFolder(graph, target);\r
-                       }\r
-                       \r
-               }\r
-               \r
-               public Resource resolveFolder(ReadGraph graph, Resource target) throws DatabaseException {\r
-                       \r
-                       String path = getFinalPath();\r
-                       if(path == null) return target;\r
-                       \r
-               Resource folder = graph.syncRequest(new Configuration(target));\r
-               String[] segments = path.split("/");\r
-               for(int i=0;i<segments.length;i++) {\r
-                       if(segments[i].isEmpty()) continue;\r
-                       folder = Layer0Utils.getPossibleChild(graph, folder, URIStringUtils.unescape(segments[i]));\r
-                       if(folder == null) return null;\r
-               }\r
-               \r
-               return folder;\r
-                       \r
-               }\r
-               \r
-               \r
-               @Override\r
-               public int hashCode() {\r
-                       \r
-                       if(useGuids) return guid.hashCode();\r
-                       \r
-                       final int prime = 31;\r
-                       int result = name.hashCode();\r
-                       result = prime * result + ((path == null) ? 0 : path.hashCode());\r
-                       return result;\r
-                       \r
-               }\r
-\r
-               @Override\r
-               public boolean equals(Object obj) {\r
-                       \r
-                       if (this == obj)\r
-                               return true;\r
-                       if (obj == null)\r
-                               return false;\r
-                       if (getClass() != obj.getClass())\r
-                               return false;\r
-                       \r
-                       CompositeInfo other = (CompositeInfo) obj;\r
-                       \r
-                       if(useGuids) return guid.equals(other.guid);\r
-                       \r
-                       if (!name.equals(other.name))\r
-                               return false;\r
-                       \r
-                       if(applyPaths)\r
-                               if (!path.equals(other.path))\r
-                                       return false;\r
-                       \r
-                       return true;\r
-                       \r
-               }\r
-               \r
-       }\r
-       \r
-    public static char   COMPOSITE_SEPARATOR_CHAR = '#';\r
-    public static String COMPOSITE_SEPARATOR      = String.valueOf(COMPOSITE_SEPARATOR_CHAR);\r
-    \r
-    public static CompositeInfo parseCompositeNameFromRoot(Root root, boolean applyPaths, boolean useGuids) {\r
-       return CompositeInfo.parse(root.name, applyPaths, useGuids);\r
-    }\r
-\r
-    public static CompositeInfo parseCompositeNameFromRoot(Identity root, boolean applyPaths, boolean useGuids) {\r
-       String coded = TransferableGraphUtils.getName(root);\r
-       return CompositeInfo.parse(coded, applyPaths, useGuids);\r
-    }\r
-    \r
-       private static StringBuilder getDiagramCompositePathInternal(ReadGraph graph, Resource folder, StringBuilder builder) throws DatabaseException {\r
-               SimulationResource SIMU = SimulationResource.getInstance(graph);\r
-               Resource model = graph.getPossibleObject(folder, SIMU.IsConfigurationOf);\r
-               if (model != null) return builder;\r
-\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               String name = graph.getPossibleRelatedValue(folder, L0.HasName, Bindings.STRING);\r
-               if (name == null) return null;\r
-               Resource parent = graph.getPossibleObject(folder, L0.PartOf);\r
-               if (parent == null) return null;\r
-\r
-               StringBuilder sb = getDiagramCompositePathInternal(graph, parent, builder);\r
-               if (sb == null) return null;\r
-               if (sb.length() > 0)\r
-                       sb.append(URIStringUtils.NAMESPACE_PATH_SEPARATOR);\r
-               sb.append( URIStringUtils.escape(name) );\r
-               return sb;\r
-       }\r
-\r
-       /**\r
-        * @param graph\r
-        * @param diagram\r
-        * @return diagram/folder path up until model configuration root with each\r
-        *         segment escaped using {@link URIStringUtils#escape(String)} and\r
-        *         {@value URIStringUtils#NAMESPACE_PATH_SEPARATOR} between each\r
-        *         segment or <code>null</code> if the specified diagram composite\r
-        *         is not part of any model configuration structure.\r
-        * @throws DatabaseException\r
-        */\r
-       public static String getDiagramCompositePath(ReadGraph graph, Resource diagram) throws DatabaseException {\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               Resource parent = graph.getPossibleObject(diagram, L0.PartOf);\r
-               if(parent == null) return null;\r
-               StringBuilder sb = getDiagramCompositePathInternal(graph, parent, new StringBuilder());\r
-               return sb != null ? sb.toString() : null;\r
-       }\r
-       \r
-       public static void exportModel(ReadGraph graph, Resource model, String fileName, String format, int version) throws DatabaseException {\r
-       \r
-               try {\r
-                       TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model, true, false);\r
-               TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));\r
-                       TransferableGraphs.writeTransferableGraph(graph, format, version, s, new File(fileName));\r
-               } catch (Exception e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-\r
-       }\r
-\r
-       public static void exportSharedOntology(ReadGraph graph, Resource library, String fileName, String format, int version) throws DatabaseException {\r
-               \r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        String name = graph.getRelatedValue(library, L0.HasName, Bindings.STRING);\r
-\r
-        DraftStatusBean draft = null;\r
-        boolean published = Layer0Utils.isPublished(graph, library);\r
-        if(!published) draft = new DraftStatusBean(new String[0]);\r
-        \r
-        LibraryInfo info = new LibraryInfo(name, library, draft);\r
-               \r
-       try {\r
-                       exportSharedOntology(new NullProgressMonitor(), graph, new File(fileName), format, version, info);\r
-               } catch (IOException e) {\r
-                       throw new DatabaseException(e);\r
-               }\r
-\r
-       }\r
-\r
-    public static DraftStatusBean getDependencyDraftStatus(ReadGraph graph, Resource library) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(graph);\r
-        List<String> drafts = new ArrayList<>();\r
-        for (Resource shared : graph.syncRequest(new ObjectsWithType(library, L0.IsLinkedTo, L0.SharedOntology))) {\r
-            boolean published = Layer0Utils.isPublished(graph, shared);\r
-            if (!published)\r
-                drafts.add(graph.getURI(shared));\r
-        }\r
-        return drafts.isEmpty() ? null : new DraftStatusBean(drafts);\r
-    }\r
-\r
-       public static Set<Resource> getMostUnspecificTypes(final ReadGraph graph, Collection<Resource> types) throws DatabaseException {\r
-               \r
-               final Set<Resource> work = new HashSet<Resource>(types);\r
-               for(Resource type : types) {\r
-                       Set<Resource> supers = graph.getSupertypes(type);\r
-                       if(!Collections.disjoint(supers, work)) work.remove(type);\r
-               }\r
-\r
-               return work;\r
-               \r
-       }\r
-       \r
-       public static void rewriteGUIDS(WriteGraph graph, Resource root, boolean deep) throws DatabaseException {\r
-               List<Resource> todo = new ArrayList<Resource>();\r
-               todo.add(root);\r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               while(!todo.isEmpty()) {\r
-                       Resource resource = todo.remove(todo.size()-1);\r
-            graph.claimLiteral(resource, L0.identifier, L0.GUID, GUID.random(), GUID.BINDING);\r
-            if(deep)\r
-               todo.addAll(graph.getObjects(resource, L0.ConsistsOf));\r
-               }\r
-       }\r
-       \r
-       public static void createMissingGUIDs(IProgressMonitor monitor, WriteGraph graph, Collection<Resource> roots) throws DatabaseException {\r
-               \r
-       if(monitor == null) monitor = new NullProgressMonitor();\r
-       \r
-               Layer0 L0 = Layer0.getInstance(graph);\r
-               \r
-        // Allow this process to make 50k queries\r
-        QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000);\r
-\r
-               for(Resource root : roots) {\r
-                       \r
-                       boolean madeChanges = false;\r
-                       \r
-               monitor.setTaskName("Creating missing GUID identifiers " + NameUtils.getSafeName(graph, root));\r
-                       Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(root));\r
-                       for(Resource r : searchByType(graph, indexRoot, L0.Entity)) {\r
-\r
-                               memory.maintain();\r
-\r
-                               if(graph.isImmutable(r)) continue;\r
-\r
-                               if(!ModelingUtils.needsIdentifier(graph, r)) continue;\r
-                               \r
-                               GUID existing = graph.getPossibleRelatedValue(r, L0.identifier, GUID.BINDING);\r
-                               if(existing == null) {\r
-                                       graph.addLiteral(r, L0.identifier, L0.identifier_Inverse, L0.GUID, GUID.random(), GUID.BINDING);\r
-                                       madeChanges = true;\r
-                               }\r
-                               \r
-                       }\r
-                       \r
-                       if(madeChanges)\r
-                               ModelingUtils.deleteIndex(graph, root);\r
-                       \r
-               }\r
-               \r
-               \r
-       }\r
-       \r
-       public static boolean activateModel(WriteGraph graph, Resource model) throws DatabaseException {\r
-               return graph.syncRequest(new ActivateModel(Simantics.getProjectResource(), model));\r
-       }\r
-       \r
-       public static File fileDialog(String title, List<Tuple> namesAndExtensions) {\r
-               \r
-               Display display = Display.getCurrent();\r
-               Shell shell = display.getActiveShell();\r
-               \r
-        FileDialog dialog = new FileDialog(shell, SWT.OPEN);\r
-        dialog.setText(title);\r
-        \r
-        String[] extensions = new String[namesAndExtensions.size()];\r
-        String[] filterNames = new String[namesAndExtensions.size()];\r
-        int index = 0;\r
-        for(Tuple t : namesAndExtensions) {\r
-               String filterName = (String)t.get(0);\r
-               String extension = (String)t.get(1);\r
-               filterNames[index] = filterName;\r
-               extensions[index] = extension;\r
-        }\r
-        \r
-        dialog.setFilterExtensions(extensions);\r
-        dialog.setFilterNames(filterNames);\r
-        final String fileName = dialog.open();\r
-        if (fileName == null) return null;\r
-        \r
-        return new File(fileName);\r
-\r
-       }\r
-       \r
-       public static Resource createLibrary(WriteGraph graph, Resource parent) throws DatabaseException {\r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-        return createLibrary(graph, parent, NameUtils.findFreshName(graph, "Library", parent, l0.ConsistsOf));\r
-    }\r
-    \r
-    public static Resource createLibrary(WriteGraph graph, Resource parent, String name) throws DatabaseException {\r
-        graph.markUndoPoint();\r
-        Layer0 l0 = Layer0.getInstance(graph);\r
-\r
-        Resource library = graph.newResource();\r
-        graph.claim(library, l0.InstanceOf, null, l0.Library);\r
-        graph.addLiteral(library, l0.HasName, l0.NameOf, l0.String, name, Bindings.STRING);\r
-        graph.claim(library, l0.PartOf, parent);\r
-\r
-        Layer0Utils.addCommentMetadata(graph, "Created new Library named " + name + ", resource " + library);\r
-\r
-        return library;\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.modeling;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.WizardDialog;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.FileDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IWorkbenchWizard;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.wizards.IWizardDescriptor;
+import org.simantics.Simantics;
+import org.simantics.annotation.ontology.AnnotationResource;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.binding.Binding;
+import org.simantics.databoard.binding.mutable.Variant;
+import org.simantics.databoard.container.DataContainer;
+import org.simantics.databoard.container.DataContainers;
+import org.simantics.databoard.container.DataFormatException;
+import org.simantics.databoard.container.FormatHandler;
+import org.simantics.databoard.serialization.SerializationException;
+import org.simantics.databoard.type.Datatype;
+import org.simantics.databoard.util.URIStringUtils;
+import org.simantics.datatypes.literal.GUID;
+import org.simantics.db.MetadataI;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.RequestProcessor;
+import org.simantics.db.Resource;
+import org.simantics.db.Session;
+import org.simantics.db.Statement;
+import org.simantics.db.VirtualGraph;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.Indexing;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.QueryMemoryWatcher;
+import org.simantics.db.common.changeset.GenericChangeListener;
+import org.simantics.db.common.primitiverequest.IsInstanceOf;
+import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
+import org.simantics.db.common.procedure.adapter.TransientCacheListener;
+import org.simantics.db.common.request.IndexRoot;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.PossibleIndexRoot;
+import org.simantics.db.common.request.ReadRequest;
+import org.simantics.db.common.request.ResourceRead2;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.request.WriteResultRequest;
+import org.simantics.db.common.utils.ListUtils;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.utils.NameUtils;
+import org.simantics.db.common.utils.OrderedSetUtils;
+import org.simantics.db.common.utils.VersionInfo;
+import org.simantics.db.common.utils.VersionInfoRequest;
+import org.simantics.db.common.utils.Versions;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.layer0.QueryIndexUtils;
+import org.simantics.db.layer0.SelectionHints;
+import org.simantics.db.layer0.adapter.CopyHandler;
+import org.simantics.db.layer0.adapter.GenericRelationIndex;
+import org.simantics.db.layer0.adapter.Instances;
+import org.simantics.db.layer0.adapter.impl.DefaultPasteImportAdvisor;
+import org.simantics.db.layer0.adapter.impl.ImportAdvisorFactory;
+import org.simantics.db.layer0.genericrelation.DependenciesRelation.DependencyChangesRequest;
+import org.simantics.db.layer0.genericrelation.DependencyChanges;
+import org.simantics.db.layer0.genericrelation.IndexedRelations;
+import org.simantics.db.layer0.migration.MigratedImportResult;
+import org.simantics.db.layer0.migration.MigrationUtils;
+import org.simantics.db.layer0.request.ActivateModel;
+import org.simantics.db.layer0.request.ActiveModels;
+import org.simantics.db.layer0.request.Configuration;
+import org.simantics.db.layer0.request.IsLinkedTo;
+import org.simantics.db.layer0.request.PossibleModel;
+import org.simantics.db.layer0.util.ClipboardUtils;
+import org.simantics.db.layer0.util.DraftStatusBean;
+import org.simantics.db.layer0.util.ExternalDownloadBean;
+import org.simantics.db.layer0.util.Layer0Utils;
+import org.simantics.db.layer0.util.ModelTransferableGraphSourceRequest;
+import org.simantics.db.layer0.util.PasteEventHandler;
+import org.simantics.db.layer0.util.RemoverUtil;
+import org.simantics.db.layer0.util.SimanticsClipboard;
+import org.simantics.db.layer0.util.SimanticsClipboard.Representation;
+import org.simantics.db.layer0.util.SimanticsClipboardImpl;
+import org.simantics.db.layer0.util.SimanticsKeys;
+import org.simantics.db.layer0.util.TransferableGraphConfiguration2;
+import org.simantics.db.layer0.variable.Variable;
+import org.simantics.db.layer0.variable.Variables;
+import org.simantics.db.request.Read;
+import org.simantics.db.service.ClusterControl;
+import org.simantics.db.service.CollectionSupport;
+import org.simantics.db.service.GraphChangeListenerSupport;
+import org.simantics.db.service.QueryControl;
+import org.simantics.db.service.VirtualGraphSupport;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.diagram.stubs.G2DResource;
+import org.simantics.diagram.synchronization.graph.AddElement;
+import org.simantics.diagram.synchronization.graph.DiagramGraphUtil;
+import org.simantics.graph.db.IImportAdvisor2;
+import org.simantics.graph.db.ImportAdvisors;
+import org.simantics.graph.db.MissingDependencyException;
+import org.simantics.graph.db.StreamingTransferableGraphFileReader;
+import org.simantics.graph.db.TransferableGraphException;
+import org.simantics.graph.db.TransferableGraphSource;
+import org.simantics.graph.db.TransferableGraphs;
+import org.simantics.graph.representation.Identity;
+import org.simantics.graph.representation.Root;
+import org.simantics.graph.representation.TransferableGraph1;
+import org.simantics.graph.representation.TransferableGraphUtils;
+import org.simantics.issues.common.IssueSourceUtils;
+import org.simantics.issues.ontology.IssueResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.layer0.utils.direct.GraphUtils;
+import org.simantics.modeling.adapters.ChangeInformation;
+import org.simantics.modeling.template2d.ontology.Template2dResource;
+import org.simantics.modeling.utils.OntologicalRequirementTracker;
+import org.simantics.operation.Layer0X;
+import org.simantics.project.ontology.ProjectResource;
+import org.simantics.scenegraph.profile.ProfileUtils;
+import org.simantics.scl.runtime.function.Function1;
+import org.simantics.scl.runtime.tuple.Tuple;
+import org.simantics.simulation.ontology.SimulationResource;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.structural2.modelingRules.IModelingRules;
+import org.simantics.structural2.scl.StructuralComponent;
+import org.simantics.structural2.utils.StructuralUtils;
+import org.simantics.utils.ObjectUtils;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.datastructures.Triple;
+import org.simantics.utils.datastructures.hints.HintContext;
+import org.simantics.utils.ui.dialogs.ListDialog;
+
+/**
+ * @author Hannu Niemist&ouml;
+ */
+public class ModelingUtils {
+
+       private ReadGraph g;
+       private WriteGraph wg;
+       public Layer0 b;
+       private StructuralResource2 sr;
+       private DiagramResource dr;
+       public ModelingResources mr;
+       public SimulationResource SIMU;
+
+       public ModelingUtils(WriteGraph g) {
+               wg = g;
+               this.g = g;
+               b = Layer0.getInstance(g);
+               sr = StructuralResource2.getInstance(g);
+               dr = DiagramResource.getInstance(g);
+               mr = ModelingResources.getInstance(g);
+               SIMU = SimulationResource.getInstance(g);
+       }
+
+       @Deprecated
+       public Resource createSymbol2(String name) throws DatabaseException {
+               return createSymbol2(name, dr.Composite);
+       }
+
+       @Deprecated
+       public Resource createSymbol2(String name, Resource diagramType) throws DatabaseException {
+           return createSymbol2(name, diagramType, dr.DefinedElement);
+       }
+       @Deprecated
+       public Resource createSymbol2(String name, Resource diagramType, Resource symbolType) throws DatabaseException {
+               G2DResource g2d = G2DResource.getInstance(g);
+
+//             Resource visibleTag = wg.newResource();
+//             wg.claim(visibleTag, b.SubrelationOf, null, dr.IsVisible);
+//             Resource focusableTag = wg.newResource();
+//             wg.claim(focusableTag, b.SubrelationOf, null, dr.IsFocusable);
+
+               Double boxDimension = 6.0;
+               Collection<Statement> grid = g.getAssertedStatements(diagramType, dr.HasGridSize);
+               if(grid.size() == 1) {
+                       Double d = g.getPossibleValue(grid.iterator().next().getObject(), Bindings.DOUBLE);
+                       if(d != null) boxDimension = 2*d;
+               }
+
+
+               Resource element  = GraphUtils.create(wg,
+                               b.InstanceOf, dr.SVGElement,
+                               g2d.HasSVGDocument,
+                               "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>" +
+                                               // REMOVED by Tuukka, because This will cause
+                                               // parsers to get on the net and get the doctype
+                                               // definitions which can stall the UI for a long time.
+                                               // Besides, we're not using the validation for anything
+                                               // so it's useless to us.
+                                               //"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" +
+                                               "<svg xmlns=\"http://www.w3.org/2000/svg\" overflow=\"visible\" version=\"1.1\">" +
+                                               "<rect x=\"-" + boxDimension + "\" y=\"-" + boxDimension + "\" width=\"" + (2*boxDimension) + "\" height=\"" + (2*boxDimension) + "\" fill=\"none\" stroke=\"rgb(0,0,0)\" stroke-width=\"0.1\"/>" +
+                                               "</svg>"
+                               );
+
+//             wg.claim(element, visibleTag, element);
+//             wg.claim(element, focusableTag, element);
+
+               Resource orderedSet = OrderedSetUtils.create(wg, diagramType, element);
+
+//             wg.claim(orderedSet, dr.HasLayer, GraphUtils.create2(wg, dr.Layer,
+//                             b.HasName, "Default",
+//                             dr.IsActive, Boolean.TRUE,
+//                             dr.HasVisibleTag, visibleTag,
+//                             dr.HasFocusableTag, focusableTag));
+
+               Resource result = GraphUtils.create(wg,
+                               b.HasName, name,
+                               b.HasLabel, "",
+                               sr.IsDefinedBy, orderedSet);
+
+               wg.claim(result, b.ConsistsOf, orderedSet);
+               wg.claimLiteral(orderedSet, b.HasName, "__DIAGRAM__", Bindings.STRING);
+               AddElement.claimFreshElementName(wg, orderedSet, element);
+               wg.claim(orderedSet, b.ConsistsOf, element);
+
+               wg.claim(result, b.Inherits, null, symbolType);
+               return result;
+       }
+
+       public static Collection<Resource> getElementCorrespondendences(ReadGraph g, Resource element) throws DatabaseException {
+               DiagramResource dr = DiagramResource.getInstance(g);
+               ModelingResources mr = ModelingResources.getInstance(g);
+               if(g.isInstanceOf(element, dr.Connection)) {
+                       Resource mappedComponent = g.getPossibleObject(element, mr.ElementToComponent);
+                       if(mappedComponent != null) return Collections.singletonList(mappedComponent);
+                       Resource mappedConnection = g.getPossibleObject(element, mr.DiagramConnectionToConnection);
+                       if(mappedConnection == null)
+                               return Collections.emptyList();
+                       ArrayList<Resource> result = new ArrayList<Resource>();
+                       Collection<Resource> relatedMappedConnections = StructuralUtils.getRelatedConnections(g, mappedConnection);
+                       for(Resource relatedMappedConnection : relatedMappedConnections)
+                               for(Resource relatedConnection : g.getObjects(relatedMappedConnection, mr.ConnectionToDiagramConnection))
+                                       result.addAll(g.getObjects(relatedConnection, mr.ElementToComponent));
+                       return result;
+               }
+               else
+                       return g.getObjects(element, mr.ElementToComponent);
+       }
+
+       public static Resource getPossibleElement(ReadGraph g, Resource component) throws DatabaseException {
+               ModelingResources mr = ModelingResources.getInstance(g);
+               return g.getPossibleObject(component, mr.ComponentToElement);
+       }
+
+       public static Resource getPossibleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {
+               Collection<Resource> corrs = getElementCorrespondendences(g, element);
+               if(corrs.size() != 1) return null;
+               else return corrs.iterator().next();
+       }
+
+       public static Resource getSingleElementCorrespondendence(ReadGraph g, Resource element) throws DatabaseException {
+               Collection<Resource> corrs = getElementCorrespondendences(g, element);
+               if(corrs.size() != 1) throw new DatabaseException("Expected 1 element correspondence, got " + corrs.size());
+               else return corrs.iterator().next();
+       }
+
+       public static Resource createExperiment(WriteGraph graph, Resource model) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               SimulationResource SIMU = SimulationResource.getInstance(graph);
+               Resource experiment = graph.newResource();
+               graph.claim(experiment, L0.InstanceOf, SIMU.Experiment);
+               graph.claimLiteral(experiment, L0.HasName, "Experiment");
+               graph.claim(model, L0.ConsistsOf, experiment);
+               return experiment;
+
+       }
+
+       public static Resource createModel(WriteGraph graph, Resource type) throws DatabaseException {
+               return createModel(graph, type, Simantics.getProjectResource(), null);
+       }
+               
+       public static Resource createModel(WriteGraph graph, Resource type, String name) throws DatabaseException {
+               return createModel(graph, type, Simantics.getProjectResource(), name);
+       }
+
+       public static Resource createModel(WriteGraph graph, Resource type, final Resource target, String name) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               SimulationResource SIMU = SimulationResource.getInstance(graph);
+               StructuralResource2 STR = StructuralResource2.getInstance(graph);
+               ModelingResources MOD = ModelingResources.getInstance(graph);
+
+               if(name == null)
+                       name = NameUtils.findFreshName(graph, "Model", target, L0.ConsistsOf, "%s%d");
+
+               final Resource model = graph.newResource();
+               graph.newClusterSet(model);
+               graph.claim(model, L0.InstanceOf, null, type);
+               graph.claimLiteral(model, L0.HasName, name);
+
+               graph.claim(target, L0.ConsistsOf, model);
+
+               Resource configurationType = graph.getPossibleObject(model, MOD.StructuralModel_HasConfigurationType);
+               if(configurationType == null) configurationType = STR.Composite;
+
+               Resource configuration = graph.newResource();
+               graph.claimLiteral(configuration, L0.HasName, "Configuration", Bindings.STRING);
+               graph.claim(configuration, L0.InstanceOf, null, configurationType);
+               graph.claim(model, L0.ConsistsOf, configuration);
+               graph.claim(model, SIMU.HasConfiguration, configuration);
+
+               Resource joinClusterSet = graph.newResource();
+               graph.newClusterSet(joinClusterSet);
+               graph.claim(joinClusterSet, L0.InstanceOf, L0.ClusterSet);
+               graph.claim(model, STR.HasJoinClusterSet, joinClusterSet);
+
+               linkOntologyDependenciesToModel(graph, model, target);
+               
+               Resource ontology = graph.syncRequest(new PossibleIndexRoot(type));
+               if(ontology != null) {
+                       graph.claim(model, L0.IsLinkedTo, ontology);
+               }
+
+               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
+               graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("activations")) {
+
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+                               Layer0X L0X = Layer0X.getInstance(graph);
+                               Collection<Resource> actives = graph.syncRequest(new ActiveModels(target));
+                               if(actives.isEmpty()) {
+                                       graph.claim(model,  L0X.IsActivatedBy, target);
+                               }
+                       }
+
+               });
+
+               return model;
+
+       }
+       
+       public static void linkOntologyDependenciesToModel(WriteGraph graph, Resource model, Resource target) 
+                       throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               ProjectResource PROJ = ProjectResource.getInstance(graph);
+               for(Resource dep : graph.getObjects(target, L0.IsLinkedTo)) {
+                       if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {
+                               for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {
+                                       String uri = graph.getPossibleValue(req, Bindings.STRING);
+                                       if(uri != null) {
+                                               Resource ns = graph.getResource(uri);
+                                               if(ns != null) {
+                                                       graph.claim(model, L0.IsLinkedTo, null, ns);
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+       
+       public static void addSCLMainToModel(WriteGraph graph, Resource model) 
+                       throws DatabaseException {
+               addSCLMainToModel(graph, model, "SCLMain", "include \"Simantics/All\"\n");
+       }
+       
+       public static void addSCLMainToModel(WriteGraph graph, Resource model, String name, String contents) 
+                       throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+        Resource sclmain = GraphUtils.create2(graph, L0.SCLModule, L0.PartOf, model, L0.HasName, name);
+        graph.claimLiteral(sclmain, L0.SCLModule_definition, contents, Bindings.STRING);
+       }
+
+    public static Resource createLocalLibrary(WriteGraph graph, Resource container, String name) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        Resource library = graph.newResource();
+        graph.claim(library, L0.InstanceOf, null, L0.Library);
+        graph.addLiteral(library, L0.HasName, L0.NameOf, "Library", Bindings.STRING);
+        if (container != null) {
+            graph.claim(container, L0.ConsistsOf, L0.PartOf, library);
+            graph.claim(container, MOD.HasLocalLibrary, MOD.IsLocalLibraryOf, library);
+        }
+        return library;
+    }
+
+       public static void importModel(String fileName) {
+
+               Resource project = Simantics.getProject().get();
+
+               try (StreamingTransferableGraphFileReader importer = new StreamingTransferableGraphFileReader(new File(fileName))) {
+                       TransferableGraphSource tg = importer.readTG();
+
+                       final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(project) {
+                               @Override
+                               public void analyzeType(ReadGraph graph, Root root) throws DatabaseException {
+                               }
+                               @Override
+                               public Resource analyzeRoot(ReadGraph graph, Root root) throws DatabaseException {
+                                       library = Simantics.getProjectResource();
+                                       String newName = newName(graph, library, root.name);
+                                       nameMappings.put(root.name, newName);
+                                       return null;
+                               }
+                       };
+                       TransferableGraphs.importGraph1(Simantics.getSession(), tg, advisor);
+
+               } catch (MissingDependencyException e) {
+
+                       final Set<String> missingURIs = e.getMissingURIs();
+
+                       class ErrorMessageDialog extends MessageDialog {
+
+                               public ErrorMessageDialog(Shell shell) {
+                                       super(shell, 
+                                                       "Unsatisfied dependencies", null, 
+                                                       "The following dependencies were missing. Please import the dependencies and try again.", 
+                                                       MessageDialog.ERROR, new String[] { "Continue" }, 0);
+                               }
+
+                               @Override
+                               protected Control createCustomArea(Composite composite) {
+                                       GridLayoutFactory.fillDefaults().applyTo(composite);
+                                       
+                                       org.eclipse.swt.widgets.List list = new org.eclipse.swt.widgets.List(composite, SWT.BORDER | SWT.READ_ONLY);
+                                       GridDataFactory.fillDefaults().grab(true, true).applyTo(list);
+                                       for(String s : missingURIs) list.add(s);
+                                       return composite;
+                               }
+
+                       }
+
+                       Display display = Display.getCurrent();
+                       if(display != null) {
+                               ErrorMessageDialog md = new ErrorMessageDialog(display.getActiveShell());
+                               md.open();
+                       } else {
+                               Display.getDefault().asyncExec(new Runnable() {
+
+                                       @Override
+                                       public void run() {
+                                               Shell shell = Display.getCurrent().getActiveShell();
+                                               ErrorMessageDialog md = new ErrorMessageDialog(shell);
+                                               md.open();
+                                       }
+                                       
+                               });
+                       }
+                       
+
+               } catch (Exception e) {
+                       Logger.defaultLogError(e);
+               }
+
+       }
+
+       public static void primeVirtualGraphs() {
+               VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);
+               support.getWorkspacePersistent("activations");
+               support.getWorkspacePersistent("experiments");
+               support.getWorkspacePersistent("issues");
+               support.getWorkspacePersistent("preferences");
+       }
+
+       public static Resource createProfileEntry(WriteGraph graph, String name, Resource style, Resource group) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               DiagramResource DIA = DiagramResource.getInstance(graph);
+
+               Resource entry = graph.newResource();
+               graph.claim(entry, L0.InstanceOf, null, DIA.GroupStyleProfileEntry);
+               graph.claimLiteral(entry, L0.HasName, name);
+               graph.claimLiteral(entry, L0.HasLabel, name);
+               graph.claim(entry, DIA.ProfileEntry_HasStyle, style);
+               graph.claim(entry, DIA.ProfileEntry_HasGroup, group);
+
+               return entry;
+
+       }
+
+       public static Resource createProfile(WriteGraph graph, String profileName, Resource... entries) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               DiagramResource DIA = DiagramResource.getInstance(graph);
+
+               Resource list = ListUtils.create(graph, DIA.Profile, entries);
+
+               Resource profile = graph.newResource();
+               graph.claim(profile, L0.InstanceOf, null, DIA.Profile);
+               graph.claimLiteral(profile, L0.HasName, profileName);
+               graph.claim(profile, DIA.HasEntries, null, list);
+
+               return profile;
+
+       }
+       
+       public static Resource createProfile(WriteGraph graph, String profileName, Collection<Resource> entries) throws DatabaseException {
+           return createProfile(graph, profileName, entries.toArray(new Resource[entries.size()]));
+       }
+
+       public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Resource ... profiles) throws DatabaseException {
+
+               Resource work = createProfile(graph, name, profiles);
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               DiagramResource DIA = DiagramResource.getInstance(graph);
+
+               graph.deny(model, DIA.HasActiveProfile);
+               graph.claim(model, DIA.HasActiveProfile, work);
+               graph.claim(model, L0.ConsistsOf, L0.PartOf, work);
+
+               return work;
+
+       }
+       
+       public static Resource createToplevelProfile(WriteGraph graph, Resource model, String name, Collection<Resource> profiles) throws DatabaseException {
+           return createToplevelProfile(graph, model, name, profiles.toArray(new Resource[profiles.size()]));
+       }
+
+       public static void activateProfileEntries(WriteGraph graph, final Resource profile, final Resource ... entries) {
+
+               VirtualGraphSupport support = graph.getService(VirtualGraphSupport.class);
+               graph.asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {
+
+                       @Override
+                       public void perform(WriteGraph graph) throws DatabaseException {
+                               SimulationResource SIMU = SimulationResource.getInstance(graph);
+                               for(Resource entry : entries)
+                                       graph.claim(profile, SIMU.IsActive, entry);
+                       }
+
+               });
+
+       }
+       
+       public static void activateProfileEntries(WriteGraph graph, Resource profile, Collection<Resource> entries) {
+           activateProfileEntries(graph, profile, entries.toArray(new Resource[entries.size()]));
+       }
+       
+       public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, String groupName, boolean enabled) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               for (Resource group : ProfileUtils.getProfileChildren(graph, runtimeProfile)) {
+                       String name = graph.getRelatedValue2(group, L0.HasName);
+                       if (name.equals(groupName)) {
+                               toggleProfileGroup(graph, runtimeProfile, group, enabled);
+                               return;
+                       }
+               }
+       }
+       
+       public static void toggleProfileGroup(WriteGraph graph, Resource runtimeProfile, Resource group, boolean enabled) throws DatabaseException {
+       DiagramResource DIA = DiagramResource.getInstance(graph);
+               
+       if(graph.isInstanceOf(group, DIA.Profile)) {
+               
+               for(Resource child : ProfileUtils.getProfileChildren(graph, group)) {
+                       toggleProfileGroup(graph, runtimeProfile, child, enabled);
+               }
+               
+       } else if(graph.isInstanceOf(group, DIA.ProfileEntry)) {
+
+            if(enabled) {
+                graph.claim(runtimeProfile, SimulationResource.getInstance(graph).IsActive, null, group);
+            } else {
+                graph.denyStatement(runtimeProfile, SimulationResource.getInstance(graph).IsActive, group);
+            }
+
+               }
+       }
+
+    public static void untrackDependencies() {
+       untrackDependencies(Simantics.getSession());
+    }
+
+       public static void untrackDependencies(RequestProcessor processor) {
+        
+        try {
+            processor.syncRequest(new ReadRequest() {
+
+                @Override
+                public void run(ReadGraph graph) throws DatabaseException {
+                    Layer0X L0X = Layer0X.getInstance(graph);
+                    GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);
+                    index.untrack(graph.getSession(), graph.getRootLibrary());
+                }
+                
+            });
+        } catch (DatabaseException e) {
+            Logger.defaultLogError(e);
+        }
+
+    }
+
+    public static void trackDependencies() {
+       trackDependencies(Simantics.getSession());
+    }
+
+       public static void trackDependencies(RequestProcessor processor) {
+           
+           try {
+            processor.syncRequest(new ReadRequest() {
+
+                @Override
+                public void run(ReadGraph graph) throws DatabaseException {
+                    Layer0X L0X = Layer0X.getInstance(graph);
+                    GenericRelationIndex index = graph.adapt(L0X.DependenciesRelation, GenericRelationIndex.class);
+                    index.trackAndIndex(graph.getSession(), graph.getRootLibrary());
+                }
+                
+            });
+        } catch (DatabaseException e) {
+            Logger.defaultLogError(e);
+        }
+
+       }
+
+    public static void trackOntologicalRequirements() {
+        Session session = Simantics.getSession();
+        GraphChangeListenerSupport changeListenerSupport = session.getService(GraphChangeListenerSupport.class);
+        changeListenerSupport.addMetadataListener( OntologicalRequirementListener.getInstance() );
+    }
+
+    public static void untrackOntologicalRequirements() {
+        Session session = Simantics.getSession();
+        GraphChangeListenerSupport changeListenerSupport = session.getService(GraphChangeListenerSupport.class);
+        changeListenerSupport.removeMetadataListener( OntologicalRequirementListener.getInstance() );
+    }
+
+    public static class OntologicalRequirementListener extends GenericChangeListener<DependencyChangesRequest, DependencyChanges> {
+
+        private static OntologicalRequirementListener INSTANCE;
+
+        public static OntologicalRequirementListener getInstance() {
+            if(INSTANCE == null) {
+                INSTANCE = new OntologicalRequirementListener();
+            }
+            return INSTANCE;
+        }
+
+        private OntologicalRequirementListener() {
+        }
+
+        private OntologicalRequirementTracker changeInformationUpdater = new OntologicalRequirementTracker();
+
+        @Override
+        public boolean preEventRequest() {
+            return !Indexing.isDependenciesIndexingDisabled();
+        }
+
+        @Override
+        public void onEvent(ReadGraph graph, MetadataI metadata, DependencyChanges event) throws DatabaseException {
+            changeInformationUpdater.update(graph, metadata, event);
+        }
+
+    }
+
+    public static void removeIndex(WriteGraph graph, Resource model) throws DatabaseException {
+        Layer0X L0X = Layer0X.getInstance(graph);
+        IndexedRelations ir = graph.getService(IndexedRelations.class);
+        // Deletes index files
+        ir.reset(null, graph, L0X.DependenciesRelation, model);
+    }
+    
+    public static void resetIssueSources(WriteGraph graph, Resource model) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        IssueResource ISSUE = IssueResource.getInstance(graph);
+        for(Resource source : graph.sync(new ObjectsWithType(model, L0.ConsistsOf, ISSUE.ContinuousIssueSource))) {
+            IssueSourceUtils.update(graph, source);
+        }
+    }
+    
+    public static void copyAnnotationTypes(WriteGraph graph, Resource sourceModel, Resource targetModel) throws DatabaseException {
+
+        Layer0 L0 = Layer0.getInstance(graph);
+        AnnotationResource ANNO = AnnotationResource.getInstance(graph);
+
+        Instances query = graph.adapt(ANNO.AnnotationType, Instances.class);
+
+        Resource library = graph.getPossibleObject(targetModel, ANNO.HasAnnotationTypeRoot);
+        // HAXX:
+        if(library == null) {
+            library = graph.newResource();
+            graph.claim(library, L0.InstanceOf, null, ANNO.AnnotationTypeLibrary);
+            graph.claimLiteral(library, L0.HasName, L0.NameOf, L0.String, "Annotation types", Bindings.STRING);
+            graph.claim(library, L0.PartOf, L0.ConsistsOf, targetModel);
+            graph.claim(targetModel, ANNO.HasAnnotationTypeRoot, library);
+        }
+
+        for(Resource type : query.find(graph, sourceModel)) {
+            String name = graph.getRelatedValue(type, L0.HasName);
+            Resource existing = Layer0Utils.getPossibleChild(graph, library, name);
+            if(existing != null) {
+                RemoverUtil.remove(graph, existing);
+            }
+            Layer0Utils.copyTo(graph, library, type);
+        }
+
+    }
+    
+       public static void deleteIndex(WriteGraph graph, Resource model) throws DatabaseException {
+               Layer0X L0X = Layer0X.getInstance(graph);
+               IndexedRelations ir = graph.getService(IndexedRelations.class);
+               // Deletes index files
+               ir.reset(null, graph, L0X.DependenciesRelation, model);
+       }
+    
+       public static void disableDependencies(WriteGraph graph, Resource dummy) {
+               Layer0Utils.setDependenciesIndexingDisabled(graph, true);               
+       }
+
+    public static void releaseMemory(WriteGraph graph) {
+       
+               QueryControl qc = graph.getService(QueryControl.class);
+               ClusterControl cc = graph.getService(ClusterControl.class);
+               cc.flushClusters();
+               qc.flush(graph);
+       
+    }
+
+    public static List<Resource> filterByIndexRoot(ReadGraph graph, Resource indexRoot, List<Resource> resources) throws DatabaseException {
+        ArrayList<Resource> result =  new ArrayList<Resource>(resources.size());
+        for (Resource r : resources) {
+            Resource root = graph.syncRequest(new PossibleIndexRoot(r));
+            if (indexRoot.equals(root))
+                result.add(r);
+        }
+        return result;
+    }
+
+    @Deprecated
+    public static List<Resource> searchByTypeShallow(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
+        return QueryIndexUtils.searchByTypeShallow(graph, model, type);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByType(ReadGraph graph, Resource model, Resource type) throws DatabaseException {
+        return QueryIndexUtils.searchByType(graph, model, type);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, GUID guid) throws DatabaseException {
+        return QueryIndexUtils.searchByGUID(graph, indexRoot, guid);
+    }
+    
+    @Deprecated
+    public static List<Resource> searchByGUID(ReadGraph graph, Resource indexRoot, String indexString) throws DatabaseException {
+        return QueryIndexUtils.searchByGUID(graph, indexRoot, indexString);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByQueryShallow(ReadGraph graph, Resource model, String query) throws DatabaseException {
+        return QueryIndexUtils.searchByQueryShallow(graph, model, query);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByQuery(ReadGraph graph, Resource model, String query) throws DatabaseException {
+        return QueryIndexUtils.searchByQuery(graph, model, query);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByTypeAndFilter(ReadGraph graph, Resource model, Resource type, Function1<Resource,Boolean> filter) throws DatabaseException {
+        return QueryIndexUtils.searchByTypeAndFilter(graph, model, type, filter);
+    }
+
+    @Deprecated
+    public static List<Triple<Resource, Resource, String>> getIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {
+        return QueryIndexUtils.getIndexEntries(graph, model, filter);
+    }
+
+    @Deprecated
+    public static String listIndexEntries(ReadGraph graph, Resource model, String filter) throws DatabaseException {
+        return QueryIndexUtils.listIndexEntries(graph, model, filter);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByTypeAndName(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
+        return QueryIndexUtils.searchByTypeAndName(graph, model, type, name);
+    }
+
+    @Deprecated
+    public static List<Resource> searchByTypeAndNameShallow(ReadGraph graph, Resource model, Resource type, String name) throws DatabaseException {
+        return QueryIndexUtils.searchByTypeAndNameShallow(graph, model, type, name);
+    }
+
+       /**
+        * @param graph
+        *            database write access
+        * @param sourceContainer
+        *            the source container to look for annotationProperty from to be
+        *            used as the copy source
+        * @param targetContainer
+        *            the target container for the copied annotationProperty
+        *            annotation
+        * @param annotationProperty
+        *            the annotation property relation
+        * @return created copy of the original annotation or <code>null</code> if
+        *         there was nothing to copy
+        * @throws DatabaseException
+        */
+       public static Resource copyPossibleAnnotation(WriteGraph graph, Resource sourceContainer, Resource targetContainer, Resource annotationProperty) throws DatabaseException {
+               return copyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, null);
+       }
+
+       public static List<String> getPossibleNamePath(ReadGraph graph, Resource resource) throws DatabaseException {
+               return getPossibleNamePath(graph, resource, null);
+       }
+        
+       private static List<String> getPossibleNamePath(ReadGraph graph, Resource resource, List<String> result) throws DatabaseException {
+               
+               Layer0 L0 = Layer0.getInstance(graph);
+               String name = graph.getPossibleRelatedValue(resource, L0.HasName, Bindings.STRING);
+               if(name == null) return null;
+
+               if(result == null) result = new ArrayList<String>();
+               
+               SimulationResource SIMU = SimulationResource.getInstance(graph);
+               if(graph.isInstanceOf(resource, SIMU.Model)) return result;
+               
+               Resource parent = graph.getPossibleObject(resource, L0.PartOf);
+               if(parent != null) {
+                       getPossibleNamePath(graph, parent, result);
+               } else {
+                       return null;
+               }
+
+               result.add(name);
+               
+               return result;
+
+       }
+       
+       public static Resource claimLibraryPath(WriteGraph graph, Resource resource, List<String> path) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               for(int i=0;i<path.size()-1;i++) {
+                       String p = path.get(i);
+                       Resource child = Layer0Utils.getPossibleChild(graph, resource, p);
+                       if(child == null) {
+                               child = graph.newResource();
+                               graph.claim(child, L0.InstanceOf, L0.Library);
+                               graph.addLiteral(child, L0.HasName, L0.NameOf, L0.String, p, Bindings.STRING);
+                               graph.claim(resource, L0.ConsistsOf, L0.PartOf, child);
+                       }
+                       resource = child;
+               }
+               return resource;
+       }
+       
+       /**
+        * @param graph
+        *            database write access
+        * @param sourceContainer
+        *            the source container to look for annotationProperty from to be
+        *            used as the copy source
+        * @param targetContainer
+        *            the target container for the copied annotationProperty
+        *            annotation
+        * @param annotationProperty
+        *            the annotation property relation
+        * @param annotationProperty
+        *            the 2nd level annotation property relation or
+        *            <code>null</code> if no 2nd level annotation exists
+        * @return created copy of the original annotation or <code>null</code> if
+        *         there was nothing to copy
+        * @throws DatabaseException
+        */
+       public static Resource copyPossibleAnnotation2(WriteGraph graph,
+                       Resource sourceContainer, Resource targetContainer,
+                       Resource annotationProperty, Resource entryType) throws DatabaseException {
+
+               // Delete existing target value first
+               Layer0 L0 = Layer0.getInstance(graph);
+               Resource targetValue = graph.getPossibleObject(targetContainer, annotationProperty);
+               if (targetValue != null) {
+                       if(!graph.hasStatement(targetValue, L0.PartOf))
+                               RemoverUtil.remove(graph, targetValue);
+                       graph.deny(targetContainer, annotationProperty);
+               }
+
+               Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);
+               if (sourceValue == null)
+                       return null;
+               
+               List<String> sourceValuePath = getPossibleNamePath(graph, sourceValue);
+               if(sourceValuePath != null) {
+                       Resource targetModel = graph.sync(new PossibleModel(targetContainer));
+                       if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);
+                       Resource library = claimLibraryPath(graph, targetModel, sourceValuePath);
+                       Resource existing = Layer0Utils.getPossibleChild(graph, library, sourceValuePath.get(sourceValuePath.size()-1));
+                       if(existing == null) {
+                               existing = doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);
+                               graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);
+                       }
+                       graph.claim(targetContainer, annotationProperty, existing);
+                       return existing;
+               } else {
+                       return doCopyPossibleAnnotation2(graph, sourceContainer, targetContainer, annotationProperty, entryType);
+               }
+
+       }
+
+       private static Resource doCopyPossibleAnnotation2(WriteGraph graph,
+                       Resource sourceContainer, Resource targetContainer,
+                       Resource annotationProperty, Resource entryType) throws DatabaseException {
+
+               Resource sourceValue = graph.getPossibleObject(sourceContainer, annotationProperty);
+               if (sourceValue == null)
+                       return null;
+               
+               // Copy 1st level annotation
+               Resource targetValue = createAnnotation(graph, targetContainer, annotationProperty, sourceValue);
+
+               // Copy possible 2nd level annotations and attach to 1st if entry
+               // property is defined.
+               Layer0 L0 = Layer0.getInstance(graph);
+               if (entryType != null) {
+                       
+                       AnnotationResource ANNO = AnnotationResource.getInstance(graph);
+                       for (Resource entry : graph.getObjects(sourceValue, ANNO.Annotation_HasEntry)) {
+
+                               String name = graph.getRelatedValue(entry, L0.HasName, Bindings.STRING);
+
+                               List<String> entryPath = getPossibleNamePath(graph, entry);
+                               if(entryPath != null) {
+                                       Resource targetModel = graph.sync(new PossibleModel(targetContainer));
+                                       if(targetModel == null) throw new DatabaseException("No target model found for " + targetContainer);
+                                       Resource library = claimLibraryPath(graph, targetModel, entryPath);
+                                       Resource existing = Layer0Utils.getPossibleChild(graph, library, entryPath.get(entryPath.size()-1));
+                                       if(existing == null) {
+                                               existing = createTypedAnnotation(graph, null, null, entry, entryType, name);
+                                               graph.claim(library, L0.ConsistsOf, L0.PartOf, existing);
+                                       }
+                                       graph.claim(targetValue, ANNO.Annotation_HasEntry, existing);
+                               } else {
+                                       Resource result = createTypedAnnotation(graph, null, null, entry, entryType, name);
+                                       graph.claim(targetValue, ANNO.Annotation_HasEntry, result);
+                               }
+                               
+                       }
+               }
+
+               return targetValue;
+
+       }
+
+       /**
+        * @param graph
+        *            database write access
+        * @param container
+        *            the container resource to attach the new annotation to
+        * @param property
+        *            the annotation property relation. The type of the created
+        *            annotation is decided from this property relation's range
+        * @param sourceAnnotation
+        *            the annotation to copy data from or <code>null</code> if
+        *            nothing shall be copied
+        * @return the newly created annotation resource or <code>null</code> if the
+        *         annotation property relation didn't have a single range type
+        * @throws DatabaseException
+        */
+       public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation) throws DatabaseException {
+               return createAnnotation(graph, container, property, sourceAnnotation, null);
+       }
+
+       /**
+        * @param graph
+        *            database write access
+        * @param container
+        *            the container resource to attach the new annotation to
+        * @param property
+        *            the annotation property relation. The type of the created
+        *            annotation is decided from this property relation's range
+        * @param sourceAnnotation
+        *            the annotation to copy data from or <code>null</code> if
+        *            nothing shall be copied
+        * @param name
+        *            name for newly created annotation or <code>null</code> to copy
+        *            name from source if available
+        * @return the newly created annotation resource or <code>null</code> if the
+        *         annotation property relation didn't have a single range type
+        * @throws DatabaseException
+        */
+       public static Resource createAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, String name) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               Resource annotationType = graph.getSingleObject(property, L0.HasRange);
+               if (annotationType == null)
+                       return null;
+
+               return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, name);
+
+       }
+
+       /**
+        * @param graph
+        *            database write access
+        * @param container
+        *            the container resource to attach the new annotation to
+        * @param property
+        *            the annotation property relation
+        * @param sourceAnnotation
+        *            the annotation to copy data from or <code>null</code> if
+        *            nothing shall be copied
+        * @param annotationType
+        *            the type of the new annotation
+        * @return the newly created annotation resource
+        * @throws DatabaseException
+        */
+       public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType) throws DatabaseException {
+               return createTypedAnnotation(graph, container, property, sourceAnnotation, annotationType, null);
+       }
+
+       /**
+        * @param graph
+        *            database write access
+        * @param container
+        *            the container resource to attach the new annotation to
+        * @param property
+        *            the annotation property relation
+        * @param sourceAnnotation
+        *            the annotation to copy data from or <code>null</code> if
+        *            nothing shall be copied
+        * @param annotationType
+        *            the type of the new annotation
+        * @param name
+        *            name for newly created annotation or <code>null</code> to copy
+        *            name from source if available
+        * @return the newly created annotation resource
+        * @throws DatabaseException
+        */
+       public static Resource createTypedAnnotation(WriteGraph graph, Resource container, Resource property, Resource sourceAnnotation, Resource annotationType, String name) throws DatabaseException {
+
+               Layer0 L0 = Layer0.getInstance(graph);
+
+               Resource anno = graph.newResource();
+
+               graph.claim(anno, L0.InstanceOf, null, annotationType);
+
+               if (name != null)
+                       graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, name, Bindings.STRING);
+
+               if (sourceAnnotation != null) {
+
+                       if (name == null) {
+                               String sourceName = graph.getPossibleRelatedValue(sourceAnnotation, L0.HasName, Bindings.STRING);
+                               if(sourceName != null) graph.addLiteral(anno, L0.HasName, L0.NameOf, L0.String, sourceName, Bindings.STRING);
+                       }
+
+                       Resource sourceType = graph.getSingleType(sourceAnnotation);
+                       List<AnnotationMap> am = getAnnotationMap(graph, annotationType, sourceType);
+                       for (AnnotationMap a : am) {
+                               Resource object = graph.getSingleObject(sourceAnnotation, a.sourcePredicate);
+                               Collection<Resource> objectTypes = graph.getTypes(object);
+                               if (objectTypes.contains(L0.Literal)) {
+                                       Object value = graph.getValue(object, a.defaultValueBinding);
+                                       if (!ObjectUtils.objectEquals(value, a.defaultValue)) {
+                                               graph.addLiteral(anno, a.annotationPredicate, a.annotationPredicateInverse, a.defaultValueType, value, a.defaultValueBinding);
+                                       }
+                               }
+                       }
+               }
+
+               if (container != null && property != null) {
+                       graph.claim(container, property, anno);
+               }
+
+               return anno;
+
+       }
+
+       private static class AnnotationMap {
+
+               final public Resource sourcePredicate;
+               final public Resource sourcePredicateInverse;
+
+               final public Resource annotationPredicate;
+               final public Resource annotationPredicateInverse;
+
+               final public Resource defaultValueType;
+               final public Object defaultValue;
+               final public Binding defaultValueBinding;
+
+               public AnnotationMap(Resource sp, Resource spi, Resource tp, Resource tpi, Resource defaultValueType, Object defaultValue, Binding defaultValueBinding) {
+                       sourcePredicate = sp;
+                       sourcePredicateInverse = spi;
+                       annotationPredicate = tp;
+                       annotationPredicateInverse = tpi;
+                       this.defaultValueType = defaultValueType;
+                       this.defaultValue = defaultValue;
+                       this.defaultValueBinding = defaultValueBinding;
+               }
+
+       }
+
+       public static List<AnnotationMap> getAnnotationMap(ReadGraph graph, Resource annotationType, Resource sourceType) throws DatabaseException {
+               return graph.syncRequest(new AnnotationMapRequest(annotationType, sourceType), TransientCacheListener.<List<AnnotationMap>>instance());
+       }
+
+       static class AnnotationMapRequest extends ResourceRead2<List<AnnotationMap>> {
+
+               public AnnotationMapRequest(Resource annotationType, Resource sourceType) {
+                       super(annotationType, sourceType);
+               }
+
+               @Override
+               public List<AnnotationMap> perform(ReadGraph graph) throws DatabaseException {
+
+                       Layer0 L0 = Layer0.getInstance(graph);
+
+                       ArrayList<AnnotationMap> result = new ArrayList<AnnotationMap>(); 
+
+                       Map<String, Resource> annotationPredicates = new HashMap<String, Resource>();
+                       for(Resource predicate : graph.getObjects(resource, L0.DomainOf)) {
+                               String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);
+                               annotationPredicates.put(name, predicate);
+                       }
+                       Map<String, Resource> sourcePredicates = new HashMap<String, Resource>();
+                       for(Resource predicate : graph.getObjects(resource2, L0.DomainOf)) {
+                               String name = graph.getRelatedValue(predicate, L0.HasName, Bindings.STRING);
+                               sourcePredicates.put(name, predicate);
+                       }
+
+                       for(String key : sourcePredicates.keySet()) {
+                               Resource sourcePredicate = sourcePredicates.get(key);
+                               Resource anno = annotationPredicates.get(key);
+                               if(sourcePredicate != null && anno != null) {
+                                       Resource defaultValueType = graph.getSingleObject(anno, L0.HasRange);
+                                       Binding defaultValueBinding = null;
+                                       Object defaultValue = null;
+                                       Resource assertion = graph.getPossibleObject(anno, L0.HasPredicateInverse);
+                                       if (assertion != null) {
+                                               Resource object = graph.getPossibleObject(assertion, L0.HasObject);
+                                               if (object != null) {
+                                                       if(graph.isInstanceOf(object, L0.Literal)) {
+                                                               Datatype dt = graph.getDataType(object);
+                                                               defaultValueBinding = Bindings.getBeanBinding(dt);
+                                                               defaultValue = graph.getPossibleValue(object);
+                                                       }
+                                               }
+                                       }
+                                       result.add(new AnnotationMap(
+                                                       sourcePredicate, graph.getInverse(sourcePredicate),
+                                                       anno, graph.getInverse(anno),
+                                                       defaultValueType, defaultValue, defaultValueBinding));
+                               }
+                       }
+
+                       return result;
+
+               }
+
+       }
+
+       public static final String DRAWING_TEMPLATE_FORMAT    = "drawingTemplate";
+    public static final String DRAWING_TEMPLATE_FORMAT_V1 = DRAWING_TEMPLATE_FORMAT + ":1";
+    public static final String DRAWING_TEMPLATE_FORMAT_V2 = DRAWING_TEMPLATE_FORMAT + ":2";
+
+    public static Resource importDrawingTemplate(final Resource model, final File file) throws IOException, SerializationException, DatabaseException, TransferableGraphException {
+
+               try {
+
+                       final Resource library = Simantics.sync(new WriteResultRequest<Resource>() {
+
+                               @Override
+                               public Resource perform(WriteGraph graph) throws DatabaseException {
+                                       
+                                       Layer0 L0 = Layer0.getInstance(graph);
+                                       Template2dResource TEMPLATE = Template2dResource.getInstance(graph);
+                                       Resource root = graph.getPossibleObject(model, TEMPLATE.HasDrawingTemplateRoot);
+                                       if(root == null) {
+                                               Template2dResource TEMPLATE2D = Template2dResource.getInstance(graph);
+                                               root = graph.newResource();
+                                               graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibrary);
+                                               graph.claim(root, L0.InstanceOf, null, TEMPLATE2D.DrawingTemplateLibraryUI);
+                                               graph.claimLiteral(root, L0.HasName, L0.NameOf, L0.String, "Diagram Templates", Bindings.STRING);
+                                               graph.claim(root, L0.PartOf, L0.ConsistsOf, model);
+                                               graph.claim(model, TEMPLATE2D.HasDrawingTemplateRoot, root);
+                                       }
+                                       
+                                       String name = new Path(file.getAbsolutePath()).removeFileExtension().lastSegment();
+                                       if(name != null) {
+                                               Resource existing = Layer0Utils.getPossibleChild(graph, root, name);
+                                               if(existing != null)
+                                                       graph.deny(root, L0.ConsistsOf, existing);
+                                       }
+                                       
+                                       return root;
+                                       
+                               }
+
+                       });
+
+                       final DefaultPasteImportAdvisor advisor = new DefaultPasteImportAdvisor(library);
+
+                       try {
+                               HashMap<String, FormatHandler<Object>> handlers = new HashMap<String, FormatHandler<Object>>();
+                               FormatHandler<Object> handler = new FormatHandler<Object>() {
+                                       @Override
+                                       public Binding getBinding() {
+                                               return TransferableGraph1.BINDING;
+                                       }
+
+                                       @Override
+                                       public Object process(DataContainer container) throws Exception {
+                                               TransferableGraphs.importGraph1(Simantics.getSession(), (TransferableGraph1)container.content.getValue(), 
+                                                               advisor, null);
+                                               return null;
+                                       }
+                               };
+                               handlers.put(DRAWING_TEMPLATE_FORMAT_V1, handler);
+                               handlers.put(DRAWING_TEMPLATE_FORMAT_V2, handler);
+                               try {
+                                       DataContainers.readFile(file, handlers);
+                               } catch(DataFormatException e) {
+                                       throw new IOException(e);
+                               } catch(IOException e) {
+                                       throw e;
+                               } catch(Exception e) {
+                                       if(e instanceof RuntimeException)
+                                               throw (RuntimeException)e;
+                                       else
+                                               throw new RuntimeException(e);
+                               }
+
+                       } catch(IOException e) {
+                       }
+
+                       return advisor.getRoot();
+
+               } catch (Throwable t) {
+                       Logger.defaultLogError("Unexpected exception while importing diagram template.", t);
+               } finally {
+               }
+
+               return null;
+
+       }
+    
+    public static Collection<Variable> getMappedVariables(ReadGraph graph, Variable source) throws DatabaseException {
+       
+        ArrayList<Variable> result = new ArrayList<Variable>();
+       Resource represents = source.getPossibleRepresents(graph);
+       if(represents == null) return Collections.emptyList();
+       ModelingResources MOD = ModelingResources.getInstance(graph);
+       for(Resource r : getElementCorrespondendences(graph, represents)) {
+           result.add(Variables.getVariable(graph, r));
+       }
+       for(Resource r : graph.getObjects(represents, MOD.ComponentToElement)) {
+            result.add(Variables.getVariable(graph, r));
+       }
+        for(Resource r : graph.getObjects(represents, MOD.DiagramToComposite)) {
+            result.add(Variables.getVariable(graph, r));
+        }
+        for(Resource r : graph.getObjects(represents, MOD.CompositeToDiagram)) {
+            result.add(Variables.getVariable(graph, r));
+        }
+       return result;
+       
+    }
+    
+    public static Resource getPossibleModel(ReadGraph graph, Resource resource) throws DatabaseException {
+       
+       PossibleModel pm = new PossibleModel(resource);
+       Resource model = pm.perform(graph);
+       return model;
+    }
+    
+    public static Resource possibleIndexRoot(ReadGraph graph, Resource resource) throws DatabaseException {
+       return graph.syncRequest(new PossibleIndexRoot(resource));
+    }
+
+    public static Object getMonitorValue(StructuralComponent _variable, ReadGraph graph, String path) throws DatabaseException {
+        Variable variable = ((VariableStructuralContext)_variable).variable;
+        Variable var = variable.browse(graph, path);
+        return var.getValue(graph);
+    }
+    
+    public static void createSharedOntologyWithUI(ReadGraph graph, Variable variable, Resource baseType) throws DatabaseException {
+       createSharedOntologyWithUI(graph, baseType);
+    }
+
+    public static void createSharedOntologyWithUI(ReadGraph graph, Resource baseType) throws DatabaseException {
+       
+//     Resource indexRoot_ = variable.getPossibleRepresents(graph);
+//     if(indexRoot_ == null) return;
+
+           final Map<Resource, Pair<String,ImageDescriptor>> map = new HashMap<Resource, Pair<String,ImageDescriptor>>();
+
+       Layer0 L0 = Layer0.getInstance(graph);
+       SimulationResource SIMU = SimulationResource.getInstance(graph);
+       Instances query = graph.adapt(L0.IndexRootType, Instances.class);
+       for(Resource ontology : Layer0Utils.listOntologies(graph)) {
+               for(Resource type : query.find(graph, ontology)) {
+                       if(graph.isInheritedFrom(type, SIMU.Model)) continue;
+                       if(graph.hasStatement(type, L0.Abstract)) continue;
+                       if(!graph.isInheritedFrom(type, baseType)) continue;
+                       String name = graph.getPossibleRelatedValue(type, L0.HasLabel, Bindings.STRING);
+                       if(name == null) name = graph.getRelatedValue(type, L0.HasName, Bindings.STRING);
+                       map.put(type, new Pair<String,ImageDescriptor>(name, null));
+               }
+       }
+       
+       Display.getDefault().asyncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                               CreateSharedOntologyDialog page = new CreateSharedOntologyDialog(shell, map, "Select type and name of new shared library");
+                               if (page.open() == Window.OK) {
+                                       Object[] result = page.getResult();
+                                       if (result != null && result.length == 1) {
+                                               final Resource res = (Resource)result[0];
+                                               final String name = "http://" + page.getName();
+                                               Simantics.getSession().asyncRequest(new WriteRequest() {
+
+                                                       @Override
+                                                       public void perform(WriteGraph graph) throws DatabaseException {
+                                                               graph.markUndoPoint();
+                                                               Resource target = Simantics.applySCL("Simantics/SharedOntologies", "createSharedOntology", graph, name+"@A", res);
+                                                               
+                                                               ProjectResource PROJ = ProjectResource.getInstance(graph);
+                                                               Layer0 L0 = Layer0.getInstance(graph);
+                                                               for(Resource dep : graph.getObjects(Simantics.getProjectResource(), L0.IsLinkedTo)) {
+                                                                       if(graph.isInstanceOf(dep, PROJ.NamespaceRequirement)) {
+                                                                               for(Resource req : graph.getObjects(dep, PROJ.RequiresNamespace)) {
+                                                                                       String uri = graph.getPossibleValue(req, Bindings.STRING);
+                                                                                       if(uri != null) {
+                                                                                               Resource ns = graph.getResource(uri);
+                                                                                               if(ns != null) {
+                                                                                                       graph.claim(target, L0.IsLinkedTo, null, ns);
+                                                                                               }
+                                                                                       }
+                                                                               }
+                                                                       }
+                                                               }
+                                                               
+                                                       }
+                                                       
+                                               });
+                                       }
+                               }
+                       }
+               });
+       
+    }
+
+    public static void unlinkSharedOntologyWithUI(ReadGraph graph, Variable variable, final List<Resource> libraries) throws DatabaseException {
+        
+       final Resource indexRoot = variable.getPossibleRepresents(graph);
+       if(indexRoot == null) return;
+       
+       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+       final List<String> instances = new ArrayList<String>();
+       
+       DiagramResource DIA = DiagramResource.getInstance(graph);
+       
+       for(Resource library : libraries) {
+               for(Resource type : ModelingUtils.searchByTypeShallow(graph, library, STR.ComponentType)) {
+                       for(Resource instance : ModelingUtils.searchByTypeShallow(graph, indexRoot, type)) {
+                               // TODO: haxx
+                               if(graph.isInstanceOf(instance, DIA.Element)) continue;
+                               String name = Versions.getStandardPathNameString(graph, instance);
+                               instances.add(name);
+                       }
+               }
+       }
+       
+       if(instances.isEmpty()) {
+               graph.getSession().asyncRequest(new WriteRequest() {
+                       
+                               @Override
+                               public void perform(WriteGraph graph) throws DatabaseException {
+                               Layer0 L0 = Layer0.getInstance(graph);
+                               for(Resource library : libraries)
+                                       graph.deny(indexRoot, L0.IsLinkedTo, library);
+                               }
+                       
+               });
+               return;
+       }
+       
+        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+               
+                if (!PlatformUI.isWorkbenchRunning())
+                    return;
+
+                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                ListDialog<String> dialog = new ListDialog<String>(
+                        shell,
+                        instances,
+                        "Cannot unlink selected libraries",
+                        "Libraries cannot be unlinked since the following instances are referring to them.") {
+
+                       protected void createButtonsForButtonBar(Composite parent) {
+                               createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);
+                       }
+                       
+                };
+                int result = dialog.open();
+                if (result != Dialog.OK)
+                    return;
+
+            }
+        });
+       
+    }
+    
+    public static MigratedImportResult importSharedOntologyWithResult(String fileName) throws Exception {
+       try {
+               DataContainer dc = DataContainers.readFile(new File(fileName));
+               TransferableGraph1 tg = (TransferableGraph1)dc.content.getValue(TransferableGraph1.BINDING);
+               Variant draftStatus = dc.metadata.get(DraftStatusBean.EXTENSION_KEY);
+               return MigrationUtils.importSharedOntology(Simantics.getSession(), tg, draftStatus == null);
+       } catch (Exception e) {
+               Logger.defaultLogError(e);
+               throw e;
+       }
+    }
+    
+    public static void importSharedOntology(String fileName) throws Exception {
+       importSharedOntologyWithResult(fileName);
+    }
+
+    public static List<Resource> importSharedOntology2(String fileName) throws Exception {
+       MigratedImportResult result = importSharedOntologyWithResult(fileName);
+       return new ArrayList<Resource>(result.roots);
+    }
+    
+    public static void importSharedOntologyWithUI(ReadGraph graph, final Variable variable) throws DatabaseException {
+       
+       Display.getDefault().asyncExec(new Runnable() {
+
+                       @Override
+                       public void run() {
+                               IStructuredSelection sel = new StructuredSelection(variable);
+                       openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyImportWizard");
+                       }
+                       
+               });
+       
+    }
+    
+       public static class LibraryInfo implements Comparable<LibraryInfo> {
+               public NamedResource library;
+               public DraftStatusBean draft;
+               public LibraryInfo(String name, Resource r, DraftStatusBean draft) {
+                       library = new NamedResource(name, r);
+                       this.draft = draft;
+               }
+               @Override
+               public int compareTo(LibraryInfo o) {
+                       return library.compareTo(o.library);
+               }
+               @Override
+               public int hashCode() {
+                       return library.hashCode();
+               }
+               @Override
+               public boolean equals(Object object) {
+               if (this == object)
+                   return true;
+               else if (object == null)
+                   return false;
+               else if (!(object instanceof LibraryInfo))
+                   return false;
+               LibraryInfo info = (LibraryInfo)object;
+               return info.library.equals(library);
+               }
+               
+       }
+       
+    public static void exportSharedOntologyWithUI(final Resource sharedOntology) {
+
+       Display.getDefault().asyncExec(new Runnable() {
+
+               @Override
+               public void run() {
+                       HintContext hc = new HintContext();
+                       hc.setHint(SelectionHints.KEY_MAIN, sharedOntology);
+                       IStructuredSelection sel = new StructuredSelection(hc);
+               openWizard(Display.getCurrent(), sel, "org.simantics.modeling.ui.sharedOntologyExportWizard");
+               }
+               
+       });
+       
+    }
+       
+    public static TransferableGraph1 exportSharedOntology(IProgressMonitor monitor, RequestProcessor processor, File location, String format, int version, final LibraryInfo info) throws DatabaseException, IOException {
+        SubMonitor mon = SubMonitor.convert(monitor, "Exporting shared library", 100);
+
+        // TODO: figure out a way to make the TG go directly into a file
+        // instead of having it all in memory at once.
+
+        SimanticsClipboard clipboard = processor.syncRequest((ReadGraph graph) -> {
+            CopyHandler ch = graph.adapt(info.library.getResource(), CopyHandler.class);
+            SimanticsClipboardImpl result = new SimanticsClipboardImpl();
+            ch.copyToClipboard(graph, result, mon.split(5));
+            return result;
+        });
+
+        TreeMap<String,Variant> metadata = getExportMetadata();
+        DraftStatusBean draft = info.draft;
+        if(draft != null) {
+            metadata.put(DraftStatusBean.EXTENSION_KEY, new Variant(DraftStatusBean.BINDING ,draft));
+        }
+
+        for (Set<Representation> object : clipboard.getContents()) {
+            mon.subTask("Constructing exported material");
+            TransferableGraph1 tg = ClipboardUtils.accept(processor, object, SimanticsKeys.KEY_TRANSFERABLE_GRAPH);
+            mon.worked(90);
+
+            Variant edb = tg.extensions.get(ExternalDownloadBean.EXTENSION_KEY);
+            if(edb != null) {
+                metadata.put(ExternalDownloadBean.EXTENSION_KEY, edb);
+            }
+
+            if(location != null) {
+                   monitor.subTask("Writing transferable graph");
+                   DataContainers.writeFile(location, new DataContainer(
+                           format, version,
+                           metadata, new Variant(TransferableGraph1.BINDING, tg)));
+                   monitor.worked(5);
+            }
+
+            return tg;
+        }
+
+        throw new DatabaseException("Export failed, no contents to export");
+    }
+
+    public static TreeMap<String, Variant> getExportMetadata() {
+
+        TreeMap<String,Variant> metadata = new TreeMap<String,Variant>();
+        metadata.put("date", Variant.ofInstance(DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(new Date())));
+        metadata.put("author", Variant.ofInstance(System.getProperty("user.name", "")));
+
+        return metadata;
+        
+    }
+    
+    public static void createNewVersionWithoutUI(WriteGraph graph, Resource resource) throws DatabaseException {
+        VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));
+        int currentVersion = Integer.parseInt(info.version);
+        String result = Integer.toString(currentVersion + 1);
+        createNewVersion(graph, resource, info, result);
+    }
+    
+    public static void createNewVersionWithUI(ReadGraph graph, final Resource resource) throws DatabaseException {
+       
+       final VersionInfo info = graph.syncRequest(new VersionInfoRequest(resource));
+       
+       Display.getDefault().asyncExec(new Runnable() {
+                       @Override
+                       public void run() {
+                               Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                               CreateVersionDialog dialog = new CreateVersionDialog(shell, info);
+                               if (dialog.open() == Window.OK) {
+                                       final String result = dialog.getResult();
+                                       Simantics.getSession().asyncRequest(new WriteRequest() {
+                                               @Override
+                                               public void perform(WriteGraph graph) throws DatabaseException {
+                                                   createNewVersion(graph, resource, info, result);
+                                               }
+                                       });
+                               }
+                       }
+               });
+       
+    }
+    
+    public static void createNewVersion(WriteGraph graph, Resource resource, final VersionInfo info, final String result) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        Resource parent = graph.getPossibleObject(resource, L0.PartOf);
+        if(parent == null) return;
+        final String parentURI = graph.getPossibleURI(parent);
+        if(parentURI == null) return;
+        Layer0Utils.copyTo(graph, parent, resource, new PasteEventHandler() {
+
+            @Override
+            public void postProcess(WriteGraph graph, Resource root) throws DatabaseException {
+                Layer0 L0 = Layer0.getInstance(graph);
+                graph.deny(root, L0.Entity_published);
+            }
+            
+            @Override
+            public IImportAdvisor2 createAdvisor(ReadGraph graph, ImportAdvisorFactory factory, Resource target) throws DatabaseException {
+                Map<String,Object> context = new HashMap<String,Object>();
+                String base = parentURI + "/" + URIStringUtils.escape( info.baseName ) + "@";
+                Map<String,String> renameMap = new HashMap<String,String>();
+                renameMap.put(base + info.version, base + result);
+                renameMap.put(info.baseName + "@" + info.version, info.baseName + "@" + result);
+                context.put(ImportAdvisors.RENAME_MAP, renameMap);
+                return factory.create(graph, target, context);
+            }
+            
+        });
+        Layer0Utils.addCommentMetadata(graph, "Created new version of " + info.baseName);
+    }
+    
+    public static boolean isUserComponent(ReadGraph graph, Resource type) throws DatabaseException {
+       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+       if(graph.isInstanceOf(type, STR.ProceduralComponentType)) return true;
+       else if (graph.hasStatement(type, STR.IsDefinedBy)) return true;
+       return false;
+    }
+    
+    public static void publishComponentTypeWithUI(WriteGraph graph, final Resource componentType) throws DatabaseException {
+
+       Layer0 L0 = Layer0.getInstance(graph);
+       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+       Resource composite = graph.getPossibleObject(componentType, STR.IsDefinedBy);
+       final List<String> instances = new ArrayList<String>();
+       if(composite != null) {
+               for(Resource component : graph.syncRequest(new ObjectsWithType(composite, L0.ConsistsOf, STR.Component))) {
+               Resource type = graph.getPossibleType(component, STR.Component);
+                       if(type != null && isUserComponent(graph, type)) {
+                               if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, component));
+                       }
+               }
+       }
+
+       if(instances.isEmpty()) {
+               graph.getSession().asyncRequest(new WriteRequest() {
+                       
+                               @Override
+                               public void perform(WriteGraph graph) throws DatabaseException {
+                               graph.markUndoPoint();
+                               publish(graph, componentType);
+                               }
+                       
+               });
+               return;
+       }
+       
+        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+               
+                if (!PlatformUI.isWorkbenchRunning())
+                    return;
+
+                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                ListDialog<String> dialog = new ListDialog<String>(
+                        shell,
+                        instances,
+                        "Cannot publish user component",
+                        "The following instances are referring to unpublished user components.") {
+
+                       protected void createButtonsForButtonBar(Composite parent) {
+                               createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);
+                       }
+                       
+                };
+                int result = dialog.open();
+                if (result != Dialog.OK)
+                    return;
+
+            }
+        });
+       
+    }
+
+    public static void publishSharedOntologyWithUI(WriteGraph graph, final Resource sharedOntology) throws DatabaseException {
+       
+       Layer0 L0 = Layer0.getInstance(graph);
+       DiagramResource DIA = DiagramResource.getInstance(graph);
+       StructuralResource2 STR = StructuralResource2.getInstance(graph);
+       final List<String> instances = new ArrayList<String>();
+       for(Resource type : searchByTypeShallow(graph, sharedOntology, STR.ComponentType)) {
+                       // TODO: haxx
+                       if(graph.isInheritedFrom(type, DIA.Element)) continue;
+               if(!Layer0Utils.isPublished(graph, type)) instances.add(Versions.getStandardPathNameString(graph, type));
+       }
+       for(Resource dep : graph.syncRequest(new ObjectsWithType(sharedOntology, L0.IsLinkedTo, L0.SharedOntology))) {
+               if(!Layer0Utils.isPublished(graph, dep)) instances.add(Versions.getStandardPathNameString(graph, dep));
+       }
+       
+       if(instances.isEmpty()) {
+               graph.getSession().asyncRequest(new WriteRequest() {
+                       
+                               @Override
+                               public void perform(WriteGraph graph) throws DatabaseException {
+                               graph.markUndoPoint();
+                               publish(graph, sharedOntology);
+                               }
+                       
+               });
+               return;
+       }
+       
+        PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
+            @Override
+            public void run() {
+               
+                if (!PlatformUI.isWorkbenchRunning())
+                    return;
+
+                Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
+                ListDialog<String> dialog = new ListDialog<String>(
+                        shell,
+                        instances,
+                        "Cannot publish shared library",
+                        "The following dependencies are unpublished.") {
+
+                       protected void createButtonsForButtonBar(Composite parent) {
+                               createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL,true);
+                       }
+                       
+                };
+                int result = dialog.open();
+                if (result != Dialog.OK)
+                    return;
+
+            }
+        });
+       
+    }
+
+    public static Resource createSCLModuleDefault(WriteGraph graph, Resource target) throws DatabaseException {
+        String name = NameUtils.findFreshEscapedName(graph, "SCLModule", target);
+        return createSCLModule(graph, target, name);
+    }
+
+    public static Resource createSCLModule(WriteGraph graph, Resource target, String name) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        Resource sclModule = GraphUtils.create2(graph, L0.SCLModule,
+                L0.HasName, name,
+                L0.PartOf, target,
+                L0.SCLModule_definition, "");
+        Layer0Utils.addCommentMetadata(graph, "Created SCL Module " + name + " " + sclModule.toString());
+        return sclModule;
+    }
+
+    public static Resource setSCLModuleDefinition(WriteGraph graph, Resource module, String definition) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        graph.claimLiteral(module, L0.SCLModule_definition, definition, Bindings.STRING);
+        Layer0Utils.addCommentMetadata(graph, "Set SCL module " + module + " definition.");
+        return module;
+    }
+
+    public static Resource createSCLScriptDefault(WriteGraph graph, Resource target) throws DatabaseException {
+        String name = NameUtils.findFreshEscapedName(graph, "SCLScript", target);
+        return createSCLScript(graph, target, name);
+    }
+
+    public static Resource createSCLScript(WriteGraph graph, Resource target, String name) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        Resource sclModule = GraphUtils.create2(graph, L0.SCLScript,
+                L0.HasName, name,
+                L0.PartOf, target,
+                L0.SCLScript_definition, "");
+        Layer0Utils.addCommentMetadata(graph, "Created SCL Script " + name + " " + sclModule.toString());
+        return sclModule;
+    }
+
+    public static Resource setSCLScriptDefinition(WriteGraph graph, Resource script, String definition) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        graph.claimLiteral(script, L0.SCLScript_definition, definition, Bindings.STRING);
+        Layer0Utils.addCommentMetadata(graph, "Set SCL script " + script + " definition.");
+        return script;
+    }
+
+    public static Resource createPGraphDefault(WriteGraph graph, Resource target) throws DatabaseException {
+        String name = NameUtils.findFreshEscapedName(graph, "Ontology Definition File", target);
+        return createPGraph(graph, target, name);
+    }
+
+    public static Resource createPGraph(WriteGraph graph, Resource target, String name) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        Resource file = GraphUtils.create2(graph, L0.PGraph,
+                L0.HasName, name,
+                L0.PartOf, target,
+                L0.PGraph_definition, "");
+        Layer0Utils.addCommentMetadata(graph, "Created Ontology Definition File " + name + " " + file.toString());
+        return file;
+    }
+
+    public static Resource setPGraphDefinition(WriteGraph graph, Resource pgraph, String definition) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 L0 = Layer0.getInstance(graph);
+        graph.claimLiteral(pgraph, L0.PGraph_definition, definition, Bindings.STRING);
+        Layer0Utils.addCommentMetadata(graph, "Set PGraph " + pgraph + " definition.");
+        return pgraph;
+    }
+
+    public static void publish(WriteGraph graph, Resource target) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(graph);
+       graph.claimLiteral(target, L0.Entity_published, true, Bindings.BOOLEAN);
+       Layer0Utils.addCommentMetadata(graph, "Published " + graph.getPossibleRelatedValue2(target, L0.HasName, Bindings.STRING) + " " + target.toString());
+    }
+
+    public static boolean isLinkedToDeep(ReadGraph graph, Resource r1, Resource r2) throws DatabaseException {
+       return graph.syncRequest(new IsLinkedTo(r1, r2));
+    }
+    
+    public static void openWizard(Display display, IStructuredSelection selection, String id) {
+       // First see if this is a "new wizard".
+       IWizardDescriptor descriptor = PlatformUI.getWorkbench()
+                       .getNewWizardRegistry().findWizard(id);
+       // If not check if it is an "import wizard".
+       if  (descriptor == null) {
+               descriptor = PlatformUI.getWorkbench().getImportWizardRegistry()
+                               .findWizard(id);
+       }
+       // Or maybe an export wizard
+       if  (descriptor == null) {
+               descriptor = PlatformUI.getWorkbench().getExportWizardRegistry()
+                               .findWizard(id);
+       }
+       try  {
+               // Then if we have a wizard, open it.
+               if  (descriptor != null) {
+                       IWorkbenchWizard wizard = descriptor.createWizard();
+                       wizard.init(PlatformUI.getWorkbench(), selection);
+                       WizardDialog wd = new  WizardDialog(display.getActiveShell(), wizard);
+                       wd.setTitle(wizard.getWindowTitle());
+                       wd.open();
+               }
+       } catch  (CoreException e) {
+               e.printStackTrace();
+       }
+    }
+    
+    public static String withinEpsilon(double value, double reference, double epsilon) {
+       if(Math.abs(value-reference) < epsilon) return "True";
+       else return "Not within epsilon value=" + value + ", reference=" + reference + " , epsilon=" + epsilon; 
+    }
+    
+    public static boolean needsIdentifier(ReadGraph graph, Resource r) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(graph);
+       Collection<Resource> types = graph.getPrincipalTypes(r);
+       for(Resource type : types)
+               if(graph.syncRequest(new IsInstanceOf(type, L0.TypeWithIdentifier), TransientCacheAsyncListener.<Boolean>instance()))
+                               return true;
+       return false;
+    }
+
+    public static boolean needsModificationInfo(ReadGraph graph, Resource r) throws DatabaseException {
+       ModelingResources MOD = ModelingResources.getInstance(graph);
+       Collection<Resource> types = graph.getPrincipalTypes(r);
+       for(Resource type : types)
+               if(graph.syncRequest(new IsInstanceOf(type, MOD.TypeWithChangeInformation), TransientCacheAsyncListener.<Boolean>instance()))
+                               return true;
+       return false;
+    }
+
+    public static void attachCreationInformation(IProgressMonitor monitor, WriteGraph graph, Resource model) throws DatabaseException {
+       
+       if(monitor == null) monitor = new NullProgressMonitor();
+       
+        final String author = System.getProperty("user.name", "");
+        final long time = System.currentTimeMillis();
+       
+        monitor.setTaskName("Attach creation information");
+
+       ModelingResources MOD = ModelingResources.getInstance(graph);
+       Collection<Resource> rs = ModelingUtils.searchByType(graph, model, MOD.TypeWithChangeInformation);
+       Collection<Resource> supers = ModelingUtils.getMostUnspecificTypes(graph, rs);
+       
+       CollectionSupport cs = graph.getService(CollectionSupport.class);
+       Collection<Resource> set = cs.createSet();
+        for(Resource type : supers) {
+               set.addAll(ModelingUtils.searchByTypeShallow(graph, model, type));
+        }
+        Collection<Resource> instances = Layer0Utils.sortByCluster(graph, set);
+
+       int pc = instances.size() / 100;
+       int done = 0;
+       int stint = pc;
+
+        for(Resource instance : instances) {
+               ChangeInformation info = graph.getPossibleRelatedValue(instance, MOD.changeInformation, ChangeInformation.BINDING);
+               if(info == null) {
+                       info = new ChangeInformation();
+                       info.createdAt = time;
+                       info.createdBy = author;
+                       info.modifiedAt = time;
+                       info.modifiedBy = author;
+                       graph.claimLiteral(instance, MOD.changeInformation, MOD.changeInformation_Inverse, MOD.ChangeInformation, info, ChangeInformation.BINDING);
+               }
+               done++;
+               stint--;
+               if(stint == 0) {
+                       Double d = (100.0*done)/instances.size();
+                       monitor.setTaskName("Attach creation information " +  d.intValue() + "%");
+                       stint = pc;
+               }
+        }
+        
+               monitor.setTaskName("Attach creation information - commit");
+       
+    }
+
+    public static class DiagramComponentInfo {
+
+        private static String CHILD_PREFIX             = "child:";
+
+               final private String compositePathAndName;
+               final private String componentName;
+               final private GUID guid;
+               
+               public DiagramComponentInfo(String compositePathAndName, String componentName, GUID guid) {
+                       this.compositePathAndName = compositePathAndName;
+                       this.componentName = componentName;
+                       this.guid = guid;
+               }
+               
+               public static boolean isDiagramComponent(String tgName) {
+                       return tgName.startsWith(CHILD_PREFIX);
+               }
+
+               public String getTGName(CompositeInfo info) {
+                       return CHILD_PREFIX + info.getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + info.getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedComponentName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();
+               }
+               
+               public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {
+                       Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);
+                       return !res.isEmpty();
+               }
+
+               public static DiagramComponentInfo fromResource(ReadGraph graph, CompositeInfo info, Resource resource) throws DatabaseException {
+                       Layer0 L0 = Layer0.getInstance(graph);
+               GUID childId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);
+            String childName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);
+            return new DiagramComponentInfo(info.getStateKey(), URIStringUtils.escape(childName), childId);
+               }
+               
+               public GUID getGUID() {
+                       return guid;
+               }
+               
+               public String getEscapedCompositePathAndName() {
+                       return compositePathAndName;
+               }
+               
+               public String getEscapedComponentName() {
+                       return componentName;
+               }
+               
+               public String getUnescapedComponentName() {
+                       return URIStringUtils.unescape(getEscapedComponentName());
+               }
+               
+               // "child:path#compositeName#componentName#guid"
+               public static DiagramComponentInfo parse(String tgName) {
+                       
+            String name = tgName.substring(CHILD_PREFIX.length());
+            String compositePathAndName = "";
+            String moduleName = name;
+            GUID guid = GUID.invalid();
+            int lastHash = name.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);
+            if(lastHash >= 0) {
+               String first = name.substring(0, lastHash);
+               String second = name.substring(lastHash+1);
+               lastHash = first.lastIndexOf(ModelingUtils.COMPOSITE_SEPARATOR_CHAR);
+               if(lastHash >= 0) {
+                       compositePathAndName = first.substring(0, lastHash);
+                       moduleName = first.substring(lastHash+1);
+                       guid = GUID.parseIndexString(second);
+               } else {
+                       compositePathAndName = first;
+                       moduleName = second;
+               }
+            }
+            return new DiagramComponentInfo(compositePathAndName, moduleName, guid); 
+                       
+               }
+
+
+       @Override
+               public int hashCode() {
+                       final int prime = 31;
+                       int result = 1;
+                       result = prime * result + ((compositePathAndName == null) ? 0 : compositePathAndName.hashCode());
+                       result = prime * result + ((componentName == null) ? 0 : componentName.hashCode());
+                       return result;
+               }
+
+               @Override
+               public boolean equals(Object obj) {
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       DiagramComponentInfo other = (DiagramComponentInfo) obj;
+                       if (compositePathAndName == null) {
+                               if (other.compositePathAndName != null)
+                                       return false;
+                       } else if (!compositePathAndName.equals(other.compositePathAndName))
+                               return false;
+                       if (componentName == null) {
+                               if (other.componentName != null)
+                                       return false;
+                       } else if (!componentName.equals(other.componentName))
+                               return false;
+                       return true;
+               }
+               
+    }
+    
+       public static class CompositeInfo {
+
+           public static String COMPOSITE_PREFIX         = "composite:";
+
+               final private boolean useGuids;
+               final private boolean applyPaths;
+               final private String path;
+               final private String name;
+               final private GUID guid;
+               
+               private CompositeInfo(boolean useGuids, boolean applyPaths, String path, String name, GUID guid) {
+                       this.useGuids = useGuids;
+                       this.applyPaths = applyPaths;
+                       this.path = path;
+                       this.name = name;
+                       this.guid = guid;
+               }
+
+               @Override
+               public String toString() {
+                       return "CompositeInfo[useGuids=" + useGuids + ", applyPaths=" + applyPaths + ", path=" + path + ", name=" + name + ", guid=" + guid.indexString() + "]";
+               }
+
+               public static boolean isComposite(String tgName) {
+                       return tgName.startsWith(COMPOSITE_PREFIX);
+               }
+
+               public String getTGName() {
+                       return COMPOSITE_PREFIX + getOriginalPath() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + getEscapedName() + ModelingUtils.COMPOSITE_SEPARATOR_CHAR + guid.indexString();
+               }
+               
+               public boolean existsGUID(ReadGraph graph, Resource indexRoot) throws DatabaseException {
+                       Collection<Resource> res = ModelingUtils.searchByGUID(graph, indexRoot, guid);
+                       return !res.isEmpty();
+               }
+
+               public static CompositeInfo fromResource(ReadGraph graph, Resource resource) throws DatabaseException {
+                       
+                       Layer0 L0 = Layer0.getInstance(graph);
+            GUID rootId = graph.getRelatedValue(resource, L0.identifier, GUID.BINDING);
+            String rootName = graph.getRelatedValue(resource, L0.HasName, Bindings.STRING);
+            String escapedRootName = URIStringUtils.escape(rootName);
+            String escapedPath = ModelingUtils.getDiagramCompositePath(graph, resource);
+            return new CompositeInfo(true, true, escapedPath, escapedRootName, rootId);
+                       
+               }
+
+           public static CompositeInfo parse(String tgName) {
+               return parse(tgName, true, true);
+           }
+
+           /*
+            * Index 0 is root-relative folder path separated with '/' or null if target-relative positioning is used
+            * Index 1 is diagram name
+            */
+           public static CompositeInfo parse(String tgName, boolean applyPaths, boolean useGuids) {
+               if(!tgName.startsWith(COMPOSITE_PREFIX)) return null;
+               tgName = tgName.substring(COMPOSITE_PREFIX.length());
+               if(!tgName.contains(COMPOSITE_SEPARATOR)) {
+                       if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");
+                       return new CompositeInfo(useGuids, applyPaths, null, tgName, null);
+               }
+               String[] parts = tgName.split(COMPOSITE_SEPARATOR);
+               if(parts.length == 2) {
+                       String name = parts[1];
+                       String path = applyPaths ? parts[0] : null;
+                       if(useGuids) throw new IllegalStateException("GUID identifiers were not found for diagrams.");
+                       return new CompositeInfo(useGuids, applyPaths, path, name, null);
+               } else if(parts.length == 3) {
+                       String path = parts[0];
+                       String name = parts[1];
+                       GUID guid = GUID.parseIndexString(parts[2]);
+                       return new CompositeInfo(useGuids, applyPaths, path, name, guid);
+               } else {
+                       return null;
+               }
+           }
+
+               public GUID getGUID() {
+                       return guid;
+               }
+
+               public String getEscapedName() {
+                       return name;
+               }
+               
+               public String getUnescapedName() {
+                       return URIStringUtils.unescape(name);
+               }
+               
+               public String getOriginalPath() {
+                       return path;
+               }
+               
+               public String getFinalPath() {
+                       if(applyPaths) return path;
+                       else return null;
+               }
+               
+               public CompositeInfo renamed(String newName) {
+                       return new CompositeInfo(useGuids, applyPaths, path, newName, guid);
+               }
+               
+               public String getStateKey() {
+                       return path + "#" + getEscapedName();
+               }
+               
+               private Resource getFromFolder(ReadGraph graph, Resource target) throws DatabaseException {
+            Resource diagram = Layer0Utils.getPossibleChild(graph, target, URIStringUtils.unescape(name));
+            if(diagram == null) return null;
+            StructuralResource2 STR = StructuralResource2.getInstance(graph);
+            return graph.isInstanceOf(diagram, STR.Composite) ? diagram : null;
+               }
+               
+               public Resource resolve(ReadGraph graph, Resource target) throws DatabaseException {
+
+                       if(useGuids && guid != null) {
+                               Resource indexRoot = graph.syncRequest(new IndexRoot(target));
+                               Collection<Resource> queryResult = searchByGUID(graph, indexRoot, guid);
+                               if(queryResult.size() == 1) {
+                                       Resource composite = queryResult.iterator().next(); 
+                           StructuralResource2 STR = StructuralResource2.getInstance(graph);
+                           if(!graph.isInstanceOf(composite, STR.Composite)) return null;
+                           return composite;
+                               }
+                       }
+                       
+                       if(applyPaths) {
+                               Resource folder = resolveFolder(graph, target);
+                               if(folder == null) return null;
+                       return getFromFolder(graph, folder);
+                       } else {
+                       return getFromFolder(graph, target);
+                       }
+                       
+               }
+               
+               public Resource resolveFolder(ReadGraph graph, Resource target) throws DatabaseException {
+                       
+                       String path = getFinalPath();
+                       if(path == null) return target;
+                       
+               Resource folder = graph.syncRequest(new Configuration(target));
+               String[] segments = path.split("/");
+               for(int i=0;i<segments.length;i++) {
+                       if(segments[i].isEmpty()) continue;
+                       folder = Layer0Utils.getPossibleChild(graph, folder, URIStringUtils.unescape(segments[i]));
+                       if(folder == null) return null;
+               }
+               
+               return folder;
+                       
+               }
+               
+               
+               @Override
+               public int hashCode() {
+                       
+                       if(useGuids) return guid.hashCode();
+                       
+                       final int prime = 31;
+                       int result = name.hashCode();
+                       result = prime * result + ((path == null) ? 0 : path.hashCode());
+                       return result;
+                       
+               }
+
+               @Override
+               public boolean equals(Object obj) {
+                       
+                       if (this == obj)
+                               return true;
+                       if (obj == null)
+                               return false;
+                       if (getClass() != obj.getClass())
+                               return false;
+                       
+                       CompositeInfo other = (CompositeInfo) obj;
+                       
+                       if(useGuids) return guid.equals(other.guid);
+                       
+                       if (!name.equals(other.name))
+                               return false;
+                       
+                       if(applyPaths)
+                               if (!path.equals(other.path))
+                                       return false;
+                       
+                       return true;
+                       
+               }
+               
+       }
+       
+    public static char   COMPOSITE_SEPARATOR_CHAR = '#';
+    public static String COMPOSITE_SEPARATOR      = String.valueOf(COMPOSITE_SEPARATOR_CHAR);
+    
+    public static CompositeInfo parseCompositeNameFromRoot(Root root, boolean applyPaths, boolean useGuids) {
+       return CompositeInfo.parse(root.name, applyPaths, useGuids);
+    }
+
+    public static CompositeInfo parseCompositeNameFromRoot(Identity root, boolean applyPaths, boolean useGuids) {
+       String coded = TransferableGraphUtils.getName(root);
+       return CompositeInfo.parse(coded, applyPaths, useGuids);
+    }
+    
+       private static StringBuilder getDiagramCompositePathInternal(ReadGraph graph, Resource folder, StringBuilder builder) throws DatabaseException {
+               SimulationResource SIMU = SimulationResource.getInstance(graph);
+               Resource model = graph.getPossibleObject(folder, SIMU.IsConfigurationOf);
+               if (model != null) return builder;
+
+               Layer0 L0 = Layer0.getInstance(graph);
+               String name = graph.getPossibleRelatedValue(folder, L0.HasName, Bindings.STRING);
+               if (name == null) return null;
+               Resource parent = graph.getPossibleObject(folder, L0.PartOf);
+               if (parent == null) return null;
+
+               StringBuilder sb = getDiagramCompositePathInternal(graph, parent, builder);
+               if (sb == null) return null;
+               if (sb.length() > 0)
+                       sb.append(URIStringUtils.NAMESPACE_PATH_SEPARATOR);
+               sb.append( URIStringUtils.escape(name) );
+               return sb;
+       }
+
+       /**
+        * @param graph
+        * @param diagram
+        * @return diagram/folder path up until model configuration root with each
+        *         segment escaped using {@link URIStringUtils#escape(String)} and
+        *         {@value URIStringUtils#NAMESPACE_PATH_SEPARATOR} between each
+        *         segment or <code>null</code> if the specified diagram composite
+        *         is not part of any model configuration structure.
+        * @throws DatabaseException
+        */
+       public static String getDiagramCompositePath(ReadGraph graph, Resource diagram) throws DatabaseException {
+               Layer0 L0 = Layer0.getInstance(graph);
+               Resource parent = graph.getPossibleObject(diagram, L0.PartOf);
+               if(parent == null) return null;
+               StringBuilder sb = getDiagramCompositePathInternal(graph, parent, new StringBuilder());
+               return sb != null ? sb.toString() : null;
+       }
+       
+       public static void exportModel(ReadGraph graph, Resource model, String fileName, String format, int version) throws DatabaseException {
+               TransferableGraphConfiguration2 conf = new TransferableGraphConfiguration2(graph, model, true, false);
+               exportModel(graph, conf, fileName, format, version);
+       }
+       
+       public static void exportModel(ReadGraph graph, TransferableGraphConfiguration2 conf, String fileName, String format, int version) throws DatabaseException {
+               
+               try {
+               TransferableGraphSource s = graph.syncRequest(new ModelTransferableGraphSourceRequest(conf));
+                       TransferableGraphs.writeTransferableGraph(graph, format, version, s, new File(fileName));
+               } catch (DatabaseException e) {
+                       throw e;
+               } catch (Exception e) {
+                       throw new DatabaseException(e);
+               }
+
+       }
+
+       public static TransferableGraph1 exportSharedOntology(ReadGraph graph, Resource library, String fileName, String format, int version) throws DatabaseException {
+               
+        Layer0 L0 = Layer0.getInstance(graph);
+        String name = graph.getRelatedValue(library, L0.HasName, Bindings.STRING);
+
+        DraftStatusBean draft = null;
+        boolean published = Layer0Utils.isPublished(graph, library);
+        if(!published) draft = new DraftStatusBean(new String[0]);
+        
+        LibraryInfo info = new LibraryInfo(name, library, draft);
+               
+       try {
+                       return exportSharedOntology(new NullProgressMonitor(), graph, fileName != null ? new File(fileName) : null, format, version, info);
+               } catch (IOException e) {
+                       throw new DatabaseException(e);
+               }
+
+       }
+
+    public static DraftStatusBean getDependencyDraftStatus(ReadGraph graph, Resource library) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        List<String> drafts = new ArrayList<>();
+        for (Resource shared : graph.syncRequest(new ObjectsWithType(library, L0.IsLinkedTo, L0.SharedOntology))) {
+            boolean published = Layer0Utils.isPublished(graph, shared);
+            if (!published)
+                drafts.add(graph.getURI(shared));
+        }
+        return drafts.isEmpty() ? null : new DraftStatusBean(drafts);
+    }
+
+       public static Set<Resource> getMostUnspecificTypes(final ReadGraph graph, Collection<Resource> types) throws DatabaseException {
+               
+               final Set<Resource> work = new HashSet<Resource>(types);
+               for(Resource type : types) {
+                       Set<Resource> supers = graph.getSupertypes(type);
+                       if(!Collections.disjoint(supers, work)) work.remove(type);
+               }
+
+               return work;
+               
+       }
+       
+       public static void rewriteGUIDS(WriteGraph graph, Resource root, boolean deep) throws DatabaseException {
+               List<Resource> todo = new ArrayList<Resource>();
+               todo.add(root);
+               Layer0 L0 = Layer0.getInstance(graph);
+               while(!todo.isEmpty()) {
+                       Resource resource = todo.remove(todo.size()-1);
+                       Layer0Utils.claimNewIdentifier(graph, resource, false);
+            if(deep)
+               todo.addAll(graph.getObjects(resource, L0.ConsistsOf));
+               }
+       }
+       
+       public static void createMissingGUIDs(IProgressMonitor monitor, WriteGraph graph, Collection<Resource> roots) throws DatabaseException {
+               
+       if(monitor == null) monitor = new NullProgressMonitor();
+       
+               Layer0 L0 = Layer0.getInstance(graph);
+               
+        // Allow this process to make 50k queries
+        QueryMemoryWatcher memory = new QueryMemoryWatcher(graph, 50000);
+
+               for(Resource root : roots) {
+                       
+                       boolean madeChanges = false;
+                       
+               monitor.setTaskName("Creating missing GUID identifiers " + NameUtils.getSafeName(graph, root));
+                       Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(root));
+                       for(Resource r : searchByTypeShallow(graph, indexRoot, L0.Entity)) {
+
+                               memory.maintain();
+
+                               if(graph.isImmutable(r)) continue;
+
+                               if(!ModelingUtils.needsIdentifier(graph, r)) continue;
+                               
+                               GUID existing = graph.getPossibleRelatedValue(r, L0.identifier, GUID.BINDING);
+                               if(existing == null) {
+                                   Layer0Utils.claimNewIdentifier(graph, r, true);
+                                       madeChanges = true;
+                               }
+                               
+                       }
+                       
+                       if(madeChanges)
+                               ModelingUtils.deleteIndex(graph, root);
+                       
+               }
+               
+               
+       }
+       
+       public static boolean activateModel(WriteGraph graph, Resource model) throws DatabaseException {
+               return graph.syncRequest(new ActivateModel(Simantics.getProjectResource(), model));
+       }
+       
+       public static File fileDialog(String title, List<Tuple> namesAndExtensions) {
+               return new Runnable() {
+                       private File result;
+                       
+                       File getFile() {
+                               Display.getDefault().syncExec(this);
+                               return result;
+                       }
+                       
+                       @Override
+                       public void run() {
+                               result = showDialog();
+                       }
+
+                       private File showDialog() {
+                               Display display = Display.getCurrent();
+                               Shell shell = display.getActiveShell();
+                               
+                       FileDialog dialog = new FileDialog(shell, SWT.OPEN);
+                       dialog.setText(title);
+                       
+                       String[] extensions = new String[namesAndExtensions.size()];
+                       String[] filterNames = new String[namesAndExtensions.size()];
+                       int index = 0;
+                       for(Tuple t : namesAndExtensions) {
+                               String filterName = (String)t.get(0);
+                               String extension = (String)t.get(1);
+                               filterNames[index] = filterName;
+                               extensions[index] = extension;
+                               index++;
+                       }
+                       
+                       dialog.setFilterExtensions(extensions);
+                       dialog.setFilterNames(filterNames);
+                       final String fileName = dialog.open();
+                       if (fileName == null) return null;
+                       
+                       return new File(fileName);
+                       }
+               }.getFile();
+       }
+       
+       public static Resource createLibrary(WriteGraph graph, Resource parent) throws DatabaseException {
+        Layer0 l0 = Layer0.getInstance(graph);
+        return createLibrary(graph, parent, NameUtils.findFreshName(graph, "Library", parent, l0.ConsistsOf));
+    }
+    
+    public static Resource createLibrary(WriteGraph graph, Resource parent, String name) throws DatabaseException {
+        graph.markUndoPoint();
+        Layer0 l0 = Layer0.getInstance(graph);
+
+        Resource library = graph.newResource();
+        graph.claim(library, l0.InstanceOf, null, l0.Library);
+        graph.addLiteral(library, l0.HasName, l0.NameOf, l0.String, name, Bindings.STRING);
+        graph.claim(library, l0.PartOf, parent);
+
+        Layer0Utils.addCommentMetadata(graph, "Created new Library named " + name + ", resource " + library);
+
+        return library;
+    }
+
+    public static IModelingRules getModelingRules(ReadGraph graph, Resource diagramResource) throws DatabaseException {
+        return DiagramGraphUtil.getModelingRules(graph, diagramResource, null);
+    }
+
+    public static void markChanged(WriteGraph graph, Resource r) throws DatabaseException {
+        VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);
+        VirtualGraph vg = support.getWorkspacePersistent("changeInformation");
+        graph.syncRequest(new WriteRequest(vg) {
+            @Override
+            public void perform(WriteGraph graph) throws DatabaseException {
+                ModelingResources MOD = ModelingResources.getInstance(graph);
+                graph.claim(r, MOD.changed, MOD.changed, r);
+            }
+        });
+    }
+    
+}