]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.utils.ui/src/org/simantics/utils/ui/ISelectionUtils.java
Fixed all line endings of the repository
[simantics/platform.git] / bundles / org.simantics.utils.ui / src / org / simantics / utils / ui / ISelectionUtils.java
index 1f4e22824315ede3f0b20eb79dfde21319fdd990..c04ad572bad1ebd48ed130e3c8916cf64fa2311b 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-/*\r
- * 25.8.2006\r
- */\r
-package org.simantics.utils.ui;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collection;\r
-import java.util.Collections;\r
-import java.util.HashMap;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.eclipse.core.runtime.Assert;\r
-import org.eclipse.core.runtime.IAdaptable;\r
-import org.eclipse.jface.viewers.ISelection;\r
-import org.eclipse.jface.viewers.IStructuredSelection;\r
-import org.eclipse.jface.viewers.StructuredSelection;\r
-import org.simantics.utils.datastructures.hints.IHintContext;\r
-import org.simantics.utils.datastructures.hints.IHintContext.Key;\r
-\r
-/**\r
- * ISelectionUtils contains static utility methods for dealing with the\r
- * ISelection interface.\r
- * \r
- * @author Toni Kalajainen\r
- */\r
-public class ISelectionUtils<T> {\r
-\r
-    /**\r
-     * This method converts selection sel for to collection of instances of T.\r
-     * All elements of the selection are assumed to be instances of T.\r
-     * \r
-     * @param <T> type of interest\r
-     * @param sel selection\r
-     * @return list\r
-     * @throws ClassCastException if the selection contains elements not\r
-     *         instance of T\r
-     */\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> List<T> convertSelection(ISelection sel) throws ClassCastException\r
-    {\r
-        if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
-            return Collections.emptyList();\r
-\r
-        List<T> result = new ArrayList<T>();\r
-        //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];\r
-        IStructuredSelection ss = (IStructuredSelection) sel;\r
-        for (Object o : ss.toArray())\r
-            //if (tClass.isAssignableFrom(o.getClass()))\r
-            result.add((T)o);\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * This method reads selection sel for all instances of T.\r
-     * All elements of the selection are assumed to be instances of T.\r
-     * \r
-     * @param <T> type of interest\r
-     * @param sel selection\r
-     * @return set\r
-     * @throws ClassCastException if the selection contains elements not\r
-     *         instance of T\r
-     */\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> Set<T> convertSetSelection(ISelection sel) throws ClassCastException\r
-    {\r
-        if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
-            return Collections.emptySet();\r
-\r
-        Set<T> result = new HashSet<T>();\r
-        //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];\r
-        IStructuredSelection ss = (IStructuredSelection) sel;\r
-        for (Object o : ss.toArray())\r
-            //if (tClass.isAssignableFrom(o.getClass()))\r
-            result.add((T)o);\r
-        return result;\r
-    }\r
-\r
-\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> T convertSingleSelection(ISelection sel)\r
-    {\r
-        if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
-            return null;\r
-        IStructuredSelection ss = (IStructuredSelection) sel;\r
-        return (ss.size() == 1) ? (T) ss.getFirstElement() : null;\r
-    }\r
-\r
-    /**\r
-     * This method converts selection sel to collection of instances of T\r
-     * @param <T> type of interest\r
-     * @param sel selection\r
-     * @return list\r
-     */\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> List<T> filterSelection(ISelection sel, Class<T> assignableFrom)\r
-    {\r
-        if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
-            return Collections.emptyList();\r
-\r
-        List<T> result = new ArrayList<T>();\r
-        IStructuredSelection ss = (IStructuredSelection) sel;\r
-        for (Object o : ss.toArray()) {\r
-            if (o != null && assignableFrom.isAssignableFrom(o.getClass())) {\r
-                result.add((T)o);\r
-            } else if (o instanceof IAdaptable) {\r
-                T t = (T) ((IAdaptable) o).getAdapter(assignableFrom);\r
-                if (t != null)\r
-                    result.add(t);\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * This method reads selection sel for all instances of T.\r
-     * \r
-     * @param <T> type of interest\r
-     * @param sel selection\r
-     * @return all instances of T in sel\r
-     */\r
-    public static <T> Set<T> filterSetSelection(Object sel, Class<T> assignableFrom)\r
-    {\r
-        if (sel instanceof IStructuredSelection) {\r
-            IStructuredSelection ss = (IStructuredSelection) sel;\r
-            if (!ss.isEmpty())\r
-                return filterCollection(ss.toList(), assignableFrom, new HashSet<T>());\r
-        } else if (sel instanceof Collection<?>) {\r
-            Collection<?> c = (Collection<?>) sel;\r
-            if (!c.isEmpty())\r
-                return filterCollection(c, assignableFrom, new HashSet<T>());\r
-        }\r
-\r
-        return Collections.emptySet();\r
-    }\r
-\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> T filterSingleSelection(Object sel, Class<T> assignableTo)\r
-    {\r
-       if (sel == null) {\r
-               return null;\r
-       } else if (sel instanceof IStructuredSelection) {\r
-            IStructuredSelection ss = (IStructuredSelection) sel;\r
-            if (ss.size() == 1)\r
-                return tryAdapt(ss.getFirstElement(), assignableTo);\r
-        } else if (sel instanceof Collection<?>) {\r
-            Collection<?> c = (Collection<?>) sel;\r
-            if (c.size() == 1)\r
-                return tryAdapt(c.iterator().next(), assignableTo);\r
-        } else if (sel.getClass().isArray()) {\r
-               Object[] os = (Object[])sel;\r
-               Object result = null;\r
-               for(Object o : os) {\r
-                       Object r = tryAdapt(o, assignableTo);\r
-                       if(r != null) {\r
-                               if(result != null) return null;\r
-                               result = r;\r
-                       }\r
-               }\r
-               return (T)result;\r
-        }\r
-        return null;\r
-    }\r
-\r
-    public static <T> T findFirstAdaptable(Object sel, Class<T> assignableTo)\r
-    {\r
-        if (sel instanceof IStructuredSelection) {\r
-            IStructuredSelection ss = (IStructuredSelection) sel;\r
-            if (!ss.isEmpty())\r
-                return findFirstAdaptable_(ss.toList(), assignableTo);\r
-        } else if (sel instanceof Collection<?>) {\r
-            Collection<?> c = (Collection<?>) sel;\r
-            if (!c.isEmpty())\r
-                return findFirstAdaptable_(c, assignableTo);\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static <T> T findFirstAdaptable_(Collection<?> objects, Class<T> assignableTo) {\r
-        for (Object o : objects) {\r
-            T t = tryAdapt(o, assignableTo);\r
-            if (t != null)\r
-                return t;\r
-        }\r
-        return null;\r
-    }\r
-\r
-    private static <T, C extends Collection<T>> C filterCollection(Collection<?> objects, Class<T> assignableTo, C result) {\r
-        for (Object o : objects) {\r
-            T t = tryAdapt(o, assignableTo);\r
-            if (t != null)\r
-                result.add(t);\r
-        }\r
-        return result;\r
-    }\r
-\r
-    @SuppressWarnings("unchecked")\r
-    private static <T> T tryAdapt(Object o, Class<T> assignableTo) {\r
-        if (o != null && assignableTo.isAssignableFrom(o.getClass())) {\r
-            return (T) o;\r
-        } else if (o instanceof IAdaptable) {\r
-            T t = (T) ((IAdaptable) o).getAdapter(assignableTo);\r
-            if (t != null) {\r
-                return t;\r
-            }\r
-        }\r
-        return null;\r
-    }\r
-\r
-    /**\r
-     * Try to extract a single object that is an instance of the specified class\r
-     * out of the provided selection object.\r
-     * \r
-     * This tries everything even remotely plausible - and then some.\r
-     * \r
-     * This method works as follows:\r
-     * <ul>\r
-     * <li>Supported input selection objects: IStructuredSelection and\r
-     * Collection&lt;?&gt;, IHintContext, IAdaptable, direct instances of the\r
-     * requested class</li>\r
-     * <li>Selection elements are assumed to be either instances of\r
-     * IHintContext, IAdaptable or direct instances of the requested class</li>\r
-     * <li>If an IHintContext is found, the result object is searched within it\r
-     * with the specified key.</li>\r
-     * <li>Searching involves testing whether the hint value is an instance of\r
-     * clazz or adaptable to it through {@link IAdaptable}.</li>\r
-     * </ul>\r
-     * \r
-     * \r
-     * \r
-     * @param selection\r
-     * @param key\r
-     * @param clazz desired class of the objects to look for in the selection\r
-     * @return a single objects matching the search criteria. If there are no or\r
-     *         several matches, <code>null</code> is returned\r
-     */\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz) {\r
-        return getSinglePossibleKey(object, key, clazz, true);\r
-    }\r
-\r
-    /**\r
-     * Try to extract a single object that is an instance of the specified class\r
-     * out of the provided selection object.\r
-     * \r
-     * This tries everything even remotely plausible - and then some.\r
-     * \r
-     * This method works as follows:\r
-     * <ul>\r
-     * <li>Supported input selection objects: IStructuredSelection and\r
-     * Collection&lt;?&gt;, IHintContext, IAdaptable, direct instances of the\r
-     * requested class</li>\r
-     * <li>Selection elements are assumed to be either instances of\r
-     * IHintContext, IAdaptable or direct instances of the requested class</li>\r
-     * <li>If an IHintContext is found, the result object is searched within it\r
-     * with the specified key.</li>\r
-     * <li>Searching involves testing whether the hint value is an instance of\r
-     * clazz or adaptable to it through {@link IAdaptable}.</li>\r
-     * </ul>\r
-     * \r
-     * \r
-     * \r
-     * @param selection\r
-     * @param key\r
-     * @param clazz desired class of the objects to look for in the selection\r
-     * @return a single objects matching the search criteria. If there are no or\r
-     *         several matches, <code>null</code> is returned\r
-     */\r
-    @SuppressWarnings("unchecked")\r
-    public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz, boolean allowDirectMatch) {\r
-        if (object == null)\r
-            return null;\r
-\r
-        // Direct match is returned without key analysis\r
-        if (allowDirectMatch && clazz.isInstance(object))\r
-            return (T) object;\r
-\r
-        if (object instanceof ISelection) {\r
-            ISelection sel = (ISelection) object;\r
-\r
-            if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))\r
-                return null;\r
-\r
-            IStructuredSelection ss = (IStructuredSelection) sel;\r
-            if (ss.size() != 1)\r
-                return null;\r
-\r
-            // The result must now be in the first and only element\r
-            return getSinglePossibleKey(ss.getFirstElement(), key, clazz, allowDirectMatch);\r
-        }\r
-\r
-        if (object instanceof Collection<?>) {\r
-            Collection<?> c = (Collection<?>) object;\r
-            if (c.size() != 1)\r
-                return null;\r
-\r
-            return getSinglePossibleKey(c.iterator().next(), key, clazz, allowDirectMatch);\r
-        }\r
-\r
-        // If there was no success so far now we must take the Key into account\r
-        if (object instanceof IHintContext) {\r
-            IHintContext context = (IHintContext) object;\r
-            Object hint = context.getHint(key);\r
-\r
-            // We had a hint context and a matching key was not available - now try single hint - TODO: this somewhat questionable\r
-            if (hint == null) {\r
-                // NOTE: Removed because of a bug:\r
-                // https://www.simantics.org/redmine/issues/3061\r
-                // Hope this doesn't break existing code.\r
-                Map<Key, Object> hints = context.getHints();\r
-                // There are multiple hints, thats it, there is no result\r
-                if(hints.size() != 1) return null;\r
-                hint = hints.values().iterator().next();\r
-\r
-                T t = getSinglePossibleKey(hint, key, clazz);\r
-//                if (t != null) {\r
-//                    System.out.println("******************** GEEZ: " + t);\r
-//                    new Exception().printStackTrace();\r
-//                }\r
-                return t;\r
-//                return null;\r
-            }\r
-\r
-            if (clazz.isInstance(hint)) {\r
-                return (T) hint;\r
-            } else if (hint instanceof IAdaptable) {\r
-                T adapter = (T) ((IAdaptable) hint).getAdapter(clazz);\r
-                if (adapter != null)\r
-                    return adapter;\r
-            } else {\r
-                return getSinglePossibleKey(hint, key, clazz);\r
-            }\r
-        }\r
-\r
-        if (object instanceof IAdaptable)\r
-            return getSinglePossibleKey(((IAdaptable) object).getAdapter(IHintContext.class), key, clazz, allowDirectMatch);\r
-\r
-        return null;\r
-\r
-    }\r
-\r
-    /**\r
-     * Try to extract the possible objects that are instances of the specified\r
-     * class out of the provided selection object.\r
-     * \r
-     * This method works as follows:\r
-     * <ul>\r
-     * <li>Supported input selection objects: IStructuredSelection and\r
-     * Collection&lt;?&gt;</li>\r
-     * <li>Selection elements are assumed to be IHintContext instances</li>\r
-     * <li>The result objects are searched for in the IHintContexts with the\r
-     * specified key.</li>\r
-     * <li>Searching involves testing whether the hint value is an instance of\r
-     * clazz or adaptable to it through {@link IAdaptable}.</li>\r
-     * </ul>\r
-     * \r
-     * All objects that pass through this filter are returned as the result.\r
-     * \r
-     * @param selection\r
-     * @param key\r
-     * @param clazz desired class of the objects to look for in the selection\r
-     * @return list of the criteria matching elements in the selection or empty\r
-     *         list if nothing suitable was found\r
-     */\r
-    public static <T> List<T> getPossibleKeys(Object selection, Key key, Class<T> clazz) {\r
-        if (selection == null)\r
-            return Collections.emptyList();\r
-\r
-        if (selection instanceof IStructuredSelection) {\r
-            IStructuredSelection ss = (IStructuredSelection) selection;\r
-            if (ss.isEmpty())\r
-                return Collections.emptyList();\r
-            return extractPossibleKeys(ss.toList(), key, clazz);\r
-        }\r
-\r
-        if (selection instanceof Collection<?>) {\r
-            Collection<?> c = (Collection<?>) selection;\r
-            return extractPossibleKeys(c, key, clazz);\r
-        }\r
-\r
-        if (selection.getClass().isArray()) {\r
-               Object[] c = (Object[]) selection;\r
-            return extractPossibleKeys(c, key, clazz);\r
-        }\r
-\r
-        return extractPossibleKeys(Collections.singleton(selection), key, clazz);\r
-    }\r
-\r
-    @SuppressWarnings("unchecked")\r
-    private static <T> List<T> extractPossibleKeys(Collection<?> objects, Key key, Class<T> clazz) {\r
-        if (objects.isEmpty())\r
-            return Collections.emptyList();\r
-\r
-        ArrayList<T> result = new ArrayList<T>(objects.size());\r
-        for (Object o : objects) {\r
-            if (o instanceof IHintContext) {\r
-                IHintContext context = (IHintContext) o;\r
-                Object object = context.getHint(key);\r
-                if (object != null) {\r
-                    if (clazz.isInstance(object)) {\r
-                        result.add((T) object);\r
-                    } else if (object instanceof IAdaptable) {\r
-                        Object adapter = ((IAdaptable) object).getAdapter(clazz);\r
-                        if (adapter != null)\r
-                            result.add((T) adapter);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    @SuppressWarnings("unchecked")\r
-    private static <T> List<T> extractPossibleKeys(Object[] objects, Key key, Class<T> clazz) {\r
-        if (objects.length==0)\r
-            return Collections.emptyList();\r
-\r
-        ArrayList<T> result = new ArrayList<T>(objects.length);\r
-        for (Object o : objects) {\r
-            if (o instanceof IHintContext) {\r
-                IHintContext context = (IHintContext) o;\r
-                Object object = context.getHint(key);\r
-                if (object != null) {\r
-                    if (clazz.isInstance(object)) {\r
-                        result.add((T) object);\r
-                    } else if (object instanceof IAdaptable) {\r
-                        Object adapter = ((IAdaptable) object).getAdapter(clazz);\r
-                        if (adapter != null)\r
-                            result.add((T) adapter);\r
-                    }\r
-                }\r
-            }\r
-        }\r
-        return result;\r
-    }\r
-\r
-    /**\r
-     * This method creates selection from set of objects\r
-     * \r
-     * @param objects objects\r
-     * @return selection\r
-     */\r
-    public static ISelection createSelection(Object ... objects)\r
-    {\r
-        return new StructuredSelection(objects);\r
-    }\r
-\r
-\r
-    /**\r
-     * A testcase.\r
-     * \r
-     * @param args\r
-     */\r
-    public static void main(String[] args) {\r
-        Object o1 = new Integer(9);\r
-        Object o2 = new HashMap<Object, Object>();\r
-        Object o3 = new Long(1);\r
-\r
-        ISelection s1 = createSelection(o1, o2, o3);\r
-\r
-        List<Number> f1 = convertSelection(s1);\r
-        List<Number> f2 = filterSelection(s1, Number.class);\r
-\r
-        System.out.println(f1.toString());\r
-        System.out.println(f2.toString());\r
-\r
-        Assert.isTrue(f2.contains(o1) && f2.contains(o3) && !f2.contains(o2));\r
-        Assert.isTrue(f1.contains(o1) && f1.contains(o3) && !f1.contains(o2));\r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+/*
+ * 25.8.2006
+ */
+package org.simantics.utils.ui;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.runtime.Assert;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.simantics.utils.datastructures.hints.IHintContext;
+import org.simantics.utils.datastructures.hints.IHintContext.Key;
+
+/**
+ * ISelectionUtils contains static utility methods for dealing with the
+ * ISelection interface.
+ * 
+ * @author Toni Kalajainen
+ */
+public class ISelectionUtils<T> {
+
+    /**
+     * This method converts selection sel for to collection of instances of T.
+     * All elements of the selection are assumed to be instances of T.
+     * 
+     * @param <T> type of interest
+     * @param sel selection
+     * @return list
+     * @throws ClassCastException if the selection contains elements not
+     *         instance of T
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> convertSelection(ISelection sel) throws ClassCastException
+    {
+        if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+            return Collections.emptyList();
+
+        List<T> result = new ArrayList<T>();
+        //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];
+        IStructuredSelection ss = (IStructuredSelection) sel;
+        for (Object o : ss.toArray())
+            //if (tClass.isAssignableFrom(o.getClass()))
+            result.add((T)o);
+        return result;
+    }
+
+    /**
+     * This method reads selection sel for all instances of T.
+     * All elements of the selection are assumed to be instances of T.
+     * 
+     * @param <T> type of interest
+     * @param sel selection
+     * @return set
+     * @throws ClassCastException if the selection contains elements not
+     *         instance of T
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> Set<T> convertSetSelection(ISelection sel) throws ClassCastException
+    {
+        if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+            return Collections.emptySet();
+
+        Set<T> result = new HashSet<T>();
+        //Class<T> tClass = (Class<T>)result.getClass().getTypeParameters()[0].getBounds()[0];
+        IStructuredSelection ss = (IStructuredSelection) sel;
+        for (Object o : ss.toArray())
+            //if (tClass.isAssignableFrom(o.getClass()))
+            result.add((T)o);
+        return result;
+    }
+
+
+    @SuppressWarnings("unchecked")
+    public static <T> T convertSingleSelection(ISelection sel)
+    {
+        if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+            return null;
+        IStructuredSelection ss = (IStructuredSelection) sel;
+        return (ss.size() == 1) ? (T) ss.getFirstElement() : null;
+    }
+
+    /**
+     * This method converts selection sel to collection of instances of T
+     * @param <T> type of interest
+     * @param sel selection
+     * @return list
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> List<T> filterSelection(ISelection sel, Class<T> assignableFrom)
+    {
+        if (sel == null || sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+            return Collections.emptyList();
+
+        List<T> result = new ArrayList<T>();
+        IStructuredSelection ss = (IStructuredSelection) sel;
+        for (Object o : ss.toArray()) {
+            if (o != null && assignableFrom.isAssignableFrom(o.getClass())) {
+                result.add((T)o);
+            } else if (o instanceof IAdaptable) {
+                T t = (T) ((IAdaptable) o).getAdapter(assignableFrom);
+                if (t != null)
+                    result.add(t);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * This method reads selection sel for all instances of T.
+     * 
+     * @param <T> type of interest
+     * @param sel selection
+     * @return all instances of T in sel
+     */
+    public static <T> Set<T> filterSetSelection(Object sel, Class<T> assignableFrom)
+    {
+        if (sel instanceof IStructuredSelection) {
+            IStructuredSelection ss = (IStructuredSelection) sel;
+            if (!ss.isEmpty())
+                return filterCollection(ss.toList(), assignableFrom, new HashSet<T>());
+        } else if (sel instanceof Collection<?>) {
+            Collection<?> c = (Collection<?>) sel;
+            if (!c.isEmpty())
+                return filterCollection(c, assignableFrom, new HashSet<T>());
+        }
+
+        return Collections.emptySet();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T filterSingleSelection(Object sel, Class<T> assignableTo)
+    {
+       if (sel == null) {
+               return null;
+       } else if (sel instanceof IStructuredSelection) {
+            IStructuredSelection ss = (IStructuredSelection) sel;
+            if (ss.size() == 1)
+                return tryAdapt(ss.getFirstElement(), assignableTo);
+        } else if (sel instanceof Collection<?>) {
+            Collection<?> c = (Collection<?>) sel;
+            if (c.size() == 1)
+                return tryAdapt(c.iterator().next(), assignableTo);
+        } else if (sel.getClass().isArray()) {
+               Object[] os = (Object[])sel;
+               Object result = null;
+               for(Object o : os) {
+                       Object r = tryAdapt(o, assignableTo);
+                       if(r != null) {
+                               if(result != null) return null;
+                               result = r;
+                       }
+               }
+               return (T)result;
+        }
+        return null;
+    }
+
+    public static <T> T findFirstAdaptable(Object sel, Class<T> assignableTo)
+    {
+        if (sel instanceof IStructuredSelection) {
+            IStructuredSelection ss = (IStructuredSelection) sel;
+            if (!ss.isEmpty())
+                return findFirstAdaptable_(ss.toList(), assignableTo);
+        } else if (sel instanceof Collection<?>) {
+            Collection<?> c = (Collection<?>) sel;
+            if (!c.isEmpty())
+                return findFirstAdaptable_(c, assignableTo);
+        }
+        return null;
+    }
+
+    private static <T> T findFirstAdaptable_(Collection<?> objects, Class<T> assignableTo) {
+        for (Object o : objects) {
+            T t = tryAdapt(o, assignableTo);
+            if (t != null)
+                return t;
+        }
+        return null;
+    }
+
+    private static <T, C extends Collection<T>> C filterCollection(Collection<?> objects, Class<T> assignableTo, C result) {
+        for (Object o : objects) {
+            T t = tryAdapt(o, assignableTo);
+            if (t != null)
+                result.add(t);
+        }
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> T tryAdapt(Object o, Class<T> assignableTo) {
+        if (o != null && assignableTo.isAssignableFrom(o.getClass())) {
+            return (T) o;
+        } else if (o instanceof IAdaptable) {
+            T t = (T) ((IAdaptable) o).getAdapter(assignableTo);
+            if (t != null) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Try to extract a single object that is an instance of the specified class
+     * out of the provided selection object.
+     * 
+     * This tries everything even remotely plausible - and then some.
+     * 
+     * This method works as follows:
+     * <ul>
+     * <li>Supported input selection objects: IStructuredSelection and
+     * Collection&lt;?&gt;, IHintContext, IAdaptable, direct instances of the
+     * requested class</li>
+     * <li>Selection elements are assumed to be either instances of
+     * IHintContext, IAdaptable or direct instances of the requested class</li>
+     * <li>If an IHintContext is found, the result object is searched within it
+     * with the specified key.</li>
+     * <li>Searching involves testing whether the hint value is an instance of
+     * clazz or adaptable to it through {@link IAdaptable}.</li>
+     * </ul>
+     * 
+     * 
+     * 
+     * @param selection
+     * @param key
+     * @param clazz desired class of the objects to look for in the selection
+     * @return a single objects matching the search criteria. If there are no or
+     *         several matches, <code>null</code> is returned
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz) {
+        return getSinglePossibleKey(object, key, clazz, true);
+    }
+
+    /**
+     * Try to extract a single object that is an instance of the specified class
+     * out of the provided selection object.
+     * 
+     * This tries everything even remotely plausible - and then some.
+     * 
+     * This method works as follows:
+     * <ul>
+     * <li>Supported input selection objects: IStructuredSelection and
+     * Collection&lt;?&gt;, IHintContext, IAdaptable, direct instances of the
+     * requested class</li>
+     * <li>Selection elements are assumed to be either instances of
+     * IHintContext, IAdaptable or direct instances of the requested class</li>
+     * <li>If an IHintContext is found, the result object is searched within it
+     * with the specified key.</li>
+     * <li>Searching involves testing whether the hint value is an instance of
+     * clazz or adaptable to it through {@link IAdaptable}.</li>
+     * </ul>
+     * 
+     * 
+     * 
+     * @param selection
+     * @param key
+     * @param clazz desired class of the objects to look for in the selection
+     * @return a single objects matching the search criteria. If there are no or
+     *         several matches, <code>null</code> is returned
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getSinglePossibleKey(Object object, Key key, Class<T> clazz, boolean allowDirectMatch) {
+        if (object == null)
+            return null;
+
+        // Direct match is returned without key analysis
+        if (allowDirectMatch && clazz.isInstance(object))
+            return (T) object;
+
+        if (object instanceof ISelection) {
+            ISelection sel = (ISelection) object;
+
+            if (sel.isEmpty() || (!(sel instanceof IStructuredSelection)))
+                return null;
+
+            IStructuredSelection ss = (IStructuredSelection) sel;
+            if (ss.size() != 1)
+                return null;
+
+            // The result must now be in the first and only element
+            return getSinglePossibleKey(ss.getFirstElement(), key, clazz, allowDirectMatch);
+        }
+
+        if (object instanceof Collection<?>) {
+            Collection<?> c = (Collection<?>) object;
+            if (c.size() != 1)
+                return null;
+
+            return getSinglePossibleKey(c.iterator().next(), key, clazz, allowDirectMatch);
+        }
+
+        // If there was no success so far now we must take the Key into account
+        if (object instanceof IHintContext) {
+            IHintContext context = (IHintContext) object;
+            Object hint = context.getHint(key);
+
+            // We had a hint context and a matching key was not available - now try single hint - TODO: this somewhat questionable
+            if (hint == null) {
+                // NOTE: Removed because of a bug:
+                // https://www.simantics.org/redmine/issues/3061
+                // Hope this doesn't break existing code.
+                Map<Key, Object> hints = context.getHints();
+                // There are multiple hints, thats it, there is no result
+                if(hints.size() != 1) return null;
+                hint = hints.values().iterator().next();
+
+                T t = getSinglePossibleKey(hint, key, clazz);
+//                if (t != null) {
+//                    System.out.println("******************** GEEZ: " + t);
+//                    new Exception().printStackTrace();
+//                }
+                return t;
+//                return null;
+            }
+
+            if (clazz.isInstance(hint)) {
+                return (T) hint;
+            } else if (hint instanceof IAdaptable) {
+                T adapter = (T) ((IAdaptable) hint).getAdapter(clazz);
+                if (adapter != null)
+                    return adapter;
+            } else {
+                return getSinglePossibleKey(hint, key, clazz);
+            }
+        }
+
+        if (object instanceof IAdaptable)
+            return getSinglePossibleKey(((IAdaptable) object).getAdapter(IHintContext.class), key, clazz, allowDirectMatch);
+
+        return null;
+
+    }
+
+    /**
+     * Try to extract the possible objects that are instances of the specified
+     * class out of the provided selection object.
+     * 
+     * This method works as follows:
+     * <ul>
+     * <li>Supported input selection objects: IStructuredSelection and
+     * Collection&lt;?&gt;</li>
+     * <li>Selection elements are assumed to be IHintContext instances</li>
+     * <li>The result objects are searched for in the IHintContexts with the
+     * specified key.</li>
+     * <li>Searching involves testing whether the hint value is an instance of
+     * clazz or adaptable to it through {@link IAdaptable}.</li>
+     * </ul>
+     * 
+     * All objects that pass through this filter are returned as the result.
+     * 
+     * @param selection
+     * @param key
+     * @param clazz desired class of the objects to look for in the selection
+     * @return list of the criteria matching elements in the selection or empty
+     *         list if nothing suitable was found
+     */
+    public static <T> List<T> getPossibleKeys(Object selection, Key key, Class<T> clazz) {
+        if (selection == null)
+            return Collections.emptyList();
+
+        if (selection instanceof IStructuredSelection) {
+            IStructuredSelection ss = (IStructuredSelection) selection;
+            if (ss.isEmpty())
+                return Collections.emptyList();
+            return extractPossibleKeys(ss.toList(), key, clazz);
+        }
+
+        if (selection instanceof Collection<?>) {
+            Collection<?> c = (Collection<?>) selection;
+            return extractPossibleKeys(c, key, clazz);
+        }
+
+        if (selection.getClass().isArray()) {
+               Object[] c = (Object[]) selection;
+            return extractPossibleKeys(c, key, clazz);
+        }
+
+        return extractPossibleKeys(Collections.singleton(selection), key, clazz);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> List<T> extractPossibleKeys(Collection<?> objects, Key key, Class<T> clazz) {
+        if (objects.isEmpty())
+            return Collections.emptyList();
+
+        ArrayList<T> result = new ArrayList<T>(objects.size());
+        for (Object o : objects) {
+            if (o instanceof IHintContext) {
+                IHintContext context = (IHintContext) o;
+                Object object = context.getHint(key);
+                if (object != null) {
+                    if (clazz.isInstance(object)) {
+                        result.add((T) object);
+                    } else if (object instanceof IAdaptable) {
+                        Object adapter = ((IAdaptable) object).getAdapter(clazz);
+                        if (adapter != null)
+                            result.add((T) adapter);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T> List<T> extractPossibleKeys(Object[] objects, Key key, Class<T> clazz) {
+        if (objects.length==0)
+            return Collections.emptyList();
+
+        ArrayList<T> result = new ArrayList<T>(objects.length);
+        for (Object o : objects) {
+            if (o instanceof IHintContext) {
+                IHintContext context = (IHintContext) o;
+                Object object = context.getHint(key);
+                if (object != null) {
+                    if (clazz.isInstance(object)) {
+                        result.add((T) object);
+                    } else if (object instanceof IAdaptable) {
+                        Object adapter = ((IAdaptable) object).getAdapter(clazz);
+                        if (adapter != null)
+                            result.add((T) adapter);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * This method creates selection from set of objects
+     * 
+     * @param objects objects
+     * @return selection
+     */
+    public static ISelection createSelection(Object ... objects)
+    {
+        return new StructuredSelection(objects);
+    }
+
+
+    /**
+     * A testcase.
+     * 
+     * @param args
+     */
+    public static void main(String[] args) {
+        Object o1 = new Integer(9);
+        Object o2 = new HashMap<Object, Object>();
+        Object o3 = new Long(1);
+
+        ISelection s1 = createSelection(o1, o2, o3);
+
+        List<Number> f1 = convertSelection(s1);
+        List<Number> f2 = filterSelection(s1, Number.class);
+
+        System.out.println(f1.toString());
+        System.out.println(f2.toString());
+
+        Assert.isTrue(f2.contains(o1) && f2.contains(o3) && !f2.contains(o2));
+        Assert.isTrue(f1.contains(o1) && f1.contains(o3) && !f1.contains(o2));
+    }
+
+}