Index: lucene/CHANGES.txt
===================================================================
--- lucene/CHANGES.txt	(revision 1006167)
+++ lucene/CHANGES.txt	(working copy)
@@ -147,6 +147,9 @@
   you also override this method on upgrade.  (Robert Muir, Mike
   McCandless)
 
+* LUCENE-2691: IndexWriter.getReader() has been made package local and is now exposed via open and reopen methods on
+  IndexReader.  The semantics of the call is the same as it was prior to the API change.  (Grant Ingersoll, Mike McCandless)
+
 New features
 
 * LUCENE-2604: Added RegexpQuery support to QueryParser. Regular expressions
Index: lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java
===================================================================
--- lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/queryParser/TestQueryParser.java	(working copy)
@@ -1151,7 +1151,7 @@
     Document doc = new Document();
     doc.add(newField("f", "the wizard of ozzy", Field.Store.NO, Field.Index.ANALYZED));
     w.addDocument(doc);
-    IndexReader r = w.getReader();
+    IndexReader r = IndexReader.open(w);
     w.close();
     IndexSearcher s = new IndexSearcher(r);
     QueryParser qp = new QueryParser(TEST_VERSION_CURRENT, "f", a);
Index: lucene/src/test/org/apache/lucene/TestExternalCodecs.java
===================================================================
--- lucene/src/test/org/apache/lucene/TestExternalCodecs.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/TestExternalCodecs.java	(working copy)
@@ -634,7 +634,7 @@
     }
     w.deleteDocuments(new Term("id", "77"));
 
-    IndexReader r = w.getReader();
+    IndexReader r = IndexReader.open(w);
     IndexReader[] subs = r.getSequentialSubReaders();
     assertTrue(subs.length > 1);
     // test each segment
@@ -654,7 +654,7 @@
 
     w.deleteDocuments(new Term("id", "44"));
     w.optimize();
-    r = w.getReader();
+    r = IndexReader.open(w);
     assertEquals(NUM_DOCS-2, r.maxDoc());
     assertEquals(NUM_DOCS-2, r.numDocs());
     s = new IndexSearcher(r);
Index: lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/TestCachingWrapperFilter.java	(working copy)
@@ -159,7 +159,7 @@
     // flipping a coin) may give us a newly opened reader,
     // but we use .reopen on this reader below and expect to
     // (must) get an NRT reader:
-    IndexReader reader = writer.w.getReader();
+    IndexReader reader = IndexReader.open(writer.w);
     IndexSearcher searcher = new IndexSearcher(reader);
 
     // add a doc, refresh the reader, and check that its there
Index: lucene/src/test/org/apache/lucene/search/TestSort.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/TestSort.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/TestSort.java	(working copy)
@@ -1160,7 +1160,7 @@
     doc.add(newField("t", "1", Field.Store.NO, Field.Index.NOT_ANALYZED));
     w.addDocument(doc);
 
-    IndexReader r = w.getReader();
+    IndexReader r = IndexReader.open(w);
     w.close();
     IndexSearcher s = new IndexSearcher(r);
     TopDocs hits = s.search(new TermQuery(new Term("t", "1")), null, 10, new Sort(new SortField("f", SortField.STRING)));
Index: lucene/src/test/org/apache/lucene/search/payloads/PayloadHelper.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/payloads/PayloadHelper.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/payloads/PayloadHelper.java	(working copy)
@@ -126,7 +126,7 @@
       doc.add(new Field(NO_PAYLOAD_FIELD, English.intToEnglish(i), Field.Store.YES, Field.Index.ANALYZED));
       writer.addDocument(doc);
     }
-    reader = writer.getReader();
+    reader = IndexReader.open(writer);
     writer.close();
 
     IndexSearcher searcher = new IndexSearcher(SlowMultiReaderWrapper.wrap(reader));
Index: lucene/src/test/org/apache/lucene/search/function/TestValueSource.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/function/TestValueSource.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/function/TestValueSource.java	(working copy)
@@ -39,7 +39,7 @@
       w.commit();
     }
 
-    IndexReader r = w.getReader();
+    IndexReader r = IndexReader.open(w);
     w.close();
 
     assertTrue(r.getSequentialSubReaders().length > 1);
Index: lucene/src/test/org/apache/lucene/search/TestFieldCache.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/TestFieldCache.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/TestFieldCache.java	(working copy)
@@ -203,7 +203,7 @@
   public void testEmptyIndex() throws Exception {
     Directory dir = newDirectory();
     IndexWriter writer= new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer()).setMaxBufferedDocs(500));
-    IndexReader r = writer.getReader();
+    IndexReader r = IndexReader.open(writer);
     FieldCache.DocTerms terms = FieldCache.DEFAULT.getTerms(r, "foobar");
     FieldCache.DocTermsIndex termsIndex = FieldCache.DEFAULT.getTermsIndex(r, "foobar");
     r.close();
