Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java	(revision 597671)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/CachingMultiReader.java	(working copy)
@@ -42,6 +42,11 @@
      * Map of OffsetReaders, identified by caching reader they are based on.
      */
     private final Map readersByBase = new IdentityHashMap();
+    
+    /**
+     * Map of CachingIndexReaders, identified by theirselve.
+     */
+    private final Map cachingReadersByBase = new IdentityHashMap();
 
     /**
      * Document number cache if available. May be <code>null</code>.
@@ -79,6 +84,7 @@
             maxDoc += subReaders[i].maxDoc();
             OffsetReader offsetReader = new OffsetReader(subReaders[i], starts[i]);
             readersByBase.put(subReaders[i].getBase().getBase(), offsetReader);
+            cachingReadersByBase.put(subReaders[i].getBase().getBase(), subReaders[i].getBase().getBase());
         }
         starts[subReaders.length] = maxDoc;
     }
@@ -125,7 +131,7 @@
                 // 2) doc must not be deleted
                 OffsetReader offsetReader = (OffsetReader) readersByBase.get(e.reader);
                 if (offsetReader != null && !offsetReader.reader.isDeleted(e.doc)) {
-                    return new SingleTermDocs(e.doc + offsetReader.offset);
+                    return new SingleTermDocs(e.doc, offsetReader.offset, offsetReader.reader.getBase().getBase());
                 }
             }
 
@@ -135,7 +141,7 @@
                 TermDocs docs = subReaders[i].termDocs(term);
                 try {
                     if (docs.next()) {
-                        return new SingleTermDocs(docs.doc() + starts[i]);
+                        return new SingleTermDocs(docs.doc(), starts[i], subReaders[i].getBase().getBase());
                     }
                 } finally {
                     docs.close();
@@ -165,6 +171,23 @@
         }
     }
 
+    /** 
+     * Returns the documentNumber in the MultiIndex
+     * 
+     * @param indexReader , segmentDocNumber
+     * @return int docNumber in the multiReader
+     */
+    
+    public int computeDocNumber(IndexReader reader, int segmentDocNumber){
+        // TODO not sure if this method needs to be synchronized because multiple threads might access it
+        // since this method is called from DocId which already checked if this MultiReader has
+        // an instance of the reader, offsetReader cannot be null.
+        OffsetReader offsetReader = (OffsetReader) readersByBase.get(reader);
+        return offsetReader.offset + segmentDocNumber;
+    }
+    
+    
+    
     //-------------------------< MultiIndexReader >-----------------------------
 
     /**
@@ -176,6 +199,20 @@
         return readers;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    public boolean hasIndexReaderInstance(IndexReader indexReader) {
+        // TODO I think no synchronized method needed because only the constructor changes the set
+        if(indexReader == null ) {
+            return false;
+        }
+        if(this.cachingReadersByBase.get(indexReader) == indexReader) {
+            return true;
+        }
+        return false;
+    }
+    
     //------------------------< internal >--------------------------------------
 
     /**
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java	(revision 597671)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/DocId.java	(working copy)
@@ -185,16 +185,16 @@
         private final long msb;
 
         /**
-         * The index reader that was used to calculate the document number.
+         * The segment index reader that was used to calculate the document number.
          * If <code>null</code> then the document number has not yet been
-         * calculated.
+         * calculated. 
          */
-        private Reference reader;
+        private Reference segmentIndexReader;
 
         /**
-         * The previously calculated document number.
+         * The calculated segment document number.
          */
