Index: lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java
===================================================================
--- lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java	(revision 1142967)
+++ lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java	(working copy)
@@ -27,6 +27,7 @@
 
 import org.apache.lucene.store.Directory; // javadoc
 import org.apache.lucene.store.NativeFSLockFactory; // javadoc
+import org.apache.lucene.store.IOContext.Context;
 
 /**
  * An {@link Directory} implementation that uses the
@@ -72,14 +73,19 @@
   public IndexInput openInput(String name, IOContext context) throws IOException {
     ensureOpen();
     //nocommit - use buffer based on IOContext
-    return new DirectIOLinuxIndexInput(new File(getDirectory(), name), forcedBufferSize == 0 ? BufferedIndexInput.BUFFER_SIZE : forcedBufferSize);
+    if (forcedBufferSize != 0) 
+      return new DirectIOLinuxIndexInput(new File(getDirectory(), name), forcedBufferSize);
+    
+    else if (context.context == Context.MERGE) 
+      return new DirectIOLinuxIndexInput(new File(getDirectory(), name), BufferedIndexInput.MERGE_BUFFER_SIZE);
+    
+    return new DirectIOLinuxIndexInput(new File(getDirectory(), name), BufferedIndexInput.BUFFER_SIZE);
   }
 
   @Override
-  public IndexOutput createOutput(String name,IOContext context) throws IOException {
+  public IndexOutput createOutput(String name, IOContext context) throws IOException {
     ensureOpen();
     ensureCanWrite(name);
-    //nocommit - use buffer based on IOContext
     return new DirectIOLinuxIndexOutput(new File(getDirectory(), name), forcedBufferSize == 0 ? BufferedIndexOutput.BUFFER_SIZE : forcedBufferSize);
   }
 
Index: lucene/src/java/org/apache/lucene/index/BufferedDeletesStream.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/BufferedDeletesStream.java	(revision 1142967)
+++ lucene/src/java/org/apache/lucene/index/BufferedDeletesStream.java	(working copy)
@@ -275,7 +275,7 @@
           // Lock order: IW -> BD -> RP
           assert readerPool.infoIsLive(info);
           //nocommit is IOContext.DEFAULT the right thing to do here?
-          SegmentReader reader = readerPool.get(info, false, IOContext.DEFAULT);
+          SegmentReader reader = readerPool.get(info, false, IOContext.READ);
           int delCount = 0;
           final boolean segAllDeletes;
           try {
Index: lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosWriter.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosWriter.java	(revision 1142967)
+++ lucene/src/java/org/apache/lucene/index/codecs/DefaultSegmentInfosWriter.java	(working copy)
@@ -23,6 +23,7 @@
 import org.apache.lucene.index.SegmentInfos;
 import org.apache.lucene.store.ChecksumIndexOutput;
 import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FlushInfo;
 import org.apache.lucene.store.IOContext;
 import org.apache.lucene.store.IndexOutput;
 import org.apache.lucene.util.IOUtils;
@@ -57,8 +58,7 @@
   @Override
   public IndexOutput writeInfos(Directory dir, String segmentFileName, SegmentInfos infos, IOContext context)
           throws IOException {
-    //nocommit should this context always be flush?
-    IndexOutput out = createOutput(dir, segmentFileName, context);
+    IndexOutput out = createOutput(dir, segmentFileName, new IOContext(new FlushInfo(infos.size(), infos.totalDocCount())));
     boolean success = false;
     try {
       out.writeInt(FORMAT_CURRENT); // write FORMAT
Index: lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java	(revision 1142967)
+++ lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java	(working copy)
@@ -24,6 +24,14 @@
 
   /** Default buffer size */
   public static final int BUFFER_SIZE = 1024;
