You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by md...@apache.org on 2011/12/15 18:35:29 UTC

svn commit: r1214885 - in /jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi: ./ hierarchy/ operation/ state/ version/

Author: mduerig
Date: Thu Dec 15 17:35:28 2011
New Revision: 1214885

URL: http://svn.apache.org/viewvc?rev=1214885&view=rev
Log:
Microkernel based Jackrabbit prototype (WIP)
defer loading ChildNodeEntry instances as much as possible

Modified:
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryFactory.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveActivity.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
    jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/ItemManager.java Thu Dec 15 17:35:28 2011
@@ -310,9 +310,7 @@ public class ItemManager implements Item
     public synchronized NodeIterator getChildNodes(NodeEntry parentEntry) throws RepositoryException {
         // check sanity of session
         session.checkIsAlive();
-
-        Iterator<NodeEntry> it = parentEntry.getNodeEntries();
-        return LazyItemIterator.nodeIterator(this, it);
+        return LazyItemIterator.nodeIterator(this, parentEntry.getNodeEntries());
     }
 
     /**

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/ChildNodeEntries.java Thu Dec 15 17:35:28 2011
@@ -16,18 +16,27 @@
  */
 package org.apache.jackrabbit.jcr2spi.hierarchy;
 
+import org.apache.commons.collections.map.ReferenceMap;
 import org.apache.jackrabbit.jcr2spi.state.Status;
 import org.apache.jackrabbit.spi.ChildInfo;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.NodeInfo;
+import org.apache.jackrabbit.spi.commons.util.Function1;
+import org.apache.jackrabbit.spi.commons.util.Iterators;
+import org.apache.jackrabbit.spi.commons.util.Predicate1;
+import org.apache.jackrabbit.spi.commons.util.Unchecked;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import javax.jcr.ItemNotFoundException;
+import javax.jcr.PathNotFoundException;
 import javax.jcr.RepositoryException;
