Index: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java	(revision 1541644)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/identifier/IdentifierManager.java	(working copy)
@@ -16,39 +16,47 @@
  */
 package org.apache.jackrabbit.oak.plugins.identifier;
 
+import static com.google.common.base.Charsets.UTF_8;
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.collect.Iterables.filter;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.singletonMap;
+import static org.apache.jackrabbit.JcrConstants.JCR_UUID;
+import static org.apache.jackrabbit.JcrConstants.MIX_REFERENCEABLE;
+import static org.apache.jackrabbit.oak.api.Type.STRING;
+import static org.apache.jackrabbit.oak.api.Type.STRINGS;
+import static org.apache.jackrabbit.oak.commons.PathUtils.concat;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getName;
+import static org.apache.jackrabbit.oak.commons.PathUtils.getParentPath;
+import static org.apache.jackrabbit.oak.namepath.NamePathMapper.DEFAULT;
+import static org.apache.jackrabbit.oak.plugins.index.reference.NodeReferenceConstants.REF_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.reference.NodeReferenceConstants.WEAK_REF_NAME;
+import static org.apache.jackrabbit.oak.spi.query.PropertyValues.create;
+
 import java.text.ParseException;
-import java.util.Collections;
 import java.util.Map;
-import java.util.Set;
 import java.util.UUID;
+
 import javax.annotation.CheckForNull;
 import javax.annotation.Nonnull;
 import javax.jcr.PropertyType;
 import javax.jcr.query.Query;
 
-import com.google.common.base.Charsets;
-import com.google.common.base.Function;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
-import org.apache.jackrabbit.JcrConstants;
 import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.api.PropertyValue;
 import org.apache.jackrabbit.oak.api.Result;
 import org.apache.jackrabbit.oak.api.ResultRow;
 import org.apache.jackrabbit.oak.api.Root;
 import org.apache.jackrabbit.oak.api.Tree;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.commons.PathUtils;
+import org.apache.jackrabbit.oak.core.AbstractTree;
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.memory.StringPropertyState;
 import org.apache.jackrabbit.oak.plugins.nodetype.ReadOnlyNodeTypeManager;
-import org.apache.jackrabbit.oak.spi.query.PropertyValues;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static com.google.common.base.Preconditions.checkArgument;
-import static org.apache.jackrabbit.oak.api.Type.STRING;
+import com.google.common.base.Predicate;
 
 /**
  * TODO document
@@ -72,7 +80,7 @@
 
     @Nonnull
     public static String generateUUID(String hint) {
-        UUID uuid = UUID.nameUUIDFromBytes(hint.getBytes(Charsets.UTF_8));
+        UUID uuid = UUID.nameUUIDFromBytes(hint.getBytes(UTF_8));
         return uuid.toString();
     }
 
@@ -93,14 +101,14 @@
      */
     @Nonnull
     public static String getIdentifier(Tree tree) {
-        PropertyState property = tree.getProperty(JcrConstants.JCR_UUID);
+        PropertyState property = tree.getProperty(JCR_UUID);
         if (property != null) {
             return property.getValue(STRING);
         } else if (tree.isRoot()) {
             return "/";
         } else {
             String parentId = getIdentifier(tree.getParent());
-            return PathUtils.concat(parentId, tree.getName());
+            return concat(parentId, tree.getName());
         }
     }
 
@@ -129,7 +137,7 @@
             } else if (k == -1) {
                 return root.getTree(basePath);
             } else {
-                return root.getTree(PathUtils.concat(basePath, identifier.substring(k + 1)));
+                return root.getTree(concat(basePath, identifier.substring(k + 1)));
             }
         }
     }
@@ -183,75 +191,63 @@
      *         specified {@code tree} and matching the constraints.
      */
     @Nonnull
