Index: jackrabbit-data/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-data/pom.xml	(revision 1748387)
+++ jackrabbit-data/pom.xml	(revision )
@@ -20,7 +20,7 @@
 	<parent>
 		<groupId>org.apache.jackrabbit</groupId>
 		<artifactId>jackrabbit-parent</artifactId>
-		<version>2.10.1</version>
+		<version>2.10.1-h11</version>
 		<relativePath>../jackrabbit-parent/pom.xml</relativePath>
 	</parent>
 	<artifactId>jackrabbit-data</artifactId>
@@ -70,12 +70,12 @@
 		<dependency>
 			<groupId>org.apache.jackrabbit</groupId>
 			<artifactId>jackrabbit-api</artifactId>
-			<version>${project.version}</version>
+			<version>${jackrabbit.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>org.apache.jackrabbit</groupId>
 			<artifactId>jackrabbit-jcr-commons</artifactId>
-			<version>${project.version}</version>
+			<version>${jackrabbit.version}</version>
 		</dependency>
 		<dependency>
 			<groupId>commons-io</groupId>
\ No newline at end of file
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ParentAxisQuery.java	(revision )
@@ -22,7 +22,9 @@
 import org.apache.jackrabbit.spi.Name;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.DocIdSetIterator;
 import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Scorer;
 import org.apache.lucene.search.Searcher;
@@ -251,6 +253,9 @@
          */
         private Float firstScore;
 
+
+        private Filter filter;
+
         /**
          * Creates a new <code>ParentAxisScorer</code>.
          *
@@ -267,7 +272,10 @@
             this.reader = reader;
             this.searcher = searcher;
             this.hResolver = resolver;
+            if (searcher instanceof JackrabbitIndexSearcher) {
+                this.filter = ((JackrabbitIndexSearcher)searcher).getFilter();
-        }
+            }
+        }
 
         @Override
         public int nextDoc() throws IOException {
@@ -327,6 +335,20 @@
 
                         @Override
                         protected void collect(int doc, float score) {
+                            if (filter != null) {
+                                try {
+                                    final DocIdSetIterator iterator = filter.getDocIdSet(reader).iterator();
+                                    if (iterator != null) {
+                                        final int advance = iterator.advance(doc);
+                                        if (advance != doc) {
+                                            // doc is not readable by filter : Don't return the possibly readable parent!
+                                            return;
+                                        }
+                                    }
+                                } catch (IOException e) {
+                                    // TODO log
+                                }
+                            }
                             try {
                                 docs = hResolver.getParents(doc, docs);
                                 if (docs.length == 1) {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventConsumer.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventConsumer.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/observation/EventConsumer.java	(revision )
@@ -303,7 +303,6 @@
      * @throws RepositoryException
      */
     private boolean canRead(EventState eventState) throws RepositoryException {
-        Path targetPath = pathFactory.create(eventState.getParentPath(), eventState.getChildRelPath().getName(), eventState.getChildRelPath().getNormalizedIndex(), true);
-        return session.getAccessManager().isGranted(targetPath, Permission.READ);
+        return true;
     }
 }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/cluster/ClusterNode.java	(revision )
@@ -697,10 +697,11 @@
                 return;
             }
             try {
-                long journalUpdateSize = record.update();
 
                 long recordRevision = record.getRevision();
                 setRevision(recordRevision);
+                
+                long journalUpdateSize = record.update();
 
                 log.debug("Stored record '{}' to Journal ({})", recordRevision, journalUpdateSize);
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/RowIteratorImpl.java	(revision )
@@ -20,13 +20,14 @@
 import org.apache.jackrabbit.core.id.NodeId;
 import org.apache.jackrabbit.core.ItemManager;
 import org.apache.jackrabbit.core.HierarchyManager;
+import org.apache.jackrabbit.core.session.SessionContext;
+import org.apache.jackrabbit.core.session.SessionOperation;
 import org.apache.jackrabbit.spi.commons.conversion.NameException;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.QValueFactory;
 import org.apache.jackrabbit.spi.QValue;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
 import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl;
-import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl;
 import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl;
 import org.apache.jackrabbit.spi.commons.query.qom.ColumnImpl;
@@ -109,7 +110,7 @@
     /**
      * The <code>NamePathResolver</code> of the user <code>Session</code>.
      */
-    private final NamePathResolver resolver;
+    private final SessionContext sessionContext;
 
     /**
      * The excerpt provider or <code>null</code> if none is available.
@@ -126,7 +127,23 @@
      */
     private final ValueFactoryQImpl valueFactory;
 
+
+
+    /** Number of invalid nodes */
+    protected int invalid = 0;
+
+    /** Reference to the next node instance */
+    private NodeImpl next;
+
+    /** Reference to the next scoreNodes instance */
+    private ScoreNode[] nextScoreNodes;
     /**
+     * Whether this iterator had been initialized.
+     */
+    private boolean initialized;
+
+
+    /**
      * Creates a new <code>RowIteratorImpl</code> that iterates over the result
      * nodes.
      *
@@ -137,7 +154,7 @@
      * @param itemMgr         the item manager of the session that executes the
      *                        query.
      * @param hmgr            the hierarchy manager of the workspace.
-     * @param resolver        <code>NamespaceResolver</code> of the user
+     * @param sessionContext  <code>SessionContext</code> of the user
      *                        <code>Session</code>.
      * @param valueFactory    the value factory of the current session.
      * @param exProvider      the excerpt provider associated with the query
@@ -152,7 +169,7 @@
                     Name[] selectorNames,
                     ItemManager itemMgr,
                     HierarchyManager hmgr,
-                    NamePathResolver resolver,
+                    SessionContext sessionContext,
                     ValueFactory valueFactory,
                     ExcerptProvider exProvider,
                     SpellSuggestion spellSuggestion)
@@ -162,14 +179,14 @@
         this.selectorNames.addAll(Arrays.asList(selectorNames));
         this.itemMgr = itemMgr;
         this.hmgr = hmgr;
-        this.resolver = resolver;
+        this.sessionContext = sessionContext;
         this.excerptProvider = exProvider;
         this.spellSuggestion = spellSuggestion;
         if (valueFactory instanceof ValueFactoryQImpl) {
             this.valueFactory = (ValueFactoryQImpl) valueFactory;
         } else {
             QValueFactory qvf = QValueFactoryImpl.getInstance();
-            this.valueFactory = new ValueFactoryQImpl(qvf, resolver);
+            this.valueFactory = new ValueFactoryQImpl(qvf, sessionContext);
         }
     }
 
@@ -181,8 +198,14 @@
      *                                <code>Row</code>s.
      */
     public Row nextRow() throws NoSuchElementException {
-        return new RowImpl(scoreNodes.nextScoreNodes());
+        initialize();
+        if (next == null) {
+            throw new NoSuchElementException();
-    }
+        }
+        final RowImpl row = new RowImpl(nextScoreNodes);
+        fetchNext();
+        return row;
+    }
 
     /**
      * Skip a number of <code>Row</code>s in this iterator.
@@ -192,8 +215,19 @@
      *                                <code>Row</code> in this iterator.
      */
     public void skip(long skipNum) throws NoSuchElementException {
-        scoreNodes.skip(skipNum);
+        // make sure to skip authorized nodes so we most go through #fetchNext and can't skip in scoreNodes directly
+        if (skipNum <= 0) {
+            return;
-    }
+        }
+        initialize();
+        while (skipNum > 0) {
+            if (next == null) {
+                throw new NoSuchElementException();
+            }
+            skipNum--;
+            fetchNext();
+        }
+    }
 
     /**
      * Returns the number of <code>Row</code>s in this iterator.
@@ -201,8 +235,13 @@
      * @return the number of <code>Row</code>s in this iterator.
      */
     public long getSize() {
-        return scoreNodes.getSize();
+        long size = scoreNodes.getSize();
+        if (size == -1) {
+            return size;
+        } else {
+            return size - invalid;
-    }
+        }
+    }
 
     /**
      * Returns the current position within this iterator. The number
@@ -215,8 +254,15 @@
      * @return the current position withing this iterator.
      */
     public long getPosition() {
-        return scoreNodes.getPosition();
+        initialize();
+        long position = scoreNodes.getPosition() - invalid;
+        // scoreNode.getPosition() is one ahead
+        // if there is a prefetched node
+        if (next != null) {
+            position--;
-    }
+        }
+        return position;
+    }
 
     /**
      * @throws UnsupportedOperationException always.
@@ -233,7 +279,8 @@
      * @return <code>true</code> if the iterator has more elements.
      */
     public boolean hasNext() {
-        return scoreNodes.hasNext();
+        initialize();
+        return next != null;
     }
 
     /**
@@ -246,6 +293,52 @@
         return nextRow();
     }
 
+
+    /**
+     * Clears {@link #next} and tries to fetch the next Node instance.
+     * When this method returns {@link #next} refers to the next available
+     * node instance in this iterator. If {@link #next} is null when this
+     * method returns, then there are no more valid element in this iterator.
+     */
+    protected void fetchNext() {
+        try {
+            next = null; // reset
+            sessionContext.getSessionState().perform(new FetchNext());
+        } catch (RepositoryException e) {
+            log.warn("Failed to fetch next node", e);
+        }
+    }
+
+    private class FetchNext implements SessionOperation<Object> {
+
+        public Object perform(SessionContext context) {
+
+            ItemManager itemMgr = context.getItemManager();
+            while (next == null && scoreNodes.hasNext()) {
+                nextScoreNodes = scoreNodes.nextScoreNodes();
+                try {
+                    next = (NodeImpl) itemMgr.getItem(
+                            nextScoreNodes[0].getNodeId());
+                } catch (RepositoryException e) {
+                    log.warn("Failed to retrieve query result node "
+                            + nextScoreNodes[0].getNodeId(), e);
+                    // try next
+                    invalid++;
+                }
+            }
+
+            return this;
+        }
+
+    }
+
+    protected void initialize() {
+        if (!initialized) {
+            fetchNext();
+            initialized = true;
+        }
+    }
+
     //---------------------< class RowImpl >------------------------------------
 
     /**
@@ -352,7 +445,7 @@
                         }
                     }
                 } else {
-                    Name prop = resolver.getQName(columnName);
+                    Name prop = sessionContext.getQName(columnName);
                     // either jcr:score, rep:excerpt,
                     // rep:spellcheck or not set
                     if (NameConstants.JCR_SCORE.equals(prop)) {
@@ -424,7 +517,7 @@
          */
         public String getPath() throws RepositoryException {
             checkSingleSelector("Use getPath(String) instead.");
-            return resolver.getJCRPath(hmgr.getPath(sn[0].getNodeId()));
+            return sessionContext.getJCRPath(hmgr.getPath(sn[0].getNodeId()));
         }
 
         /**
@@ -541,7 +634,7 @@
          */
         private int getSelectorIndex(String selectorName)
                 throws RepositoryException {
-            int idx = selectorNames.indexOf(resolver.getQName(selectorName));
+            int idx = selectorNames.indexOf(sessionContext.getQName(selectorName));
             if (idx == -1) {
                 throw new RepositoryException("Unknown selector name: " + selectorName);
             }
@@ -566,7 +659,7 @@
         private boolean isExcerptFunction(String name) {
             try {
                 return name.startsWith(
-                        resolver.getJCRName(REP_EXCERPT_LPAR));
+                        sessionContext.getJCRName(REP_EXCERPT_LPAR));
             } catch (NamespaceException e) {
                 // will never happen
                 return false;
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/NodeState.java	(revision )
@@ -375,8 +375,8 @@
             if (oldEntry.getName().equals(newName)) {
                 notifyNodesReplaced();
             } else {
-                notifyNodeAdded(newEntry);
                 notifyNodeRemoved(oldEntry);
+                notifyNodeAdded(newEntry);
             }
             return true;
         }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/BatchedItemOperations.java	(revision )
@@ -522,15 +522,6 @@
             throw new RepositoryException(msg);
         }
 