-import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * {@code ChildNodeEntries} represents a collection of {@code NodeEntry}s.
@@ -35,26 +44,21 @@ import java.util.Map;
 final class ChildNodeEntries {
     private static final Logger log = LoggerFactory.getLogger(ChildNodeEntries.class);
 
-    private boolean complete;
+    /** Entries loaded from the persistence layer */
+    private final Map<Name, NodeEntry> loaded = Unchecked.cast(new ReferenceMap());
 
-    /**
-     * Map used for lookup by name.
-     */
-    private final Map<Name, NodeEntry> entries = new HashMap<Name, NodeEntry>();
+    /** Transiently added entries */
+    private final Map<Name, NodeEntry> added = new HashMap<Name, NodeEntry>();
+
+    /** Transiently removed entries */
+    private final Set<Name> removed = new HashSet<Name>();
 
     private final NodeEntry parent;
     private final EntryFactory factory;
 
-     /**
-      * Create a new {@code ChildNodeEntries} collection.
-      *
-      * @param parent
-      * @param factory
-      */
      ChildNodeEntries(NodeEntry parent, EntryFactory factory) {
          this.parent = parent;
          this.factory = factory;
-         complete = false;
      }
 
     /**
@@ -63,81 +67,78 @@ final class ChildNodeEntries {
      * mean time.
      */
     public boolean isComplete() {
-        return parent.getStatus() != Status.INVALIDATED && complete ||
+        return parent.getStatus() != Status.INVALIDATED ||
                 parent.getStatus() == Status.NEW ||
                 Status.isTerminal(parent.getStatus());
     }
 
     /**
-     * Reloads this {@code ChildNodeEntries} object.
+     * Returns an iterator over all NodeEntry objects present in
+     * this ChildNodeEntries collection irrespective of their status.
      *
-     * @throws RepositoryException
+     * @return Iterator over all NodeEntry object
      */
-    public synchronized void reload() throws RepositoryException {
-        if (isComplete()) {
-            return;
+    public Iterator<NodeEntry> iterator() throws RepositoryException {
+        try {
+            NodeId nodeId = parent.getWorkspaceId();
+            Iterator<ChildInfo> childNodeInfos = factory.getItemStateFactory().getChildNodeInfos(nodeId);
+
+            Iterator<ChildInfo> filtered = Iterators.filterIterator(childNodeInfos, new Predicate1<ChildInfo>() {
+                @Override
+                public Boolean apply(ChildInfo info) throws Exception {
+                    return !removed.contains(info.getName()) && !added.containsKey(info.getName());
+                }
+            });
+
+            Iterator<NodeEntry> transformed = Iterators.transformIterator(filtered, new Function1<ChildInfo, NodeEntry>() {
+                @Override
+                public NodeEntry apply(ChildInfo info) throws Exception {
+                    NodeEntry nodeEntry = factory.createNodeEntry(parent, info.getName(), info.getUniqueID());
+                    loaded.put(nodeEntry.getName(), nodeEntry);
+                    return nodeEntry;
+                }
+            });
+            
+            return Iterators.iteratorChain(transformed, added.values().iterator());
         }
-
-        NodeId nodeId = parent.getWorkspaceId();
-        Iterator<ChildInfo> childNodeInfos = factory.getItemStateFactory().getChildNodeInfos(nodeId);
-        update(childNodeInfos);
-    }
-
-    /**
-     * Update the child node entries according to the child-infos obtained
-     * from the persistence layer.
-     * NOTE: the status of the entries already present is not respected. Thus
-     * new or removed entries are not touched in order not to modify the
-     * transient status of the parent. Operations that affect the set or order
-     * of child entries (AddNode, Move, Reorder) currently assert the
-     * completeness of the ChildNodeEntries, therefore avoiding an update
-     * resulting in inconsistent entries.
-     *
-     * @param childNodeInfos
-     * @see HierarchyEntry#reload(boolean) that ignores items with
-     * pending changes.
-     * @see org.apache.jackrabbit.jcr2spi.operation.AddNode
-     * @see org.apache.jackrabbit.jcr2spi.operation.Move
-     * @see org.apache.jackrabbit.jcr2spi.operation.ReorderNodes
-     */
-    synchronized void update(Iterator<ChildInfo> childNodeInfos) {
-        while (childNodeInfos.hasNext()) {
-            ChildInfo info = childNodeInfos.next();
-            if (get(info.getName()) == null) {
-                // add missing entry
-                NodeEntry entry = factory.createNodeEntry(parent, info.getName(), info.getUniqueID());
-                add(entry);
-            }
+        catch (ItemNotFoundException e) {
+            return added.values().iterator();
+        }
+        catch (PathNotFoundException e) {
+            return added.values().iterator();
         }
-
-        complete = true;
     }
 
     /**
-     * Returns an iterator over all NodeEntry objects present in
-     * this ChildNodeEntries collection irrespective of their status.
-     *
-     * @return Iterator over all NodeEntry object
+     * All child node entries loaded from the persistence layer.
      */
-    public Iterator<NodeEntry> iterator() {
-        // avoid concurrent modification exception
-        return new ArrayList<NodeEntry>(entries.values()).iterator();
+    Iterator<NodeEntry> getLoadedEntries() {
+        return loaded.values().iterator();
     }
 
-    public NodeEntry get(Name nodeName) {
-        return entries.get(nodeName);
+    public NodeEntry get(Name nodeName) throws RepositoryException {
+        if (removed.contains(nodeName)) {
+            return null;
+        }
+
+        NodeEntry nodeEntry = added.get(nodeName);
+        if (nodeEntry == null) {
+            nodeEntry = loaded.get(nodeName);
+            if (nodeEntry == null) {
+                nodeEntry = resolve(nodeName);
+            }
+        }
+
+        return nodeEntry;
     }
 
     /**
      * Return the {@code NodeEntry} that matches the given nodeName and
      * uniqueID or {@code null} if no matching entry can be found.
      *
-     * @param nodeName
-     * @param uniqueID
-     * @return
      * @throws IllegalArgumentException if the given uniqueID is null.
      */
-    public NodeEntry get(Name nodeName, String uniqueID) {
+    public NodeEntry get(Name nodeName, String uniqueID) throws RepositoryException {
         if (uniqueID == null || nodeName == null) {
             IllegalArgumentException e = new IllegalArgumentException("Node name and id must not be null");
             log.error(e.getMessage(), e);
@@ -156,17 +157,43 @@ final class ChildNodeEntries {
      * @param nodeEntry the {@code NodeEntry} to add.
      */
     public synchronized void add(NodeEntry nodeEntry) {
-        entries.put(nodeEntry.getName(), nodeEntry);
+        removed.remove(nodeEntry.getName());
+        added.put(nodeEntry.getName(), nodeEntry);
     }
 
     /**
-     * Removes the child node entry referring to the node state.
+     * Removes the child node entry
      *
      * @param nodeEntry the entry to be removed.
      * @return the removed entry or {@code null} if there is no such entry.
      */
-    public synchronized NodeEntry remove(NodeEntry nodeEntry) {
-        return entries.remove(nodeEntry.getName());
+    public synchronized NodeEntry remove(NodeEntry nodeEntry) throws RepositoryException {
+        NodeEntry removedEntry = get(nodeEntry.getName());
+        if (removedEntry == null) {
+            return null;
+        }
+
+        removed.add(nodeEntry.getName());
+        added.remove(nodeEntry.getName());
+        return removedEntry;
+    }
+
+    //------------------------------------------< private >---
+
+    private NodeEntry resolve(Name nodeName) throws RepositoryException {
+        try {
+            NodeId nodeId = parent.getWorkspaceId();
+            NodeInfo nodeInfo = factory.getItemStateFactory().getNodeInfo(nodeId, nodeName);
+            NodeEntry nodeEntry = factory.createNodeEntry(parent, nodeInfo.getPath().getName(), nodeInfo.getId().getUniqueID());
+            loaded.put(nodeEntry.getName(), nodeEntry);
+            return nodeEntry;
+        }
+        catch (ItemNotFoundException e) {
+            return null;
+        }
+        catch (PathNotFoundException e) {
+            return null;
+        }
     }
 
 }

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryFactory.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryFactory.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/EntryFactory.java Thu Dec 15 17:35:28 2011
@@ -26,6 +26,8 @@ import org.apache.jackrabbit.spi.PathFac
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 
+import javax.jcr.RepositoryException;
+
 /**
  * {@code EntryFactory}...
  */
@@ -66,7 +68,7 @@ public final class EntryFactory {
      * @param pathFactory
      */
     public EntryFactory(TransientItemStateFactory itemStateFactory, IdFactory idFactory, NodeEntryListener listener,
-        PathFactory pathFactory, NamePathResolver namePathResolver) {
+        PathFactory pathFactory, NamePathResolver namePathResolver) throws RepositoryException {
         
         this.idFactory = idFactory;
         this.pathFactory = pathFactory;
@@ -85,7 +87,7 @@ public final class EntryFactory {
         return rootEntry;
     }
 
-    public NodeEntry createNodeEntry(NodeEntry parent, Name name, String uniqueId) {
+    public NodeEntry createNodeEntry(NodeEntry parent, Name name, String uniqueId) throws RepositoryException {
         NodeEntry entry = new NodeEntry(parent, name, uniqueId, this);
         notifyEntryCreated(entry);
         return entry;
@@ -107,11 +109,11 @@ public final class EntryFactory {
         return itemStateFactory;
     }
 
-    public void notifyEntryCreated(NodeEntry entry) {
+    public void notifyEntryCreated(NodeEntry entry) throws RepositoryException {
         listener.entryCreated(entry);
     }
 
-    public void notifyIdChange(NodeEntry entry, String previousUniqueID) {
+    public void notifyIdChange(NodeEntry entry, String previousUniqueID) throws RepositoryException {
         listener.uniqueIdChanged(entry, previousUniqueID);
     }
 
@@ -139,8 +141,8 @@ public final class EntryFactory {
     //--------------------------------------------------< NodeEntryListener >---
 
     public interface NodeEntryListener {
-        void entryCreated(NodeEntry entry);
-        void uniqueIdChanged(NodeEntry entry, String previousUniqueID);
+        void entryCreated(NodeEntry entry) throws RepositoryException;
+        void uniqueIdChanged(NodeEntry entry, String previousUniqueID) throws RepositoryException;
     }
 
 }

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEntry.java Thu Dec 15 17:35:28 2011
@@ -183,7 +183,7 @@ public abstract class HierarchyEntry<STA
     /**
      * @param staleParent
      */
-    protected void remove(boolean staleParent) {
+    protected void remove(boolean staleParent) throws RepositoryException {
         STATE_TYPE state = getItemState();
         Status status = getStatus();
         if (state != null) {
@@ -503,7 +503,7 @@ public abstract class HierarchyEntry<STA
      * {@link Status#STALE_DESTROYED}, respectively. If this entry is a
      * NodeEntry all descending ItemStates must get their status changed as well.
      */
-    public void remove() {
+    public void remove() throws RepositoryException {
         remove(false);
     }
 

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyManager.java Thu Dec 15 17:35:28 2011
@@ -47,7 +47,7 @@ public class HierarchyManager {
     private final NamePathResolver namePathResolver;
 
     public HierarchyManager(TransientItemStateFactory isf, IdFactory idFactory, PathFactory pathFactory,
-            NamePathResolver namePathResolver) {
+            NamePathResolver namePathResolver) throws RepositoryException {
 
         uniqueIdResolver = new UniqueIdResolver(isf);
         rootEntry = new EntryFactory(isf, idFactory, uniqueIdResolver, pathFactory, namePathResolver).getRootEntry();
@@ -84,7 +84,7 @@ public class HierarchyManager {
      * @param workspaceItemId
      * @return the HierarchyEntry with the given {@code workspaceItemId}.
      */
-    public HierarchyEntry<?> lookup(ItemId workspaceItemId) {
+    public HierarchyEntry<?> lookup(ItemId workspaceItemId) throws RepositoryException {
         String uniqueID = workspaceItemId.getUniqueID();
         if (uniqueID == null) {
             return rootEntry.lookupDeepEntry(workspaceItemId.getPath());
@@ -111,7 +111,7 @@ public class HierarchyManager {
      * @param workspacePath
      * @return the HierarchyEntry with the given {@code workspacePath}.
      */
-    public HierarchyEntry<?> lookup(Path workspacePath) {
+    public HierarchyEntry<?> lookup(Path workspacePath) throws RepositoryException {
         return rootEntry.lookupDeepEntry(workspacePath);
     }
 

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/NodeEntry.java Thu Dec 15 17:35:28 2011
@@ -246,7 +246,7 @@ public class NodeEntry extends Hierarchy
     }
 
     @Override
-    public void remove() {
+    public void remove() throws RepositoryException {
         // handle this entry first
         super.remove(false);
         boolean staleParent = getStatus() == Status.STALE_DESTROYED;
@@ -258,7 +258,7 @@ public class NodeEntry extends Hierarchy
     }
 
     @Override
-    protected void remove(boolean staleParent) {
+    protected void remove(boolean staleParent) throws RepositoryException {
         // handle this entry first
         super.remove(staleParent);
         staleParent = staleParent || getStatus() == Status.STALE_DESTROYED;
@@ -346,7 +346,7 @@ public class NodeEntry extends Hierarchy
     /**
      * @param uniqueID
      */
-    public void setUniqueID(String uniqueID) {
+    public void setUniqueID(String uniqueID) throws RepositoryException {
         String old = this.uniqueID;
         boolean mod = uniqueID == null ? old != null : !uniqueID.equals(old);
         if (mod) {
@@ -554,7 +554,7 @@ public class NodeEntry extends Hierarchy
      * @param workspacePath
      * @return matching entry or {@code null}.
      */
-    public HierarchyEntry<?> lookupDeepEntry(Path workspacePath) {
+    public HierarchyEntry<?> lookupDeepEntry(Path workspacePath) throws RepositoryException {
         NodeEntry entry = this;
         for (int i = 0; i < workspacePath.getLength(); i++) {
             Path.Element elem = workspacePath.getElements()[i];
@@ -592,7 +592,7 @@ public class NodeEntry extends Hierarchy
      * @return {@code true} if there is a {@code NodeEntry} with
      * the specified {@code nodeName}.
      */
-    public synchronized boolean hasNodeEntry(Name nodeName) {
+    public synchronized boolean hasNodeEntry(Name nodeName) throws RepositoryException {
         List<NodeEntry> namedEntries = Collections.singletonList(childNodeEntries.get(nodeName));
         return !namedEntries.isEmpty() && EntryValidation.containsValidNodeEntry(namedEntries.iterator());
     }
@@ -680,14 +680,12 @@ public class NodeEntry extends Hierarchy
      * @throws RepositoryException If an unexpected error occurs.
      */
     public synchronized Iterator<NodeEntry> getNodeEntries() throws RepositoryException {
-        Collection<NodeEntry> entries = new ArrayList<NodeEntry>();
-        for (Iterator<NodeEntry> it = getCompleteChildNodeEntries().iterator(); it.hasNext();) {
-            NodeEntry entry = it.next();
-            if (EntryValidation.isValidNodeEntry(entry)) {
-                entries.add(entry);
+        return Iterators.filterIterator(childNodeEntries.iterator(), new Predicate1<NodeEntry>() {
+            @Override
+            public Boolean apply(NodeEntry entry) throws Exception {
+                return EntryValidation.isValidNodeEntry(entry);
             }
-        }
-        return entries.iterator();
+        });
     }
 
     /**
@@ -699,7 +697,7 @@ public class NodeEntry extends Hierarchy
      * @throws RepositoryException If an unexpected error occurs.
      */
     public synchronized List<NodeEntry> getNodeEntries(Name nodeName) throws RepositoryException {
-        List<NodeEntry> namedEntries = Collections.singletonList(getCompleteChildNodeEntries().get(nodeName));
+        List<NodeEntry> namedEntries = Collections.singletonList(childNodeEntries.get(nodeName));
         if (namedEntries.isEmpty()) {
             return Collections.emptyList();
         } else {
@@ -722,9 +720,7 @@ public class NodeEntry extends Hierarchy
      * @param childInfos
      */
     public void setNodeEntries(Iterator<ChildInfo> childInfos) throws UnsupportedRepositoryOperationException {
-        if (childNodeAttic.isEmpty()) {
-            childNodeEntries.update(childInfos);
-        } else {
+        if (!childNodeAttic.isEmpty()) {
             // filter those entries that have been moved to the attic.
             List<ChildInfo> remaining = new ArrayList<ChildInfo>();
             while (childInfos.hasNext()) {
@@ -733,7 +729,6 @@ public class NodeEntry extends Hierarchy
                     remaining.add(ci);
                 }
             }
-            childNodeEntries.update(remaining.iterator());
         }
     }
 
@@ -747,7 +742,7 @@ public class NodeEntry extends Hierarchy
      * @return the {@code NodeEntry}.
      */
     public NodeEntry getOrAddNodeEntry(Name nodeName, int index, String uniqueID)
-            throws UnsupportedRepositoryOperationException {
+            throws RepositoryException {
 
         NodeEntry ne = lookupNodeEntry(uniqueID, nodeName, index);
         if (ne == null) {
@@ -768,7 +763,7 @@ public class NodeEntry extends Hierarchy
      * @return
      */
     public NodeEntry addNewNodeEntry(Name nodeName, String uniqueID, Name primaryNodeType, QNodeDefinition definition)
-            throws UnsupportedRepositoryOperationException {
+            throws RepositoryException {
         
         NodeEntry entry = internalAddNodeEntry(nodeName, uniqueID, Path.INDEX_UNDEFINED);
         NodeState state = getItemStateFactory().createNewNodeState(entry, primaryNodeType, definition);
@@ -855,7 +850,7 @@ public class NodeEntry extends Hierarchy
      *
      * @param propNames
      */
-    public void setPropertyEntries(Collection<Name> propNames) {
+    public void setPropertyEntries(Collection<Name> propNames) throws RepositoryException {
         Set<Name> diff = new HashSet<Name>();
         diff.addAll(properties.getPropertyNames());
         boolean containsExtra = diff.removeAll(propNames);
@@ -1063,7 +1058,7 @@ public class NodeEntry extends Hierarchy
      * @param index
      * @return the added entry.
      */
-    private NodeEntry internalAddNodeEntry(Name nodeName, String uniqueID, int index) {
+    private NodeEntry internalAddNodeEntry(Name nodeName, String uniqueID, int index) throws RepositoryException {
         if (index > Path.INDEX_DEFAULT) {
             IllegalArgumentException e = new IllegalArgumentException("Invalid index: " + index);
             log.error(e.getMessage(), e);
@@ -1099,7 +1094,7 @@ public class NodeEntry extends Hierarchy
      *
      * @param childEntry
      */
-    void internalRemoveChildEntry(HierarchyEntry<?> childEntry) {
+    void internalRemoveChildEntry(HierarchyEntry<?> childEntry) throws RepositoryException {
         if (childEntry.denotesNode()) {
             NodeEntry childNodeEntry = cast(childEntry);
             if (childNodeEntries.remove(childNodeEntry) == null) {
@@ -1215,7 +1210,7 @@ public class NodeEntry extends Hierarchy
         }
     }
 
-    private NodeEntry lookupNodeEntry(String uniqueChildId, Name childName, int index) {
+    private NodeEntry lookupNodeEntry(String uniqueChildId, Name childName, int index) throws RepositoryException {
         if (index > Path.INDEX_DEFAULT) {
             IllegalArgumentException e = new IllegalArgumentException("Invalid index: " + index);
             log.error(e.getMessage(), e);
@@ -1280,7 +1275,7 @@ public class NodeEntry extends Hierarchy
      *
      * @param propName
      */
-    private void notifyUUIDorMIXINRemoved(Name propName) {
+    private void notifyUUIDorMIXINRemoved(Name propName) throws RepositoryException {
         if (NameConstants.JCR_UUID.equals(propName)) {
             setUniqueID(null);
         } else if (NameConstants.JCR_MIXINTYPES.equals(propName)) {
@@ -1292,23 +1287,6 @@ public class NodeEntry extends Hierarchy
     }
 
     /**
-     * @return The {@code ChildNodeEntries} defined for this
-     * {@code NodeEntry}. Please note, that this method never returns
-     * {@code null}, since the child node entries are loaded/reloaded
-     * in case they have not been loaded yet.
-     */
-    private ChildNodeEntries getCompleteChildNodeEntries() throws RepositoryException {
-        try {
-            childNodeEntries.reload();
-        } catch (ItemNotFoundException e) {
-            log.debug("NodeEntry does not exist (anymore) -> remove.");
-            remove();
-            throw new InvalidItemStateException(e);
-        }
-        return childNodeEntries;
-    }
-
-    /**
      * Returns an Iterator over all children entries, that currently are loaded
      * with this NodeEntry. NOTE, that if the childNodeEntries have not been
      * loaded yet, no attempt is made to do so.
@@ -1329,7 +1307,7 @@ public class NodeEntry extends Hierarchy
 
         // add childNodeEntries
         synchronized (childNodeEntries) {
-            chain.addIterator(childNodeEntries.iterator());
+            chain.addIterator(childNodeEntries.getLoadedEntries());
         }
         return cast(chain);
     }
@@ -1641,7 +1619,7 @@ public class NodeEntry extends Hierarchy
         }
     }
 
-    private void revertMove() {
+    private void revertMove() throws RepositoryException {
         NodeEntry oldParent = revertInfo.oldParent;
         if (oldParent == parent) {
             // simple renaming

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/UniqueIdResolver.java Thu Dec 15 17:35:28 2011
@@ -133,7 +133,7 @@ public class UniqueIdResolver implements
     //-------------------------------------< EntryFactory.NodeEntryListener >---
 
     @Override
-    public void entryCreated(NodeEntry entry) {
+    public void entryCreated(NodeEntry entry) throws RepositoryException {
         String uniqueID = entry.getUniqueID();
         if (uniqueID != null) {
             put(uniqueID, entry);
@@ -141,7 +141,7 @@ public class UniqueIdResolver implements
     }
 
     @Override
-    public void uniqueIdChanged(NodeEntry entry, String previousUniqueID) {
+    public void uniqueIdChanged(NodeEntry entry, String previousUniqueID) throws RepositoryException {
         if (previousUniqueID != null) {
             Object previous = nodeEntryById.get(previousUniqueID);
             if (previous == entry) {
@@ -156,7 +156,7 @@ public class UniqueIdResolver implements
 
     //------------------------------------------------------------< private >---
     
-    private void put(String uniqueID, NodeEntry entry) {
+    private void put(String uniqueID, NodeEntry entry) throws RepositoryException {
         NodeEntry previous = nodeEntryById.put(uniqueID, entry);
         if (previous != null) {
             // some other entry existed before with the same uniqueID

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AbstractOperation.java Thu Dec 15 17:35:28 2011
@@ -95,16 +95,6 @@ public abstract class AbstractOperation 
         return hierarchyManager.getNodeState(nodePath);
     }
 
-    /**
-     * Load the child entries of the NodeEntry of the given parent state if necessary.
-     *
-     * @param parentState
-     * @throws RepositoryException
-     */
-    protected static void loadChildNodeEntries(NodeState parentState) throws RepositoryException {
-        parentState.getHierarchyEntry().getNodeEntries();
-    }
-
     protected final void assertStatus(Status status) {
         if (this.status != status) {
             IllegalStateException e = new IllegalStateException("Illegal status: found " + this.status + ", expected " + status);

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/AddNode.java Thu Dec 15 17:35:28 2011
@@ -121,9 +121,6 @@ public class AddNode extends TransientOp
     public static AddNode create(NodeState parentState, Name nodeName, Name nodeTypeName, String uuid)
             throws RepositoryException {
 
-        // make sure the parent hierarchy entry has its child entries loaded
-        // in order to be able to detect conflicts.
-        loadChildNodeEntries(parentState);
         return new AddNode(parentState, nodeName, nodeTypeName, uuid, DEFAULT_OPTIONS);
     }
 }

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Move.java Thu Dec 15 17:35:28 2011
@@ -184,11 +184,6 @@ public class Move extends TransientOpera
         if (sessionMove) {
             NodeEntry destEntry = destParentState.getHierarchyEntry();
 
-            // force child node entries list to be present before the move is executed
-            // on the hierarchy entry.
-            loadChildNodeEntries(srcParentState);
-            loadChildNodeEntries(destParentState);
-
             if (destEntry.hasNodeEntry(destName)) {
                 NodeEntry existing = destEntry.getNodeEntry(destName, Path.INDEX_DEFAULT);
                 if (existing != null && sessionMove) {

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/Remove.java Thu Dec 15 17:35:28 2011
@@ -20,7 +20,6 @@ import org.apache.jackrabbit.jcr2spi.sta
 import org.apache.jackrabbit.jcr2spi.state.ItemStateValidator;
 import org.apache.jackrabbit.jcr2spi.state.NodeState;
 import org.apache.jackrabbit.spi.ItemId;
-import org.apache.jackrabbit.spi.commons.util.Unchecked;
 
 import javax.jcr.RepositoryException;
 
@@ -84,11 +83,6 @@ public class Remove extends TransientOpe
     //------------------------------------------------------------< Factory >---
 
     public static Operation create(ItemState<?> state) throws RepositoryException {
-        if (state.isNode() && Unchecked.<NodeState>cast(state).getDefinition().allowsSameNameSiblings()) {
-            // in case of SNS-siblings make sure the parent hierarchy entry has
-            // its child entries loaded.
-            loadChildNodeEntries(state.getParent());
-        }
         return new Remove(state, state.getParent(), REMOVE_OPTIONS);
     }
 }

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveActivity.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveActivity.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveActivity.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/RemoveActivity.java Thu Dec 15 17:35:28 2011
@@ -51,7 +51,7 @@ public class RemoveActivity extends Abst
      * its descendants. Second, the parent state gets invalidated.
      */
     @Override
-    public void persisted() {
+    public void persisted() throws RepositoryException {
         assertStatus(Status.PENDING);
         status = Status.PERSISTED;
 

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/operation/ReorderNodes.java Thu Dec 15 17:35:28 2011
@@ -106,9 +106,6 @@ public class ReorderNodes extends Transi
     //------------------------------------------------------------< Factory >---
 
     public static Operation create(NodeState parentState, Path srcPath, Path beforePath) throws RepositoryException {
-        // make sure the parent hierarchy entry has its child entries loaded
-        loadChildNodeEntries(parentState);
-
         NodeState insert = parentState.getChildNodeState(srcPath.getName(), srcPath.getNormalizedIndex());
         NodeState before = null;
         if (beforePath != null) {

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/ItemStateFactory.java Thu Dec 15 17:35:28 2011
@@ -16,15 +16,16 @@
  */
 package org.apache.jackrabbit.jcr2spi.state;
 
+import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
+import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 import org.apache.jackrabbit.spi.ChildInfo;
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.NodeInfo;
 import org.apache.jackrabbit.spi.PropertyId;
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.jcr2spi.hierarchy.NodeEntry;
-import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 
-import javax.jcr.RepositoryException;
 import javax.jcr.ItemNotFoundException;
+import javax.jcr.RepositoryException;
 import java.util.Iterator;
 
 /**
@@ -110,6 +111,18 @@ public interface ItemStateFactory {
     Iterator<ChildInfo> getChildNodeInfos(NodeId nodeId) throws ItemNotFoundException, RepositoryException;
 
     /**
+     * Returns the {@code ChildInfo} {@code name} of the node identified by {@code nodId}. Or 
+     * {@code null} if the node does not have a child of that name.
+     *
+     *
+     *
+     * @param nodeId
+     * @param name
+     * @throws ItemNotFoundException if {@code nodId} does not exist
+     */
+    NodeInfo getNodeInfo(NodeId nodeId, Name name) throws RepositoryException;
+
+    /**
      * Returns the identifiers of all reference properties that  point to
      * the given node.
      *

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/TransientISFactory.java Thu Dec 15 17:35:28 2011
@@ -22,6 +22,7 @@ import org.apache.jackrabbit.jcr2spi.nod
 import org.apache.jackrabbit.spi.ChildInfo;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NodeId;
+import org.apache.jackrabbit.spi.NodeInfo;
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.spi.QNodeDefinition;
 import org.apache.jackrabbit.spi.QPropertyDefinition;
@@ -108,6 +109,11 @@ public final class TransientISFactory ex
     }
 
     @Override
+    public NodeInfo getNodeInfo(NodeId nodeId, Name name) throws RepositoryException {
+        return workspaceStateFactory.getNodeInfo(nodeId, name);
+    }
+
+    @Override
     public Iterator<PropertyId> getNodeReferences(NodeState nodeState, Name propertyName, boolean weak)
             throws RepositoryException {
         

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java Thu Dec 15 17:35:28 2011
@@ -21,12 +21,14 @@ import org.apache.jackrabbit.jcr2spi.hie
 import org.apache.jackrabbit.jcr2spi.hierarchy.PropertyEntry;
 import org.apache.jackrabbit.jcr2spi.nodetype.ItemDefinitionProvider;
 import org.apache.jackrabbit.spi.ChildInfo;
+import org.apache.jackrabbit.spi.IdFactory;
 import org.apache.jackrabbit.spi.ItemInfo;
 import org.apache.jackrabbit.spi.ItemInfoCache;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.NodeId;
 import org.apache.jackrabbit.spi.NodeInfo;
 import org.apache.jackrabbit.spi.Path;
+import org.apache.jackrabbit.spi.PathFactory;
 import org.apache.jackrabbit.spi.PropertyId;
 import org.apache.jackrabbit.spi.PropertyInfo;
 import org.apache.jackrabbit.spi.RepositoryService;
@@ -158,6 +160,18 @@ public class WorkspaceItemStateFactory e
     }
 
     @Override
+    public NodeInfo getNodeInfo(NodeId nodeId, Name name) throws RepositoryException {
+        PathFactory pathFactory = service.getPathFactory();
+        Path path = pathFactory.create(name);
+
+        IdFactory idFactory = service.getIdFactory();
+        NodeId childNodeId = idFactory.createNodeId(nodeId, path);
+
+        Iterator<? extends ItemInfo> infos = service.getItemInfos(sessionInfo, childNodeId);
+        return (NodeInfo) infos.next();
+    }
+
+    @Override
     public Iterator<PropertyId> getNodeReferences(NodeState nodeState, Name propertyName, boolean weak)
             throws RepositoryException {
         

Modified: jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java?rev=1214885&r1=1214884&r2=1214885&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-mk/jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/version/VersionHistoryImpl.java Thu Dec 15 17:35:28 2011
@@ -29,6 +29,8 @@ import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.conversion.NameException;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
+import org.apache.jackrabbit.spi.commons.util.Iterators;
+import org.apache.jackrabbit.spi.commons.util.Predicate1;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -95,16 +97,14 @@ public class VersionHistoryImpl extends 
     public VersionIterator getAllVersions() throws RepositoryException {
         checkStatus();
         refreshEntry(vhEntry);
-        Iterator<NodeEntry> it = vhEntry.getNodeEntries();
-        List<NodeEntry> versionEntries = new ArrayList<NodeEntry>();
-        // all child-nodes except from jcr:versionLabels point to Versions.
-        while (it.hasNext()) {
-            NodeEntry entry = it.next();
-            if (!NameConstants.JCR_VERSIONLABELS.equals(entry.getName())) {
-                versionEntries.add(entry);
+        Iterator<NodeEntry> filtered = Iterators.filterIterator(vhEntry.getNodeEntries(), new Predicate1<NodeEntry>() {
+            @Override
+            public Boolean apply(NodeEntry entry) throws Exception {
+                return !NameConstants.JCR_VERSIONLABELS.equals(entry.getName());
             }
-        }
-        return LazyItemIterator.versionIterator(getItemManager(), versionEntries.iterator());
+        });
+
+        return LazyItemIterator.versionIterator(getItemManager(), filtered);
     }
 
     @Override