Index: lucene/src/test/org/apache/lucene/search/TestCachingSpanFilter.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/TestCachingSpanFilter.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/TestCachingSpanFilter.java	(working copy)
@@ -41,7 +41,7 @@
     // flipping a coin) may give us a newly opened reader,
     // but we use .reopen on this reader below and expect to
     // (must) get an NRT reader:
-    IndexReader reader = writer.w.getReader();
+    IndexReader reader = IndexReader.open(writer.w);
     IndexSearcher searcher = new IndexSearcher(reader);
 
     // add a doc, refresh the reader, and check that its there
Index: lucene/src/test/org/apache/lucene/search/TestElevationComparator.java
===================================================================
--- lucene/src/test/org/apache/lucene/search/TestElevationComparator.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/search/TestElevationComparator.java	(working copy)
@@ -45,7 +45,7 @@
     writer.addDocument(adoc(new String[] {"id", "y", "title", "boosted boosted", "str_s","y"}));
     writer.addDocument(adoc(new String[] {"id", "z", "title", "boosted boosted boosted","str_s", "z"}));
 
-    IndexReader r = writer.getReader();
+    IndexReader r = IndexReader.open(writer);
     writer.close();
 
     IndexSearcher searcher = new IndexSearcher(r);
Index: lucene/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java
===================================================================
--- lucene/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java	(revision 1006167)
+++ lucene/src/test/org/apache/lucene/store/TestFileSwitchDirectory.java	(working copy)
@@ -48,7 +48,7 @@
     ((LogMergePolicy) writer.getConfig().getMergePolicy()).setUseCompoundFile(false);
     ((LogMergePolicy) writer.getConfig().getMergePolicy()).setUseCompoundDocStore(false);
     TestIndexWriterReader.createIndexNoClose(true, "ram", writer);
-    IndexReader reader = writer.getReader();
+    IndexReader reader = IndexReader.open(writer);
     assertEquals(100, reader.maxDoc());
     writer.commit();
     // we should see only fdx,fdt files here
Index: lucene/src/java/org/apache/lucene/index/IndexReader.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/IndexReader.java	(revision 1006167)
+++ lucene/src/java/org/apache/lucene/index/IndexReader.java	(working copy)
@@ -233,6 +233,44 @@
     return open(directory, null, null, readOnly, DEFAULT_TERMS_INDEX_DIVISOR, null);
   }
 