+  
+  // The normal read buffer size defaults to 1024, but
+  // increasing this during merging seems to yield
+  // performance gains.  However we don't want to increase
+  // it too much because there are quite a few
+  // BufferedIndexInputs created during merging.  See
+  // LUCENE-888 for details.
+  public static final int MERGE_BUFFER_SIZE = 1024;
 
   private int bufferSize = BUFFER_SIZE;
   
Index: lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java	(revision 1142967)
+++ lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java	(working copy)
@@ -21,7 +21,9 @@
 import java.io.IOException;
 import java.io.RandomAccessFile;
 
+import org.apache.lucene.store.IOContext.Context;
 
+
 /** A straightforward implementation of {@link FSDirectory}
  *  using java.io.RandomAccessFile.  However, this class has
  *  poor concurrent performance (multiple threads will
@@ -89,6 +91,9 @@
     public SimpleFSIndexInput(File path, IOContext context, int chunkSize) throws IOException {
       //nocommit Use IOContext to decide bufferSize instead of BufferedIndexInput.BUFFER_SIZE
       super(BufferedIndexInput.BUFFER_SIZE);
+      if (context.context == Context.MERGE) {
+        setBufferSize(MERGE_BUFFER_SIZE);
+      }
       file = new Descriptor(path, "r");
       this.chunkSize = chunkSize;
     }
Index: lucene/src/java/org/apache/lucene/store/MergeInfo.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/MergeInfo.java	(revision 1138659)
+++ lucene/src/java/org/apache/lucene/store/MergeInfo.java	(working copy)
@@ -1,4 +1,4 @@
-package org.apache.lucene.index;
+package org.apache.lucene.store;
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
@@ -15,7 +15,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-//nocommit javadoc
+
+/**
+ * <p>A MergeInfo provides information required for a MERGE context and other optimization operations.
+ *  It is used as part of an {@link IOContext} in case of MERGE context.</p>
+ */
+
 public class MergeInfo {
   
   public int totalDocCount;
@@ -25,7 +30,16 @@
   boolean isExternal;               // used by IndexWriter
   
   boolean optimize;                 // used by IndexWriter
+  
 
+  /**
+   * <p>Creates a new {@link MergeInfo} instance from
+   * the values required for a MERGE {@link IOContext} context.
+   * 
+   * These values are only estimates and are not the actual values.
+   * 
+   */
+
   public MergeInfo(int totalDocCount, long estimatedMergeBytes, boolean isExternal, boolean optimize) {
     this.totalDocCount = totalDocCount;
     this.estimatedMergeBytes = estimatedMergeBytes;
Index: lucene/src/java/org/apache/lucene/store/IOContext.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/IOContext.java	(revision 1138659)
+++ lucene/src/java/org/apache/lucene/store/IOContext.java	(working copy)
@@ -1,4 +1,4 @@
-package org.apache.lucene.index;
+package org.apache.lucene.store;
 
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -37,6 +37,8 @@
   
   public final MergeInfo mergeInfo;
   
+  public final FlushInfo flushInfo;
+  
   public final boolean readOnce;
   
   public static final IOContext DEFAULT = new IOContext(Context.DEFAULT);
@@ -49,14 +51,23 @@
     this(false);
   }
   
-  public IOContext(Context context) {
+  public IOContext (FlushInfo flushInfo) {
+    assert flushInfo != null;
+    this.context = Context.FLUSH;
+    this.mergeInfo = null;
+    this.readOnce = false;
+    this.flushInfo = flushInfo;    
+  }
+  
+  public IOContext (Context context) {
     this(context, null);    
   }
   
-  private IOContext(boolean readOnce) {
+  private IOContext (boolean readOnce) {
     this.context = Context.READ;
     this.mergeInfo = null;    
     this.readOnce = readOnce;
+    this.flushInfo = null;
   }
   
   public IOContext (MergeInfo mergeInfo) {    
@@ -68,6 +79,7 @@
     this.context = context;
     this.readOnce = false;
     this.mergeInfo = mergeInfo;
+    this.flushInfo = null;
   }
   
 }
\ No newline at end of file