-        HierarchyManagerImpl hierMgr = (HierarchyManagerImpl) this.hierMgr;
-        if (hierMgr.isShareAncestor(target.getNodeId(), destParent.getNodeId())) {
-            String msg =
-                safeGetJCRPath(destPath) + ": invalid destination path"
-                + " (share cycle detected)";
-            log.debug(msg);
-            throw new RepositoryException(msg);
-        }
-
         // 2. check if target state can be removed from old/added to new parent
 
         checkRemoveNode(target, srcParent.getNodeId(),
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/LocalItemStateManager.java	(revision )
@@ -38,7 +38,7 @@
      * cache of weak references to ItemState objects issued by this
      * ItemStateManager
      */
-    private final ItemStateCache cache;
+    protected final ItemStateCache cache;
 
     /**
      * Shared item state manager
Index: jackrabbit-core/src/test/java/org/apache/jackrabbit/core/CachingHierarchyManagerTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/test/java/org/apache/jackrabbit/core/CachingHierarchyManagerTest.java	(revision 1748387)
+++ jackrabbit-core/src/test/java/org/apache/jackrabbit/core/CachingHierarchyManagerTest.java	(revision )
@@ -308,7 +308,7 @@
         path = cache.getPath(b2.getNodeId());
         assertEquals(toPath("/a1/b[2]"), path);
         ism.renameNode(b1, "b1");
-        assertTrue(cache.isCached(b1.getNodeId(), null));
+//        assertTrue(cache.isCached(b1.getNodeId(), null));
         assertTrue(cache.isCached(b2.getNodeId(), null));
         path = cache.getPath(b1.getNodeId());
         assertEquals(toPath("/a1/b1"), path);
Index: pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- pom.xml	(revision 1748387)
+++ pom.xml	(revision )
@@ -27,7 +27,7 @@
   <parent>
     <groupId>org.apache.jackrabbit</groupId>
     <artifactId>jackrabbit-parent</artifactId>
-    <version>2.10.1</version>
+    <version>2.10.1-h11</version>
     <relativePath>jackrabbit-parent/pom.xml</relativePath>
   </parent>
 
@@ -38,26 +38,26 @@
   <modules>
     <module>jackrabbit-parent</module>
     <module>jackrabbit-api</module>
-    <module>jackrabbit-jcr-commons</module>
+    <!--<module>jackrabbit-jcr-commons</module>-->
     <module>jackrabbit-jcr-tests</module>
     <module>jackrabbit-data</module>
-    <module>jackrabbit-aws-ext</module>
+    <!--<module>jackrabbit-aws-ext</module>-->
     <module>jackrabbit-core</module>
-    <module>jackrabbit-webdav</module>
-    <module>jackrabbit-jcr-server</module>
-    <module>jackrabbit-jcr-rmi</module>
-    <module>jackrabbit-jcr-servlet</module>
-    <module>jackrabbit-webapp</module>
-    <module>jackrabbit-jca</module>
-    <module>jackrabbit-spi</module>
+    <!--<module>jackrabbit-webdav</module>-->
+    <!--<module>jackrabbit-jcr-server</module>-->
+    <!--<module>jackrabbit-jcr-rmi</module>-->
+    <!--<module>jackrabbit-jcr-servlet</module>-->
+    <!--<module>jackrabbit-webapp</module>-->
+    <!--<module>jackrabbit-jca</module>-->
+    <!--<module>jackrabbit-spi</module>-->
     <module>jackrabbit-spi-commons</module>
-    <module>jackrabbit-jcr2spi</module>
-    <module>jackrabbit-spi2jcr</module>
-    <module>jackrabbit-spi2dav</module>
-    <module>jackrabbit-jcr2dav</module>
-    <module>jackrabbit-jcr-client</module>
-    <module>jackrabbit-bundle</module>
-    <module>jackrabbit-standalone</module>
+    <!--<module>jackrabbit-jcr2spi</module>-->
+    <!--<module>jackrabbit-spi2jcr</module>-->
+    <!--<module>jackrabbit-spi2dav</module>-->
+    <!--<module>jackrabbit-jcr2dav</module>-->
+    <!--<module>jackrabbit-jcr-client</module>-->
+    <!--<module>jackrabbit-bundle</module>-->
+    <!--<module>jackrabbit-standalone</module>-->
   </modules>
 
   <scm>
Index: jackrabbit-spi-commons/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-spi-commons/pom.xml	(revision 1748387)
+++ jackrabbit-spi-commons/pom.xml	(revision )
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.jackrabbit</groupId>
     <artifactId>jackrabbit-parent</artifactId>
-    <version>2.10.1</version>
+    <version>2.10.1-h11</version>
     <relativePath>../jackrabbit-parent/pom.xml</relativePath>
   </parent>
   <artifactId>jackrabbit-spi-commons</artifactId>
@@ -80,12 +80,12 @@
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-spi</artifactId>
-      <version>${project.version}</version>
+      <version>${jackrabbit.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-jcr-commons</artifactId>
-      <version>${project.version}</version>
+      <version>${jackrabbit.version}</version>
     </dependency>
     <dependency>
       <groupId>commons-collections</groupId>
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java	(revision )
@@ -691,6 +691,10 @@
         // based on removed ids get affected aggregate root nodes
         retrieveAggregateRoot(removedIds, aggregateRoots);
 
+        // again remove any aggregateRoot nodes that are new
+        // and therefore already up-to-date
+        aggregateRoots.keySet().removeAll(addedIds);
+
         // update aggregates if there are any affected
         if (!aggregateRoots.isEmpty()) {
             Collection<Document> modified =
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/NodeIteratorImpl.java	(revision )
@@ -110,9 +110,16 @@
      *          if skipped past the last <code>Node</code> in this iterator.
      */
     public void skip(long skipNum) throws NoSuchElementException {
+        // make sure to skip authorized nodes so we most go through #fetchNext and can't skip in scoreNodes directly
+        if (skipNum <= 0) {
+            return;
+        }
         initialize();
-        if (skipNum > 0) {
-            scoreNodes.skip(skipNum - 1);
+        while (skipNum > 0) {
+            if (next == null) {
+                throw new NoSuchElementException();
+            }
+            skipNum--;
             fetchNext();
         }
     }
Index: jackrabbit-api/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-api/pom.xml	(revision 1748387)
+++ jackrabbit-api/pom.xml	(revision )
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.jackrabbit</groupId>
     <artifactId>jackrabbit-parent</artifactId>
-    <version>2.10.1</version>
+    <version>2.10.1-h11</version>
     <relativePath>../jackrabbit-parent/pom.xml</relativePath>
   </parent>
   <artifactId>jackrabbit-api</artifactId>
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/RepositoryImpl.java	(revision )
@@ -37,6 +37,8 @@
 import javax.jcr.AccessDeniedException;
 import javax.jcr.Credentials;
 import javax.jcr.LoginException;
+import javax.jcr.NamespaceException;
+import javax.jcr.NamespaceRegistry;
 import javax.jcr.NoSuchWorkspaceException;
 import javax.jcr.PropertyType;
 import javax.jcr.Repository;
@@ -240,6 +242,32 @@
      */
     private WorkspaceEventChannel createWorkspaceEventChannel;
 
+    private class DelegatingClusterContext extends ExternalEventListener implements ClusterContext {
+
+        private NamespaceResolver namespaceResolver;
+
+        private final NamespaceResolver delegatingNamespaceResolver = new NamespaceResolver() {
+            @Override
+            public String getURI(final String prefix) throws NamespaceException {
+                return namespaceResolver != null ? namespaceResolver.getURI(prefix) : null;
+            }
+
+            @Override
+            public String getPrefix(final String uri) throws NamespaceException {
+                return namespaceResolver != null ? namespaceResolver.getPrefix(uri) : null;
+            }
+        };
+
+        public void setNamespaceRegistry(NamespaceRegistry namespaceRegistry) {
+            namespaceResolver = new RegistryNamespaceResolver(namespaceRegistry);
+        }
+
+        @Override
+        public NamespaceResolver getNamespaceResolver() {
+            return delegatingNamespaceResolver;
+        }
+    }
+
     /**
      * Protected constructor.
      *
@@ -270,6 +298,20 @@
             initRepositoryDescriptors();
 
             // create registries
+            // initialize optional clustering before setting up any other
+            // external event source that a cluster node will be interested in
+            ClusterNode clusterNode = null;
+            DelegatingClusterContext clusterContext = null;
+            if (repConfig.getClusterConfig() != null) {
+                clusterNode = new ClusterNode();
+                clusterContext = new DelegatingClusterContext();
+                try {
+                    clusterNode.init(clusterContext);
+                }
+                catch (Exception e) {
+                    throw new RepositoryException(e);
+                }
+            }
             context.setNamespaceRegistry(createNamespaceRegistry());
             context.setNodeTypeRegistry(createNodeTypeRegistry());
             context.setPrivilegeRegistry(new PrivilegeRegistry(context.getNamespaceRegistry(), context.getFileSystem()));
@@ -295,11 +337,8 @@
                 wspInfos.put(config.getName(), info);
             }
 
-            // initialize optional clustering before setting up any other
-            // external event source that a cluster node will be interested in
-            ClusterNode clusterNode = null;
-            if (repConfig.getClusterConfig() != null) {
-                clusterNode = createClusterNode();
+            if (clusterNode != null) {
+                clusterContext.setNamespaceRegistry(context.getNamespaceRegistry());
                 context.setClusterNode(clusterNode);
                 context.getNamespaceRegistry().setEventChannel(clusterNode);
                 context.getNodeTypeRegistry().setEventChannel(clusterNode);
Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java	(revision 1748387)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/nodetype/NodeTypeDefDiff.java	(revision )
@@ -16,15 +16,6 @@
  */
 package org.apache.jackrabbit.spi.commons.nodetype;
 
-import org.apache.jackrabbit.spi.Name;
-import org.apache.jackrabbit.spi.QItemDefinition;
-import org.apache.jackrabbit.spi.QNodeDefinition;
-import org.apache.jackrabbit.spi.QNodeTypeDefinition;
-import org.apache.jackrabbit.spi.QPropertyDefinition;
-import org.apache.jackrabbit.spi.QValueConstraint;
-import org.apache.jackrabbit.spi.commons.name.NameConstants;
-
-import javax.jcr.PropertyType;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
@@ -36,8 +27,17 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.atomic.AtomicInteger;
 
+import javax.jcr.PropertyType;
+
+import org.apache.jackrabbit.spi.Name;
+import org.apache.jackrabbit.spi.QItemDefinition;
+import org.apache.jackrabbit.spi.QNodeDefinition;
+import org.apache.jackrabbit.spi.QNodeTypeDefinition;
+import org.apache.jackrabbit.spi.QPropertyDefinition;
+import org.apache.jackrabbit.spi.QValueConstraint;
+import org.apache.jackrabbit.spi.commons.name.NameConstants;
+
 /**
  * A <code>NodeTypeDefDiff</code> represents the result of the comparison of
  * two node type definitions.
@@ -106,13 +106,6 @@
     private NodeTypeDefDiff(QNodeTypeDefinition oldDef, QNodeTypeDefinition newDef) {
         this.oldDef = oldDef;
         this.newDef = newDef;
-        init();
-    }
-
-    /**
-     *
-     */
-    private void init() {
         if (oldDef.equals(newDef)) {
             // definitions are identical
             type = NONE;
@@ -144,13 +137,17 @@
             // no need to check queryable flag (TRIVIAL modification)
 
             // check property definitions
-            tmpType = buildPropDefDiffs();
+            PropDefDiffBuilder propDefDiffBuilder = new PropDefDiffBuilder(oldDef.getPropertyDefs(), newDef.getPropertyDefs());
+            propDefDiffs.addAll(propDefDiffBuilder.getChildItemDefDiffs());
+            tmpType = propDefDiffBuilder.getMaxType();
             if (tmpType > type) {
                 type = tmpType;
             }
 
             // check child node definitions
-            tmpType = buildChildNodeDefDiffs();
+            ChildNodeDefDiffBuilder childNodeDefDiffBuilder = new ChildNodeDefDiffBuilder(oldDef.getChildNodeDefs(), newDef.getChildNodeDefs());
+            childNodeDefDiffs.addAll(childNodeDefDiffBuilder.getChildItemDefDiffs());
+            tmpType = childNodeDefDiffBuilder.getMaxType();
             if (tmpType > type) {
                 type = tmpType;
             }
@@ -232,95 +229,6 @@
         return !set1.equals(set2) ? MAJOR : NONE;
     }
 
-    /**
-     * @return diff type
-     */
-    private int buildPropDefDiffs() {
-        int maxType = NONE;
-        Map<QPropertyDefinitionId, QPropertyDefinition> oldDefs = new HashMap<QPropertyDefinitionId, QPropertyDefinition>();
-        for (QPropertyDefinition def : oldDef.getPropertyDefs()) {
-            oldDefs.put(new QPropertyDefinitionId(def), def);
-        }
-
-        Map<QPropertyDefinitionId, QPropertyDefinition> newDefs = new HashMap<QPropertyDefinitionId, QPropertyDefinition>();
-        for (QPropertyDefinition def : newDef.getPropertyDefs()) {
-            newDefs.put(new QPropertyDefinitionId(def), def);
-        }
-
-        /**
-         * walk through defs1 and process all entries found in
-         * both defs1 & defs2 and those found only in defs1
-         */
-        for (Map.Entry<QPropertyDefinitionId, QPropertyDefinition> entry : oldDefs.entrySet()) {
-            QPropertyDefinitionId id = entry.getKey();
-            QPropertyDefinition def1 = entry.getValue();
-            QPropertyDefinition def2 = newDefs.get(id);
-            PropDefDiff diff = new PropDefDiff(def1, def2);
-            if (diff.getType() > maxType) {
-                maxType = diff.getType();
-            }
-            propDefDiffs.add(diff);
-            newDefs.remove(id);
-        }
-
-        /**
-         * defs2 by now only contains entries found in defs2 only;
-         * walk through defs2 and process all remaining entries
-         */
-        for (Map.Entry<QPropertyDefinitionId, QPropertyDefinition> entry : newDefs.entrySet()) {
-            QPropertyDefinition def = entry.getValue();
-            PropDefDiff diff = new PropDefDiff(null, def);
-            if (diff.getType() > maxType) {
-                maxType = diff.getType();
-            }
-            propDefDiffs.add(diff);
-        }
-
-        return maxType;
-    }
-
-    /**
-     * @return diff type
-     */
-    private int buildChildNodeDefDiffs() {
-        int maxType = NONE;
-        final Map<QNodeDefinitionId, List<QNodeDefinition>> oldDefs = collectChildNodeDefs(oldDef.getChildNodeDefs());
-        final Map<QNodeDefinitionId, List<QNodeDefinition>> newDefs = collectChildNodeDefs(newDef.getChildNodeDefs());
-
-        for (QNodeDefinitionId defId : oldDefs.keySet()) {
-            final ChildNodeDefDiffs childNodeDefDiffs = new ChildNodeDefDiffs(oldDefs.get(defId), newDefs.get(defId));
-            this.childNodeDefDiffs.addAll(childNodeDefDiffs.getChildNodeDefDiffs());
-            newDefs.remove(defId);
-        }
-
-        for (QNodeDefinitionId defId : newDefs.keySet()) {
-            final ChildNodeDefDiffs childNodeDefDiffs = new ChildNodeDefDiffs(null, newDefs.get(defId));
-            this.childNodeDefDiffs.addAll(childNodeDefDiffs.getChildNodeDefDiffs());
-        }
-
-        for (ChildNodeDefDiff diff : childNodeDefDiffs) {
-            if (diff.getType() > maxType) {
-                maxType = diff.getType();
-            }
-        }
-
-        return maxType;
-    }
-
-    private Map<QNodeDefinitionId, List<QNodeDefinition>> collectChildNodeDefs(final QNodeDefinition[] cnda1) {
-        Map<QNodeDefinitionId, List<QNodeDefinition>> defs1 = new HashMap<QNodeDefinitionId, List<QNodeDefinition>>();
-        for (QNodeDefinition def1 : cnda1) {
-            final QNodeDefinitionId def1Id = new QNodeDefinitionId(def1);
-            List<QNodeDefinition> list = defs1.get(def1Id);
-            if (list == null) {
-                list = new ArrayList<QNodeDefinition>();
-                defs1.put(def1Id, list);
-            }
-            list.add(def1);
-        }
-        return defs1;
-    }
-
     @Override
     public String toString() {
         String result = getClass().getName() + "[\n\tnodeTypeName="
@@ -373,12 +281,138 @@
 
     //--------------------------------------------------------< inner classes >
 
-    abstract class ChildItemDefDiff {
-        protected final QItemDefinition oldDef;
-        protected final QItemDefinition newDef;
+    private abstract class ChildItemDefDiffBuilder<T extends QItemDefinition, V extends ChildItemDefDiff<T>> {
+
+        private final List<V> childItemDefDiffs = new ArrayList<V>();
+
+        private ChildItemDefDiffBuilder(T[] oldDefs, T[] newDefs) {
+            buildChildItemDefDiffs(collectChildNodeDefs(oldDefs), collectChildNodeDefs(newDefs));
+        }
+
+        private void buildChildItemDefDiffs(Map<Object, List<T>> oldDefs, Map<Object, List<T>> newDefs) {
+            for (Object defId : oldDefs.keySet()) {
+                this.childItemDefDiffs.addAll(getChildItemDefDiffs(oldDefs.get(defId), newDefs.get(defId)));
+                newDefs.remove(defId);
+            }
+            for (Object defId : newDefs.keySet()) {
+                this.childItemDefDiffs.addAll(getChildItemDefDiffs(null, newDefs.get(defId)));
+            }
+        }
+
+        private Map<Object, List<T>> collectChildNodeDefs(final T[] defs) {
+            Map<Object, List<T>> result = new HashMap<Object, List<T>>();
+            for (T def : defs) {
+                final Object defId = createQItemDefinitionId(def);
+                List<T> list = result.get(defId);
+                if (list == null) {
+                    list = new ArrayList<T>();
+                    result.put(defId, list);
+                }
+                list.add(def);
+            }
+            return result;
+        }
+
+        abstract Object createQItemDefinitionId(T def);
+
+        abstract V createChildItemDefDiff(T def1, T def2);
+
+        Collection<V> getChildItemDefDiffs(List<T> defs1, List<T> defs2) {
+            defs1 = defs1 != null ? defs1 : Collections.<T>emptyList();
+            defs2 = defs2 != null ? defs2 : Collections.<T>emptyList();
+            // collect all possible combinations of diffs
+            final List<V> diffs = new ArrayList<V>();
+            for (T def1 : defs1) {
+                for (T def2 : defs2) {
+                    diffs.add(createChildItemDefDiff(def1, def2));
+                }
+            }
+            if (defs2.size() < defs1.size()) {
+                for (T def1 : defs1) {
+                    diffs.add(createChildItemDefDiff(def1, null));
+                }
+            }
+            if (defs1.size() < defs2.size()) {
+                for (T def2 : defs2) {
+                    diffs.add(createChildItemDefDiff(null, def2));
+                }
+            }
+            // sort them according to decreasing compatibility
+            Collections.sort(diffs, new Comparator<V>() {
+                @Override
+                public int compare(final V o1, final V o2) {
+                    return o1.getType() - o2.getType();
+                }
+            });
+            // select the most compatible ones
+            final int size = defs1.size() > defs2.size() ? defs1.size() : defs2.size();
+            int allowedNewNull = defs1.size() - defs2.size();
+            int allowedOldNull = defs2.size() - defs1.size();
+            final List<V> results = new ArrayList<V>();
+            for (V diff : diffs) {
+                if (!alreadyMatched(results, diff.getNewDef(), diff.getOldDef(), allowedNewNull, allowedOldNull)) {
+                    results.add(diff);
+                    if (diff.getNewDef() == null) {
+                        allowedNewNull--;
+                    }
+                    if (diff.getOldDef() == null) {
+                        allowedOldNull--;
+                    }
+                }
+                if (results.size() == size) {
+                    break;
+                }
+            }
+            return results;
+        }
+
+        private boolean alreadyMatched(final List<V> result, final T newDef, final T oldDef, final int allowedNewNull, final int allowedOldNull) {
+            boolean containsNewDef = false, containsOldDef = false;
+            for (V d : result) {
+                if (d.getNewDef() != null && d.getNewDef().equals(newDef)) {
+                    containsNewDef = true;
+                    break;
+                }
+                if (d.getOldDef() != null && d.getOldDef().equals(oldDef)) {
+                    containsOldDef = true;
+                    break;
+                }
+            }
+            if (oldDef == null) {
+                if (allowedOldNull < 1) {
+                    containsOldDef = true;
+                }
+            }
+            if (newDef == null) {
+                if (allowedNewNull < 1) {
+                    containsNewDef = true;
+                }
+            }
+
+            return containsNewDef || containsOldDef;
+        }
+
+        List<V> getChildItemDefDiffs() {
+            return childItemDefDiffs;
+        }
+
+        int getMaxType() {
+            int maxType = NONE;
+            for (V childItemDefDiff : childItemDefDiffs) {
+                if (childItemDefDiff.getType() > maxType) {
+                    maxType = childItemDefDiff.getType();
+                }
+            }
+            return maxType;
+        }
+    }
+
+    private abstract class ChildItemDefDiff<T extends QItemDefinition> {
+        protected final T oldDef;
+        protected final T newDef;
         protected int type;
 
-        ChildItemDefDiff(QItemDefinition oldDef, QItemDefinition newDef) {
+        private ChildItemDefDiff(T oldDef, T newDef) {
             this.oldDef = oldDef;
             this.newDef = newDef;
             init();
@@ -430,19 +464,27 @@
             }
         }
 
-        public int getType() {
+        T getOldDef() {
+            return oldDef;
+        }
+
+        T getNewDef() {
+            return newDef;
+        }
+
+        int getType() {
             return type;
         }
 
-        public boolean isAdded() {
+        boolean isAdded() {
             return oldDef == null && newDef != null;
         }
 
-        public boolean isRemoved() {
+        boolean isRemoved() {
             return oldDef != null && newDef == null;
         }
 
-        public boolean isModified() {
+        boolean isModified() {
             return oldDef != null && newDef != null
                     && !oldDef.equals(newDef);
         }
@@ -471,20 +513,12 @@
 
     }
 
-    public class PropDefDiff extends ChildItemDefDiff {
+    private class PropDefDiff extends ChildItemDefDiff<QPropertyDefinition> {
 
-        PropDefDiff(QPropertyDefinition oldDef, QPropertyDefinition newDef) {
+        private PropDefDiff(QPropertyDefinition oldDef, QPropertyDefinition newDef) {
             super(oldDef, newDef);
         }
 
-        public QPropertyDefinition getOldDef() {
-            return (QPropertyDefinition) oldDef;
-        }
-
-        public QPropertyDefinition getNewDef() {
-            return (QPropertyDefinition) newDef;
-        }
-
         @Override
         protected void init() {
             super.init();
@@ -564,20 +598,12 @@
         }
     }
 
-    public class ChildNodeDefDiff extends ChildItemDefDiff {
+    private class ChildNodeDefDiff extends ChildItemDefDiff<QNodeDefinition> {
 
-        ChildNodeDefDiff(QNodeDefinition oldDef, QNodeDefinition newDef) {
+        private ChildNodeDefDiff(QNodeDefinition oldDef, QNodeDefinition newDef) {
             super(oldDef, newDef);
         }
 
-        public QNodeDefinition getOldDef() {
-            return (QNodeDefinition) oldDef;
-        }
-
-        public QNodeDefinition getNewDef() {
-            return (QNodeDefinition) newDef;
-        }
-
         @Override
         protected void init() {
             super.init();
@@ -624,16 +650,14 @@
     /**
      * Identifier used to identify corresponding property definitions
      */
-    static class QPropertyDefinitionId {
+    private static class QPropertyDefinitionId {
 
-        Name declaringNodeType;
-        Name name;
-        boolean definesResidual;
+        private Name declaringNodeType;
+        private Name name;
 
-        QPropertyDefinitionId(QPropertyDefinition def) {
+        private QPropertyDefinitionId(QPropertyDefinition def) {
             declaringNodeType = def.getDeclaringNodeType();
             name = def.getName();
-            definesResidual = def.definesResidual();
         }
 
         //---------------------------------------< java.lang.Object overrides >
@@ -645,8 +669,7 @@
             if (obj instanceof QPropertyDefinitionId) {
                 QPropertyDefinitionId other = (QPropertyDefinitionId) obj;
                 return declaringNodeType.equals(other.declaringNodeType)
-                        && name.equals(other.name)
-                        && definesResidual == other.definesResidual;
+                        && name.equals(other.name);
             }
             return false;
         }
@@ -656,7 +679,6 @@
             int h = 17;
             h = 37 * h + declaringNodeType.hashCode();
             h = 37 * h + name.hashCode();
-            h = 37 * h + (definesResidual ? 11 : 43);
             return h;
         }
     }
@@ -664,12 +686,12 @@
     /**
      * Identifier used to identify corresponding node definitions
      */
-    static class QNodeDefinitionId {
+    private static class QNodeDefinitionId {
 
-        Name declaringNodeType;
-        Name name;
+        private Name declaringNodeType;
+        private Name name;
 
-        QNodeDefinitionId(QNodeDefinition def) {
+        private QNodeDefinitionId(QNodeDefinition def) {
             declaringNodeType = def.getDeclaringNodeType();
             name = def.getName();
         }
@@ -697,87 +719,37 @@
         }
     }
 
-    private class ChildNodeDefDiffs {
+    private class ChildNodeDefDiffBuilder extends ChildItemDefDiffBuilder<QNodeDefinition, ChildNodeDefDiff> {
 
-        private final List<QNodeDefinition> defs1;
-        private final List<QNodeDefinition> defs2;
-
-        private ChildNodeDefDiffs(final List<QNodeDefinition> defs1, final List<QNodeDefinition> defs2) {
-            this.defs1 = defs1 != null ? defs1 : Collections.<QNodeDefinition>emptyList();
-            this.defs2 = defs2 != null ? defs2 : Collections.<QNodeDefinition>emptyList();
+        private ChildNodeDefDiffBuilder(final QNodeDefinition[] defs1, final QNodeDefinition[] defs2) {
+            super(defs1, defs2);
         }
 
-        private Collection<ChildNodeDefDiff> getChildNodeDefDiffs() {
-            // gather all possible combinations of diffs
-            final List<ChildNodeDefDiff> diffs = new ArrayList<ChildNodeDefDiff>();
-            for (QNodeDefinition def1 : defs1) {
-                for (QNodeDefinition def2 : defs2) {
-                    diffs.add(new ChildNodeDefDiff(def1, def2));
+        @Override
+        Object createQItemDefinitionId(final QNodeDefinition def) {
+            return new QNodeDefinitionId(def);
-                }
+        }
-            }
-            if (defs2.size() < defs1.size()) {
-                for (QNodeDefinition def1 : defs1) {
-                    diffs.add(new ChildNodeDefDiff(def1, null));
-                }
-            }
-            if (defs1.size() < defs2.size()) {
-                for (QNodeDefinition def2 : defs2) {
-                    diffs.add(new ChildNodeDefDiff(null, def2));
-                }
-            }
-            // sort them according to decreasing compatibility
-            Collections.sort(diffs, new Comparator<ChildNodeDefDiff>() {
+
-                @Override
+        @Override
-                public int compare(final ChildNodeDefDiff o1, final ChildNodeDefDiff o2) {
-                    return o1.getType() - o2.getType();
+        ChildNodeDefDiff createChildItemDefDiff(final QNodeDefinition def1, final QNodeDefinition def2) {
+            return new ChildNodeDefDiff(def1, def2);
-                }
+        }
-            });
-            // select the most compatible ones
-            final int size = defs1.size() > defs2.size() ? defs1.size() : defs2.size();
-            AtomicInteger allowedNewNull = new AtomicInteger(defs1.size() - defs2.size());
-            AtomicInteger allowedOldNull = new AtomicInteger(defs2.size() - defs1.size());
-            final List<ChildNodeDefDiff> results = new ArrayList<ChildNodeDefDiff>();
-            for (ChildNodeDefDiff diff : diffs) {
-                if (!alreadyMatched(results, diff.getNewDef(), diff.getOldDef(), allowedNewNull, allowedOldNull)) {
-                    results.add(diff);
-                    if (diff.getNewDef() == null) {
-                        allowedNewNull.decrementAndGet();
-                    }
+    }
-                    if (diff.getOldDef() == null) {
-                        allowedOldNull.decrementAndGet();
+
+    private class PropDefDiffBuilder extends ChildItemDefDiffBuilder<QPropertyDefinition, PropDefDiff> {
+
+        private PropDefDiffBuilder(final QPropertyDefinition[] defs1, final QPropertyDefinition[] defs2) {
+            super(defs1, defs2);
-                    }
+        }
-                }
-                if (results.size() == size) {
-                    break;
-                }
-            }
-            return results;
-        }
 
-        private boolean alreadyMatched(final List<ChildNodeDefDiff> result, final QNodeDefinition newDef, final QNodeDefinition oldDef, final AtomicInteger allowedNewNull, final AtomicInteger allowedOldNull) {
-            boolean containsNewDef = false, containsOldDef = false;
-            for (ChildNodeDefDiff d : result) {
-                if (d.getNewDef() != null && d.getNewDef().equals(newDef)) {
-                    containsNewDef = true;
-                    break;
+        @Override
+        Object createQItemDefinitionId(final QPropertyDefinition def) {
+            return new QPropertyDefinitionId(def);
-                }
+        }
-                if (d.getOldDef() != null && d.getOldDef().equals(oldDef)) {
-                    containsOldDef = true;
-                    break;
-                }
-            }
-            if (oldDef == null) {
-                if (allowedOldNull.get() < 1) {
-                    containsOldDef = true;
-                }
-            }
-            if (newDef == null) {
-                if (allowedNewNull.get() < 1) {
-                    containsNewDef = true;
-                }
-            }
 
-            return containsNewDef || containsOldDef;
+        @Override
+        PropDefDiff createChildItemDefDiff(final QPropertyDefinition def1, final QPropertyDefinition def2) {
+            return new PropDefDiff(def1, def2);
         }
     }
 
Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathBuilder.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathBuilder.java	(revision 1748387)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathBuilder.java	(revision )
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.spi.commons.name;
 
+import javax.jcr.RepositoryException;
 import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.PathFactory;
@@ -89,9 +90,9 @@
      */
     public void addRoot() {
         if (path != null) {
-            path = RootPath.ROOT_PATH.resolve(path);
+            path = ((Path)factory.getRootElement()).resolve(path);
         } else {
-            path = RootPath.ROOT_PATH;
+            path = (Path) factory.getRootElement();
         }
     }
 
@@ -172,7 +173,11 @@
      * @param index
      */
     public void addLast(Name name, int index) {
-        path = new NamePath(path, name, index);
+        try {
+            path = factory.create(path, name, index, false);
+        } catch(RepositoryException ex) {
+            // because normalize argument to create method is false, will not occur
+        }
     }
 
     /**
\ No newline at end of file
Index: jackrabbit-core/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/pom.xml	(revision 1748387)
+++ jackrabbit-core/pom.xml	(revision )
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.jackrabbit</groupId>
     <artifactId>jackrabbit-parent</artifactId>
-    <version>2.10.1</version>
+    <version>2.10.1-h11</version>
     <relativePath>../jackrabbit-parent/pom.xml</relativePath>
   </parent>
   <artifactId>jackrabbit-core</artifactId>
@@ -103,17 +103,13 @@
 org.apache.jackrabbit.core.xml.DocumentViewTest#testMultiValue
 org.apache.jackrabbit.core.NodeImplTest#testReferentialIntegrityCorruptionGetPath
 org.apache.jackrabbit.core.integration.ConcurrentQueryTest#testConcurrentQueryWithDeletes
-org.apache.jackrabbit.test.api.ShareableNodeTest#testGetName
-org.apache.jackrabbit.test.api.ShareableNodeTest#testGetNode
-org.apache.jackrabbit.test.api.ShareableNodeTest#testGetNodes
-org.apache.jackrabbit.test.api.ShareableNodeTest#testGetNodesByPattern
-org.apache.jackrabbit.test.api.ShareableNodeTest#testMoveShareableNode<!--JCR-3381-->
-org.apache.jackrabbit.test.api.ShareableNodeTest#testTransientMoveShareableNode<!--JCR-3381-->
+org.apache.jackrabbit.test.api.ShareableNodeTest
 org.apache.jackrabbit.test.api.lock.OpenScopedLockTest#testLockExpiration
 org.apache.jackrabbit.test.api.lock.SessionScopedLockTest#testLockExpiration
 org.apache.jackrabbit.test.api.observation.NodeReorderTest#testNodeReorderMove
 org.apache.jackrabbit.core.data.ConcurrentGcTest#testDatabases
 org.apache.jackrabbit.core.data.GarbageCollectorTest#testCloseSessionWhileRunningGc
+org.apache.jackrabbit.core.query.lucene.DecimalConvertTest#testRandomized <!-- JCR-3834 -->
 org.apache.jackrabbit.core.ReplacePropertyWhileOthersReadTest <!-- JCR-3835 -->
               </value>
             </property>
@@ -239,12 +235,12 @@
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-api</artifactId>
-      <version>${project.version}</version>
+      <version>${jackrabbit.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-jcr-commons</artifactId>
-      <version>${project.version}</version>
+      <version>${jackrabbit.version}</version>
     </dependency>
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
@@ -266,13 +262,13 @@
     <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-spi</artifactId>
-      <version>${project.version}</version>
+      <version>${jackrabbit.version}</version>
       <classifier />
     </dependency>
       <dependency>
       <groupId>org.apache.jackrabbit</groupId>
       <artifactId>jackrabbit-spi</artifactId>
-      <version>${project.version}</version>
+      <version>${jackrabbit.version}</version>
       <classifier>tests</classifier>
       <scope>test</scope>
     </dependency>
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/bundle/AbstractBundlePersistenceManager.java	(revision )
@@ -644,7 +644,6 @@
                 PropertyId id = (PropertyId) state.getId();
                 // skip redundant primaryType, mixinTypes and uuid properties
                 if (id.getName().equals(JCR_PRIMARYTYPE)
-                    || id.getName().equals(JCR_MIXINTYPES)
                     || id.getName().equals(JCR_UUID)) {
                     continue;
                 }
@@ -692,7 +691,6 @@
                 PropertyId id = (PropertyId) state.getId();
                 // skip primaryType pr mixinTypes properties
                 if (id.getName().equals(JCR_PRIMARYTYPE)
-                    || id.getName().equals(JCR_MIXINTYPES)
                     || id.getName().equals(JCR_UUID)) {
                     continue;
                 }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/MemoryJournal.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/MemoryJournal.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/MemoryJournal.java	(revision )
@@ -99,6 +99,11 @@
         checkState();
     }
 
+    @Override
+    protected void appending(AppendRecord record) {
+        record.setRevision(records.size()+1);
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -129,7 +134,6 @@
             throw new JournalException("Interrupted in append().");
         }
         records.add(new MemoryRecord(getId(), record.getProducerId(), data));
-        record.setRevision(records.size());
     }
 
     /**
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/SessionImpl.java	(revision )
@@ -16,6 +16,10 @@
  */
 package org.apache.jackrabbit.core;
 
+import org.apache.jackrabbit.core.observation.EventStateCollectionFactory;
+import org.apache.jackrabbit.core.state.ItemStateCacheFactory;
+import org.apache.jackrabbit.core.state.LocalItemStateManager;
+import org.apache.jackrabbit.core.state.SharedItemStateManager;
 import static org.apache.jackrabbit.core.ItemValidator.CHECK_CHECKED_OUT;
 import static org.apache.jackrabbit.core.ItemValidator.CHECK_CONSTRAINTS;
 import static org.apache.jackrabbit.core.ItemValidator.CHECK_HOLD;
@@ -1330,4 +1334,7 @@
         }
     }
 
+    public LocalItemStateManager createItemStateManager(RepositoryContext repositoryContext, WorkspaceImpl workspace, SharedItemStateManager sharedStateMgr, EventStateCollectionFactory factory, String attribute, ItemStateCacheFactory cacheFactory) {
+        return LocalItemStateManager.createInstance(sharedStateMgr, factory, cacheFactory);
+    }
 }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SessionItemStateManager.java	(revision )
@@ -803,7 +803,19 @@
                 visibleState = transientState;
             }
         }
+        boolean notifyTransientSpace;
+        if (visibleState instanceof NodeState) {
+            // No need to push "node created" to transient space:
+            // either the transient already knows about this state, or it doesn't.
+            // If we notify in this case, this can lead to a deadlock,
+            // see JCR-3226.
+            notifyTransientSpace = false;
+        } else {
+            notifyTransientSpace = true;
+        }
+        if (notifyTransientSpace) {
-        dispatcher.notifyStateCreated(visibleState);
+            dispatcher.notifyStateCreated(visibleState);
+        }
     }
 
     /**
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseRecordIterator.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseRecordIterator.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseRecordIterator.java	(revision )
@@ -16,6 +16,7 @@
  */
 package org.apache.jackrabbit.core.journal;
 
+import org.apache.jackrabbit.core.util.db.ConnectionHelper;
 import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver;
 import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver;
 import org.slf4j.Logger;
@@ -32,56 +33,30 @@
  */
 class DatabaseRecordIterator implements RecordIterator {
 
-    /**
-     * Logger.
-     */
-    private static Logger log = LoggerFactory.getLogger(DatabaseRecordIterator.class);
+    private static final Logger log = LoggerFactory.getLogger(DatabaseRecordIterator.class);
+    private static final int BATCH_SIZE = 1024;
 
-    /**
-     * Underlying result set.
-     */
-    private final ResultSet rs;
-
-    /**
-     * Namespace resolver.
-     */
+    private final ConnectionHelper conHelper;
+    private ResultSet rs;
+    private final String selectRecordsStmt;
+    private final long startRevision;
     private final NamespaceResolver resolver;
-
-    /**
-     * Name and Path resolver.
-     */
     private final NamePathResolver npResolver;
-
-    /**
-     * Current record.
-     */
     private ReadRecord record;
-
-    /**
-     * Last record returned.
-     */
     private ReadRecord lastRecord;
-
-    /**
-     * Flag indicating whether EOF was reached.
-     */
     private boolean isEOF;
 
-    /**
-     * Create a new instance of this class.
-     */
-    public DatabaseRecordIterator(ResultSet rs, NamespaceResolver resolver, NamePathResolver npResolver) {
-        this.rs = rs;
+    public DatabaseRecordIterator(final ConnectionHelper conHelper, final String selectRevisionsStmtSQL, final long startRevision, final NamespaceResolver resolver, final NamePathResolver npResolver) {
+        this.selectRecordsStmt = selectRevisionsStmtSQL;
+        this.startRevision = startRevision;
+        this.conHelper = conHelper;
         this.resolver = resolver;
         this.npResolver = npResolver;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     public boolean hasNext() {
         try {
-            if (!isEOF && record == null) {
+            if (record == null) {
                 fetchRecord();
             }
             return !isEOF;
@@ -113,16 +88,15 @@
         return lastRecord;
     }
 
-    /**
-     * {@inheritDoc}
-     */
     public void close() {
         if (lastRecord != null) {
             close(lastRecord);
             lastRecord = null;
         }
         try {
+            if (rs != null) {
-            rs.close();
+                rs.close();
+            }
         } catch (SQLException e) {
             String msg = "Error while closing result set: " + e.getMessage();
             log.warn(msg);
@@ -133,15 +107,32 @@
      * Fetch the next record.
      */
     private void fetchRecord() throws SQLException {
+        if (rs != null && rs.next()) {
+            readRecord();
+        } else {
+            try {
+                if (rs != null) {
+                    rs.close();
+                }
+                final long fromRevision = lastRecord != null ? lastRecord.getRevision() : startRevision;
+                rs = conHelper.exec(selectRecordsStmt, new Object[]{ fromRevision }, false, BATCH_SIZE);
-        if (rs.next()) {
+                if (rs.next()) {
+                    readRecord();
+                } else {
+                    isEOF = true;
+                }
+            } catch (SQLException e) {
+                log.error("Failed to retrieve journal records", e);
+            }
+        }
+    }
+
+    private void readRecord() throws SQLException {
-            long revision = rs.getLong(1);
-            String journalId = rs.getString(2);
-            String producerId = rs.getString(3);
-            DataInputStream dataIn = new DataInputStream(rs.getBinaryStream(4));
-            record = new ReadRecord(journalId, producerId, revision, dataIn, 0, resolver, npResolver);
+        long revision = rs.getLong(1);
+        String journalId = rs.getString(2);
+        String producerId = rs.getString(3);
+        DataInputStream dataIn = new DataInputStream(rs.getBinaryStream(4));
+        record = new ReadRecord(journalId, producerId, revision, dataIn, 0, resolver, npResolver);
-        } else {
-            isEOF = true;
-        }
     }
 
     /**
Index: jackrabbit-api/src/main/java/org/apache/jackrabbit/api/stats/RepositoryStatistics.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-api/src/main/java/org/apache/jackrabbit/api/stats/RepositoryStatistics.java	(revision 1748387)
+++ jackrabbit-api/src/main/java/org/apache/jackrabbit/api/stats/RepositoryStatistics.java	(revision )
@@ -34,7 +34,7 @@
         BUNDLE_WRITE_DURATION(true),
         BUNDLE_WRITE_AVERAGE(false),
         BUNDLE_CACHE_ACCESS_COUNTER(true),
-        BUNDLE_CACHE_SIZE_COUNTER(true),
+        BUNDLE_CACHE_SIZE_COUNTER(false),
         BUNDLE_CACHE_MISS_COUNTER(true),
         BUNDLE_CACHE_MISS_DURATION(true),
         BUNDLE_CACHE_MISS_AVERAGE(false),
Index: jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/TestAll.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/TestAll.java	(revision 1748387)
+++ jackrabbit-jcr-tests/src/main/java/org/apache/jackrabbit/test/api/TestAll.java	(revision )
@@ -155,7 +155,7 @@
         suite.addTestSuite(WorkspaceTest.class);
 
         //// shareable nodes
-        suite.addTestSuite(ShareableNodeTest.class);
+//        suite.addTestSuite(ShareableNodeTest.class);
 
         //// repository factory
         suite.addTestSuite(RepositoryFactoryTest.class);
\ No newline at end of file
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/NodeImpl.java	(revision )
@@ -256,7 +256,7 @@
      *                             relative path
      */
     private NodeId getNodeId(Path p) throws RepositoryException {
-        if (p.getLength() == 1 && p.denotesName()) {
+        if (p.getLength() == 1 && p.denotesName() && !p.denotesIdentifier()) {
             // check if node entry exists
             ChildNodeEntry cne = data.getNodeState().getChildNodeEntry(
                     p.getName(), p.getNormalizedIndex());
Index: jackrabbit-parent/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-parent/pom.xml	(revision 1748387)
+++ jackrabbit-parent/pom.xml	(revision )
@@ -34,7 +34,7 @@
   <groupId>org.apache.jackrabbit</groupId>
   <artifactId>jackrabbit-parent</artifactId>
   <name>Jackrabbit Parent POM</name>
-  <version>2.10.1</version>
+  <version>2.10.1-h11</version>
   <packaging>pom</packaging>
 
   <issueManagement>
@@ -56,8 +56,16 @@
     <slf4j.api.version>1.6.6</slf4j.api.version>
     <slf4j.version>1.7.4</slf4j.version> <!-- sync with logback version -->
     <logback.version>1.0.12</logback.version>
+    <jackrabbit.version>2.10.1</jackrabbit.version>
   </properties>
 
+   <distributionManagement>
+     <repository>
+       <id>hippo-maven2</id>
+       <url>https://maven.onehippo.com/content/repositories/releases/</url>
+     </repository>
+   </distributionManagement>
+
   <url>http://jackrabbit.apache.org/</url>
   <inceptionYear>2004</inceptionYear>
   <description>
@@ -191,6 +199,18 @@
           </excludes>
         </configuration>
       </plugin>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-source-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>attach-sources</id>
+            <goals>
+              <goal>jar</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
     <pluginManagement>
       <!-- JCRSITE-9: Fix versions of key Maven plugins      -->
@@ -324,7 +344,7 @@
       <dependency>
         <groupId>commons-collections</groupId>
         <artifactId>commons-collections</artifactId>
-        <version>3.2.1</version>
+        <version>3.2.2</version>
       </dependency>
       <dependency>
         <groupId>commons-io</groupId>
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/lock/LockManagerImpl.java	(revision )
@@ -24,8 +24,6 @@
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
 
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.PropertyType;
@@ -99,11 +97,6 @@
     private XAReentrantLock lockPropertiesLock = new XAReentrantLock();
 
     /**
-     * The periodically invoked lock timeout handler.
-     */
-    private final ScheduledFuture<?> timeoutHandler;
-
-    /**
      * System session
      */
     private final SessionImpl sysSession;
@@ -150,54 +143,32 @@
             throw new RepositoryException("I/O error while reading locks from '"
                     + locksFile.getPath() + "'", e);
         }
-
-        timeoutHandler = executor.scheduleWithFixedDelay(
-                new TimeoutHandler(), 1, 1, TimeUnit.SECONDS);
     }
 
-    /**
-     * Close this lock manager. Writes back all changes.
-     */
-    public void close() {
-        timeoutHandler.cancel(false);
-        save();
-    }
-
-    /**
-     * Periodically (at one second delay) invoked timeout handler. Traverses
-     * all locks and unlocks those that have expired.
-     *
-     * @see <a href="https://issues.apache.org/jira/browse/JCR-1590">JCR-1590</a>:
-     *      JSR 283: Locking
-     */
-    private class TimeoutHandler implements Runnable {
-        private final TimeoutHandlerVisitor visitor = new TimeoutHandlerVisitor();
-
-        public void run() {
-            lockMap.traverse(visitor, false);
-        }
-    }
-
-    private class TimeoutHandlerVisitor implements
-            PathMap.ElementVisitor<LockInfo> {
-        public void elementVisited(PathMap.Element<LockInfo> element) {
-            LockInfo info = element.get();
-            if (info != null && info.isLive() && info.isExpired()) {
-                NodeId id = info.getId();
+    private boolean unlockIfExpired(final LockInfo info) {
+        if (info.isLive() && info.isExpired()) {
+            final NodeId id = info.getId();
-                SessionImpl holder = info.getLockHolder();
-                if (holder == null) {
-                    info.setLockHolder(sysSession);
-                    holder = sysSession;
-                }
-                try {
+            SessionImpl holder = info.getLockHolder();
+            if (holder == null) {
+                info.setLockHolder(sysSession);
+                holder = sysSession;
+            }
+            try {
-                    // FIXME: This session access is not thread-safe!
-                    log.debug("Try to unlock expired lock. NodeId {}", id);
-                    unlock(holder.getNodeById(id));
+                log.debug("Try to unlock expired lock. NodeId {}", id);
+                unlock(holder.getNodeById(id));
+                return true;
-                } catch (RepositoryException e) {
-                    log.warn("Unable to expire the lock. NodeId " + id, e);
-                }
-            }
+            } catch (RepositoryException e) {
+                log.warn("Unable to expire the lock. NodeId " + id, e);
+            }
+        }
+        return false;
-        }
+    }
+
+    /**
+     * Close this lock manager. Writes back all changes.
+     */
+    public void close() {
+        save();
     }
 
     /**
@@ -205,10 +176,8 @@
      */
     private void load() throws FileSystemException {
         BufferedReader reader = null;
-
         try {
-            reader = new BufferedReader(
-                    new InputStreamReader(locksFile.getInputStream()));
+            reader = new BufferedReader(new InputStreamReader(locksFile.getInputStream()));
             while (true) {
                 String s = reader.readLine();
                 if (s == null || s.equals("")) {
@@ -356,7 +325,7 @@
             PathMap.Element<LockInfo> element = lockMap.map(path, false);
 
             LockInfo other = element.get();
-            if (other != null) {
+            if (other != null && !unlockIfExpired(other)) {
                 if (element.hasPath(path)) {
                     other.throwLockException(
                             "Node already locked: " + node, session);
@@ -365,10 +334,19 @@
                             "Parent node has a deep lock: " + node, session);
                 }
             }
-            if (info.isDeep() && element.hasPath(path)
-                    && element.getChildrenCount() > 0) {
+            if (info.isDeep() && element.hasPath(path) && element.getChildrenCount() > 0) {
+                boolean childLocked = false;
+                for (PathMap.Element<LockInfo> child : element.getChildren()) {
+                    final LockInfo childLockInfo = child.get();
+                    if (childLockInfo != null && !unlockIfExpired(childLockInfo)) {
+                        childLocked = true;
+                        break;
+                    }
+                }
+                if (childLocked) {
-                info.throwLockException("Some child node is locked", session);
-            }
+                    info.throwLockException("Some child node is locked", session);
+                }
+            }
 
             // create lock token
             info.setLockHolder(session);
@@ -455,7 +433,7 @@
         lockMap.traverse(new PathMap.ElementVisitor<LockInfo>() {
             public void elementVisited(PathMap.Element<LockInfo> element) {
                 LockInfo info = element.get();
-                if (info.isLive() && info.isLockHolder(session)) {
+                if (info.isLive() && !info.isExpired() && info.isLockHolder(session)) {
                     infos.add(info);
                 }
             }
@@ -506,7 +484,7 @@
         try {
             PathMap.Element<LockInfo> element = lockMap.map(path, false);
             LockInfo info = element.get();
-            if (info != null) {
+            if (info != null && !unlockIfExpired(info)) {
                 if (element.hasPath(path) || info.isDeep()) {
                     return info;
                 }
@@ -549,7 +527,7 @@
 
             PathMap.Element<LockInfo> element = lockMap.map(path, false);
             LockInfo info = element.get();
-            if (info != null && (element.hasPath(path) || info.isDeep())) {
+            if (info != null && !unlockIfExpired(info) && (element.hasPath(path) || info.isDeep())) {
                 NodeImpl lockHolder = (NodeImpl)
                     session.getItemManager().getItem(info.getId());
                 return new LockImpl(info, lockHolder);
@@ -610,7 +588,8 @@
             if (element == null) {
                 return false;
             }
-            return element.get() != null;
+            final LockInfo lockInfo = element.get();
+            return lockInfo != null && !unlockIfExpired(lockInfo);
         } catch (ItemNotFoundException e) {
             return false;
         } finally {
@@ -633,6 +612,9 @@
             if (info == null) {
                 return false;
             }
+            if (unlockIfExpired(info)) {
+                return false;
+            }
             if (element.hasPath(path)) {
                 return true;
             } else {
@@ -685,12 +667,10 @@
      * @param info info to check
      * @param session session
      * @throws LockException if write access to the specified path is not allowed
-     * @throws RepositoryException if some other error occurs
      */
     protected void checkLock(LockInfo info, Session session)
-            throws LockException, RepositoryException {
-
-        if (!info.isLockHolder(session)) {
+            throws LockException {
+        if (!unlockIfExpired(info) && !info.isLockHolder(session)) {
             throw new LockException("Node locked.");
         }
     }
@@ -754,7 +734,7 @@
             PathMap.Element<LockInfo> element = lockMap.map(path, true);
             if (element != null) {
                 LockInfo info = element.get();
-                if (info != null && !info.isLockHolder(session)) {
+                if (info != null && !unlockIfExpired(info) && !info.isLockHolder(session)) {
                     if (info.getLockHolder() == null) {
                         info.setLockHolder(session);
                         if (info instanceof InternalLockInfo) {
@@ -794,7 +774,7 @@
                 lockMap.map(node.getPrimaryPath(), true);
             if (element != null) {
                 LockInfo info = element.get();
-                if (info != null) {
+                if (info != null && !unlockIfExpired(info)) {
                     if (info.isLockHolder(session)) {
                         info.setLockHolder(null);
                     } else if (info.getLockHolder() != null) {
@@ -1101,17 +1081,21 @@
      */
     public void onEvent(EventIterator events) {
         Iterator<HierarchyEvent> iter = consolidateEvents(events);
+        boolean needsSave = false;
         while (iter.hasNext()) {
             HierarchyEvent event = iter.next();
             if (event.type == Event.NODE_ADDED) {
-                nodeAdded(event.path);
+                needsSave |= nodeAdded(event.path);
             } else if (event.type == Event.NODE_REMOVED) {
-                nodeRemoved(event.path);
+                needsSave |= nodeRemoved(event.path);
             } else if (event.type == (Event.NODE_ADDED | Event.NODE_REMOVED)) {
-                nodeMoved(event.getOldPath(), event.getNewPath());
+                needsSave |= nodeMoved(event.getOldPath(), event.getNewPath());
             }
         }
+        if (needsSave) {
+            save();
-    }
+        }
+    }
 
     /**
      * Consolidate an event iterator obtained from observation, merging
@@ -1152,7 +1136,7 @@
      * Refresh a non-empty path element whose children might have changed
      * its position.
      */
-    private void refresh(PathMap.Element<LockInfo> element) {
+    private boolean refresh(PathMap.Element<LockInfo> element) {
         final ArrayList<LockInfo> infos = new ArrayList<LockInfo>();
         boolean needsSave = false;
 
@@ -1186,11 +1170,8 @@
             }
         }
 
-        // save if required
-        if (needsSave) {
-            save();
+        return needsSave;
-        }
+    }
-    }
 
     /**
      * Invoked when some node has been added. If the parent of that node
@@ -1199,43 +1180,44 @@
      *
      * @param path path of added node
      */
-    private void nodeAdded(Path path) {
+    private boolean nodeAdded(Path path) {
         acquire();
 
         try {
             PathMap.Element<LockInfo> parent =
                 lockMap.map(path.getAncestor(1), true);
             if (parent != null) {
-                refresh(parent);
+                return refresh(parent);
             }
         } catch (RepositoryException e) {
             log.warn("Unable to determine path of added node's parent.", e);
         } finally {
             release();
         }
+        return false;
     }
 
     /**
      * Invoked when some node has been moved. Relink the child inside our
      * map to the new parent.
-     *
-     * @param oldPath old path
+     *  @param oldPath old path
      * @param newPath new path
      */
-    private void nodeMoved(Path oldPath, Path newPath) {
+    private boolean nodeMoved(Path oldPath, Path newPath) {
         acquire();
 
         try {
             PathMap.Element<LockInfo> parent =
                 lockMap.map(oldPath.getAncestor(1), true);
             if (parent != null) {
-                refresh(parent);
+                return refresh(parent);
             }
         } catch (RepositoryException e) {
             log.warn("Unable to determine path of moved node's parent.", e);
         } finally {
             release();
         }
+        return false;
     }
 
     /**
@@ -1244,20 +1226,21 @@
      *
      * @param path path of removed node
      */
-    private void nodeRemoved(Path path) {
+    private boolean nodeRemoved(Path path) {
         acquire();
 
         try {
             PathMap.Element<LockInfo> parent =
                 lockMap.map(path.getAncestor(1), true);
             if (parent != null) {
-                refresh(parent);
+                return refresh(parent);
             }
         } catch (RepositoryException e) {
             log.warn("Unable to determine path of removed node's parent.", e);
         } finally {
             release();
         }
+        return false;
     }
 
     /**
Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java	(revision 1748387)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/PathFactoryImpl.java	(revision )
@@ -124,6 +124,8 @@
     public Path create(Path.Element element) {
         if (element.denotesCurrent()) {
             return CurrentPath.CURRENT_PATH;
+        } else if (element.denotesIdentifier() && element.denotesName()) {
+            return new CargoNamePath(null, element.getName(), element.getIdentifier());
         } else if (element.denotesIdentifier()) {
             return new IdentifierPath(element.getIdentifier());
         } else if (element.denotesName()) {
@@ -146,6 +148,8 @@
         for (Path.Element element : elements) {
             if (element.denotesCurrent()) {
                 path = new CurrentPath(path);
+            } else if (element.denotesName() && element.denotesIdentifier()) {
+                path = new CargoNamePath(path, element.getName(), element.getIdentifier());
             } else if (element.denotesIdentifier()) {
                 if (path != null) {
                     throw new IllegalArgumentException();
@@ -267,6 +271,10 @@
         int pos1 = elementString.indexOf(']');
         if (pos1 == -1) {
             throw new IllegalArgumentException("invalid PathElement literal: " + elementString + " (missing ']')");
+        }
+        if(elementString.charAt(pos+1)=='[') {
+             String argument = elementString.substring(pos + 2, pos1);
+             return new CargoNamePath(null, name, argument);
         }
         try {
             int index = Integer.valueOf(elementString.substring(pos + 1, pos1));
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/JackrabbitIndexSearcher.java	(revision )
@@ -24,6 +24,7 @@
 import org.apache.jackrabbit.spi.Name;
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Filter;
 import org.apache.lucene.search.IndexSearcher;
 import org.apache.lucene.search.Query;
 import org.apache.lucene.search.Sort;
@@ -50,6 +51,7 @@
      * The item state manager of the workspace.
      */
     private final ItemStateManager ism;
+    private Filter filter;
 
     /**
      * Creates a new jackrabbit index searcher.
@@ -61,10 +63,18 @@
     public JackrabbitIndexSearcher(SessionImpl s,
                                    IndexReader r,
                                    ItemStateManager ism) {
+        this(s,r, ism, null);
+    }
+
+    public JackrabbitIndexSearcher(SessionImpl s,
+                                   IndexReader r,
+                                   ItemStateManager ism,
+                                   Filter f) {
         super(r);
         this.session = s;
         this.reader = r;
         this.ism = ism;
+        this.filter = f;
     }
 
     /**
@@ -151,5 +161,12 @@
      */
     public ItemStateManager getItemStateManager() {
         return ism;
+    }
+
+    /**
+     * @return the {@link Filter} used for this searcher or {@code null} if not present
+     */
+    public Filter getFilter() {
+        return filter;
     }
 }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/CachingHierarchyManager.java	(revision )
@@ -574,6 +574,8 @@
             if (element.get() != null) {
                 if (!id.equals(((LRUEntry) element.get()).getId())) {
                     log.debug("overwriting PathMap.Element");
+                    evict(element, true);
+                    element = pathCache.put(path);
                 }
             }
             LRUEntry entry = (LRUEntry) idCache.get(id);
@@ -752,17 +754,7 @@
             if (entry != null && !entry.getId().equals(id)) {
                 return;
             }
-            // if item is shareable, remove this path only, otherwise
-            // every path this item has been mapped to
-            NodeState child = null;
-            if (hasItemState(id)) {
-                child = (NodeState) getItemState(id);
-            }
-            if (child == null || !child.isShareable()) {
-                evictAll(id, true);
+            evictAll(id, true);
-            } else {
-                evict(element, true);
-            }
         } else {
             // element itself is not cached, but removal might cause SNS
             // index shifting
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/ConsistencyCheck.java	(revision )
@@ -21,6 +21,9 @@
 import org.apache.jackrabbit.core.RepositoryImpl;
 import org.apache.jackrabbit.core.cluster.ClusterException;
 import org.apache.jackrabbit.core.cluster.ClusterNode;
+import org.apache.jackrabbit.core.nodetype.EffectiveNodeType;
+import org.apache.jackrabbit.core.nodetype.NodeTypeConflictException;
+import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
 import org.apache.jackrabbit.core.persistence.IterablePersistenceManager;
 import org.apache.jackrabbit.core.persistence.PersistenceManager;
 import org.apache.jackrabbit.core.state.ItemState;
@@ -30,6 +33,7 @@
 import org.apache.jackrabbit.core.state.ItemStateException;
 import org.apache.jackrabbit.core.state.ChildNodeEntry;
 import org.apache.jackrabbit.core.id.NodeId;
+import org.apache.jackrabbit.spi.Name;
 import org.apache.jackrabbit.spi.Path;
 import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException;
 import org.apache.jackrabbit.spi.commons.name.NameConstants;
@@ -40,8 +44,10 @@
 
 import javax.jcr.ItemNotFoundException;
 import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NoSuchNodeTypeException;
 
 import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -108,6 +114,8 @@
      */
     private final Set<Path> ignoredPaths = new HashSet<Path>();
 
+    private Name skipIndexTypeName;
+
     /**
      * List of all errors.
      */
@@ -151,7 +159,18 @@
         if (pm instanceof IterablePersistenceManager) {
             this.pm = (IterablePersistenceManager) pm;
         }
+
+        try {
+            final IndexingConfiguration indexingConfig = handler.getIndexingConfig();
+            skipIndexTypeName = (Name) indexingConfig.getClass().getMethod("getSkipIndexName").invoke(indexingConfig);
+        } catch (IllegalAccessException e) {
+            log.error("Failed to determine skip index type name", e);
+        } catch (InvocationTargetException e) {
+            log.error("Failed to determine skip index type name", e);
+        } catch (NoSuchMethodException e) {
+            log.error("Failed to determine skip index type name", e);
-    }
+        }
+    }
 
     /**
      * Runs the consistency check on <code>index</code>.
@@ -417,7 +436,49 @@
                     return true;
                 }
             }
+            if (skipIndexTypeName != null) {
+                NodeState nodeState = (NodeState) handler.getContext().getItemStateManager().getItemState(id);
+                while (nodeState != null) {
+                    if (isNodeType(nodeState, skipIndexTypeName)) {
+                        return true;
+                    }
+                    final NodeId parentId = nodeState.getParentId();
+                    if (parentId == null) {
+                        nodeState = null;
+                    } else {
+                        nodeState = (NodeState) handler.getContext().getItemStateManager().getItemState(parentId);
+                    }
+                }
+            }
         } catch (RepositoryException ignored) {
+        } catch (ItemStateException ignored) {
+        }
+        return false;
+    }
+
+    private boolean isNodeType(final NodeState nodeState, final Name nodeType) {
+        if (nodeState == null) {
+            return false;
+        }
+        // first do trivial checks without using type hierarchy
+        Name primary = nodeState.getNodeTypeName();
+        if (nodeType.equals(primary)) {
+            return true;
+        }
+        Set<Name> mixins = nodeState.getMixinTypeNames();
+        if (mixins.contains(nodeType)) {
+            return true;
+        }
+
+        // check effective node type
+        try {
+            NodeTypeRegistry registry = handler.getContext().getNodeTypeRegistry();
+            EffectiveNodeType type = registry.getEffectiveNodeType(primary, mixins);
+            return type.includesNodeType(nodeType);
+        } catch (NodeTypeConflictException e) {
+            log.warn("Failed to build effective node type for node {}", nodeState.getId());
+        } catch (NoSuchNodeTypeException e) {
+            log.warn("Failed to build effective node type for node {}", nodeState.getId());
         }
         return false;
     }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/XASessionImpl.java	(revision )
@@ -19,7 +19,12 @@
 import org.apache.jackrabbit.api.XASession;
 import org.apache.jackrabbit.core.config.WorkspaceConfig;
 import org.apache.jackrabbit.core.lock.XALockManager;
+import org.apache.jackrabbit.core.observation.EventStateCollectionFactory;
 import org.apache.jackrabbit.core.security.authentication.AuthContext;
+import org.apache.jackrabbit.core.session.SessionContext;
+import org.apache.jackrabbit.core.state.ItemStateCacheFactory;
+import org.apache.jackrabbit.core.state.LocalItemStateManager;
+import org.apache.jackrabbit.core.state.SharedItemStateManager;
 import org.apache.jackrabbit.core.state.XAItemStateManager;
 import org.apache.jackrabbit.core.version.InternalVersionManager;
 import org.apache.jackrabbit.core.version.InternalXAVersionManager;
@@ -410,5 +415,10 @@
         } else {
             return s1.equals(s2);
         }
+    }
+
+    @Override
+    public LocalItemStateManager createItemStateManager(RepositoryContext repositoryContext, WorkspaceImpl workspace, SharedItemStateManager sharedStateMgr, EventStateCollectionFactory factory, String attributeName, ItemStateCacheFactory cacheFactory) {
+            return XAItemStateManager.createInstance(sharedStateMgr, factory, attributeName, cacheFactory);
     }
 }
Index: jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java	(revision 1748387)
+++ jackrabbit-spi-commons/src/main/java/org/apache/jackrabbit/spi/commons/name/AbstractPath.java	(revision )
@@ -133,7 +133,9 @@
     }
 
     public final Path resolve(Element element) {
-        if (element.denotesName()) {
+        if (element.denotesName() && element.denotesIdentifier()) {
+            return new CargoNamePath(this, element.getName(), element.getIdentifier());
+        } else if (element.denotesName()) {
             return new NamePath(this, element.getName(), element.getIndex());
         } else if (element.denotesParent()) {
             if (isAbsolute() && getDepth() == 0) {
@@ -164,6 +166,8 @@
             return new CurrentPath(this);
         } else if (relative.denotesParent()) {
             return new ParentPath(this);
+        } else if (relative.denotesIdentifier() && relative.denotesName()) {
+            return new CargoNamePath(this, relative.getName(), relative.getIdentifier());
         } else if (relative.denotesName()) {
             return new NamePath(this, relative.getName(), relative.getIndex());
         } else {
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/journal/DatabaseJournal.java	(revision )
@@ -415,25 +415,15 @@
      * {@inheritDoc}
      */
     public RecordIterator getRecords(long startRevision) throws JournalException {
-        try {
-            return new DatabaseRecordIterator(conHelper.exec(selectRevisionsStmtSQL, new Object[]{new Long(
-                    startRevision)}, false, 0), getResolver(), getNamePathResolver());
-        } catch (SQLException e) {
-            throw new JournalException("Unable to return record iterator.", e);
+        return new DatabaseRecordIterator(conHelper, selectRevisionsStmtSQL, startRevision, getResolver(), getNamePathResolver());
-        }
+    }
-    }
 
     /**
      * {@inheritDoc}
      */
     public RecordIterator getRecords() throws JournalException {
-        try {
-            return new DatabaseRecordIterator(conHelper.exec(selectRevisionsStmtSQL, new Object[]{new Long(
-                    Long.MIN_VALUE)}, false, 0), getResolver(), getNamePathResolver());
-        } catch (SQLException e) {
-            throw new JournalException("Unable to return record iterator.", e);
+        return new DatabaseRecordIterator(conHelper, selectRevisionsStmtSQL, Long.MIN_VALUE, getResolver(), getNamePathResolver());
-        }
+    }
-    }
 
     /**
      * Synchronize contents from journal. May be overridden by subclasses.
@@ -800,6 +790,13 @@
 
                 // Insert the given revision in the database
                 if (!exists) {
+                    if (revision == 0l) {
+                        // cluster node is new, start revision is current journal head
+                        rs = conHelper.exec(selectGlobalStmtSQL, null, false, 0);
+                        if (rs.next()) {
+                            revision = rs.getLong(1);
+                        }
+                    }
                     conHelper.exec(insertLocalRevisionStmtSQL, revision, getId());
                 }
 
Index: jackrabbit-jcr-tests/pom.xml
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-jcr-tests/pom.xml	(revision 1748387)
+++ jackrabbit-jcr-tests/pom.xml	(revision )
@@ -26,7 +26,7 @@
   <parent>
     <groupId>org.apache.jackrabbit</groupId>
     <artifactId>jackrabbit-parent</artifactId>
-    <version>2.10.1</version>
+    <version>2.10.1-h11</version>
     <relativePath>../jackrabbit-parent/pom.xml</relativePath>
   </parent>
   <artifactId>jackrabbit-jcr-tests</artifactId>
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/NodePropBundle.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/NodePropBundle.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/util/NodePropBundle.java	(revision )
@@ -306,7 +306,6 @@
      */
     public void addProperty(PropertyEntry entry) {
         assert !NameConstants.JCR_PRIMARYTYPE.equals(entry.getName());
-        assert !NameConstants.JCR_MIXINTYPES.equals(entry.getName());
         assert !NameConstants.JCR_UUID.equals(entry.getName());
         properties.put(entry.getName(), entry);
     }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/WorkspaceImpl.java	(revision )
@@ -895,15 +895,7 @@
         SharedItemStateManager sism = getSharedItemStateManager();
         ItemStateCacheFactory iscf =
             context.getRepositoryContext().getItemStateCacheFactory();
-
-        // FIXME We should be able to avoid the instanceof operator here
-        if (context.getSessionImpl() instanceof XASessionImpl) {
-            return XAItemStateManager.createInstance(
-                    sism, this, null, iscf);
-        } else {
-            return LocalItemStateManager.createInstance(
-                    sism, this, iscf);
-        }
+        return context.getSessionImpl().createItemStateManager(this.context.getRepositoryContext(), this, sism, this, null, iscf);
 
     }
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java	(revision 1748387)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/persistence/pool/BundleDbPersistenceManager.java	(revision )
@@ -152,6 +152,7 @@
     protected String nodeReferenceUpdateSQL;
     protected String nodeReferenceSelectSQL;
     protected String nodeReferenceDeleteSQL;
+    protected String nodeReferenceSelectAllSQL;
 
     /** file system where BLOB data is stored */
     protected CloseableBLOBStore blobStore;
@@ -1016,6 +1017,41 @@
         }
     }
 
+    public synchronized List<NodeReferences> getAllNodeReference() throws ItemStateException {
+        if (!initialized) {
+            throw new IllegalStateException("not initialized");
+        }
+        List<NodeReferences> result = new ArrayList<NodeReferences>();
+        ResultSet rs = null;
+        InputStream in = null;
+        try {
+            rs = conHelper.exec(nodeReferenceSelectAllSQL, new Object[] {}, false, 0);
+            while (rs.next()) {
+                NodeId nodeId;
+                if (getStorageModel() == SM_BINARY_KEYS) {
+                    nodeId = new NodeId(rs.getBytes(1));
+                } else {
+                    long high = rs.getLong(1);
+                    long low = rs.getLong(2);
+                    nodeId = new NodeId(high, low);
+                }
+                NodeReferences refs = new NodeReferences(nodeId);
+                in = rs.getBinaryStream(getStorageModel() == SM_BINARY_KEYS ? 2 : 3);
+                Serializer.deserialize(refs, in);
+                result.add(refs);
+                IOUtils.closeQuietly(in);
+            }
+        } catch (Exception e) {
+            String msg = "failed to read references";
+            log.error(msg, e);
+            throw new ItemStateException(msg, e);
+        } finally {
+            IOUtils.closeQuietly(in);
+            DbUtility.close(rs);
+        }
+        return result;
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -1108,6 +1144,7 @@
      */
     protected void buildSQLStatements() {
         // prepare statements
+        nodeReferenceSelectAllSQL = "select * from " + schemaObjectPrefix + "REFS";
         if (getStorageModel() == SM_BINARY_KEYS) {
             bundleInsertSQL = "insert into " + schemaObjectPrefix + "BUNDLE (BUNDLE_DATA, NODE_ID) values (?, ?)";
             bundleUpdateSQL = "update " + schemaObjectPrefix + "BUNDLE set BUNDLE_DATA = ? where NODE_ID = ?";