-    public Set<String> getReferences(boolean weak, Tree tree, final String propertyName, final String... nodeTypeNames) {
-        if (!nodeTypeManager.isNodeType(tree, JcrConstants.MIX_REFERENCEABLE)) {
-            return Collections.emptySet(); // shortcut
+    public Iterable<String> getReferences(boolean weak, Tree tree,
+            final String propertyName, final String... nodeTypeNames) {
+        if (!nodeTypeManager.isNodeType(tree, MIX_REFERENCEABLE)) {
+            return emptySet();
         }
 
-        try {
-            final String uuid = getIdentifier(tree);
-            String reference = weak ? PropertyType.TYPENAME_WEAKREFERENCE : PropertyType.TYPENAME_REFERENCE;
-            String pName = propertyName == null ? "*" : propertyName;   // TODO: sanitize against injection attacks!?
-            Map<String, ? extends PropertyValue> bindings = Collections.singletonMap("uuid", PropertyValues.newString(uuid));
-
-            Result result = root.getQueryEngine().executeQuery(
-                    "SELECT * FROM [nt:base] WHERE PROPERTY([" + pName + "], '" + reference + "') = $uuid",
-                    Query.JCR_SQL2, Long.MAX_VALUE, 0, bindings, new NamePathMapper.Default());
-
-            Iterable<String> paths = Iterables.transform(result.getRows(),
-                    new Function<ResultRow, String>() {
-                @Override
-                public String apply(ResultRow row) {
-                    String pName = propertyName == null
-                            ? findProperty(row.getPath(), uuid)
-                                    : propertyName;
-                            return PathUtils.concat(row.getPath(), pName);
-                }
-            });
+        // TODO fetch the node state from the tree
+        NodeState ns = null;
+        if (tree instanceof AbstractTree) {
+            AbstractTree at = (AbstractTree) tree;
+            ns = at.getNodeState();
+        }
 
-            if (nodeTypeNames.length > 0) {
-                paths = Iterables.filter(paths, new Predicate<String>() {
-                    @Override
-                    public boolean apply(String path) {
-                        Tree tree = root.getTree(PathUtils.getParentPath(path));
-                        if (tree.exists()) {
-                            for (String ntName : nodeTypeNames) {
-                                if (nodeTypeManager.isNodeType(tree, ntName)) {
-                                    return true;
-                                }
-                            }
-                        }
-                        return false;
-                    }
-                });
-            }
+        String refPropertyName = weak ? WEAK_REF_NAME : REF_NAME;
+        if (ns == null || !ns.hasProperty(refPropertyName)) {
+            return emptySet();
+        }
 
-            return Sets.newHashSet(paths);
-        } catch (ParseException e) {
-            log.error("query failed", e);
-            return Collections.emptySet();
+        Iterable<String> paths = ns.getProperty(refPropertyName).getValue(
+                STRINGS);
+        if (propertyName != null) {
+            paths = filter(paths, newPropertyNameFilter(propertyName));
         }
+        if (nodeTypeNames.length > 0) {
+            return filter(paths,
+                    newNodeTypeFilter(nodeTypeNames, root, nodeTypeManager));
+        }
+        return paths;
     }
 
-    private String findProperty(String path, final String uuid) {
-        Tree tree = root.getTree(path);
-        final PropertyState refProp = Iterables.find(tree.getProperties(), new Predicate<PropertyState>() {
+    private static Predicate<String> newNodeTypeFilter(
+            final String[] nodeTypeNames, final Root root,
+            final ReadOnlyNodeTypeManager nodeTypeManager) {
+        return new Predicate<String>() {
             @Override
-            public boolean apply(PropertyState pState) {
-                if (pState.isArray()) {
-                    for (String value : pState.getValue(Type.STRINGS)) {
-                        if (uuid.equals(value)) {
+            public boolean apply(String path) {
+                Tree tree = root.getTree(getParentPath(path));
+                if (tree.exists()) {
+                    for (String ntName : nodeTypeNames) {
+                        if (nodeTypeManager.isNodeType(tree, ntName)) {
                             return true;
                         }
                     }
-                    return false;
-                } else {
-                    return uuid.equals(pState.getValue(STRING));
                 }
+                return false;
             }
-        });
+        };
+    }
 
-        return refProp.getName();
+    private static Predicate<String> newPropertyNameFilter(
+            final String propertyName) {
+        return new Predicate<String>() {
+            @Override
+            public boolean apply(String path) {
+                return propertyName.equals(getName(path));
+            }
+        };
     }
 
     @CheckForNull
@@ -261,10 +257,10 @@
 
     private String resolveUUID(PropertyState uuid) {
         try {
-            Map<String, PropertyValue> bindings = Collections.singletonMap("id", PropertyValues.create(uuid));
+            Map<String, PropertyValue> bindings = singletonMap("id", create(uuid));
             Result result = root.getQueryEngine().executeQuery(
                     "SELECT * FROM [nt:base] WHERE [jcr:uuid] = $id", Query.JCR_SQL2,
-                    Long.MAX_VALUE, 0, bindings, new NamePathMapper.Default());
+                    Long.MAX_VALUE, 0, bindings, DEFAULT);
 
             String path = null;
             for (ResultRow rr : result.getRows()) {
Index: oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractSecurityTest.java
===================================================================
--- oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractSecurityTest.java	(revision 1541644)
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/AbstractSecurityTest.java	(working copy)
@@ -44,6 +44,7 @@
 import org.apache.jackrabbit.oak.namepath.NamePathMapper;
 import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexEditorProvider;
 import org.apache.jackrabbit.oak.plugins.index.property.PropertyIndexProvider;
+import org.apache.jackrabbit.oak.plugins.index.reference.ReferenceEditorProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.RegistrationEditorProvider;
 import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent;
 import org.apache.jackrabbit.oak.plugins.value.ValueFactoryImpl;
@@ -78,6 +79,7 @@
     public void before() throws Exception {
         Oak oak = new Oak()
                 .with(new InitialContent())
+                .with(new ReferenceEditorProvider())
                 .with(new PropertyIndexEditorProvider())
                 .with(new PropertyIndexProvider())
                 .with(new RegistrationEditorProvider())
Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java
===================================================================
--- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java	(revision 1541644)
+++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/session/NodeImpl.java	(working copy)
@@ -21,7 +21,6 @@
 import java.util.Calendar;
 import java.util.Iterator;
 import java.util.List;
-import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Binary;
@@ -65,7 +64,6 @@
 import org.apache.jackrabbit.oak.api.Tree.Status;
 import org.apache.jackrabbit.oak.api.Type;
 import org.apache.jackrabbit.oak.commons.PathUtils;
-import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
 import org.apache.jackrabbit.oak.jcr.delegate.NodeDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.PropertyDelegate;
 import org.apache.jackrabbit.oak.jcr.delegate.VersionManagerDelegate;
@@ -74,6 +72,7 @@
 import org.apache.jackrabbit.oak.jcr.session.operation.NodeOperation;
 import org.apache.jackrabbit.oak.jcr.version.VersionHistoryImpl;
 import org.apache.jackrabbit.oak.jcr.version.VersionImpl;
+import org.apache.jackrabbit.oak.plugins.identifier.IdentifierManager;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
 import org.apache.jackrabbit.oak.plugins.nodetype.EffectiveNodeType;
 import org.apache.jackrabbit.oak.spi.security.authorization.permission.Permissions;
@@ -746,7 +745,7 @@
             public PropertyIterator perform() throws InvalidItemStateException {
                 IdentifierManager idManager = sessionDelegate.getIdManager();
 
-                Set<String> propertyOakPaths = idManager.getReferences(weak, node.getTree(), name); // TODO: oak name?
+                Iterable<String> propertyOakPaths = idManager.getReferences(weak, node.getTree(), name); // TODO: oak name?
                 Iterable<Property> properties = Iterables.transform(
                         propertyOakPaths,
                         new Function<String, Property>() {
@@ -758,7 +757,7 @@
                         }
                 );
 
-                return new PropertyIteratorAdapter(properties.iterator(), propertyOakPaths.size());
+                return new PropertyIteratorAdapter(properties.iterator());
             }
         });
     }
Index: oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java	(revision 1541644)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/MembershipProvider.java	(working copy)
@@ -101,7 +101,7 @@
     @Nonnull
     Iterator<String> getMembership(Tree authorizableTree, boolean includeInherited) {
         Set<String> groupPaths = new HashSet<String>();
-        Set<String> refPaths = identifierManager.getReferences(true, authorizableTree, REP_MEMBERS, NT_REP_GROUP, NT_REP_MEMBERS);
+        Iterable<String> refPaths = identifierManager.getReferences(true, authorizableTree, REP_MEMBERS, NT_REP_GROUP, NT_REP_MEMBERS);
         for (String propPath : refPaths) {
             int index = propPath.indexOf('/' + REP_MEMBERS);
             if (index > 0) {
