Index: src/java/org/apache/lucene/index/DocumentsWriterPerThread.java
===================================================================
--- src/java/org/apache/lucene/index/DocumentsWriterPerThread.java	(revision 1060189)
+++ src/java/org/apache/lucene/index/DocumentsWriterPerThread.java	(working copy)
@@ -170,14 +170,11 @@
     aborting = true;
   }
 
-  public void updateDocument(Document doc, Analyzer analyzer, Term delTerm) throws IOException {
+  public void updateDocument(Document doc, Analyzer analyzer) throws IOException {
     assert writer.testPoint("DocumentsWriterPerThread addDocument start");
     docState.doc = doc;
     docState.analyzer = analyzer;
     docState.docID = numDocsInRAM;
-    if (delTerm != null) {
-      pendingDeletes.addTerm(delTerm, docState.docID);
-    }
 
     if (segment == null) {
       // this call is synchronized on IndexWriter.segmentInfos
Index: src/java/org/apache/lucene/index/DocumentsWriter.java
===================================================================
--- src/java/org/apache/lucene/index/DocumentsWriter.java	(revision 1060189)
+++ src/java/org/apache/lucene/index/DocumentsWriter.java	(working copy)
@@ -147,7 +147,7 @@
     this.perThreadPool.initialize(this);
   }
 
-  boolean deleteQueries(final Query... queries) throws IOException {
+  synchronized boolean deleteQueries(final Query... queries) throws IOException {
     Iterator<ThreadState> threadsIterator = perThreadPool.getActivePerThreadsIterator();
 
     boolean deleted = false;
@@ -173,11 +173,11 @@
     return false;
   }
 
-  boolean deleteQuery(final Query query) throws IOException {
+  synchronized boolean deleteQuery(final Query query) throws IOException {
     return deleteQueries(query);
   }
 
-  boolean deleteTerms(final Term... terms) throws IOException {
+  synchronized boolean deleteTerms(final Term... terms) throws IOException {
     Iterator<ThreadState> threadsIterator = perThreadPool.getActivePerThreadsIterator();
 
     boolean deleted = false;
@@ -203,11 +203,11 @@
     return false;
   }
 
-  boolean deleteTerm(final Term term) throws IOException {
+  synchronized boolean deleteTerm(final Term term) throws IOException {
     return deleteTerms(term);
   }
 
-  boolean deleteTerm(final Term term, ThreadState exclude) {
+  synchronized boolean deleteTerm(final Term term, ThreadState exclude) {
     Iterator<ThreadState> threadsIterator = perThreadPool.getActivePerThreadsIterator();
 
     boolean deleted = false;
@@ -348,7 +348,7 @@
     return numDocsInRAM.get() != 0 || anyDeletions();
   }
 
-  public int getBufferedDeleteTermsSize() {
+  public synchronized int getBufferedDeleteTermsSize() {
     int size = 0;
     Iterator<ThreadState> it = perThreadPool.getActivePerThreadsIterator();
     while (it.hasNext()) {
@@ -360,7 +360,7 @@
   }
 
   //for testing
-  public int getNumBufferedDeleteTerms() {
+  public synchronized int getNumBufferedDeleteTerms() {
     int numDeletes = 0;
     Iterator<ThreadState> it = perThreadPool.getActivePerThreadsIterator();
     while (it.hasNext()) {
@@ -404,12 +404,18 @@
 
     SegmentInfo newSegment = null;
     SegmentDeletes segmentDeletes = null;
-
-    ThreadState perThread = perThreadPool.getAndLock(Thread.currentThread(), this, doc);
+    ThreadState perThread = null;
+    synchronized (this) {
+    	perThread = perThreadPool.getAndLock(Thread.currentThread(), this, doc);
+    	if (delTerm != null) {
+    	  perThread.perThread.pendingDeletes.addTerm(delTerm, 
+    	      perThread.perThread.getNumDocsInRAM());
+    	}
+    }
     try {
       DocumentsWriterPerThread dwpt = perThread.perThread;
       long perThreadRAMUsedBeforeAdd = dwpt.bytesUsed();
-      dwpt.updateDocument(doc, analyzer, delTerm);
+      dwpt.updateDocument(doc, analyzer);
       numDocsInRAM.incrementAndGet();
 
       newSegment = finishAddDocument(dwpt, perThreadRAMUsedBeforeAdd);
@@ -429,17 +435,13 @@
     }
 
     if (newSegment != null) {
-      perThreadPool.clearThreadBindings(perThread);
+      synchronized (this) {
+        perThreadPool.clearThreadBindings(perThread);
+      }
       indexWriter.addFlushedSegment(newSegment);
       return true;
     }
 
-    // delete term from other DWPTs later, so that this thread
-    // doesn't have to lock multiple DWPTs at the same time
-    if (delTerm != null) {
-      deleteTerm(delTerm, perThread);
-    }
-
     return false;
   }
 
@@ -466,10 +468,11 @@
       oldValue = numDocsInRAM.get();
     }
   }
-
+  
+  // Lock order: DW -> IW
   private final void pushDeletes(SegmentInfo segmentInfo, SegmentDeletes segmentDeletes) {
     synchronized(indexWriter) {
-      // Lock order: DW -> BD
+      
       if (segmentDeletes.any()) {
         if (segmentInfo != null) {
           bufferedDeletes.pushDeletes(segmentDeletes, segmentInfo);
@@ -543,7 +546,9 @@
       }
 
       if (segmentDeletes != null) {
+        synchronized (this) {
           pushDeletes(newSegment, segmentDeletes);
+        }
       }
 
 
@@ -553,7 +558,18 @@
         indexWriter.addFlushedSegment(newSegment);
       }
     }
-
+    /**
+    synchronized (this) {
+      ThreadState perThread = threadsIterator.next();
+      perThread.lock();
+      try {
+        DocumentsWriterPerThread dwpt = perThread.perThread;
+        pushDeletes(newSegment, dwpt.pendingDeletes);
+      } finally {
+        perThread.unlock();
+      }
+    }
+    **/
     return anythingFlushed;
   }
 
Index: src/java/org/apache/lucene/index/IndexWriter.java
===================================================================
--- src/java/org/apache/lucene/index/IndexWriter.java	(revision 1060189)
+++ src/java/org/apache/lucene/index/IndexWriter.java	(working copy)
@@ -1053,7 +1053,7 @@
     try {
       if (infoStream != null)
         message("now flush at close");
-
+      
       docWriter.close();
 
       // Only allow a new merge to be triggered if we are
@@ -1061,7 +1061,7 @@
       if (!hitOOM) {
         flush(waitForMerges, true);
       }
-
+      
       if (waitForMerges)
         // Give merge scheduler last chance to run, in case
         // any pending merges are waiting:
@@ -2571,6 +2571,7 @@
         }
 
         if (applyAllDeletes) {
+          assert !docWriter.pendingDeletes.any();
           if (infoStream != null) {
             message("apply all deletes during flush");
           }
