]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.common/src/org/simantics/db/common/utils/ListUtils.java
ListUtils.create(g,elements) creates a list without element inverses
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / utils / ListUtils.java
index 6474bf79cccb4133ada70f5703886113d710d08e..656dfeb27550b8acfe8e1f1c8801cbebefe6e879 100644 (file)
-package org.simantics.db.common.utils;\r
-\r
-import java.util.ArrayList;\r
-import java.util.List;\r
-import java.util.Set;\r
-\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Resource;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.WriteOnlyGraph;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.layer0.Layer0;\r
-\r
-public class ListUtils {\r
-\r
-    /**\r
-     * Inserts {@code elements} between list nodes \r
-     * {@code before} and {@code after}.\r
-     */\r
-    private static void insertBetween(\r
-            WriteGraph g, Layer0 L0, Resource list,\r
-            Resource before, Resource after, \r
-            Iterable<Resource> elements) throws DatabaseException {\r
-        for(Resource item : elements) {\r
-            Resource cur = g.newResource();\r
-            g.claim(cur, L0.InstanceOf, null, L0.List_Entry);\r
-            g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);\r
-            g.claim(before, L0.List_Next, L0.List_Previous, cur);\r
-            g.claim(cur, L0.List_Element, item);\r
-            before = cur;\r
-        }  \r
-        g.claim(before, L0.List_Next, L0.List_Previous, after);\r
-    }\r
-\r
-    private static void insertBetween(\r
-            WriteGraph g, Layer0 L0, Resource list, \r
-            Resource before, Resource after, \r
-            Resource[] elements) throws DatabaseException {\r
-        for(Resource item : elements) {\r
-            Resource cur = g.newResource();\r
-            g.claim(cur, L0.InstanceOf, null, L0.List_Entry);\r
-            g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);\r
-            g.claim(before, L0.List_Next, L0.List_Previous, cur);\r
-            g.claim(cur, L0.List_Element, item);\r
-            before = cur;\r
-        }  \r
-        g.claim(before, L0.List_Next, L0.List_Previous, after);\r
-    }\r
-    \r
-    /**\r
-     * Creates a list containing the givens {@code elements}.\r
-     */\r
-    public static Resource create(WriteGraph g, Iterable<Resource> elements) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource list = g.newResource();\r
-        g.claim(list, L0.InstanceOf, L0.List);\r
-        \r
-        insertBetween(g, L0, list, list, list, elements);\r
-        return list;\r
-    }\r
-\r
-    /**\r
-     * Creates a list containing the givens {@code elements}.\r
-     */\r
-    public static Resource create(WriteGraph g, Resource type, Iterable<Resource> elements) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource list = g.newResource();\r
-        g.claim(list, L0.InstanceOf, null, type);\r
-        \r
-        insertBetween(g, L0, list, list, list, elements);\r
-        return list;\r
-    }\r
-\r
-    public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource list = g.newResource();\r
-        g.claim(list, L0.InstanceOf, null, type);\r
-        \r
-        insertBetween(g, L0, list, list, list, elements);\r
-        return list;\r
-    }\r
-    \r
-    /**\r
-     * Inserts given {@code elements} into the front of the list.\r
-     */\r
-    public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {\r
-        if (!elements.iterator().hasNext())\r
-            return;\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource first = g.getSingleObject(list, L0.List_Next);        \r
-        g.deny(list, L0.List_Next, L0.List_Previous, first);        \r
-        insertBetween(g, L0, list, list, first, elements);\r
-    }\r
-    \r
-    public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {\r
-    \r
-        Layer0 L0 = g.getService(Layer0.class);\r
-        Resource before = list;\r
-        for(Resource item : elements) {\r
-            Resource cur = g.newResource();\r
-            g.claim(cur, L0.InstanceOf, null, L0.List_Entry);\r
-            g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);\r
-            g.claim(before, L0.List_Next, L0.List_Previous, cur);\r
-            g.claim(cur, L0.List_Element, null, item);\r
-            before = cur;\r
-        }  \r
-        g.claim(before, L0.List_Next, L0.List_Previous, list);\r
-       \r
-    }\r
-    \r
-    /**\r
-     * Inserts given {@code elements} into the back of the list.\r
-     */\r
-    public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {\r
-        if (!elements.iterator().hasNext())\r
-            return;\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource last = g.getSingleObject(list, L0.List_Previous);        \r
-        g.deny(last, L0.List_Next, L0.List_Previous, list);        \r
-        insertBetween(g, L0, list, last, list, elements);\r
-    }\r
-    \r
-    /**\r
-     * Replaces a given element in the a given list\r
-     * @param g WriteGraph\r
-     * @param list List resource\r
-     * @param element Element to be replaced\r
-     * @param replacement Resource that replaces element\r
-     * @return true if successful replacement, false otherwise\r
-     * @throws DatabaseException\r
-     */\r
-    public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {\r
-        if(list == null || element == null || replacement == null)\r
-            return false;\r
-        \r
-        Layer0 L0 = Layer0.getInstance(g);\r
-\r
-        Resource node = getNode(g, list, element);\r
-        if(node != null) {\r
-            g.deny(node, L0.List_Element);\r
-            g.claim(node, L0.List_Element, replacement);\r
-            return true;\r
-        } else {\r
-            return false;\r
-        }\r
-    }\r
-    \r
-    private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {\r
-       \r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource cur = g.getSingleObject(list, L0.List_Next);\r
-        while(!cur.equals(list)) {\r
-            Resource el = g.getPossibleObject(cur, L0.List_Element);\r
-            if(el != null)\r
-                result.add(el);\r
-            cur = g.getSingleObject(cur, L0.List_Next);\r
-        }\r
-        \r
-    }\r
-    \r
-    /**\r
-     * Converts a list in the graph to a Java List.\r
-     */\r
-    public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {\r
-        ArrayList<Resource> result = new ArrayList<Resource>();\r
-        toList(g, result, list);\r
-        return result;\r
-    }\r
-\r
-    public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {\r
-       try {\r
-               return toList(g, list);\r
-       } catch (DatabaseException e) {\r
-               return null;\r
-       }\r
-    }\r
-\r
-    /**\r
-     * Removes an element from a list. Returns true if actually removed something.\r
-     */\r
-    public static boolean removeElement(WriteGraph g, Resource list, Resource element) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        Resource prev = list;\r
-        Resource cur = g.getSingleObject(list, L0.List_Next);\r
-        while(!cur.equals(list)) {\r
-            Resource el = g.getPossibleObject(cur, L0.List_Element);\r
-            Resource next = g.getSingleObject(cur, L0.List_Next);\r
-            if(element.equals(el)) {                \r
-                g.deny(cur);\r
-                g.claim(prev, L0.List_Next, next);\r
-                return true;\r
-            }\r
-            prev = cur;\r
-            cur = next;\r
-        }\r
-        return false;\r
-    }\r
-    \r
-    /**\r
-     * Removes an elements from a list. Returns true if actually removed something.\r
-     */\r
-    public static boolean removeElements(WriteGraph g, Resource list, Set<Resource> elements) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        Resource prev = list;\r
-        Resource cur = g.getSingleObject(list, L0.List_Next);\r
-        boolean removed = false;\r
-        while(!cur.equals(list)) {\r
-            Resource el = g.getPossibleObject(cur, L0.List_Element);\r
-            Resource next = g.getSingleObject(cur, L0.List_Next);\r
-            if(elements.contains(el)) {                \r
-                g.deny(cur);\r
-                g.claim(prev, L0.List_Next, next);\r
-                removed = true;\r
-            }\r
-            else\r
-                prev = cur;\r
-            cur = next;\r
-        }\r
-        return removed;\r
-    }\r
-    \r
-    private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {\r
-        \r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource cur = g.getSingleObject(list, L0.List_Next);\r
-        while(!cur.equals(list)) {\r
-            result.add(cur);\r
-            cur = g.getSingleObject(cur, L0.List_Next);\r
-        }\r
-        \r
-    }\r
-    \r
-    public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {\r
-        ArrayList<Resource> result = new ArrayList<Resource>();\r
-        getListNodes(g, result, list);\r
-        return result;\r
-    }\r
-    \r
-    public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        \r
-        Resource cur = g.getSingleObject(list, L0.List_Next);\r
-        while(!cur.equals(list)) {\r
-            Resource el = g.getPossibleObject(cur, L0.List_Element);\r
-            if(element.equals(el))\r
-                return cur;\r
-            cur = g.getSingleObject(cur, L0.List_Next);\r
-        }\r
-        return null;\r
-    }     \r
-    \r
-    public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {\r
-        Resource node = getNode(g, list, element);\r
-        if(node == null)\r
-            return false;\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        Resource prev = g.getSingleObject(node, L0.List_Previous);\r
-        if(list.equals(prev))\r
-            return false;\r
-        swap(g, node, prev);\r
-        return true;\r
-    }\r
-    \r
-    public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {\r
-        Resource node = getNode(g, list, element);\r
-        if(node == null)\r
-            return false;\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        Resource next = g.getSingleObject(node, L0.List_Next);\r
-        if(list.equals(next))\r
-            return false;\r
-        swap(g, node, next);\r
-        return true;\r
-    }\r
-\r
-    private static void swap(WriteGraph g, Resource a, Resource b) throws DatabaseException {\r
-        Layer0 L0 = Layer0.getInstance(g);\r
-        Resource ea = g.getPossibleObject(a, L0.List_Element);\r
-        Resource eb = g.getPossibleObject(b, L0.List_Element);\r
-        \r
-        g.deny(a, L0.List_Element);\r
-        g.deny(b, L0.List_Element);\r
-        \r
-        if(eb != null)\r
-            g.claim(a, L0.List_Element, eb);\r
-        if(ea != null)\r
-            g.claim(b, L0.List_Element, ea);\r
-    }\r
-\r
-    \r
-}\r
+package org.simantics.db.common.utils;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Resource;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.WriteOnlyGraph;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.layer0.Layer0;
+
+public class ListUtils {
+
+    /**
+     * Inserts {@code elements} between list nodes 
+     * {@code before} and {@code after}.
+     */
+    private static void insertBetween(
+            WriteGraph g, Layer0 L0, Resource list,
+            Resource before, Resource after, 
+            Iterable<Resource> elements) throws DatabaseException {
+        Resource elementPredicate = getElementPredicate(g, list);
+        for(Resource item : elements) {
+            Resource cur = g.newResource();
+            g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
+            g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
+            g.claim(before, L0.List_Next, L0.List_Previous, cur);
+            g.claim(cur, elementPredicate, item);
+            before = cur;
+        }  
+        g.claim(before, L0.List_Next, L0.List_Previous, after);
+    }
+
+    private static void insertBetween(
+            WriteGraph g, Layer0 L0, Resource list, 
+            Resource before, Resource after, 
+            Resource[] elements) throws DatabaseException {
+        Resource elementPredicate = getElementPredicate(g, list);
+        for(Resource item : elements) {
+            Resource cur = g.newResource();
+            g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
+            g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
+            g.claim(before, L0.List_Next, L0.List_Previous, cur);
+            g.claim(cur, elementPredicate, item);
+            before = cur;
+        }  
+        g.claim(before, L0.List_Next, L0.List_Previous, after);
+    }
+    
+    /**
+     * Creates a list containing the given {@code elements}.
+     */
+    public static Resource create(WriteGraph g, Iterable<Resource> elements) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(g);
+       return ListUtils.create(g,L0.List, L0.List_Element, null, elements);
+    }
+    
+    public static Resource createWithInverses(WriteGraph g, Iterable<Resource> elements) throws DatabaseException {
+       Layer0 L0 = Layer0.getInstance(g);
+       return ListUtils.create(g,L0.ListWithInverses, L0.List_ElementWithInverse, L0.List_ElementWithInverse_Inverse, elements);
+    }
+    
+    /**
+     * Creates a list of the given list type containing the given {@code elements}.
+     */
+    public static Resource create(WriteGraph g, Resource type, Iterable<Resource> elements) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        Resource list = g.newResource();
+        g.claim(list, L0.InstanceOf, null, type);
+        
+        insertBetween(g, L0, list, list, list, elements);
+        return list;
+    }
+
+    public static Resource create(WriteGraph g, Resource type, Resource ... elements) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        Resource list = g.newResource();
+        g.claim(list, L0.InstanceOf, null, type);
+        
+        insertBetween(g, L0, list, list, list, elements);
+        return list;
+    }
+
+    public static Resource create(WriteOnlyGraph g, Resource type, Resource elementPredicate, Resource elementPredicateInverse, Iterable<Resource> elements) throws DatabaseException {
+        Layer0 L0 = g.getService(Layer0.class);
+        Resource list = g.newResource();
+        g.claim(list, L0.InstanceOf, null, type);
+        if (!elementPredicate.equals(L0.List_Element))
+               g.claim(list, L0.List_ElementPredicate, L0.List_ElementPredicate_Inverse, elementPredicate);
+        createExisting(g, list, elementPredicate, elementPredicateInverse, elements);
+        return list;
+    }
+
+    public static Resource create(WriteOnlyGraph g, Resource type, Resource elementPredicate, Resource elementPredicateInverse, Resource... elements) throws DatabaseException {
+        return create(g, type, elementPredicate, elementPredicateInverse, Arrays.asList(elements));
+    }
+
+    /**
+     * Inserts given {@code elements} into the front of the list.
+     */
+    public static void insertFront(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
+        if (!elements.iterator().hasNext())
+            return;
+        Layer0 L0 = Layer0.getInstance(g);
+
+        Resource first = g.getSingleObject(list, L0.List_Next);
+        g.deny(list, L0.List_Next, L0.List_Previous, first);
+        insertBetween(g, L0, list, list, first, elements);
+    }
+
+    public static void createExisting(WriteOnlyGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
+        createExisting(g, list, false, elements);
+    }
+
+    public static void createExisting(WriteOnlyGraph g, Resource list, boolean withInverses, Iterable<Resource> elements) throws DatabaseException {
+        Layer0 L0 = g.getService(Layer0.class);
+        Resource elementPredicate = withInverses ? L0.List_ElementWithInverse : L0.List_Element;
+        Resource elementPredicateInverse = withInverses ? L0.List_ElementWithInverse_Inverse : null;
+        createExisting(g, list, elementPredicate, elementPredicateInverse, elements);
+    }
+
+    public static void createExisting(WriteOnlyGraph g, Resource list, Resource elementPredicate, Resource elementPredicateInverse, Iterable<Resource> elements) throws DatabaseException {
+        Layer0 L0 = g.getService(Layer0.class);
+        Resource before = list;
+        for(Resource item : elements) {
+            Resource cur = g.newResource();
+            g.claim(cur, L0.InstanceOf, null, L0.List_Entry);
+            g.claim(cur, L0.IsOwnedBy, L0.IsComposedOf, list);
+            g.claim(before, L0.List_Next, L0.List_Previous, cur);
+            g.claim(cur, elementPredicate, elementPredicateInverse, item);
+            before = cur;
+        }  
+        g.claim(before, L0.List_Next, L0.List_Previous, list);
+    }
+
+    public static void createExisting(WriteOnlyGraph g, Resource list, Resource elementPredicate, Resource elementPredicateInverse, Resource... elements) throws DatabaseException {
+        createExisting(g, list, elementPredicate, elementPredicateInverse, Arrays.asList(elements));
+    }
+
+    /**
+     * Inserts given {@code elements} into the back of the list.
+     */
+    public static void insertBack(WriteGraph g, Resource list, Iterable<Resource> elements) throws DatabaseException {
+        if (!elements.iterator().hasNext())
+            return;
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        Resource last = g.getSingleObject(list, L0.List_Previous);        
+        g.deny(last, L0.List_Next, L0.List_Previous, list);        
+        insertBetween(g, L0, list, last, list, elements);
+    }
+    
+    /**
+     * Replaces a given element in the a given list
+     * @param g WriteGraph
+     * @param list List resource
+     * @param element Element to be replaced
+     * @param replacement Resource that replaces element
+     * @return true if successful replacement, false otherwise
+     * @throws DatabaseException
+     */
+    public static boolean replace(WriteGraph g, Resource list, Resource element, Resource replacement) throws DatabaseException {
+        if(list == null || element == null || replacement == null)
+            return false;
+        
+        Layer0 L0 = Layer0.getInstance(g);
+
+        Resource node = getNode(g, list, element);
+        if(node != null) {
+            Resource elementPredicate = getElementPredicate(g, list);
+            g.deny(node, L0.List_Element);
+            g.claim(node, elementPredicate, replacement);
+            return true;
+        } else {
+            return false;
+        }
+    }
+    
+    private static void toList(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
+       
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        Resource cur = g.getSingleObject(list, L0.List_Next);
+        while(!cur.equals(list)) {
+            Resource el = g.getPossibleObject(cur, L0.List_Element);
+            if(el != null)
+                result.add(el);
+            cur = g.getSingleObject(cur, L0.List_Next);
+        }
+        
+    }
+    
+    /**
+     * Converts a list in the graph to a Java List.
+     */
+    public static List<Resource> toList(ReadGraph g, Resource list) throws DatabaseException {
+        ArrayList<Resource> result = new ArrayList<Resource>();
+        toList(g, result, list);
+        return result;
+    }
+
+    public static List<Resource> toPossibleList(ReadGraph g, Resource list) throws DatabaseException {
+       try {
+               return toList(g, list);
+       } catch (DatabaseException e) {
+               return null;
+       }
+    }
+
+    /**
+     * Removes an element from a list. Returns true if actually removed something.
+     */
+    public static boolean removeElement(WriteGraph g, Resource list, Resource element) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource prev = list;
+        Resource cur = g.getSingleObject(list, L0.List_Next);
+        while(!cur.equals(list)) {
+            Resource el = g.getPossibleObject(cur, L0.List_Element);
+            Resource next = g.getSingleObject(cur, L0.List_Next);
+            if(element.equals(el)) {
+                g.deny(cur);
+                g.claim(prev, L0.List_Next, next);
+                return true;
+            }
+            prev = cur;
+            cur = next;
+        }
+        return false;
+    }
+    
+    /**
+     * Removes an elements from a list. Returns true if actually removed something.
+     */
+    public static boolean removeElements(WriteGraph g, Resource list, Set<Resource> elements) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource prev = list;
+        Resource cur = g.getSingleObject(list, L0.List_Next);
+        boolean removed = false;
+        while(!cur.equals(list)) {
+            Resource el = g.getPossibleObject(cur, L0.List_Element);
+            Resource next = g.getSingleObject(cur, L0.List_Next);
+            if(elements.contains(el)) {
+                g.deny(cur);
+                g.claim(prev, L0.List_Next, next);
+                removed = true;
+            }
+            else
+                prev = cur;
+            cur = next;
+        }
+        return removed;
+    }
+    
+    private static void getListNodes(ReadGraph g, List<Resource> result, Resource list) throws DatabaseException {
+        
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        Resource cur = g.getSingleObject(list, L0.List_Next);
+        while(!cur.equals(list)) {
+            result.add(cur);
+            cur = g.getSingleObject(cur, L0.List_Next);
+        }
+        
+    }
+    
+    public static List<Resource> getListNodes(ReadGraph g, Resource list) throws DatabaseException {
+        ArrayList<Resource> result = new ArrayList<Resource>();
+        getListNodes(g, result, list);
+        return result;
+    }
+    
+    public static Resource getNode(ReadGraph g, Resource list, Resource element) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        
+        Resource cur = g.getSingleObject(list, L0.List_Next);
+        while(!cur.equals(list)) {
+            Resource el = g.getPossibleObject(cur, L0.List_Element);
+            if(element.equals(el))
+                return cur;
+            cur = g.getSingleObject(cur, L0.List_Next);
+        }
+        return null;
+    }     
+    
+    public static boolean swapWithPrevious(WriteGraph g, Resource list, Resource element) throws DatabaseException {
+        Resource node = getNode(g, list, element);
+        if(node == null)
+            return false;
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource prev = g.getSingleObject(node, L0.List_Previous);
+        if(list.equals(prev))
+            return false;
+        swap(g, list, node, prev);
+        return true;
+    }
+    
+    public static boolean swapWithNext(WriteGraph g, Resource list, Resource element) throws DatabaseException {
+        Resource node = getNode(g, list, element);
+        if(node == null)
+            return false;
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource next = g.getSingleObject(node, L0.List_Next);
+        if(list.equals(next))
+            return false;
+        swap(g, list, node, next);
+        return true;
+    }
+
+    private static void swap(WriteGraph g, Resource list, Resource a, Resource b) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource ea = g.getPossibleObject(a, L0.List_Element);
+        Resource eb = g.getPossibleObject(b, L0.List_Element);
+        
+        g.deny(a, L0.List_Element);
+        g.deny(b, L0.List_Element);
+        
+        Resource elementPredicate = getElementPredicate(g, list);
+        
+        if(eb != null)
+            g.claim(a, elementPredicate, eb);
+        if(ea != null)
+            g.claim(b, elementPredicate, ea);
+    }
+
+    public static Resource getElementPredicate(ReadGraph g, Resource list) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        Resource predicate = g.getPossibleObject(list, L0.List_ElementPredicate);
+        if(predicate != null) return predicate;
+        return g.isInstanceOf(list, L0.ListWithInverses) ?
+                L0.List_ElementWithInverse : L0.List_Element; 
+    }
+
+    public static Resource getListElementList(ReadGraph g, Resource element) throws DatabaseException {
+        Layer0 L0 = Layer0.getInstance(g);
+        return g.getSingleObject(element, L0.IsOwnedBy);
+    }
+
+}