Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java	(revision 1308448)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java	(revision )
@@ -605,7 +605,7 @@
                  * respective shared item and add the shared items to a
                  * new change log.
                  */
-                for (ItemState state : local.modifiedStates()) {
+                for (final ItemState state : local.modifiedStates()) {
                     state.connect(getItemState(state.getId()));
                     if (state.isStale()) {
                         boolean merged = false;
@@ -615,8 +615,7 @@
                                         public boolean isAdded(ItemId id) {
                                             try {
                                                 ItemState is = local.get(id);
-                                                return is != null
-                                                        && is.getStatus() == ItemState.STATUS_NEW;
+                                                return is != null && is.getStatus() == ItemState.STATUS_NEW;
                                             } catch (NoSuchItemStateException e) {
                                                 return false;
                                             }
@@ -650,8 +649,7 @@
                                             return ntReg.getEffectiveNodeType(ntName);
                                         }
 
-                                        protected NodeState getNodeState(NodeId id)
-                                                throws ItemStateException {
+                                        public NodeState getNodeState(NodeId id) throws ItemStateException {
                                             if (local.has(id)) {
                                                 return (NodeState) local.get(id);
                                             } else {
@@ -1312,7 +1310,7 @@
                 }
 
                 if (!(parentId == null && oldParentId == null)
-                        && !parentId.equals(oldParentId)) {
+                        && (parentId != null && !parentId.equals(oldParentId))) {
                     // This node (not the root) has been moved; check
                     // whether the parent has been modified as well
                     if (changeLog.has(parentId)) {
@@ -1397,7 +1395,7 @@
             if (sharedSet.contains(expectedParent)) {
                 return;
             }
-            String message = "Child node has another parent id " + parentId + ", expected " + expectedParent;
+            String message = "Child node " + childState.getId() + " has another parent id " + parentId + ", expected " + expectedParent;
             log.error(message);
             throw new ItemStateException(message);
         }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java	(revision 1308448)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeStateMerger.java	(revision )
@@ -109,8 +109,8 @@
                     ArrayList<ChildNodeEntry> removed = new ArrayList<ChildNodeEntry>();
 
                     for (ChildNodeEntry cne : state.getAddedChildNodeEntries()) {
-                        // locally added?
-                        if (context.isAdded(cne.getId()) || context.isModified(cne.getId())) {
+                        // locally added or moved?
+                        if (context.isAdded(cne.getId()) || (context.isModified(cne.getId()) && isParent(state, cne, context))) {
                             // a new child node entry has been added to this state;
                             // check for name collisions with other state
                             if (overlayedState.hasChildNodeEntry(cne.getName())) {
@@ -188,6 +188,14 @@
         }
     }
 
+    private static boolean isParent(NodeState state, ChildNodeEntry entry, MergeContext context) {
+        try {
+            return state.getId().equals(context.getNodeState(entry.getId()).getParentId());
+        } catch (ItemStateException e) {
+            return false;
+        }
+    }
+
     /**
      * 
      * @param state
@@ -368,5 +376,6 @@
         boolean isModified(ItemId id);
         boolean allowsSameNameSiblings(NodeId id);
         EffectiveNodeType getEffectiveNodeType(Name ntName) throws NoSuchNodeTypeException;
+        NodeState getNodeState(NodeId id) throws ItemStateException;
     }
 }
