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