]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.browsing.ui.swt / src / org / simantics / browsing / ui / swt / widgets / GraphExplorerComposite.java
diff --git a/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java b/bundles/org.simantics.browsing.ui.swt/src/org/simantics/browsing/ui/swt/widgets/GraphExplorerComposite.java
new file mode 100644 (file)
index 0000000..5e324fa
--- /dev/null
@@ -0,0 +1,1253 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2012 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.browsing.ui.swt.widgets;\r
+\r
+import java.util.Collection;\r
+import java.util.Collections;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.function.Consumer;\r
+\r
+import org.eclipse.core.runtime.IAdaptable;\r
+import org.eclipse.core.runtime.Platform;\r
+import org.eclipse.jface.action.IMenuManager;\r
+import org.eclipse.jface.layout.GridDataFactory;\r
+import org.eclipse.jface.layout.GridLayoutFactory;\r
+import org.eclipse.jface.layout.TreeColumnLayout;\r
+import org.eclipse.jface.resource.JFaceResources;\r
+import org.eclipse.jface.resource.LocalResourceManager;\r
+import org.eclipse.jface.viewers.ColumnWeightData;\r
+import org.eclipse.jface.viewers.ISelectionProvider;\r
+import org.eclipse.swt.SWT;\r
+import org.eclipse.swt.dnd.DND;\r
+import org.eclipse.swt.dnd.DragSource;\r
+import org.eclipse.swt.dnd.DragSourceEvent;\r
+import org.eclipse.swt.dnd.DragSourceListener;\r
+import org.eclipse.swt.dnd.DropTarget;\r
+import org.eclipse.swt.dnd.DropTargetEvent;\r
+import org.eclipse.swt.dnd.DropTargetListener;\r
+import org.eclipse.swt.dnd.FileTransfer;\r
+import org.eclipse.swt.dnd.TextTransfer;\r
+import org.eclipse.swt.dnd.Transfer;\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.Listener;\r
+import org.eclipse.swt.widgets.Tree;\r
+import org.eclipse.swt.widgets.TreeColumn;\r
+import org.eclipse.swt.widgets.TreeItem;\r
+import org.eclipse.ui.ISelectionListener;\r
+import org.eclipse.ui.IWorkbenchSite;\r
+import org.eclipse.ui.contexts.IContextService;\r
+import org.simantics.browsing.ui.BuiltinKeys;\r
+import org.simantics.browsing.ui.Column;\r
+import org.simantics.browsing.ui.ExplorerState;\r
+import org.simantics.browsing.ui.GraphExplorer;\r
+import org.simantics.browsing.ui.GraphExplorer.TransientExplorerState;\r
+import org.simantics.browsing.ui.NodeContext;\r
+import org.simantics.browsing.ui.StatePersistor;\r
+import org.simantics.browsing.ui.common.ColumnKeys;\r
+import org.simantics.browsing.ui.common.EvaluatorData;\r
+import org.simantics.browsing.ui.common.EvaluatorDataImpl;\r
+import org.simantics.browsing.ui.common.processors.ComparableFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.ComparableSelectorQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.FilterSelectionRequestQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.ImageDecoratorFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.ImagerFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.LabelDecoratorFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.LabelerFactoryResolver;\r
+import org.simantics.browsing.ui.common.processors.UserSelectedComparableFactoryQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.UserSelectedViewpointFactoryQueryProcessor;\r
+import org.simantics.browsing.ui.common.processors.ViewpointFactoryResolver;\r
+import org.simantics.browsing.ui.common.views.FilterAreaSource;\r
+import org.simantics.browsing.ui.common.views.IFilterArea;\r
+import org.simantics.browsing.ui.common.views.IFilterAreaProvider;\r
+import org.simantics.browsing.ui.graph.impl.AsyncReadGraphDataSource;\r
+import org.simantics.browsing.ui.graph.impl.Evaluators;\r
+import org.simantics.browsing.ui.graph.impl.InheritsQueryProcessor;\r
+import org.simantics.browsing.ui.graph.impl.ReadGraphDataSource;\r
+import org.simantics.browsing.ui.graph.impl.RelatedObjectsQueryProcessor;\r
+import org.simantics.browsing.ui.graph.impl.SessionContextInputSource;\r
+import org.simantics.browsing.ui.model.browsecontexts.BrowseContext;\r
+import org.simantics.browsing.ui.model.nodetypes.NodeType;\r
+import org.simantics.browsing.ui.swt.Activator;\r
+import org.simantics.browsing.ui.swt.AdaptableHintContext;\r
+import org.simantics.browsing.ui.swt.ComparatorSelector;\r
+import org.simantics.browsing.ui.swt.ContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.DefaultExplorerSelectionListener;\r
+import org.simantics.browsing.ui.swt.DefaultIsCheckedProcessor2;\r
+import org.simantics.browsing.ui.swt.DefaultKeyListener;\r
+import org.simantics.browsing.ui.swt.DefaultMouseListener;\r
+import org.simantics.browsing.ui.swt.DefaultSelectionDataResolver;\r
+import org.simantics.browsing.ui.swt.FilterArea;\r
+import org.simantics.browsing.ui.swt.GraphExplorerFactory;\r
+import org.simantics.browsing.ui.swt.IContextMenuInitializer;\r
+import org.simantics.browsing.ui.swt.RootFilterArea;\r
+import org.simantics.browsing.ui.swt.StandardContextTypesQueryProcessor;\r
+import org.simantics.browsing.ui.swt.TypesQueryProcessor;\r
+import org.simantics.browsing.ui.swt.ViewpointSelector;\r
+import org.simantics.browsing.ui.swt.widgets.impl.Widget;\r
+import org.simantics.browsing.ui.swt.widgets.impl.WidgetSupport;\r
+import org.simantics.db.AsyncReadGraph;\r
+import org.simantics.db.ReadGraph;\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.Session;\r
+import org.simantics.db.common.request.ResourceRead;\r
+import org.simantics.db.common.utils.Logger;\r
+import org.simantics.db.exception.DatabaseException;\r
+import org.simantics.db.layer0.SelectionHints;\r
+import org.simantics.db.layer0.variable.Variable;\r
+import org.simantics.db.layer0.variable.Variables;\r
+import org.simantics.db.management.ISessionContext;\r
+import org.simantics.db.management.ISessionContextChangedListener;\r
+import org.simantics.db.management.ISessionContextProvider;\r
+import org.simantics.db.management.SessionContextChangedEvent;\r
+import org.simantics.project.ProjectKeys;\r
+import org.simantics.ui.SimanticsUI;\r
+import org.simantics.ui.dnd.LocalObjectTransfer;\r
+import org.simantics.ui.dnd.LocalSelectionDragSourceListener;\r
+import org.simantics.ui.dnd.NoImageDragSourceEffect;\r
+import org.simantics.ui.dnd.SessionContainer;\r
+import org.simantics.ui.selection.AnyResource;\r
+import org.simantics.ui.selection.AnyVariable;\r
+import org.simantics.ui.selection.ExplorerColumnContentType;\r
+import org.simantics.ui.selection.ExplorerInputContentType;\r
+import org.simantics.ui.selection.WorkbenchSelectionContentType;\r
+import org.simantics.ui.selection.WorkbenchSelectionElement;\r
+import org.simantics.ui.selection.WorkbenchSelectionUtils;\r
+import org.simantics.utils.ObjectUtils;\r
+import org.simantics.utils.datastructures.BinaryFunction;\r
+import org.simantics.utils.datastructures.Function;\r
+import org.simantics.utils.datastructures.disposable.DisposeState;\r
+import org.simantics.utils.datastructures.hints.HintListenerAdapter;\r
+import org.simantics.utils.datastructures.hints.HintTracker;\r
+import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
+import org.simantics.utils.datastructures.hints.IHintListener;\r
+import org.simantics.utils.datastructures.hints.IHintObservable;\r
+import org.simantics.utils.datastructures.hints.IHintTracker;\r
+\r
+\r
+public class GraphExplorerComposite extends Composite implements Widget, IAdaptable {\r
+\r
+    protected UserSelectedComparableFactoryQueryProcessor userSelectedComparableFactoryQueryProcessor;\r
+    protected UserSelectedViewpointFactoryQueryProcessor  userSelectedViewpointFactoryQueryProcessor;\r
+    protected FilterSelectionRequestQueryProcessor        filterSelectionRequestQueryProcessor;\r
+    protected IFilterArea                                 filterArea;\r
+    protected EvaluatorData                               evaluatorData;\r
+\r
+    protected LocalResourceManager                        resourceManager;\r
+\r
+    protected ISelectionListener                          workbenchSelectionListener;\r
+\r
+    private final int                                     style;\r
+\r
+    final private IWorkbenchSite                          site;\r
+\r
+    protected GraphExplorer                               explorer;\r
+\r
+    protected IMenuManager                                menuManager;\r
+\r
+    private final Map<String, Object>                     args;\r
+\r
+    protected ISessionContextProvider                       contextProvider;\r
+\r
+    private ISessionContext                               sessionContext;\r
+\r
+    private Object                                        dragSource;\r
+\r
+    private IHintTracker                                  sessionContextTracker = new SessionContextProjectTracker();\r
+\r
+    private InputSource                                   inputSource           = new DirectInputSource();\r
+    private FilterAreaSource                              filterAreaSource    = new SelectionFilterAreaSource();\r
+\r
+    private final TreeColumnLayout                                                       ad;\r
+    private String[]                                        editingColumn = ColumnKeys.KEYS_SINGLE;\r
+    \r
+    private StatePersistor                                                                     persistor = null;\r
+\r
+    private final Composite                                                                      toolComposite;\r
+    private final Composite                                                                      toolComposite2;\r
+    private final Composite                                                                      explorerComposite;\r
+    final private WidgetSupport                                 support;\r
+    private final boolean                                                                      useNodeBrowseContexts;\r
+    private final boolean                                                                      useNodeActionContexts;\r
+\r
+    static class SelectionElement extends AdaptableHintContext {\r
+\r
+        final public WorkbenchSelectionElement wse;\r
+        final public Object content;\r
+        final public Resource resource;\r
+        final public Variable variable;\r
+        final public Object input;\r
+        final public TransientExplorerState explorerState;\r
+        \r
+        private WorkbenchSelectionElement extractWse(Object content) {\r
+            if(content instanceof NodeContext) {\r
+                NodeContext context = (NodeContext)content;\r
+                Object input = context.getConstant(NodeType.TYPE);\r
+                if(input instanceof NodeType) \r
+                    return ((NodeType)input).getWorkbenchSelectionElement(context);\r
+            }\r
+            return null;\r
+        }\r
+        \r
+        private Resource extractResource(Object content) {\r
+               if(content instanceof NodeContext) {\r
+                       NodeContext context = (NodeContext)content;\r
+                       Object input = context.getConstant(BuiltinKeys.INPUT);\r
+                       if(input instanceof Resource) return (Resource)input;\r
+                       if(input instanceof IAdaptable) {\r
+                               Resource var = (Resource)((IAdaptable)input).getAdapter(Resource.class);\r
+                               if(var != null) return var;\r
+                       }\r
+               }\r
+               return null;\r
+        }\r
+        \r
+        private Variable extractVariable(Object content) {\r
+               if(content instanceof NodeContext) {\r
+                       NodeContext context = (NodeContext)content;\r
+                       Object input = context.getConstant(BuiltinKeys.INPUT);\r
+                       if(input instanceof Variable) return (Variable)input;\r
+                       if(input instanceof IAdaptable) {\r
+                               Variable var = (Variable)((IAdaptable)input).getAdapter(Variable.class);\r
+                               if(var != null) return var;\r
+                       }\r
+               }\r
+               return null;\r
+        }\r
+\r
+        private Object extractInput(Object content) {\r
+               if(content instanceof NodeContext) {\r
+                       NodeContext context = (NodeContext)content;\r
+                       return context.getConstant(BuiltinKeys.INPUT);\r
+               }\r
+               return null;\r
+        }\r
+\r
+        public SelectionElement(GraphExplorer explorer, Key[] keys, Object content) {\r
+            super(keys);\r
+            this.content = content;\r
+            this.wse = extractWse(content);\r
+            this.resource = extractResource(content);\r
+            this.variable = extractVariable(content);\r
+            this.input = extractInput(content);\r
+            this.explorerState = explorer.getTransientState();\r
+        }\r
+\r
+        @SuppressWarnings("unchecked")\r
+        @Override\r
+        public <T> T getContent(WorkbenchSelectionContentType<T> contentType) {\r
+\r
+            if(wse != null) {\r
+                T result = wse.getContent(contentType);\r
+                if(result != null) return result;\r
+            }\r
+            \r
+            if(contentType instanceof AnyResource) return (T)resource;\r
+            else if(contentType instanceof AnyVariable) {\r
+                AnyVariable type = (AnyVariable)contentType;\r
+                try {\r
+                       \r
+                       if(variable != null) return (T)variable;\r
+                       \r
+                       if(resource == null) return null;\r
+                       \r
+                    return (T) type.processor.sync(new ResourceRead<Variable>(resource) {\r
+                        @Override\r
+                        public Variable perform(ReadGraph graph) throws DatabaseException {\r
+                            return Variables.getPossibleVariable(graph, resource);\r
+                        }\r
+                        \r
+                    });\r
+                } catch (DatabaseException e) {\r
+                    Logger.defaultLogError(e);\r
+                }\r
+            } else if (contentType instanceof ExplorerInputContentType) {\r
+               return (T)input;\r
+            } else if (contentType instanceof ExplorerColumnContentType) {\r
+               return (T)explorerState.getActiveColumn();\r
+            }\r
+            return null;\r
+        }\r
+        \r
+        @SuppressWarnings("rawtypes")\r
+        @Override\r
+        public Object getAdapter(Class adapter) {\r
+               if(WorkbenchSelectionElement.class == adapter) {\r
+                       return wse;\r
+               }\r
+               if(NodeContext.class == adapter) {\r
+                   if(content instanceof NodeContext)\r
+                       return (NodeContext)content;\r
+                   else\r
+                       return null;\r
+               }\r
+               return super.getAdapter(adapter);\r
+        }\r
+\r
+    }\r
+    private BinaryFunction<Object[], GraphExplorer, Object[]> selectionTransformation = new BinaryFunction<Object[], GraphExplorer, Object[]>() {\r
+\r
+       private Key[] KEYS = new Key[] { SelectionHints.KEY_MAIN };\r
+       \r
+        @Override\r
+        public Object[] call(GraphExplorer explorer, Object[] objects) {\r
+            Object[] result = new Object[objects.length];\r
+            for (int i = 0; i < objects.length; i++) {\r
+               SelectionElement context = new SelectionElement(explorer, KEYS, objects[i]);\r
+               context.setHint(SelectionHints.KEY_MAIN, objects[i]);\r
+               result[i] = context;\r
+            }\r
+            return result;\r
+        }\r
+\r
+    };\r
+\r
+    private Set<String>                                   browseContexts        = null;\r
+\r
+    private DisposeState                                  disposeState          = DisposeState.Alive;\r
+\r
+    private boolean                                       created               = false;\r
+\r
+    protected String                                      contextMenuId         = null;\r
+\r
+    protected Set<String>                                 uiContext             = null;\r
+\r
+    protected ISessionContextChangedListener              contextChangeListener = new ISessionContextChangedListener() {\r
+        @Override\r
+        public void sessionContextChanged(SessionContextChangedEvent event) {\r
+            sessionContext = event.getNewValue();\r
+            sessionContextTracker.track(sessionContext);\r
+        }\r
+    };\r
+\r
+    public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, WidgetSupport support, int style) {\r
+\r
+        super(parent, SWT.NONE);\r
+\r
+        if (args == null)\r
+            args = Collections.emptyMap();\r
+\r
+        this.args = args;\r
+        this.site = site;\r
+        this.style = style;\r
+        this.resourceManager = new LocalResourceManager(JFaceResources.getResources(parent.getDisplay()), this);\r
+\r
+        contextProvider = getSessionContextProvider(site);\r
+\r
+        Integer maxChildren = (Integer)args.get("maxChildren");\r
+\r
+        GridLayoutFactory.fillDefaults().equalWidth(false).numColumns(1).margins(0,0).spacing(0,0).applyTo(this);\r
+\r
+        toolComposite = new Composite(this, SWT.NONE);\r
+//        toolComposite.setBackground(toolComposite.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
+//        GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite);\r
+        GridLayoutFactory.fillDefaults().applyTo(toolComposite);\r
+\r
+        ad = new TreeColumnLayout();\r
+        explorerComposite = new Composite(this, SWT.NONE);\r
+        explorerComposite.setLayout(ad);\r
+        GridDataFactory.fillDefaults().grab(true, true).minSize(1, 50).applyTo(explorerComposite);\r
+\r
+        if (args.containsKey("treeView") && Boolean.TRUE.equals(args.get("treeView"))) {\r
+               explorer = createExplorerControl2(explorerComposite, maxChildren);\r
+        } else {\r
+               explorer = createExplorerControl(explorerComposite, maxChildren);\r
+        }\r
+        \r
+        if (args.containsKey("useNodeBrowseContexts") && Boolean.TRUE.equals(args.get("useNodeBrowseContexts"))) {\r
+               useNodeBrowseContexts = true;\r
+        } else {\r
+               useNodeBrowseContexts = false;\r
+        }\r
+        \r
+        if (args.containsKey("useNodeActionContexts") && Boolean.TRUE.equals(args.get("useNodeActionContexts"))) {\r
+               useNodeActionContexts = true;\r
+        } else {\r
+               useNodeActionContexts = false;\r
+        }\r
+        \r
+        toolComposite2 = new Composite(this, SWT.NONE);\r
+//        toolComposite2.setBackground(toolComposite2.getDisplay().getSystemColor(SWT.COLOR_DARK_YELLOW));\r
+//        GridDataFactory.fillDefaults().grab(true, false).minSize(1, 1).applyTo(toolComposite);\r
+        GridDataFactory.fillDefaults().grab(true, false).applyTo(toolComposite2);\r
+        GridLayoutFactory.fillDefaults().applyTo(toolComposite2);\r
+\r
+        this.support = support;\r
+\r
+        if (support != null)\r
+            support.register(this);\r
+\r
+    }\r
+\r
+    public GraphExplorerComposite(Map<String, Object> args, IWorkbenchSite site, Composite parent, int style) {\r
+\r
+        this(args, site, parent, null, style);\r
+\r
+    }\r
+\r
+    public ISessionContextProvider getSessionContextProvider(IWorkbenchSite site) {\r
+        if(site != null)\r
+            return SimanticsUI.getSessionContextProvider(site.getWorkbenchWindow());\r
+        else\r
+            return SimanticsUI.getSessionContextProvider();\r
+    }\r
+\r
+    public GraphExplorer getExplorer() {\r
+        return explorer;\r
+    }\r
+\r
+    public Composite getExplorerComposite() {\r
+        return explorerComposite;\r
+    }\r
+\r
+    public <T> T getExplorerControl() {\r
+        return explorer.getControl();\r
+    }\r
+\r
+    public void addListenerToControl(int eventType, Listener listener) {\r
+        ((Tree)explorer.getControl()).addListener(eventType, listener);\r
+    }\r
+\r
+    public void finish() {\r
+        created = true;\r
+        createControls(site);\r
+        attachToSession();\r
+    }\r
+\r
+    IWorkbenchSite getSite() {\r
+        return site;\r
+    }\r
+\r
+    protected void activateUiContexts() {\r
+        Collection<String> contexts = getUiContexts();\r
+        if (contexts == null || contexts.isEmpty())\r
+            return;\r
+        IWorkbenchSite site = getSite();\r
+        if (site != null) {\r
+            IContextService cs = (IContextService) getSite().getService(IContextService.class);\r
+            for (String context : contexts)\r
+                cs.activateContext(context);\r
+        }\r
+    }\r
+\r
+    protected void createControls(IWorkbenchSite site) {\r
+\r
+        // Initialize explorer control.\r
+//        GridDataFactory.fillDefaults().grab(true, true).applyTo(explorer.getControl());\r
+\r
+        Control control = explorer.getControl();\r
+\r
+        // Initialize context menu if an initializer is provided.\r
+        IContextMenuInitializer cmi = getContextMenuInitializer();\r
+        if (cmi != null) {\r
+            ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+            menuManager = cmi.createContextMenu(control, selectionProvider, site);\r
+        }\r
+\r
+        // Initialize UI contexts\r
+        activateUiContexts();\r
+\r
+        // Initialize DND.\r
+        dragSource = setupDND(explorer);\r
+\r
+        // Listeners are only added once per listener, not every time the\r
+        // session context changes.\r
+        addListeners(explorer, menuManager);\r
+\r
+        userSelectedComparableFactoryQueryProcessor = new UserSelectedComparableFactoryQueryProcessor();\r
+        userSelectedViewpointFactoryQueryProcessor = new UserSelectedViewpointFactoryQueryProcessor();\r
+        filterSelectionRequestQueryProcessor = new FilterSelectionRequestQueryProcessor();\r
+        \r
+        explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
+\r
+        boolean hasExtraControls = false;\r
+        boolean hasExtraControls2 = false;\r
+\r
+        Boolean displaySelectors = (Boolean)args.get("displaySelectors");\r
+        if(displaySelectors == null || displaySelectors == true) {\r
+\r
+            @SuppressWarnings("unused")\r
+            ComparatorSelector comparatorSelector = new ComparatorSelector(explorer, userSelectedComparableFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
+//            comparatorSelector.moveAbove(control);\r
+\r
+            @SuppressWarnings("unused")\r
+            ViewpointSelector viewpointSelector = new ViewpointSelector(explorer, userSelectedViewpointFactoryQueryProcessor, toolComposite, SWT.READ_ONLY);\r
+//            viewpointSelector.moveAbove(control);\r
+\r
+            hasExtraControls = true;\r
+\r
+        }\r
+\r
+        Boolean displayFilter = (Boolean)args.get("displayFilter");\r
+        if(displayFilter == null || displayFilter == true) {\r
+\r
+               \r
+               filterArea = filterAreaSource.getFilterArea(toolComposite, explorer);\r
+//            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite, SWT.READ_ONLY);\r
+            //filterArea.moveAbove(control);\r
+\r
+            hasExtraControls = true;\r
+\r
+        }\r
+\r
+        Boolean displayFilter2 = (Boolean)args.get("displayFilter2");\r
+        if(displayFilter2 != null && displayFilter2 == true) {\r
+\r
+               filterArea = filterAreaSource.getFilterArea(toolComposite2, explorer);\r
+//            filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, toolComposite2, SWT.READ_ONLY);\r
+//            //filterArea.moveAbove(control);\r
+\r
+            hasExtraControls2 = true;\r
+\r
+        }\r
+\r
+//        filterArea = new FilterArea(explorer, filterSelectionRequestQueryProcessor, this, SWT.READ_ONLY);\r
+//        filterArea.moveAbove(control);\r
+\r
+        if(!hasExtraControls)\r
+            GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite);\r
+        if(!hasExtraControls2)\r
+            GridDataFactory.fillDefaults().grab(true, false).minSize(0, 0).hint(0, 0).applyTo(toolComposite2);\r
+\r
+        GridDataFactory.fillDefaults().grab(true, true).span(2,1).applyTo(control);\r
+\r
+        //tree.getTree().setLayout(new FillLayout()\r
+        //this.setLayout(LayoutUtils.createNoBorderGridLayout(2, false));\r
+\r
+        DropTarget target = new DropTarget(control, DND.DROP_COPY | DND.DROP_LINK);\r
+        target.setTransfer(getAcceptedDataTypes());\r
+        target.addDropListener(new DropTargetListener() {\r
+\r
+            Tree tree = (Tree)explorer.getControl();\r
+\r
+            @Override\r
+            public void dragEnter(DropTargetEvent event) {\r
+                event.detail = DND.DROP_COPY;\r
+            }\r
+\r
+            @Override\r
+            public void dragLeave(DropTargetEvent event) {\r
+            }\r
+\r
+            @Override\r
+            public void dragOperationChanged(DropTargetEvent event) {\r
+            }\r
+\r
+            @Override\r
+            public void dragOver(DropTargetEvent event) {\r
+            }\r
+\r
+            @Override\r
+            public void drop(DropTargetEvent event) {\r
+                TreeItem item = tree.getItem(tree.toControl(event.x, event.y));\r
+                if(item != null) {\r
+                       Object data = item.getData();\r
+                       if (data instanceof NodeContext)\r
+                               handleDrop(event.data, (NodeContext) data);\r
+                       else if (data instanceof IAdaptable) {\r
+                               IAdaptable a = (IAdaptable) data;\r
+                               handleDrop(event.data, (NodeContext) a.getAdapter(NodeContext.class));\r
+                       }\r
+                } else\r
+                    handleDrop(event.data, null);\r
+            }\r
+\r
+            @Override\r
+            public void dropAccept(DropTargetEvent event) {\r
+            }\r
+\r
+        });\r
+\r
+        // Add workbench listeners and make sure they are cleaned up\r
+        setWorkbenchListeners();\r
+        control.addListener(SWT.Dispose, new Listener() {\r
+            @Override\r
+            public void handleEvent(Event event) {\r
+                doDispose();\r
+            }\r
+        });\r
+    }\r
+\r
+    @SuppressWarnings({ "rawtypes", "unchecked" })\r
+    @Override\r
+    public Object getAdapter(Class adapter) {\r
+        if (GraphExplorer.class == adapter)\r
+            return explorer;\r
+        if (EvaluatorData.class == adapter)\r
+            return evaluatorData;\r
+        if (BrowseContext.class == adapter) {\r
+            EvaluatorData ed = evaluatorData;\r
+            return ed != null ? ed.getBrowseContext() : null;\r
+        }\r
+        if (adapter == IFilterAreaProvider.class)\r
+            return filterArea;\r
+        return explorer.getAdapter(adapter);\r
+    }\r
+\r
+    protected void doDispose() {\r
+        //System.out.println(this + ".GraphExplorerComposite.doDispose()");\r
+        removeWorkbenchListeners();\r
+        userSelectedComparableFactoryQueryProcessor = null;\r
+        userSelectedViewpointFactoryQueryProcessor = null;\r
+        filterSelectionRequestQueryProcessor = null;\r
+\r
+        disposeState = DisposeState.Disposing;\r
+        try {\r
+            //System.out.println(this + ".GraphExplorerViewBase.dispose()");\r
+            if (contextProvider != null) {\r
+                contextProvider.removeContextChangedListener(contextChangeListener);\r
+                contextProvider = null;\r
+            }\r
+            sessionContextTracker.untrack();\r
+            resourceManager = null;\r
+            explorer = null;\r
+            sessionContext = null;\r
+            dragSource = null;\r
+//            parent = null;\r
+        } finally {\r
+            disposeState = DisposeState.Disposed;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void dispose() {\r
+        doDispose();\r
+        super.dispose();\r
+    }\r
+\r
+    protected StatePersistor getStatePersistor() {\r
+       return persistor;\r
+    }\r
+    \r
+    public void setStatePersistor(StatePersistor persistor) {\r
+       this.persistor = persistor;\r
+    }\r
+    \r
+    protected void initializeExplorer(GraphExplorer explorer, ISessionContext context) {\r
+\r
+        if(explorer == null || explorer.isDisposed()) return;\r
+        if(context == null) return;\r
+        if(browseContexts == null) return;\r
+\r
+        Session session = context != null ? context.getSession() : null;\r
+        setupDragSource(session);\r
+\r
+        if (session != null) {\r
+            evaluatorData = createEvaluatorData(session);\r
+            explorer.setDataSource(new AsyncReadGraphDataSource(session));\r
+            explorer.setDataSource(new ReadGraphDataSource(session));\r
+        }\r
+        else {\r
+            evaluatorData = new EvaluatorDataImpl();\r
+            explorer.removeDataSource(AsyncReadGraph.class);\r
+            explorer.removeDataSource(ReadGraph.class);\r
+        }\r
+\r
+        explorer.setPersistor(getStatePersistor());\r
+        \r
+        explorer.setProcessor(new ComparableFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new ViewpointFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new LabelerFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new ImagerFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new LabelDecoratorFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new ImageDecoratorFactoryResolver(evaluatorData));\r
+        explorer.setProcessor(new DefaultIsCheckedProcessor2(evaluatorData));\r
+        explorer.setPrimitiveProcessor(new TypesQueryProcessor());\r
+        explorer.setPrimitiveProcessor(new StandardContextTypesQueryProcessor());\r
+        explorer.setPrimitiveProcessor(new InheritsQueryProcessor());\r
+        explorer.setPrimitiveProcessor(new RelatedObjectsQueryProcessor());\r
+\r
+        explorer.setPrimitiveProcessor(userSelectedViewpointFactoryQueryProcessor);\r
+        explorer.setProcessor(new ComparableSelectorQueryProcessor());\r
+        explorer.setPrimitiveProcessor(userSelectedComparableFactoryQueryProcessor);\r
+        explorer.setPrimitiveProcessor(filterSelectionRequestQueryProcessor);\r
+\r
+        initializeExplorerWithEvaluator(explorer, context, evaluatorData);\r
+    }\r
+\r
+    protected void initializeExplorerWithEvaluator(GraphExplorer explorer, ISessionContext context, EvaluatorData data) {\r
+    }\r
+\r
+    protected EvaluatorData createEvaluatorData(Session context) {\r
+\r
+//        Set<String> browseContexts = getArgument("browseContexts");\r
+\r
+        return Evaluators.load(context.getSession(), browseContexts, resourceManager, useNodeBrowseContexts, useNodeActionContexts);\r
+\r
+    }\r
+\r
+    protected Transfer[] getAcceptedDataTypes() {\r
+        return new Transfer[] {  LocalObjectTransfer.getTransfer(), FileTransfer.getInstance() };\r
+    }\r
+\r
+    protected void handleDrop(Object data, NodeContext target) {\r
+    }\r
+\r
+    DragSourceListenerFactory dragSourceListenerFactory = new DragSourceListenerFactory() {\r
+\r
+        final Transfer[] transfers = new Transfer[] {LocalObjectTransfer.getTransfer(), TextTransfer.getInstance() };\r
+\r
+        @Override\r
+        public DragSourceListener get(ISelectionProvider selectionProvider) {\r
+\r
+               LocalSelectionDragSourceListener ls = new LocalSelectionDragSourceListener(selectionProvider);\r
+\r
+               return new DragSourceListener() {\r
+                               \r
+                               @Override\r
+                               public void dragStart(DragSourceEvent event) {\r
+                                       ls.dragStart(event);\r
+                               }\r
+                               \r
+                               @Override\r
+                               public void dragSetData(DragSourceEvent event) {\r
+                                       if(TextTransfer.getInstance().isSupportedType(event.dataType)) {\r
+                                       try {\r
+                                                       event.data = WorkbenchSelectionUtils.getPossibleJSON(selectionProvider.getSelection());\r
+                                               } catch (DatabaseException e) {\r
+                                                       event.data = "{ type:\"Exception\" }";\r
+                                                       Logger.defaultLogError(e);\r
+                                               }\r
+                                       } else if (LocalObjectTransfer.getTransfer().isSupportedType(event.dataType)) {\r
+                                               ls.dragSetData(event);\r
+                                       }\r
+                               }\r
+                               \r
+                               @Override\r
+                               public void dragFinished(DragSourceEvent event) {\r
+                                       ls.dragFinished(event);\r
+                               }\r
+                       };\r
+        }\r
+\r
+        @Override\r
+        public Transfer[] getTransfers() {\r
+            return transfers;\r
+        }\r
+\r
+    };\r
+\r
+    public void setDragSourceListenerFactory(DragSourceListenerFactory dragSourceListenerFactory) {\r
+        this.dragSourceListenerFactory = dragSourceListenerFactory;\r
+    }\r
+\r
+    protected DragSourceListener setupDND(GraphExplorer explorer) {\r
+\r
+        ISelectionProvider selectionProvider = (ISelectionProvider)explorer.getAdapter(ISelectionProvider.class);\r
+\r
+        DragSourceListener listener = createDragSourceListener(selectionProvider);\r
+\r
+        Control control = explorer.getControl();\r
+        DragSource source = createDragSource(control);\r
+        source.setTransfer(getTransfers());\r
+        source.addDragListener(listener);\r
+        source.setDragSourceEffect(new NoImageDragSourceEffect(control));\r
+\r
+        return listener;\r
+\r
+    }\r
+\r
+    protected DragSourceListener createDragSourceListener(ISelectionProvider selectionProvider) {\r
+        return dragSourceListenerFactory.get(selectionProvider);\r
+    }\r
+\r
+    private int dragStyle = DND.DROP_LINK | DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;\r
+\r
+    protected void setDragStyle(int style) {\r
+        this.dragStyle = style;\r
+    }\r
+\r
+    protected int getDragStyle() {\r
+        return dragStyle;\r
+    }\r
+\r
+    protected DragSource createDragSource(Control control) {\r
+        return new DragSource(control, getDragStyle());\r
+    }\r
+\r
+    protected Transfer[] getTransfers() {\r
+        return dragSourceListenerFactory.getTransfers();\r
+    }\r
+\r
+    public EvaluatorData getEvaluatorData() {\r
+        return evaluatorData;\r
+    }\r
+\r
+    public interface InputSource {\r
+        /**\r
+         * @param ctx the session context to read the input from. May be\r
+         *        <code>null</code> if there is no session.\r
+         * @return the input object of a graph explorer. To indicate no input,\r
+         *         use {@link GraphExplorerConstants#EMPTY_INPUT}. Never return\r
+         *         <code>null</code>.\r
+         */\r
+        Object get(ISessionContext ctx, Object selection);\r
+    }\r
+    \r
+    public interface FilterSource {\r
+       \r
+       \r
+       \r
+    }\r
+\r
+    /**\r
+     * The default hint tracker that will be active if\r
+     * {@link GraphExplorerComposite#setSessionContextTracker(IHintTracker) is\r
+     * not called.\r
+     */\r
+    public class SessionContextProjectTracker extends HintTracker {\r
+        public SessionContextProjectTracker() {\r
+            IHintListener activeProjectListener = new HintListenerAdapter() {\r
+                @Override\r
+                public void hintChanged(IHintObservable sender, Key key, Object oldValue, Object newValue) {\r
+                    applySessionContext(getSessionContext());\r
+                }\r
+            };\r
+            addKeyHintListener(ProjectKeys.KEY_PROJECT, activeProjectListener);\r
+        }\r
+    }\r
+\r
+    public class DirectInputSource implements InputSource {\r
+        @Override\r
+        public Object get(ISessionContext ctx, Object selection) {\r
+            return selection;\r
+        }\r
+    }\r
+    \r
+    public static class SelectionFilterAreaSource implements FilterAreaSource {\r
+\r
+               @Override\r
+               public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
+                       FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
+                       return new FilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
+               }\r
+       \r
+    }\r
+\r
+    public static class RootFilterAreaSource implements FilterAreaSource {\r
+\r
+               @Override\r
+               public IFilterArea getFilterArea(Composite parent, GraphExplorer explorer) {\r
+                       FilterSelectionRequestQueryProcessor processor = (FilterSelectionRequestQueryProcessor)explorer.getPrimitiveProcessor(BuiltinKeys.SELECTION_REQUESTS);\r
+                       return new RootFilterArea(explorer, processor, parent, SWT.READ_ONLY);\r
+               }\r
+       \r
+    }\r
+\r
+    protected void setSessionContextTracker(IHintTracker tracker) {\r
+        this.sessionContextTracker = tracker;\r
+    }\r
+\r
+    public void setInputSource(InputSource source) {\r
+        this.inputSource = source;\r
+    }\r
+    \r
+    public void setFilterAreaSource(FilterAreaSource provider) {\r
+       this.filterAreaSource = provider;\r
+    }\r
+\r
+    public void setSelectionTransformation(BinaryFunction<Object[], GraphExplorer, Object[]> transformation) {\r
+        this.selectionTransformation = transformation;\r
+        if(explorer != null) explorer.setSelectionTransformation(transformation);\r
+    }\r
+\r
+    protected Set<String> getBrowseContexts() {\r
+       return browseContexts;\r
+    }\r
+    \r
+    public void setBrowseContexts(Set<String> contexts) {\r
+        this.browseContexts = contexts;\r
+        //initializeExplorer(explorer, getSessionContext());\r
+    }\r
+\r
+    public void setBrowseContexts(String ... contexts) {\r
+        this.browseContexts = new HashSet<String>();\r
+        for(String s : contexts) this.browseContexts.add(s);\r
+        initializeExplorer(explorer, getSessionContext());\r
+    }\r
+\r
+    public void setContextMenuId(String contextMenuId) {\r
+        this.contextMenuId = contextMenuId;\r
+    }\r
+\r
+//    protected IContextMenuInitializer getContextMenuInitializer() {\r
+//        String contextMenuId = getContextMenuId();\r
+//        if(contextMenuId != null) {\r
+//            return new ContextMenuInitializer(contextMenuId);\r
+//        } else {\r
+//            return null;\r
+//        }\r
+//    }\r
+\r
+    protected String getContextMenuId() {\r
+        return this.contextMenuId;\r
+    }\r
+\r
+    public void setUiContexts(Set<String> uiContext) {\r
+        this.uiContext = uiContext;\r
+    }\r
+\r
+    public Set<String> getUiContexts() {\r
+        return uiContext;\r
+    }\r
+\r
+    protected InputSource getInputSource() {\r
+        return inputSource;\r
+    }\r
+\r
+    protected Map<String, Object> getArguments() {\r
+        return args;\r
+    }\r
+\r
+    @SuppressWarnings("unchecked")\r
+    protected <T> T getArgument(String key) {\r
+        return (T) args.get(key);\r
+    }\r
+\r
+    protected DisposeState getDisposeState() {\r
+        return disposeState;\r
+    }\r
+\r
+    public ISessionContext getSessionContext() {\r
+        return sessionContext;\r
+    }\r
+\r
+    public ISessionContextProvider getSessionContextProvider() {\r
+        return contextProvider;\r
+    }\r
+\r
+    @Override\r
+    public boolean setFocus() {\r
+        if (explorer != null && !explorer.isDisposed())\r
+            explorer.setFocus();\r
+        return true;\r
+    }\r
+\r
+    public void setWorkbenchListeners() {\r
+        if (workbenchSelectionListener == null && getSite() != null) {\r
+            ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
+            getSite().setSelectionProvider(selectionProvider);\r
+\r
+            // Listen to the workbench selection also to propagate it to\r
+            // the explorer also.\r
+            workbenchSelectionListener = new DefaultExplorerSelectionListener(site.getPage().getActivePart(), explorer);\r
+            //System.out.println("ADD WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
+            getSite().getWorkbenchWindow().getSelectionService().addPostSelectionListener(workbenchSelectionListener);\r
+        }\r
+    }\r
+\r
+    protected void removeWorkbenchListeners() {\r
+        //System.out.println("REMOVE WORKBENCH SELECTION LISTENER: " + workbenchSelectionListener);\r
+        // Remember to remove the installed workbench selection listener\r
+        if (workbenchSelectionListener != null) {\r
+            getSite().getWorkbenchWindow().getSelectionService().removePostSelectionListener(workbenchSelectionListener);\r
+            workbenchSelectionListener = null;\r
+\r
+            ISelectionProvider selectionProvider = (ISelectionProvider) explorer.getAdapter(ISelectionProvider.class);\r
+            if(getSite().getSelectionProvider() == selectionProvider) getSite().setSelectionProvider(null);\r
+            \r
+        }\r
+    }\r
+\r
+    protected final void attachToSession() {\r
+\r
+        // Track active ISessionContext changes\r
+        //contextProvider = SimanticsUI.getSessionContextProvider(getViewSite().getWorkbenchWindow());\r
+        contextProvider.addContextChangedListener(contextChangeListener);\r
+\r
+        // Start tracking the current session context for input changes.\r
+        // This will/must cause applySessionContext to get called.\r
+        // Doing the applySessionContext initialization this way\r
+        // instead of directly calling it will also make sure that\r
+        // applySessionContext is only called once when first initialized,\r
+        // and not twice like with the direct invocation.\r
+        this.sessionContext = contextProvider.getSessionContext();\r
+        sessionContextTracker.track(sessionContext);\r
+    }\r
+\r
+    // /////////////////////////////////////////////////////////////////////////\r
+    // Override / implement these:\r
+\r
+//    /**\r
+//     * Returns an ID that is used for persisting a GraphExplorer instance.\r
+//     *\r
+//     * Used for </code>restoreState(IMemento)</code> and\r
+//     * <code>restoreState(IMemento)</code> in OntologyExplorer. Must be unique\r
+//     * within a workbench part.\r
+//     *\r
+//     * @return a unique name for this particular graph explorer view used for\r
+//     *         saving and restoring the state of this view part\r
+//     */\r
+//    public String getExplorerName() {\r
+//        return "GraphExplorerViewBase";\r
+//    }\r
+\r
+    /**\r
+     * Override this method to add controls to the view part. This is invoked\r
+     * before attaching the view part to a database session.\r
+     * \r
+     * @param parent\r
+     */\r
+    protected void createControls(Composite parent) {\r
+\r
+    }\r
+\r
+    /**\r
+     * Override this method and provide a proper context menu initializer if you\r
+     * want to have this base class initialize one for you.\r
+     * \r
+     * @return the initializer to be used by {@link #createControls(Composite)}\r
+     */\r
+    protected IContextMenuInitializer getContextMenuInitializer() {\r
+        String contextMenuId = getContextMenuId();\r
+        if(contextMenuId != null) {\r
+            return new ContextMenuInitializer(contextMenuId);\r
+        } else {\r
+            return null;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param parent\r
+     * @return\r
+     */\r
+    protected GraphExplorer createExplorerControl(Composite parent, Integer maxChildren) {\r
+        GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
+        if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
+\r
+        GraphExplorer ge = factory\r
+        .selectionDataResolver(new DefaultSelectionDataResolver())\r
+        .selectionTransformation(selectionTransformation)\r
+        .setServiceLocator(site)\r
+        .create(parent, style);\r
+\r
+        return ge;\r
+    }\r
+    \r
+    protected GraphExplorer createExplorerControl2(Composite parent, Integer maxChildren) {\r
+        GraphExplorerFactory factory = GraphExplorerFactory.getInstance();\r
+        if(maxChildren != null) factory = factory.maxChildrenShown(maxChildren);\r
+\r
+        GraphExplorer ge = factory\r
+        .selectionDataResolver(new DefaultSelectionDataResolver())\r
+        .selectionTransformation(selectionTransformation)\r
+        .setServiceLocator(site)\r
+        .create2(parent, style);\r
+\r
+        return ge;\r
+    }\r
+\r
+    protected void setupDragSource(Session session) {\r
+        if (dragSource instanceof SessionContainer) {\r
+            ((SessionContainer) dragSource).setSession(session);\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Override to customize the addition of listeners a newly created\r
+     * GraphExplorer.\r
+     * \r
+     * @param explorer\r
+     */\r
+    protected void addListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
+        addSelectionInputListeners(explorer, menuManager);\r
+    }\r
+\r
+    protected void addSelectionInputListeners(GraphExplorer explorer, IMenuManager menuManager) {\r
+        // Consider ENTER presses to simulate mouse left button double clicks\r
+        explorer.addListener(new DefaultKeyListener(contextProvider, explorer, new Function<String[]>() {\r
+            @Override\r
+            public String[] execute(Object... obj) {\r
+                return getEditingColumn((NodeContext) obj[0]);\r
+            }\r
+        }));\r
+        // Default double click handling\r
+        explorer.addListener(new DefaultMouseListener(explorer));\r
+    }\r
+\r
+    protected String[] getEditingColumn(NodeContext context) {\r
+        return editingColumn;\r
+    }\r
+    \r
+    public void setEditingColumn(String... columnKeysInOrderOfTrial) {\r
+       this.editingColumn = columnKeysInOrderOfTrial;\r
+    }\r
+\r
+    // Needed for preventing unnecessary re-initialization of the explorer with the same input.\r
+    private Object currentInput;\r
+    private Object currentRoot;\r
+\r
+    /**\r
+     * Invoke this to reinitialize the explorer and reset its input. The input\r
+     * will be resolved from the specified ISessionContext based on the\r
+     * {@link SessionContextInputSource} that is currently in use. If the input\r
+     * is identical to the previous input, nothing will be done.\r
+     * \r
+     * @param context\r
+     */\r
+    public final boolean applySessionContext(ISessionContext context) {\r
+\r
+        // If control is not alive anymore, do nothing.\r
+        //System.out.println(this + ": applySessionContext(" + context + "), explorer="  + explorer);\r
+        if (disposeState != DisposeState.Alive)\r
+            return false;\r
+\r
+        //System.out.println(this + ": initializeExplorer(" + explorer + ", " + context + ")");\r
+        initializeExplorer(explorer, context);\r
+\r
+\r
+        // Start tracking the session context.\r
+        //\r
+        // If this is not the same session that is currently tracked, it will\r
+        // cause IHintListeners of the sessionContextTracker to fire.\r
+        // For this we need the above input equality (identity) checking.\r
+        // This is here just to make sure that we are tracking the correct\r
+        // session context.\r
+        sessionContextTracker.track(sessionContext);\r
+\r
+        this.sessionContext = context;\r
+        Object root = inputSource.get(context, currentInput);\r
+        if (ObjectUtils.objectEquals(root, currentRoot))\r
+            return false;\r
+\r
+        currentRoot = root;\r
+\r
+        //System.out.println(this + ": setRoot(" + input + ")");\r
+        explorer.setUIContexts(uiContext);\r
+        explorer.setRoot(root);\r
+\r
+        return true;\r
+\r
+    }\r
+\r
+    protected boolean isImportantInput(Object previousSelection, Object selection) {\r
+        return !ObjectUtils.objectEquals(previousSelection, selection);\r
+    }\r
+\r
+    public void setInput(Object selection, boolean force) {\r
+\r
+        assert(created);\r
+\r
+        if (isDisposed())\r
+            return;\r
+        if (sessionContext == null)\r
+            return;\r
+\r
+        // Check if this is a duplicate of the previous selection to reduce unnecessary flicker.\r
+        if (!force && !isImportantInput(currentInput, selection))\r
+            return;\r
+\r
+        currentInput = selection;\r
+\r
+        Object root = inputSource.get(sessionContext, selection);\r
+\r
+        currentRoot = root;\r
+\r
+       explorer.setUIContexts(uiContext);\r
+\r
+        if (root == null) {\r
+            explorer.setRoot(GraphExplorer.EMPTY_INPUT);\r
+        } else {\r
+            explorer.setRoot(root);\r
+        }\r
+\r
+    }\r
+\r
+    public void setColumnsVisible(boolean visible) {\r
+        explorer.setColumnsVisible(visible);\r
+    }\r
+\r
+    private int getColumnWidth(Column column, ExplorerState state) {\r
+       // Get saved width from the persistor if there is one.\r
+        if (state != null && state.columnWidths != null) {\r
+               Integer width = state.columnWidths.get(column.getLabel());\r
+               if (width != null)\r
+                       return width;\r
+        }\r
+        return column.getWidth();\r
+    }\r
+    \r
+    public void setColumns(Column[] columns) {\r
+\r
+        explorer.setColumns(columns, new Consumer<Map<Column, Object>>() {\r
+\r
+            @Override\r
+            public void accept(Map<Column, Object> objects) {\r
+               ExplorerState state = null;\r
+               if (persistor != null) {\r
+                       state = persistor.deserialize(\r
+                               Platform.getStateLocation(Activator.getDefault().getBundle()).toFile(),\r
+                               explorer.getRoot());\r
+               }\r
+\r
+                for(Map.Entry<Column, Object> entry : objects.entrySet()) {\r
+                    Column column = entry.getKey();\r
+                    TreeColumn treeColumn = (TreeColumn)entry.getValue();\r
+\r
+                    if (column.getWidth() < 0) {\r
+                        throw new IllegalArgumentException("Column minimum width cannot be < 0, got " + column.getWidth());\r
+                    }\r
+\r
+                    int width = getColumnWidth(column, state);\r
+                    if(column.hasGrab()) {\r
+                       \r
+                        ad.setColumnData(treeColumn, new ColumnWeightData(column.getWeight(), width));\r
+\r
+                    } else {\r
+\r
+                        ad.setColumnData(treeColumn, new ColumnWeightData(0, width));\r
+\r
+                    }\r
+\r
+                }\r
+            }\r
+\r
+        });\r
+\r
+    }\r
+\r
+    @Override\r
+    public void setInput(ISessionContext context, Object input) {\r
+        setInput(input, false);\r
+    }\r
+\r
+    public void setMaxChildren(int maxChildren) {\r
+        explorer.setMaxChildren(maxChildren);\r
+    }\r
+    \r
+    public <T> void addListener(ExplorerMouseListenerImpl<T> listener) {\r
+       \r
+       support.register(listener);\r
+       listener.register(explorer);\r
+       explorer.addListener(listener);\r
+       \r
+    }\r
+\r
+//    @Override\r
+//    public Point computeSize(int wHint, int hHint) {\r
+//     Point p = super.computeSize(wHint, hHint);\r
+//     System.err.println("graphExplorerComposite.computeSize " + p);\r
+//     return p;\r
+//    }\r
+//    \r
+//    @Override\r
+//    public Point computeSize(int wHint, int hHint, boolean changed) {\r
+//     Point p = super.computeSize(wHint, hHint, changed);\r
+//     System.err.println("graphExplorerComposite.computeSize " + p);\r
+//     return p;\r
+//    }\r
+    \r
+}\r