]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.modeling.ui/src/org/simantics/modeling/ui/wizard/MigrateWizard.java
Externalize strings
[simantics/platform.git] / bundles / org.simantics.modeling.ui / src / org / simantics / modeling / ui / wizard / MigrateWizard.java
index 533a4303483689340b26e1878fb885377c1d8743..751ec023c1e6d4903a41b0a4be6830a7bc75b267 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2014, 2015 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
- *     Semantum Oy - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.modeling.ui.wizard;\r
-\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.IStatus;\r
-import org.eclipse.core.runtime.OperationCanceledException;\r
-import org.eclipse.core.runtime.Status;\r
-import org.eclipse.core.runtime.SubMonitor;\r
-import org.eclipse.core.runtime.preferences.IEclipsePreferences;\r
-import org.eclipse.core.runtime.preferences.InstanceScope;\r
-import org.eclipse.jface.dialogs.IDialogSettings;\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.layout.RowLayoutFactory;\r
-import org.eclipse.jface.resource.ImageDescriptor;\r
-import org.eclipse.jface.window.Window;\r
-import org.eclipse.jface.wizard.Wizard;\r
-import org.eclipse.jface.wizard.WizardPage;\r
-import org.eclipse.swt.SWT;\r
-import org.eclipse.swt.custom.CCombo;\r
-import org.eclipse.swt.events.ModifyEvent;\r
-import org.eclipse.swt.events.ModifyListener;\r
-import org.eclipse.swt.events.SelectionEvent;\r
-import org.eclipse.swt.events.SelectionListener;\r
-import org.eclipse.swt.graphics.Point;\r
-import org.eclipse.swt.layout.GridLayout;\r
-import org.eclipse.swt.widgets.Button;\r
-import org.eclipse.swt.widgets.Composite;\r
-import org.eclipse.swt.widgets.Control;\r
-import org.eclipse.swt.widgets.Event;\r
-import org.eclipse.swt.widgets.Label;\r
-import org.eclipse.swt.widgets.List;\r
-import org.eclipse.swt.widgets.Listener;\r
-import org.eclipse.swt.widgets.Shell;\r
-import org.eclipse.swt.widgets.Text;\r
-import org.simantics.Simantics;\r
-import org.simantics.databoard.Bindings;\r
-import org.simantics.databoard.util.URIStringUtils;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.NamedResource;\r
-import org.simantics.db.common.request.ObjectsWithType;\r
-import org.simantics.db.common.request.UnaryRead;\r
-import org.simantics.db.common.request.UniqueRead;\r
-import org.simantics.db.common.request.WriteResultRequest;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.common.utils.Versions;\r
-import org.simantics.db.exception.CancelTransactionException;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.diagram.stubs.DiagramResource;\r
-import org.simantics.layer0.Layer0;\r
-import org.simantics.modeling.MigrateModel;\r
-import org.simantics.modeling.MigrateModel.MigrationOperation;\r
-import org.simantics.modeling.ModelingResources;\r
-import org.simantics.modeling.UserComponentMigration;\r
-import org.simantics.modeling.ui.Activator;\r
-import org.simantics.structural.stubs.StructuralResource2;\r
-import org.simantics.ui.workbench.dialogs.ResourceSelectionDialog3;\r
-import org.simantics.utils.datastructures.Pair;\r
-import org.simantics.utils.datastructures.Triple;\r
-import org.simantics.utils.strings.AlphanumComparator;\r
-\r
-import gnu.trove.map.hash.THashMap;\r
-import gnu.trove.set.hash.THashSet;\r
-import gnu.trove.set.hash.TIntHashSet;\r
-\r
-/**\r
- * @author Antti Villberg\r
- */\r
-public class MigrateWizard extends Wizard {\r
-\r
-       final String initial;\r
-       \r
-    MigratePage  migratePage;\r
-\r
-       IEclipsePreferences prefnode;\r
-    \r
-    public MigrateWizard(String initial) {\r
-       \r
-       this.initial = initial;\r
-\r
-        setWindowTitle("Perform migration");\r
-        setNeedsProgressMonitor(true);\r
-        setForcePreviousAndNextButtons(false);\r
-        setDialogSettings(Activator.getDefault().getDialogSettings());\r
-\r
-        prefnode = InstanceScope.INSTANCE.getNode( "org.simantics.modeling.ui.wizard.MigrateWizard" );\r
-        \r
-    }\r
-\r
-    @Override\r
-    public void addPages() {\r
-        migratePage = new MigratePage(initial);\r
-        addPage(migratePage);\r
-    }\r
-\r
-    @Override\r
-    public boolean canFinish() {\r
-//        if (model.spec.name.isEmpty())\r
-//            return false;\r
-        return true;\r
-    }\r
-\r
-    @Override\r
-    public boolean performFinish() {\r
-\r
-        int locationIndex = migratePage.locations.getSelectionIndex();\r
-        if(locationIndex == -1) return true;\r
-\r
-       if(migratePage.model == null || migratePage.model.instances.isEmpty()) return true;\r
-\r
-       int[] sel = migratePage.instances.getSelectionIndices();\r
-       TIntHashSet sels = new TIntHashSet();\r
-       for(int i : sel) sels.add(i);\r
-\r
-        Collection<MigrationOperation> ops = migratePage.model.sortedShownInstances;\r
-        int index = 0;\r
-        final ArrayList<MigrationOperation> result = new ArrayList<>();\r
-        for(MigrationOperation op : ops) {\r
-               if(sels.contains(index)) result.add(op);\r
-               index++;\r
-        }\r
-        \r
-        if(result.isEmpty()) return true;\r
-        \r
-        try {\r
-            String[] report = { null };\r
-            getContainer().run(true, true, monitor -> {\r
-                SubMonitor mon = SubMonitor.convert(monitor, 1000);\r
-                try {\r
-                    report[0] = Simantics.getSession().syncRequest(new WriteResultRequest<String>() {\r
-                        @Override\r
-                        public String perform(WriteGraph graph) throws DatabaseException {\r
-                            graph.markUndoPoint();\r
-                            String report = UserComponentMigration.doMigration(mon.newChild(500, SubMonitor.SUPPRESS_NONE), graph, result);\r
-                            UserComponentMigration.doPostMigration(mon.newChild(500, SubMonitor.SUPPRESS_NONE), graph, result);\r
-                            mon.setTaskName("Committing Changes");\r
-                            mon.subTask("");\r
-                            return report;\r
-                        }\r
-                    });\r
-                } catch (DatabaseException e) {\r
-                    throw new InvocationTargetException(e);\r
-                } finally {\r
-                    monitor.done();\r
-                }\r
-            });\r
-\r
-\r
-            ReportDialog md = new ReportDialog(getShell(), report[0], 800, 500);\r
-            md.open();\r
-\r
-            return true;\r
-        } catch (InvocationTargetException e) {\r
-            // Don't show user cancellations as errors.\r
-            Throwable cause = e.getCause();\r
-            if (!(cause instanceof CancelTransactionException || cause instanceof OperationCanceledException)) {\r
-                Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,\r
-                        "Migration failed, see Error Log for details.", e.getCause()));\r
-            }\r
-        } catch (InterruptedException e) {\r
-            Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,\r
-                    "Migration interrupted, see Error Log for details.", e));\r
-        }\r
-        return false;\r
-    }\r
-\r
-    static class ReportDialog extends MessageDialog {\r
-        private final String report;\r
-        private final int initialWidth;\r
-        private final int initialHeight;\r
-\r
-        public ReportDialog(Shell shell, String report, int width, int height) {\r
-            super(shell, \r
-                    "Migration report", null, \r
-                    "", \r
-                    MessageDialog.INFORMATION, new String[] { "Continue" }, 0);\r
-            this.report = report;\r
-            this.initialWidth = width;\r
-            this.initialHeight = height;\r
-        }\r
-\r
-        @Override\r
-        protected boolean isResizable() {\r
-            return true;\r
-        }\r
-\r
-        @Override\r
-        protected Point getInitialSize() {\r
-            return new Point(initialWidth, initialHeight);\r
-        }\r
-\r
-        @Override\r
-        protected Control createCustomArea(Composite composite) {\r
-            GridLayoutFactory.fillDefaults().applyTo(composite);\r
-            Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);\r
-            text.setText(report);\r
-            GridDataFactory.fillDefaults().grab(true, true).applyTo(text);\r
-            return composite;\r
-        }\r
-    }\r
-\r
-    abstract static class SelectionAdapter implements SelectionListener {\r
-        @Override\r
-        public void widgetDefaultSelected(SelectionEvent e) {\r
-            widgetSelected(e);\r
-        }\r
-    }\r
-\r
-    class MigratePage extends WizardPage {\r
-\r
-        String                initial;\r
-        \r
-        MigrateModel          model;\r
-\r
-        Text                  source;\r
-        Button                browseSource;\r
-        Text                  target;\r
-        Button                browseTarget;\r
-        Label                 symbolsLabel;\r
-        CCombo                symbols;\r
-        Label                 instanceLabel;\r
-        Label                            locationsLabel;\r
-        CCombo                locations;\r
-        Composite             buttonBar;\r
-        Label                 instancesLabel;\r
-        List                  instances;\r
-\r
-        /**\r
-         * ID of the location that has been previously selected by the user.\r
-         * Used to prevent the location from being reset every time the user\r
-         * makes a change in any of the other selections.\r
-         * \r
-         * See first field of {@link MigrateModel#instances}.\r
-         */\r
-        String                previouslySelectedLocationId = null;\r
-\r
-        public MigratePage(String initial) {\r
-            super("Perform migration", "Perform migration", null);\r
-            this.initial = initial;\r
-        }\r
-\r
-        @Override\r
-        public void createControl(Composite parent) {\r
-            Composite container = new Composite(parent, SWT.NONE);\r
-            {\r
-                GridLayout layout = new GridLayout();\r
-                layout.horizontalSpacing = 20;\r
-                layout.verticalSpacing = 10;\r
-                layout.numColumns = 10;\r
-                container.setLayout(layout);\r
-            }\r
-\r
-            new Label(container, SWT.NONE).setText("&Source:");\r
-            source = new Text(container, SWT.BORDER);\r
-            source.setText(initial);\r
-            source.addModifyListener(new ModifyListener() {\r
-                @Override\r
-                public void modifyText(ModifyEvent e) {\r
-                    refreshModel();\r
-                    refreshInstances();\r
-                }\r
-            });\r
-            GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(source);\r
-\r
-            browseSource = new Button(container, SWT.NONE);\r
-            browseSource.setText("&Browse");\r
-            GridDataFactory.fillDefaults().grab(false, false).applyTo(browseSource);\r
-            browseSource.addSelectionListener(new SelectionAdapter() {\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e_) {\r
-                    try {\r
-                        Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseSourceContentRequest(target.getText()));\r
-                        String uri = queryTargetSelection("Select Source Type", map);\r
-                        if (uri != null)\r
-                            source.setText(uri);\r
-                    } catch (DatabaseException e) {\r
-                        Logger.defaultLogError(e);\r
-                    }\r
-                }\r
-            });\r
-\r
-            new Label(container, SWT.NONE).setText("&Target:");\r
-            target = new Text(container, SWT.BORDER);\r
-            target.setText(initial);\r
-            target.addModifyListener(new ModifyListener() {\r
-                @Override\r
-                public void modifyText(ModifyEvent e) {\r
-                    refreshSymbols();\r
-                    refreshModel();\r
-                    refreshInstances();\r
-                }\r
-            });\r
-            GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(target);\r
-\r
-            browseTarget = new Button(container, SWT.NONE);\r
-            browseTarget.setText("B&rowse");\r
-            GridDataFactory.fillDefaults().grab(false, false).applyTo(browseTarget);\r
-            browseTarget.addSelectionListener(new SelectionAdapter() {\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e_) {\r
-                    try {\r
-                        Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseTargetContentRequest(source.getText()));\r
-                        String uri = queryTargetSelection("Select Target Type", map);\r
-                        if (uri != null)\r
-                            target.setText(uri);\r
-                    } catch (DatabaseException e) {\r
-                        Logger.defaultLogError(e);\r
-                    }\r
-                }\r
-            });\r
-\r
-            symbolsLabel = new Label(container, SWT.NONE);\r
-            symbolsLabel.setText("Target &symbol:");\r
-            GridDataFactory.fillDefaults().applyTo(symbolsLabel);\r
-\r
-            symbols = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
-            symbols.setVisibleItemCount(10);\r
-            symbols.addSelectionListener(new SelectionAdapter() {\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    refreshModel();\r
-                    refreshInstances();\r
-                }\r
-            });\r
-            GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);\r
-\r
-            instanceLabel = new Label(container, SWT.NONE);\r
-            GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instanceLabel);\r
-            instanceLabel.setText("");\r
-\r
-            locationsLabel = new Label(container, SWT.NONE);\r
-            locationsLabel.setText("&Locations:");\r
-            locations = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);\r
-            locations.setVisibleItemCount(25);\r
-            locations.addSelectionListener(new SelectionAdapter() {\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    int index = locations.getSelectionIndex();\r
-                    if (index >= 0 && index < model.instances.size()) {\r
-                        previouslySelectedLocationId = model.instances.get(index).first;\r
-                    }\r
-                    refreshInstances();\r
-                }\r
-            });\r
-            GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);\r
-\r
-            instancesLabel = new Label(container, SWT.NONE);\r
-            instancesLabel.setText("&Select instances to migrate:");\r
-            GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instancesLabel);\r
-\r
-            buttonBar = new Composite(container, SWT.NONE);\r
-            RowLayoutFactory.fillDefaults().type(SWT.HORIZONTAL).applyTo(buttonBar);\r
-            GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);\r
-            Button selectAll = new Button(buttonBar, SWT.PUSH);\r
-            selectAll.setText("Select &All");\r
-            Button selectNone = new Button(buttonBar, SWT.PUSH);\r
-            selectNone.setText("Select &None");\r
-            selectAll.addSelectionListener(new SelectionAdapter() {\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    instances.selectAll();\r
-                }\r
-            });\r
-            selectNone.addSelectionListener(new SelectionAdapter() {\r
-                @Override\r
-                public void widgetSelected(SelectionEvent e) {\r
-                    instances.deselectAll();\r
-                }\r
-            });\r
-\r
-            instances = new List(container, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);\r
-            GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);\r
-            instances.addListener(SWT.Modify, validateListener);\r
-\r
-            refreshSymbols();\r
-            refreshModel();\r
-            refreshInstances();\r
-\r
-            setControl(container);\r
-            validatePage();\r
-        }\r
-\r
-        String queryTargetSelection(String title, Map<String, Pair<String, ImageDescriptor>> map) {\r
-            Shell shell = source.getShell();\r
-            ResourceSelectionDialog3<String> dialog = new ResourceSelectionDialog3<String>(shell, map, title, false) {\r
-                @Override\r
-                protected IDialogSettings getBaseDialogSettings() {\r
-                    return Activator.getDefault().getDialogSettings();\r
-                }\r
-            };\r
-            if (dialog.open() == Window.OK)\r
-                return (String) dialog.getFirstResult();\r
-            return null;\r
-        }\r
-\r
-        void refreshSymbols() {\r
-            try {\r
-\r
-                final String uri = target.getText();\r
-\r
-                Collection<NamedResource> syms = Simantics.getSession().syncRequest(new UniqueRead<Collection<NamedResource>>() {\r
-\r
-                    @Override\r
-                    public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {\r
-\r
-                        Layer0 L0 = Layer0.getInstance(graph);\r
-                        DiagramResource DIA = DiagramResource.getInstance(graph);\r
-                        ModelingResources MOD = ModelingResources.getInstance(graph);\r
-\r
-                        Set<NamedResource> result = new THashSet<>();\r
-                        Resource componentType = graph.getResource(uri);\r
-\r
-                        Set<Resource> potentialSymbols = new THashSet<>();\r
-                        potentialSymbols.addAll(graph.syncRequest(new ObjectsWithType(componentType, L0.ConsistsOf, DIA.ElementClass)));\r
-                        potentialSymbols.addAll(graph.getObjects(componentType, MOD.ComponentTypeToSymbol));\r
-\r
-                        for(Resource symbol : potentialSymbols) {\r
-                            if(!graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType)) continue;\r
-                            String name = graph.getRelatedValue(symbol, L0.HasName, Bindings.STRING);\r
-                            if(graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType))\r
-                                result.add(new NamedResource(name, symbol));\r
-                        }\r
-\r
-                        return new ArrayList<>(result);\r
-\r
-                    }\r
-\r
-                });\r
-\r
-                symbols.removeAll();\r
-                symbols.add("<retain symbol name>");\r
-                for(NamedResource nr : syms) {\r
-                    symbols.add(nr.getName());\r
-                }\r
-                symbols.setData(syms);\r
-                symbols.select(0);\r
-\r
-                if(syms.isEmpty()) {\r
-                    symbolsLabel.setVisible(false);\r
-                    symbols.setVisible(false);\r
-                    GridDataFactory.fillDefaults().exclude(true).applyTo(symbolsLabel);\r
-                    GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(symbols);\r
-                } else {\r
-                    symbolsLabel.setVisible(true);\r
-                    symbols.setVisible(true);\r
-                    GridDataFactory.fillDefaults().applyTo(symbolsLabel);\r
-                    GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);\r
-                }\r
-\r
-                symbols.getParent().layout();\r
-\r
-            } catch (DatabaseException e) {\r
-                Logger.defaultLogError(e);\r
-            }\r
-        }\r
-\r
-        void refreshModel() {\r
-            final String sourceText = source.getText();\r
-            final String targetText = target.getText();\r
-            int symbolIndex = symbols.getSelectionIndex();\r
-            Resource symbol = null;\r
-            if(symbolIndex > 0) {\r
-                @SuppressWarnings("unchecked")\r
-                java.util.List<NamedResource> nrs = (java.util.List<NamedResource>)symbols.getData();\r
-                symbol = nrs.get(symbolIndex-1).getResource();\r
-            }\r
-            final Resource finalSymbol = symbol;\r
-\r
-            try {\r
-                model = Simantics.getSession().syncRequest(new UniqueRead<MigrateModel>() {\r
-                    @Override\r
-                    public MigrateModel perform(ReadGraph graph) throws DatabaseException {\r
-                        Layer0 L0 = Layer0.getInstance(graph);\r
-                        StructuralResource2 STR = StructuralResource2.getInstance(graph);\r
-\r
-                        Resource source = graph.getPossibleResource(sourceText);\r
-                        if(source == null) return model;\r
-                        Resource target = graph.getPossibleResource(targetText);\r
-                        if(target == null) return model;\r
-\r
-                        if(graph.isInstanceOf(source, STR.ComponentType)) {\r
-                            return UserComponentMigration.getComponentTypeModel(graph, source, target, finalSymbol);\r
-                        } else if(graph.isInstanceOf(source, L0.SharedOntology)) {\r
-                            return UserComponentMigration.getSharedOntologyModel(graph, source, target);\r
-                        } else {\r
-                            return null;\r
-                        }\r
-                    }\r
-                });\r
-            } catch (DatabaseException e) {\r
-                Logger.defaultLogError(e);\r
-            }\r
-\r
-            instances.removeAll();\r
-            locations.removeAll();\r
-\r
-            if (model == null)\r
-                return;\r
-\r
-            int preSelect = -1, i = 0;\r
-            for (Triple<String,NamedResource,Collection<MigrationOperation>> r : model.instances) {\r
-                locations.add(r.second.getName() + " (" + r.third.size() + " instances)");\r
-                if (r.first.equals(previouslySelectedLocationId))\r
-                    preSelect = i;\r
-                if (preSelect < 0 && model.activeModels.contains(r.second.getResource()))\r
-                    preSelect = i;\r
-                ++i;\r
-            }\r
-            if (locations.getItemCount() == 0) {\r
-                locations.add("<no instances were found>");\r
-                locations.select(0);\r
-            } else {\r
-                locations.select(preSelect > -1 ? preSelect : 0);\r
-            }\r
-        }\r
-\r
-        void refreshInstances() {\r
-\r
-            int toMigrate = 0;\r
-            for(Triple<String,NamedResource,Collection<MigrationOperation>> pair : model.instances) {\r
-                toMigrate += pair.third.size();\r
-            }\r
-\r
-            if(model.instanceCount == 0)\r
-                instanceLabel.setText("No instances were found.");\r
-            else if(model.instanceCount == 1) {\r
-                if(toMigrate == 1) {\r
-                    instanceLabel.setText("1 migratable instance found.");\r
-                } else {\r
-                    instanceLabel.setText("1 instance found, but it cannot be migrated with current settings.");\r
-                }\r
-            } else {\r
-                if(toMigrate < model.instanceCount) {\r
-                    if(toMigrate == 0) {\r
-                        instanceLabel.setText(model.instanceCount + " instances were found. None of them can be migrated with current settings.");\r
-                    } else {\r
-                        instanceLabel.setText(model.instanceCount + " instances were found. " + (model.instanceCount-toMigrate) + " of them cannot be migrated with current settings.");\r
-                    }\r
-                } else {\r
-                    instanceLabel.setText(model.instanceCount + " migratable instances found. ");\r
-                }\r
-            }\r
-\r
-            instances.removeAll();\r
-\r
-            if (model == null)\r
-                return;\r
-\r
-            if(toMigrate == 0) {\r
-                locationsLabel.setVisible(false);\r
-                locations.setVisible(false);\r
-                GridDataFactory.fillDefaults().exclude(true).applyTo(locationsLabel);\r
-                GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(locations);\r
-            } else {\r
-                locationsLabel.setVisible(true);\r
-                locations.setVisible(true);\r
-                GridDataFactory.fillDefaults().applyTo(locationsLabel);\r
-                GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);\r
-            }\r
-\r
-            if(!model.instances.isEmpty()) {\r
-\r
-                int locationIndex = locations.getSelectionIndex();\r
-                if(locationIndex == -1) return;\r
-\r
-                model.sortedShownInstances = new ArrayList<>();\r
-                for(MigrationOperation o : model.instances.get(locationIndex).third)\r
-                    model.sortedShownInstances.add(o);\r
-                Collections.sort(model.sortedShownInstances, MIGRATION_OP_COMPARATOR);\r
-                for(MigrationOperation o : model.sortedShownInstances) {\r
-                    String uri = o.toString();\r
-                    uri = uri.replace("http://Projects/Development%20Project/", "");\r
-                    uri = URIStringUtils.unescape(uri);\r
-                    instances.add(uri);\r
-                }\r
-\r
-            }\r
-\r
-            if(model.sortedShownInstances.isEmpty()) {\r
-                instancesLabel.setVisible(false);\r
-                instances.setVisible(false);\r
-                buttonBar.setVisible(false);\r
-                GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(instancesLabel);\r
-                GridDataFactory.fillDefaults().exclude(true).grab(true, true).span(10, 1).applyTo(instances);\r
-                GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(10, 1).applyTo(buttonBar);\r
-            } else {\r
-                GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(instancesLabel);\r
-                GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);\r
-                GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);\r
-                instancesLabel.setVisible(true);\r
-                instances.setVisible(true);\r
-                buttonBar.setVisible(true);\r
-            }\r
-\r
-            locations.getParent().layout();\r
-\r
-        }\r
-\r
-        Listener validateListener = new Listener() {\r
-            @Override\r
-            public void handleEvent(Event event) {\r
-                switch (event.type) {\r
-                    case SWT.Modify:\r
-                        validatePage();\r
-                    case SWT.Selection:\r
-                        validatePage();\r
-                        break;\r
-                    case SWT.FocusIn:\r
-                    {\r
-                        if (event.widget instanceof Text) {\r
-                            Text t = (Text) event.widget;\r
-                            t.selectAll();\r
-                        }\r
-                        break;\r
-                    }\r
-                }\r
-            }\r
-        };\r
-\r
-        private void validatePage() {\r
-            setMessage(null);\r
-            setErrorMessage(null);\r
-            setPageComplete(true);\r
-        }\r
-\r
-    }\r
-\r
-    private static final Comparator<MigrationOperation> MIGRATION_OP_COMPARATOR = new Comparator<MigrateModel.MigrationOperation>() {\r
-        @Override\r
-        public int compare(MigrationOperation o1, MigrationOperation o2) {\r
-            return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(o1.instanceToMigrate.getName(), o2.instanceToMigrate.getName());\r
-        }\r
-    };\r
-\r
-    private static abstract class BrowseContentRequest extends UnaryRead<String, Map<String, Pair<String, ImageDescriptor>>> {\r
-\r
-        public BrowseContentRequest(String uri) {\r
-            super(uri);\r
-        }\r
-\r
-        @Override\r
-        public Map<String, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {\r
-            Resource root = graph.getPossibleResource(parameter);\r
-            if (root == null)\r
-                return null;\r
-\r
-            Map<String, Pair<String, ImageDescriptor>> result = new THashMap<>();\r
-            Collection<NamedResource> infos = getVersions(graph, root); \r
-            for (NamedResource info : infos)\r
-                result.put(graph.getURI(info.getResource()), Pair.<String,ImageDescriptor>make(Versions.getStandardPathNameString(graph, info.getResource()), null));\r
-\r
-            return result;\r
-        }\r
-\r
-        protected abstract Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException;\r
-\r
-    }\r
-\r
-    private static class BrowseSourceContentRequest extends BrowseContentRequest {\r
-        public BrowseSourceContentRequest(String uri) {\r
-            super(uri);\r
-        }\r
-        @Override\r
-        protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {\r
-            return Versions.getOlderVersions(graph, root);\r
-        }\r
-    }\r
-\r
-    private static class BrowseTargetContentRequest extends BrowseContentRequest {\r
-        public BrowseTargetContentRequest(String uri) {\r
-            super(uri);\r
-        }\r
-        @Override\r
-        protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {\r
-            return Versions.getNewerVersions(graph, root);\r
-        }\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2014, 2015 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:
+ *     Semantum Oy - initial API and implementation
+ *******************************************************************************/
+package org.simantics.modeling.ui.wizard;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.layout.GridDataFactory;
+import org.eclipse.jface.layout.GridLayoutFactory;
+import org.eclipse.jface.layout.RowLayoutFactory;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.window.Window;
+import org.eclipse.jface.wizard.Wizard;
+import org.eclipse.jface.wizard.WizardPage;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.ModifyEvent;
+import org.eclipse.swt.events.ModifyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.List;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+import org.simantics.Simantics;
+import org.simantics.databoard.Bindings;
+import org.simantics.databoard.util.URIStringUtils;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.NamedResource;
+import org.simantics.db.common.request.ObjectsWithType;
+import org.simantics.db.common.request.UnaryRead;
+import org.simantics.db.common.request.UniqueRead;
+import org.simantics.db.common.request.WriteResultRequest;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.common.utils.Versions;
+import org.simantics.db.exception.CancelTransactionException;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.request.Read;
+import org.simantics.diagram.stubs.DiagramResource;
+import org.simantics.layer0.Layer0;
+import org.simantics.modeling.MigrateModel;
+import org.simantics.modeling.MigrateModel.MigrationOperation;
+import org.simantics.modeling.ModelingResources;
+import org.simantics.modeling.UserComponentMigration;
+import org.simantics.modeling.ui.Activator;
+import org.simantics.modeling.ui.diagramEditor.DiagramEditor;
+import org.simantics.structural.stubs.StructuralResource2;
+import org.simantics.ui.workbench.dialogs.ResourceSelectionDialog3;
+import org.simantics.utils.datastructures.Pair;
+import org.simantics.utils.datastructures.Triple;
+import org.simantics.utils.strings.AlphanumComparator;
+import org.simantics.utils.ui.SWTUtils;
+
+import gnu.trove.map.hash.THashMap;
+import gnu.trove.set.hash.THashSet;
+import gnu.trove.set.hash.TIntHashSet;
+
+/**
+ * @author Antti Villberg
+ */
+public class MigrateWizard extends Wizard {
+
+       final String initial;
+       
+    MigratePage  migratePage;
+
+       IEclipsePreferences prefnode;
+    
+    public MigrateWizard(String initial) {
+       
+       this.initial = initial;
+
+        setWindowTitle(Messages.MigrateWizard_PerformMigration);
+        setNeedsProgressMonitor(true);
+        setForcePreviousAndNextButtons(false);
+        setDialogSettings(Activator.getDefault().getDialogSettings());
+
+        prefnode = InstanceScope.INSTANCE.getNode( "org.simantics.modeling.ui.wizard.MigrateWizard" ); //$NON-NLS-1$
+        
+    }
+
+    @Override
+    public void addPages() {
+        migratePage = new MigratePage(initial);
+        addPage(migratePage);
+    }
+
+    @Override
+    public boolean canFinish() {
+//        if (model.spec.name.isEmpty())
+//            return false;
+        return true;
+    }
+
+    @Override
+    public boolean performFinish() {
+
+        int locationIndex = migratePage.locations.getSelectionIndex();
+        if(locationIndex == -1) return true;
+
+       if(migratePage.model == null || migratePage.model.instances.isEmpty()) return true;
+
+       int[] sel = migratePage.instances.getSelectionIndices();
+       TIntHashSet sels = new TIntHashSet();
+       for(int i : sel) sels.add(i);
+
+        Collection<MigrationOperation> ops = migratePage.model.sortedShownInstances;
+        int index = 0;
+        final ArrayList<MigrationOperation> result = new ArrayList<>();
+        for(MigrationOperation op : ops) {
+               if(sels.contains(index)) result.add(op);
+               index++;
+        }
+        
+        if(result.isEmpty()) return true;
+        
+        try {
+            String[] report = { null };
+            getContainer().run(true, true, monitor -> {
+                SubMonitor mon = SubMonitor.convert(monitor, 1000);
+                try {
+                    report[0] = Simantics.getSession().syncRequest(new WriteResultRequest<String>() {
+                        @Override
+                        public String perform(WriteGraph graph) throws DatabaseException {
+                            graph.markUndoPoint();
+                            String report = UserComponentMigration.doMigration(mon.newChild(500, SubMonitor.SUPPRESS_NONE), graph, result);
+                            UserComponentMigration.doPostMigration(mon.newChild(500, SubMonitor.SUPPRESS_NONE), graph, result);
+                            mon.setTaskName(Messages.MigrateWizard_MonitorCommitingChanges);
+                            mon.subTask(""); //$NON-NLS-1$
+                            return report;
+                        }
+                    });
+
+                    // Schedule diagram reinitialization to see actual migration changes
+                    // This needs to be done because the diagram editor can't currently
+                    // refresh itself after type (InstanceOf) changes in diagram elements.
+                    Set<Resource> diagramsToReopen = Simantics.getSession().syncRequest(
+                            (Read<Set<Resource>>) graph -> componentsToDiagrams(graph, ops));
+                    SWTUtils.asyncExec(MigrateWizard.this.getContainer().getShell().getDisplay(),
+                            () -> DiagramEditor.reinitializeDiagram(diagramsToReopen));
+                } catch (DatabaseException e) {
+                    throw new InvocationTargetException(e);
+                } finally {
+                    monitor.done();
+                }
+            });
+
+            ReportDialog md = new ReportDialog(getShell(), report[0], 800, 500);
+            md.open();
+
+            return true;
+        } catch (InvocationTargetException e) {
+            // Don't show user cancellations as errors.
+            Throwable cause = e.getCause();
+            if (!(cause instanceof CancelTransactionException || cause instanceof OperationCanceledException)) {
+                Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+                        Messages.MigrateWizard_ActivatorMigrationFailed, e.getCause()));
+            }
+        } catch (InterruptedException e) {
+            Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID,
+                    Messages.MigrateWizard_ActivatorMigrationInterrupted, e));
+        }
+        return false;
+    }
+
+    private static final Set<Resource> componentsToDiagrams(ReadGraph graph, Collection<MigrationOperation> ops) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(graph);
+        ModelingResources MOD = ModelingResources.getInstance(graph);
+        Set<Resource> diagrams = new HashSet<>();
+        for (MigrationOperation op : ops) {
+            Resource composite = graph.getPossibleObject(op.instanceToMigrate.getResource(), L0.PartOf);
+            if (composite != null) {
+                Resource diagram = graph.getPossibleObject(composite, MOD.CompositeToDiagram);
+                if (diagram != null)
+                    diagrams.add(diagram);
+            }
+        }
+        return diagrams;
+    }
+
+    static class ReportDialog extends MessageDialog {
+        private final String report;
+        private final int initialWidth;
+        private final int initialHeight;
+
+        public ReportDialog(Shell shell, String report, int width, int height) {
+            super(shell, 
+                    Messages.MigrateWizard_MigrationReport, null, 
+                    "",  //$NON-NLS-1$
+                    MessageDialog.INFORMATION, new String[] { Messages.MigrateWizard_Continue }, 0);
+            this.report = report;
+            this.initialWidth = width;
+            this.initialHeight = height;
+        }
+
+        @Override
+        protected boolean isResizable() {
+            return true;
+        }
+
+        @Override
+        protected Point getInitialSize() {
+            return new Point(initialWidth, initialHeight);
+        }
+
+        @Override
+        protected Control createCustomArea(Composite composite) {
+            GridLayoutFactory.fillDefaults().applyTo(composite);
+            Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.READ_ONLY | SWT.BORDER);
+            text.setText(report);
+            GridDataFactory.fillDefaults().grab(true, true).applyTo(text);
+            return composite;
+        }
+    }
+
+    abstract static class SelectionAdapter implements SelectionListener {
+        @Override
+        public void widgetDefaultSelected(SelectionEvent e) {
+            widgetSelected(e);
+        }
+    }
+
+    class MigratePage extends WizardPage {
+
+        String                initial;
+        
+        MigrateModel          model;
+
+        Text                  source;
+        Button                browseSource;
+        Text                  target;
+        Button                browseTarget;
+        Label                 symbolsLabel;
+        CCombo                symbols;
+        Label                 instanceLabel;
+        Label                            locationsLabel;
+        CCombo                locations;
+        Composite             buttonBar;
+        Label                 instancesLabel;
+        List                  instances;
+
+        /**
+         * ID of the location that has been previously selected by the user.
+         * Used to prevent the location from being reset every time the user
+         * makes a change in any of the other selections.
+         * 
+         * See first field of {@link MigrateModel#instances}.
+         */
+        String                previouslySelectedLocationId = null;
+
+        public MigratePage(String initial) {
+            super(Messages.MigrateWizard_PerformMigration, Messages.MigrateWizard_PerformMigration, null);
+            this.initial = initial;
+        }
+
+        @Override
+        public void createControl(Composite parent) {
+            Composite container = new Composite(parent, SWT.NONE);
+            {
+                GridLayout layout = new GridLayout();
+                layout.horizontalSpacing = 20;
+                layout.verticalSpacing = 10;
+                layout.numColumns = 10;
+                container.setLayout(layout);
+            }
+
+            new Label(container, SWT.NONE).setText(Messages.MigrateWizard_SourceAnd);
+            source = new Text(container, SWT.BORDER);
+            source.setText(initial);
+            source.addModifyListener(new ModifyListener() {
+                @Override
+                public void modifyText(ModifyEvent e) {
+                    refreshModel();
+                    refreshInstances();
+                }
+            });
+            GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(source);
+
+            browseSource = new Button(container, SWT.NONE);
+            browseSource.setText(Messages.MigrateWizard_BrowseAnd);
+            GridDataFactory.fillDefaults().grab(false, false).applyTo(browseSource);
+            browseSource.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e_) {
+                    try {
+                        Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseSourceContentRequest(target.getText()));
+                        String uri = queryTargetSelection(Messages.MigrateWizard_SelectSourceType, map);
+                        if (uri != null)
+                            source.setText(uri);
+                    } catch (DatabaseException e) {
+                        Logger.defaultLogError(e);
+                    }
+                }
+            });
+
+            new Label(container, SWT.NONE).setText(Messages.MigrateWizard_TargetAnd);
+            target = new Text(container, SWT.BORDER);
+            target.setText(initial);
+            target.addModifyListener(new ModifyListener() {
+                @Override
+                public void modifyText(ModifyEvent e) {
+                    refreshSymbols();
+                    refreshModel();
+                    refreshInstances();
+                }
+            });
+            GridDataFactory.fillDefaults().grab(true, false).span(8, 1).applyTo(target);
+
+            browseTarget = new Button(container, SWT.NONE);
+            browseTarget.setText(Messages.MigrateWizard_BrowseAnd1);
+            GridDataFactory.fillDefaults().grab(false, false).applyTo(browseTarget);
+            browseTarget.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e_) {
+                    try {
+                        Map<String, Pair<String, ImageDescriptor>> map = Simantics.getSession().syncRequest(new BrowseTargetContentRequest(source.getText()));
+                        String uri = queryTargetSelection(Messages.MigrateWizard_SelectTargetType, map);
+                        if (uri != null)
+                            target.setText(uri);
+                    } catch (DatabaseException e) {
+                        Logger.defaultLogError(e);
+                    }
+                }
+            });
+
+            symbolsLabel = new Label(container, SWT.NONE);
+            symbolsLabel.setText(Messages.MigrateWizard_TargetAndSymbol);
+            GridDataFactory.fillDefaults().applyTo(symbolsLabel);
+
+            symbols = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);
+            symbols.setVisibleItemCount(10);
+            symbols.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    refreshModel();
+                    refreshInstances();
+                }
+            });
+            GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);
+
+            instanceLabel = new Label(container, SWT.NONE);
+            GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instanceLabel);
+            instanceLabel.setText(""); //$NON-NLS-1$
+
+            locationsLabel = new Label(container, SWT.NONE);
+            locationsLabel.setText(Messages.MigrateWizard_LocationAnd);
+            locations = new CCombo(container, SWT.BORDER | SWT.READ_ONLY);
+            locations.setVisibleItemCount(25);
+            locations.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    int index = locations.getSelectionIndex();
+                    if (index >= 0 && index < model.instances.size()) {
+                        previouslySelectedLocationId = model.instances.get(index).first;
+                    }
+                    refreshInstances();
+                }
+            });
+            GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);
+
+            instancesLabel = new Label(container, SWT.NONE);
+            instancesLabel.setText(Messages.MigrateWizard_SelectInstancesToMigrate);
+            GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(instancesLabel);
+
+            buttonBar = new Composite(container, SWT.NONE);
+            RowLayoutFactory.fillDefaults().type(SWT.HORIZONTAL).applyTo(buttonBar);
+            GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);
+            Button selectAll = new Button(buttonBar, SWT.PUSH);
+            selectAll.setText(Messages.MigrateWizard_SelectAllAnd);
+            Button selectNone = new Button(buttonBar, SWT.PUSH);
+            selectNone.setText(Messages.MigrateWizard_SelectNoneAnd);
+            selectAll.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    instances.selectAll();
+                }
+            });
+            selectNone.addSelectionListener(new SelectionAdapter() {
+                @Override
+                public void widgetSelected(SelectionEvent e) {
+                    instances.deselectAll();
+                }
+            });
+
+            instances = new List(container, SWT.MULTI | SWT.WRAP | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
+            GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);
+            instances.addListener(SWT.Modify, validateListener);
+
+            refreshSymbols();
+            refreshModel();
+            refreshInstances();
+
+            setControl(container);
+            validatePage();
+        }
+
+        String queryTargetSelection(String title, Map<String, Pair<String, ImageDescriptor>> map) {
+            Shell shell = source.getShell();
+            ResourceSelectionDialog3<String> dialog = new ResourceSelectionDialog3<String>(shell, map, title, false) {
+                @Override
+                protected IDialogSettings getBaseDialogSettings() {
+                    return Activator.getDefault().getDialogSettings();
+                }
+            };
+            if (dialog.open() == Window.OK)
+                return (String) dialog.getFirstResult();
+            return null;
+        }
+
+        void refreshSymbols() {
+            try {
+
+                final String uri = target.getText();
+
+                Collection<NamedResource> syms = Simantics.getSession().syncRequest(new UniqueRead<Collection<NamedResource>>() {
+
+                    @Override
+                    public Collection<NamedResource> perform(ReadGraph graph) throws DatabaseException {
+
+                        Layer0 L0 = Layer0.getInstance(graph);
+                        DiagramResource DIA = DiagramResource.getInstance(graph);
+                        ModelingResources MOD = ModelingResources.getInstance(graph);
+
+                        Set<NamedResource> result = new THashSet<>();
+                        Resource componentType = graph.getResource(uri);
+
+                        Set<Resource> potentialSymbols = new THashSet<>();
+                        potentialSymbols.addAll(graph.syncRequest(new ObjectsWithType(componentType, L0.ConsistsOf, DIA.ElementClass)));
+                        potentialSymbols.addAll(graph.getObjects(componentType, MOD.ComponentTypeToSymbol));
+
+                        for(Resource symbol : potentialSymbols) {
+                            if(!graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType)) continue;
+                            String name = graph.getRelatedValue(symbol, L0.HasName, Bindings.STRING);
+                            if(graph.hasStatement(symbol, MOD.SymbolToComponentType, componentType))
+                                result.add(new NamedResource(name, symbol));
+                        }
+
+                        return new ArrayList<>(result);
+
+                    }
+
+                });
+
+                symbols.removeAll();
+                symbols.add(Messages.MigrateWizard_RetainSymbolName);
+                for(NamedResource nr : syms) {
+                    symbols.add(nr.getName());
+                }
+                symbols.setData(syms);
+                symbols.select(0);
+
+                if(syms.isEmpty()) {
+                    symbolsLabel.setVisible(false);
+                    symbols.setVisible(false);
+                    GridDataFactory.fillDefaults().exclude(true).applyTo(symbolsLabel);
+                    GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(symbols);
+                } else {
+                    symbolsLabel.setVisible(true);
+                    symbols.setVisible(true);
+                    GridDataFactory.fillDefaults().applyTo(symbolsLabel);
+                    GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(symbols);
+                }
+
+                symbols.getParent().layout();
+
+            } catch (DatabaseException e) {
+                Logger.defaultLogError(e);
+            }
+        }
+
+        void refreshModel() {
+            final String sourceText = source.getText();
+            final String targetText = target.getText();
+            int symbolIndex = symbols.getSelectionIndex();
+            Resource symbol = null;
+            if(symbolIndex > 0) {
+                @SuppressWarnings("unchecked")
+                java.util.List<NamedResource> nrs = (java.util.List<NamedResource>)symbols.getData();
+                symbol = nrs.get(symbolIndex-1).getResource();
+            }
+            final Resource finalSymbol = symbol;
+
+            try {
+                model = Simantics.getSession().syncRequest(new UniqueRead<MigrateModel>() {
+                    @Override
+                    public MigrateModel perform(ReadGraph graph) throws DatabaseException {
+                        Layer0 L0 = Layer0.getInstance(graph);
+                        StructuralResource2 STR = StructuralResource2.getInstance(graph);
+
+                        Resource source = graph.getPossibleResource(sourceText);
+                        if(source == null) return model;
+                        Resource target = graph.getPossibleResource(targetText);
+                        if(target == null) return model;
+
+                        if(graph.isInstanceOf(source, STR.ComponentType)) {
+                            return UserComponentMigration.getComponentTypeModel(graph, source, target, finalSymbol);
+                        } else if(graph.isInstanceOf(source, L0.SharedOntology)) {
+                            return UserComponentMigration.getSharedOntologyModel(graph, source, target);
+                        } else {
+                            return null;
+                        }
+                    }
+                });
+            } catch (DatabaseException e) {
+                Logger.defaultLogError(e);
+            }
+
+            instances.removeAll();
+            locations.removeAll();
+
+            if (model == null)
+                return;
+
+            int preSelect = -1, i = 0;
+            for (Triple<String,NamedResource,Collection<MigrationOperation>> r : model.instances) {
+                locations.add(NLS.bind(Messages.MigrateWizard_LocationInstance, r.second.getName(), r.third.size())); 
+                if (r.first.equals(previouslySelectedLocationId))
+                    preSelect = i;
+                if (preSelect < 0 && model.activeModels.contains(r.second.getResource()))
+                    preSelect = i;
+                ++i;
+            }
+            if (locations.getItemCount() == 0) {
+                locations.add(Messages.MigrateWizard_NoInstancesFound);
+                locations.select(0);
+            } else {
+                locations.select(preSelect > -1 ? preSelect : 0);
+            }
+        }
+
+        void refreshInstances() {
+
+            int toMigrate = 0;
+            for (Triple<String, NamedResource, Collection<MigrationOperation>> pair : model.instances) {
+                toMigrate += pair.third.size();
+            }
+
+            if (model.instanceCount == 0)
+                instanceLabel.setText(Messages.MigrateWizard_NoInstancesWereFound);
+            else if (model.instanceCount == 1) {
+                if (toMigrate == 1) {
+                    instanceLabel.setText(Messages.MigrateWizard_OneMigratableInstanceFound);
+                } else {
+                    instanceLabel.setText(Messages.MigrateWizard_InstanceFoundCannotBeMigrated);
+                }
+            } else {
+                if (toMigrate < model.instanceCount) {
+                    if (toMigrate == 0) {
+                        instanceLabel
+                        .setText(NLS.bind(Messages.MigrateWizard_NumberOfInstancesFound, model.instanceCount));
+                    } else {
+                        instanceLabel.setText(NLS.bind(Messages.MigrateWizard_InstancesWereFound, model.instanceCount,
+                                (model.instanceCount - toMigrate)));
+                    }
+                } else {
+                    instanceLabel
+                    .setText(NLS.bind(Messages.MigrateWizard_MigratableInstancesFound, model.instanceCount));
+                }
+            }
+
+            instances.removeAll();
+
+            if (model == null)
+                return;
+
+            if (toMigrate == 0) {
+                locationsLabel.setVisible(false);
+                locations.setVisible(false);
+                GridDataFactory.fillDefaults().exclude(true).applyTo(locationsLabel);
+                GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(locations);
+            } else {
+                locationsLabel.setVisible(true);
+                locations.setVisible(true);
+                GridDataFactory.fillDefaults().applyTo(locationsLabel);
+                GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(locations);
+            }
+
+            if (!model.instances.isEmpty()) {
+
+                int locationIndex = locations.getSelectionIndex();
+                if (locationIndex == -1)
+                    return;
+
+                model.sortedShownInstances = new ArrayList<>();
+                for (MigrationOperation o : model.instances.get(locationIndex).third)
+                    model.sortedShownInstances.add(o);
+                Collections.sort(model.sortedShownInstances, MIGRATION_OP_COMPARATOR);
+                for (MigrationOperation o : model.sortedShownInstances) {
+                    String uri = o.toString();
+                    uri = uri.replace("http://Projects/Development%20Project/", ""); //$NON-NLS-1$ //$NON-NLS-2$
+                    uri = URIStringUtils.unescape(uri);
+                    instances.add(uri);
+                }
+
+            }
+
+            if (model.sortedShownInstances.isEmpty()) {
+                instancesLabel.setVisible(false);
+                instances.setVisible(false);
+                buttonBar.setVisible(false);
+                GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(9, 1).applyTo(instancesLabel);
+                GridDataFactory.fillDefaults().exclude(true).grab(true, true).span(10, 1).applyTo(instances);
+                GridDataFactory.fillDefaults().exclude(true).grab(true, false).span(10, 1).applyTo(buttonBar);
+            } else {
+                GridDataFactory.fillDefaults().grab(true, false).span(9, 1).applyTo(instancesLabel);
+                GridDataFactory.fillDefaults().grab(true, true).span(10, 1).applyTo(instances);
+                GridDataFactory.fillDefaults().grab(true, false).span(10, 1).applyTo(buttonBar);
+                instancesLabel.setVisible(true);
+                instances.setVisible(true);
+                buttonBar.setVisible(true);
+            }
+
+            locations.getParent().layout();
+
+        }
+
+        Listener validateListener = new Listener() {
+            @Override
+            public void handleEvent(Event event) {
+                switch (event.type) {
+                    case SWT.Modify:
+                        validatePage();
+                    case SWT.Selection:
+                        validatePage();
+                        break;
+                    case SWT.FocusIn:
+                    {
+                        if (event.widget instanceof Text) {
+                            Text t = (Text) event.widget;
+                            t.selectAll();
+                        }
+                        break;
+                    }
+                }
+            }
+        };
+
+        private void validatePage() {
+            setMessage(null);
+            setErrorMessage(null);
+            setPageComplete(true);
+        }
+
+    }
+
+    private static final Comparator<MigrationOperation> MIGRATION_OP_COMPARATOR = new Comparator<MigrateModel.MigrationOperation>() {
+        @Override
+        public int compare(MigrationOperation o1, MigrationOperation o2) {
+            return AlphanumComparator.CASE_INSENSITIVE_COMPARATOR.compare(o1.instanceToMigrate.getName(), o2.instanceToMigrate.getName());
+        }
+    };
+
+    private static abstract class BrowseContentRequest extends UnaryRead<String, Map<String, Pair<String, ImageDescriptor>>> {
+
+        public BrowseContentRequest(String uri) {
+            super(uri);
+        }
+
+        @Override
+        public Map<String, Pair<String, ImageDescriptor>> perform(ReadGraph graph) throws DatabaseException {
+            Resource root = graph.getPossibleResource(parameter);
+            if (root == null)
+                return null;
+
+            Map<String, Pair<String, ImageDescriptor>> result = new THashMap<>();
+            Collection<NamedResource> infos = getVersions(graph, root); 
+            for (NamedResource info : infos)
+                result.put(graph.getURI(info.getResource()), Pair.<String,ImageDescriptor>make(Versions.getStandardPathNameString(graph, info.getResource()), null));
+
+            return result;
+        }
+
+        protected abstract Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException;
+
+    }
+
+    private static class BrowseSourceContentRequest extends BrowseContentRequest {
+        public BrowseSourceContentRequest(String uri) {
+            super(uri);
+        }
+        @Override
+        protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {
+            return Versions.getOlderVersions(graph, root);
+        }
+    }
+
+    private static class BrowseTargetContentRequest extends BrowseContentRequest {
+        public BrowseTargetContentRequest(String uri) {
+            super(uri);
+        }
+        @Override
+        protected Collection<NamedResource> getVersions(ReadGraph graph, Resource root) throws DatabaseException {
+            return Versions.getNewerVersions(graph, root);
+        }
+    }
+
+}