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-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;