-        private int docNumber;
+        private int segmentDocNumber;
 
         /**
          * Creates a <code>DocId</code> based on a Node uuid.
@@ -213,25 +213,43 @@
          * @inheritDoc
          */
         int getDocumentNumber(IndexReader reader) throws IOException {
+
+            /*
+             *  If segmentIndexReader instance is not null AND the MultiIndexReader has
+             *  the segment indexReader instance we don't have to search for the document in the 
+             *  index again. Because the MultiIndexReader might have changed, we compute the current
+             *  document number of this segmentDocNumber in the MultiIndexReader.
+             *  
+             */
             synchronized (this) {
-                if (this.reader != null && reader.equals(this.reader.get())) {
-                    return docNumber;
+                if(this.segmentIndexReader != null && reader instanceof MultiIndexReader) {
+                    if( ((MultiIndexReader)reader).hasIndexReaderInstance((IndexReader)segmentIndexReader.get())) {
+                        /*
+                         * segment index that the document was found in is unchanged. get docNumber with respect to
+                         * MultiIndexReader
+                         */  
+                        return ((CachingMultiReader)reader).computeDocNumber((IndexReader)segmentIndexReader.get(), this.segmentDocNumber);
+                    }
                 }
             }
+            
             Term id = new Term(FieldNames.UUID, new UUID(msb, lsb).toString());
-            TermDocs docs = reader.termDocs(id);
+            SingleTermDocs docs = (SingleTermDocs)reader.termDocs(id);
             int doc = -1;
+            int segmentDoc = -1; 
             try {
                 if (docs.next()) {
                     doc = docs.doc();
+                    segmentDoc = docs.segmentDoc();
                 }
-            } finally {
+                synchronized (this) {
+                    this.segmentDocNumber = segmentDoc;
+                    this.segmentIndexReader = new WeakReference(docs.reader());
+                }
+            }
+            finally {
                 docs.close();
             }
-            synchronized (this) {
-                docNumber = doc;
-                this.reader = new WeakReference(reader);
-            }
             return doc;
         }
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java	(revision 597671)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/MultiIndexReader.java	(working copy)
@@ -29,4 +29,10 @@
      *         <code>MultiIndexReader</code>.
      */
     public IndexReader[] getIndexReaders();
+    
+    /**
+     * @return boolean whether this <code>MultiIndexReader</code> contains the indexReader
+     * segment we are looking for. 
+     */
+    public boolean hasIndexReaderInstance(IndexReader indexReader);
 }
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java	(revision 597671)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SearchIndex.java	(working copy)
@@ -1132,7 +1132,7 @@
             int i = readerIndex(n);
             DocId id = subReaders[i].getParentDocId(n - starts[i]);
             id = id.applyOffset(starts[i]);
-            return id.getDocumentNumber(this);
+            return id.getDocumentNumber(subReaders[i]);
         }
 
         //-------------------------< MultiIndexReader >-------------------------
@@ -1145,6 +1145,14 @@
             System.arraycopy(subReaders, 0, readers, 0, subReaders.length);
             return readers;
         }
+        
+        /**
+         * {@inheritDoc}
+         */
+        public boolean hasIndexReaderInstance(IndexReader indexReader) {
+            // For the combinedIndexReader it is not (yet) interesting, so just return false
+            return false;
+        }
 
         //---------------------------< internal >-------------------------------
 
Index: jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleTermDocs.java
===================================================================
--- jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleTermDocs.java	(revision 597671)
+++ jackrabbit-core/src/main/java/org/apache/jackrabbit/core/query/lucene/SingleTermDocs.java	(working copy)
@@ -33,6 +33,17 @@
     private final int doc;
 
     /**
+     * Single document number in the index segment it was found in;
+     */
+    private final int segmentDoc;
+    
+    /**
+     * CachingIndexReader reader 
+     */
+    
+    private CachingIndexReader reader;
+    
+    /**
      * Flag to return the document number once.
      */
     private boolean next = true;
@@ -45,7 +56,23 @@
      */
     SingleTermDocs(int doc) {
         this.doc = doc;
+        this.segmentDoc = doc;
     }
+    
+    /**
+     * Creates a <code>SingleTermDocs</code> that returns <code>doc</code> and segmentDoc as
+     * its single document.
+     *
+     * @param doc the document number in this reader
+     * @param offset the offset of this reader
+     * @param CachingIndexReader reader
+     */
+    SingleTermDocs(int doc, int offset,  CachingIndexReader reader) {
+        this.doc = doc + offset;
+        this.segmentDoc = doc; 
+        this.reader = reader;
+    }
+    
 
     /**
      * @throws UnsupportedOperationException always
@@ -67,7 +94,21 @@
     public int doc() {
         return doc;
     }
-
+    
+    /** 
+     * return the index segment doc number
+     */
+    public int segmentDoc() {
+        return segmentDoc;
+    }
+    
+    /** 
+     * return the reader
+     */
+    public CachingIndexReader reader() {
+        return reader;
+    }
+    
     /**
      * {@inheritDoc}
      */
