Index: jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java
===================================================================
--- jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java	(revision 792604)
+++ jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/state/WorkspaceItemStateFactory.java	(working copy)
@@ -195,38 +195,41 @@
     private synchronized NodeState createItemStates(NodeId nodeId, Iterator itemInfos,
                                                     NodeEntry entry, boolean isDeep)
             throws ItemNotFoundException, RepositoryException {
-        NodeState nodeState;
+        NodeState nodeState = null;
         ItemInfos infos = new ItemInfos(itemInfos);
-        // first entry in the iterator is the originally requested Node.
-        if (infos.hasNext()) {
-            NodeInfo first = (NodeInfo) infos.next();
-            if (isDeep) {
-                // for a deep state, the hierarchy entry does not correspond to
-                // the given NodeEntry -> retrieve NodeState before executing
-                // validation check.
-                nodeState = createDeepNodeState(first, entry, infos);
-                assertValidState(nodeState, first);
-            } else {
-                // 'isDeep' == false -> the given NodeEntry must match to the
-                // first ItemInfo retrieved from the iterator.
-                assertMatchingPath(first, entry);
-                nodeState = createNodeState(first, entry);
-            }
-        } else {
-            // empty iterator
-            throw new ItemNotFoundException("Node with id " + nodeId + " could not be found.");
-        }
 
-        // deal with all additional ItemInfos that may be present.
-        NodeEntry parentEntry = nodeState.getNodeEntry();
         while (infos.hasNext()) {
             ItemInfo info = (ItemInfo) infos.next();
             if (info.denotesNode()) {
-                createDeepNodeState((NodeInfo) info, parentEntry, infos);
+                NodeInfo nodeInfo = (NodeInfo) info;
+
+                if (nodeId.equals(nodeInfo.getId())) {
+                    // This is the originally requested node
+                    if (isDeep) {
+                        // for a deep state, the hierarchy entry does not correspond to
+                        // the given NodeEntry -> retrieve NodeState before executing
+                        // validation check.
+                        nodeState = createDeepNodeState(nodeInfo, entry, infos);
+                        assertValidState(nodeState, nodeInfo);
+                    } else {
+                        // 'isDeep' == false -> the given NodeEntry must match the
+                        // ItemInfo for the originally requested node
+                        assertMatchingPath(nodeInfo, entry);
+                        nodeState = createNodeState(nodeInfo, entry);
+                    }
+                } else {
+                    // deal with additional nodeInfo
+                    createDeepNodeState(nodeInfo, entry, infos);
+                }
             } else {
-                createDeepPropertyState((PropertyInfo) info, parentEntry, infos);
+                // deal with additional propertyInfo
+                createDeepPropertyState((PropertyInfo) info, entry, infos);
             }
         }
+
+        if (nodeState == null) {
+            throw new ItemNotFoundException("Node with id " + nodeId + " could not be found.");
+        }
         return nodeState;
     }
 
@@ -360,9 +363,17 @@
 
             NodeEntry entry = anyParent;
             for (int i = 0; i < missingElems.length; i++) {
-                Name name = missingElems[i].getName();
-                int index = missingElems[i].getNormalizedIndex();
-                entry = createIntermediateNodeEntry(entry, name, index, infos);
+                if (missingElems[i].denotesParent()) {
+                    // Walk up the hierarchy for 'negative' paths
+                    // until the smallest common root is found
+                    entry = entry.getParent();
+                }
+                else {
+                    // Add missing elements starting from the smallest common root
+                    Name name = missingElems[i].getName();
+                    int index = missingElems[i].getNormalizedIndex();
+                    entry = createIntermediateNodeEntry(entry, name, index, infos);
+                }
             }
             if (entry == anyParent) {
                 throw new RepositoryException("Internal error while getting deep itemState");
@@ -401,9 +412,17 @@
             int i = 0;
             // NodeEntries except for the very last 'missingElem'
             while (i < missingElems.length - 1) {
-                Name name = missingElems[i].getName();
-                int index = missingElems[i].getNormalizedIndex();
-                entry = createIntermediateNodeEntry(entry, name, index, infos);
+                if (missingElems[i].denotesParent()) {
+                    // Walk up the hierarchy for 'negative' paths
+                    // until the smallest common root is found
+                    entry = entry.getParent();
+                }
+                else {
+                    // Add missing elements starting from the smallest common root
+                    Name name = missingElems[i].getName();
+                    int index = missingElems[i].getNormalizedIndex();
+                    entry = createIntermediateNodeEntry(entry, name, index, infos);
+                }
                 i++;
             }
             // create PropertyEntry for the last element if not existing yet
@@ -474,7 +493,7 @@
     }
 
     /**
-     * Returns true if the given <code>missingElems</code> start with a parent (..),
+     * Returns true if the given <code>missingElems</code> start with
      * a current (.) or the root element, in which case the info is not within
      * the tree as it is expected.
      * See also #JCR-1797 for the corresponding enhancement request.
@@ -484,7 +503,7 @@
      */
     private static boolean startsWithIllegalElement(Path.Element[] missingElems) {
         if (missingElems.length > 0) {
-            return !missingElems[0].denotesName();
+            return !(missingElems[0].denotesName() || missingElems[0].denotesParent());
         }
         return false;
     }
Index: jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java
===================================================================
--- jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java	(revision 792604)
+++ jackrabbit-spi/src/main/java/org/apache/jackrabbit/spi/RepositoryService.java	(working copy)
@@ -261,20 +261,16 @@
     public NodeInfo getNodeInfo(SessionInfo sessionInfo, NodeId nodeId) throws ItemNotFoundException, RepositoryException;
 
     /**
-     * Method used to 'batch-read' from the persistent storage. It returns the
-     * <code>NodeInfo</code> for the given <code>NodeId</code> as the first
-     * element in the <code>Iterator</code>. In addition the iterator may contain
-     * child <code>ItemInfo</code>s down to a certain depth. The configuration
-     * process however is left to the implementation.
+     * Method used to 'batch-read' from the persistent storage. It must contain
+     * the <code>NodeInfo</code> for the given <code>NodeId</code> in the
+     * <code>Iterator</code>. In addition the iterator may contain arbitrary
+     * child <code>ItemInfo</code>s from the entire hierarchy.
      *
      * @param sessionInfo
      * @param nodeId
      * @return An <code>Iterator</code> of <code>ItemInfo</code>s containing
      * at least a single element: the <code>NodeInfo</code> that represents
-     * the Node identified by the given <code>NodeId</code>. If the Iterator
-     * contains multiple elements, the first is expected to represent the Node
-     * identified by the given <code>NodeId</code> and all subsequent elements
-     * must represent children of that <code>Node</code>.
+     * the Node identified by the given <code>NodeId</code>.
      * @throws javax.jcr.ItemNotFoundException
      * @throws javax.jcr.RepositoryException
      * @see javax.jcr.Session#getItem(String)