+  /**
+   * Open an IndexWriter from an existing IndexWriter to take advantage of documents that are in the writer but not committed yet.  This is
+   * helpful for near real time applications.
+   *
+   *
+   * @param writer The IndexWriter to open from
+   * @return The new IndexReader
+   * @throws CorruptIndexException
+   * @throws IOException if there is a low-level IO error
+   *
+   * @see #reopen(IndexWriter)
+   *
+   * @lucene.experimental
+   */
+  public static IndexReader open(final IndexWriter writer) throws CorruptIndexException, IOException {
+    return writer.getReader();
+  }
+
+  /**
+   * Open a near real time IndexReader from the {@link org.apache.lucene.index.IndexWriter} with the appropriate term index divisor
+   *
+   * @see #open(IndexWriter)
+   * @param writer The {@link org.apache.lucene.index.IndexWriter} to open from
+   * @param termInfoIndexDivisor The divisor.
+   * @return the new, read-only, near real time IndexReader
+   * @throws CorruptIndexException
+   * @throws IOException
+   *
+   * @see #reopen(IndexWriter, int)
+   *
+   * @lucene.experimental
+   */
+  public static IndexReader open(final IndexWriter writer, int termInfoIndexDivisor) throws CorruptIndexException, IOException {
+    return writer.getReader(termInfoIndexDivisor);
+  }
+
+
+
   /** Expert: returns an IndexReader reading the index in the given
    *  {@link IndexCommit}.  You should pass readOnly=true, since it
    *  gives much better concurrent performance, unless you
@@ -483,6 +521,74 @@
   }
 
   /**
+   * Expert: returns a readonly reader, covering all
+   * committed as well as un-committed changes to the index.
+   * This provides "near real-time" searching, in that
+   * changes made during an IndexWriter session can be
+   * quickly made available for searching without closing
+   * the writer nor calling {@link #commit}.
+   *
+   * <p>Note that this is functionally equivalent to calling
+   * {#flush} and then using {@link IndexReader#open} to
+   * open a new reader.  But the turnaround time of this
+   * method should be faster since it avoids the potentially
+   * costly {@link #commit}.</p>
+   *
+   * <p>You must close the {@link IndexReader} returned by
+   * this method once you are done using it.</p>
+   *
+   * <p>It's <i>near</i> real-time because there is no hard
+   * guarantee on how quickly you can get a new reader after
+   * making changes with IndexWriter.  You'll have to
+   * experiment in your situation to determine if it's
+   * fast enough.  As this is a new and experimental
+   * feature, please report back on your findings so we can
+   * learn, improve and iterate.</p>
+   *
+   * <p>The resulting reader supports {@link
+   * IndexReader#reopen}, but that call will simply forward
+   * back to this method (though this may change in the
+   * future).</p>
+   *
+   * <p>The very first time this method is called, this
+   * writer instance will make every effort to pool the
+   * readers that it opens for doing merges, applying
+   * deletes, etc.  This means additional resources (RAM,
+   * file descriptors, CPU time) will be consumed.</p>
+   *
+   * <p>For lower latency on reopening a reader, you should
+   * call {@link #setMergedSegmentWarmer} to
+   * pre-warm a newly merged segment before it's committed
+   * to the index.  This is important for minimizing
+   * index-to-search delay after a large merge.  </p>
+   *
+   * <p>If an addIndexes* call is running in another thread,
+   * then this reader will only search those segments from
+   * the foreign index that have been successfully copied
+   * over, so far</p>.
+   *
+   * <p><b>NOTE</b>: Once the writer is closed, any
+   * outstanding readers may continue to be used.  However,
+   * if you attempt to reopen any of those readers, you'll
+   * hit an {@link AlreadyClosedException}.</p>
+   *
+   * @lucene.experimental
+   *
+   * @return IndexReader that covers entire index plus all
+   * changes made so far by this IndexWriter instance
+   *
+   * @throws IOException
+   */
+  public synchronized IndexReader reopen(IndexWriter writer) throws CorruptIndexException, IOException {
+    return writer.getReader();
+  }
+
+  public synchronized IndexReader reopen(IndexWriter writer, int termInfosIndexDivisor) throws CorruptIndexException, IOException {
+    return writer.getReader(termInfosIndexDivisor);
+  }
+
+
+  /**
    * Efficiently clones the IndexReader (sharing most
    * internal state).
    * <p>
Index: lucene/src/java/org/apache/lucene/index/IndexWriter.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/IndexWriter.java	(revision 1006167)
+++ lucene/src/java/org/apache/lucene/index/IndexWriter.java	(working copy)
@@ -339,7 +339,7 @@
    * the writer nor calling {@link #commit}.
    *
    * <p>Note that this is functionally equivalent to calling
-   * {#commit} and then using {@link IndexReader#open} to
+   * {#flush} and then using {@link IndexReader#open} to
    * open a new reader.  But the turnaround time of this
    * method should be faster since it avoids the potentially
    * costly {@link #commit}.</p>
@@ -389,7 +389,7 @@
    *
    * @throws IOException
    */
-  public IndexReader getReader() throws IOException {
+  IndexReader getReader() throws IOException {
     return getReader(config.getReaderTermsIndexDivisor());
   }
 
@@ -406,7 +406,7 @@
    *  memory usage, at the expense of higher latency when
    *  loading a TermInfo.  The default value is 1.  Set this
    *  to -1 to skip loading the terms index entirely. */
-  public IndexReader getReader(int termInfosIndexDivisor) throws IOException {
+  IndexReader getReader(int termInfosIndexDivisor) throws IOException {
 
     ensureOpen();
 
Index: lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQPHelper.java
===================================================================
--- lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQPHelper.java	(revision 1006167)
+++ lucene/contrib/queryparser/src/test/org/apache/lucene/queryParser/standard/TestQPHelper.java	(working copy)
@@ -1301,7 +1301,7 @@
     Document doc = new Document();
     doc.add(newField("field", "", Field.Store.NO, Field.Index.ANALYZED));
     w.addDocument(doc);
-    IndexReader r = w.getReader();
+    IndexReader r = IndexReader.open(w);
     IndexSearcher s = new IndexSearcher(r);
     
     Query q = new StandardQueryParser(new CannedAnalyzer()).parse("\"a\"", "field");
Index: lucene/contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NearRealtimeReaderTask.java
===================================================================
--- lucene/contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NearRealtimeReaderTask.java	(revision 1006167)
+++ lucene/contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NearRealtimeReaderTask.java	(working copy)
@@ -59,7 +59,7 @@
     }
     
     long t = System.currentTimeMillis();
-    IndexReader r = w.getReader();
+    IndexReader r = IndexReader.open(w);
     runData.setIndexReader(r);
     // Transfer our reference to runData
     r.decRef();
Index: lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java
===================================================================
--- lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java	(revision 1006167)
+++ lucene/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java	(working copy)
@@ -96,7 +96,7 @@
 
   public void testLatLongFilterOnDeletedDocs() throws Exception {
     writer.deleteDocuments(new Term("name", "Potomac"));
-    IndexReader r = writer.getReader();
+    IndexReader r = IndexReader.open(writer);
     LatLongDistanceFilter f = new LatLongDistanceFilter(new QueryWrapperFilter(new MatchAllDocsQuery()),
                                                         lat, lng, 1.0, latField, lngField);
 
