Index: lucene/contrib/misc/src/java/org/apache/lucene/store/WindowsDirectory.java
===================================================================
--- lucene/contrib/misc/src/java/org/apache/lucene/store/WindowsDirectory.java	(revision 1142263)
+++ lucene/contrib/misc/src/java/org/apache/lucene/store/WindowsDirectory.java	(working copy)
@@ -22,6 +22,7 @@
 
 import org.apache.lucene.store.Directory; // javadoc
 import org.apache.lucene.store.NativeFSLockFactory; // javadoc
+import org.apache.lucene.store.IOContext.Context;
 
 /**
  * Native {@link Directory} implementation for Microsoft Windows.
@@ -71,6 +72,10 @@
   public IndexInput openInput(String name, IOContext context) throws IOException {
     ensureOpen();
     //nocommit - use buffer based on IOContext
+    //nocommit DEFAULT_BUFFERSIZE is also 4k so this is not needed ?
+    if (context.context == Context.MERGE) {
+      return new WindowsIndexInput(new File(getDirectory(), name), BufferedIndexInput.MERGE_BUFFER_SIZE);
+    }
     return new WindowsIndexInput(new File(getDirectory(), name), DEFAULT_BUFFERSIZE);
   }
   
Index: lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java
===================================================================
--- lucene/contrib/misc/src/java/org/apache/lucene/store/DirectIOLinuxDirectory.java	(revision 1142263)
+++ 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,11 +73,14 @@
   public IndexInput openInput(String name, IOContext context) throws IOException {
     ensureOpen();
     //nocommit - use buffer based on IOContext
+    if (context.context == Context.MERGE) {
+      return new DirectIOLinuxIndexInput(new File(getDirectory(), name), BufferedIndexInput.MERGE_BUFFER_SIZE);
+    }
     return new DirectIOLinuxIndexInput(new File(getDirectory(), name), forcedBufferSize == 0 ? BufferedIndexInput.BUFFER_SIZE : forcedBufferSize);
   }
 
   @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
Index: lucene/src/java/org/apache/lucene/index/BufferedDeletesStream.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/BufferedDeletesStream.java	(revision 1142263)
+++ 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 1142263)
+++ 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;
@@ -58,7 +59,7 @@
   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 1142263)
+++ lucene/src/java/org/apache/lucene/store/BufferedIndexInput.java	(working copy)
@@ -24,6 +24,10 @@
 
   /** Default buffer size */
   public static final int BUFFER_SIZE = 1024;
+  
+  public static final int MERGE_BUFFER_SIZE = 4096;
+  
+  private int mergeBufferSize = MERGE_BUFFER_SIZE;
 
   private int bufferSize = BUFFER_SIZE;
   
@@ -74,11 +78,42 @@
       }
     }
   }
+  
+  /** Change the buffer size used by this IndexInput */
+  public void setMergeBufferSize(int newSize) {
+    assert buffer == null || mergeBufferSize == buffer.length: "buffer=" + buffer + " MergeBufferSize=" + mergeBufferSize + " buffer.length=" + (buffer != null ? buffer.length : 0);
+    if (newSize != mergeBufferSize) {
+      checkBufferSize(newSize);
+      mergeBufferSize = newSize;
+      if (buffer != null) {
+        // Resize the existing buffer and carefully save as
+        // many bytes as possible starting from the current
+        // bufferPosition
+        byte[] newBuffer = new byte[newSize];
+        final int leftInBuffer = bufferLength-bufferPosition;
+        final int numToCopy;
+        if (leftInBuffer > newSize)
+          numToCopy = newSize;
+        else
+          numToCopy = leftInBuffer;
+        System.arraycopy(buffer, bufferPosition, newBuffer, 0, numToCopy);
+        bufferStart += bufferPosition;
+        bufferPosition = 0;
+        bufferLength = numToCopy;
+        newBuffer(newBuffer);
+      }
+    }
+  }
 
   protected void newBuffer(byte[] newBuffer) {
     // Subclasses can do something here
     buffer = newBuffer;
   }
+  
+  /** Returns buffer size.  @see #setMergeBufferSize */
+  public int getMergeBufferSize() {
+    return mergeBufferSize;
+  }
 
   /** Returns buffer size.  @see #setBufferSize */
   public int getBufferSize() {
Index: lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java
===================================================================
--- lucene/src/java/org/apache/lucene/store/SimpleFSDirectory.java	(revision 1142263)
+++ 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
