Index: lucene/src/java/org/apache/lucene/index/DocInverterPerField.java
===================================================================
--- lucene/src/java/org/apache/lucene/index/DocInverterPerField.java	(revision f0571364edbaacae56da0743a3f0a33a2bd17bec)
+++ lucene/src/java/org/apache/lucene/index/DocInverterPerField.java	(revision )
@@ -138,8 +138,8 @@
             PositionIncrementAttribute posIncrAttribute = fieldState.attributeSource.addAttribute(PositionIncrementAttribute.class);
             
             consumer.start(field);
-            
+
-            for(;;) {
+            for(boolean firstToken = true; hasMoreTokens; firstToken=false) {
 
               // If we hit an exception in stream.next below
               // (which is fairly common, eg if analyzer
@@ -147,18 +147,16 @@
               // non-aborting and (above) this one document
               // will be marked as deleted, but still
               // consume a docID
-              
+
-              if (!hasMoreTokens) break;
-              
+              //ignore position increment for first value's token; relying on positionIncrementGap between values
+              if (!firstToken || i > 0) {
-              final int posIncr = posIncrAttribute.getPositionIncrement();
-              fieldState.position += posIncr;
+                final int posIncr = posIncrAttribute.getPositionIncrement();
+                fieldState.position += posIncr;
-              if (fieldState.position > 0) {
-                fieldState.position--;
+                if (posIncr == 0 && !firstToken)
+                  fieldState.numOverlap++;
               }
+              assert fieldState.position >= 0 : "LUCENE-1542, pos < 0 doesn't work with payloads";
 
-              if (posIncr == 0)
-                fieldState.numOverlap++;
-
               boolean success = false;
               try {
                 // If we hit an exception in here, we abort
@@ -173,7 +171,6 @@
                 if (!success)
                   docState.docWriter.setAborting();
               }
-              fieldState.position++;
               if (++fieldState.length >= maxFieldLength) {
                 if (docState.infoStream != null)
                   docState.infoStream.println("maxFieldLength " +maxFieldLength+ " reached for field " + fieldInfo.name + ", ignoring following tokens");
Index: lucene/src/test/org/apache/lucene/index/TestIndexWriter.java
===================================================================
--- lucene/src/test/org/apache/lucene/index/TestIndexWriter.java	(revision f0571364edbaacae56da0743a3f0a33a2bd17bec)
+++ lucene/src/test/org/apache/lucene/index/TestIndexWriter.java	(revision )
@@ -4311,27 +4311,33 @@
   public void testPositionIncrementGapEmptyField() throws Exception {
     Directory dir = newDirectory();
     MockAnalyzer analyzer = new MockAnalyzer();
-    analyzer.setPositionIncrementGap( 100 );
+    analyzer.setPositionIncrementGap(100);
     IndexWriter w = new IndexWriter(dir, newIndexWriterConfig( 
         TEST_VERSION_CURRENT, analyzer));
     Document doc = new Document();
-    Field f = newField("field", "", Field.Store.NO,
-                        Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS);
-    Field f2 = newField("field", "crunch man", Field.Store.NO,
-        Field.Index.ANALYZED, Field.TermVector.WITH_POSITIONS);
-    doc.add(f);
-    doc.add(f2);
+    doc.add(newField("field", "",
+            Store.NO, Index.ANALYZED, TermVector.WITH_POSITIONS));
+    doc.add(newField("field", "crunch man",
+            Store.NO, Index.ANALYZED, TermVector.WITH_POSITIONS));
+    doc.add(newField("field", "",
+            Store.NO, Index.ANALYZED, TermVector.WITH_POSITIONS));
+    doc.add(newField("field", "z",
+            Store.NO, Index.ANALYZED, TermVector.WITH_POSITIONS));
     w.addDocument(doc);
     w.close();
 
     IndexReader r = IndexReader.open(dir, true);
     TermPositionVector tpv = ((TermPositionVector) r.getTermFreqVector(0, "field"));
-    int[] poss = tpv.getTermPositions(0);
+    int[] poss = tpv.getTermPositions(0);//crunch
     assertEquals(1, poss.length);
-    assertEquals(100, poss[0]);
-    poss = tpv.getTermPositions(1);
-    assertEquals(1, poss.length);
     assertEquals(101, poss[0]);
+    poss = tpv.getTermPositions(1);//man
+    assertEquals(1, poss.length);
+    assertEquals(102, poss[0]);
+    poss = tpv.getTermPositions(2);//z
+    assertEquals(1, poss.length);
+    assertEquals(303, poss[0]);
+
     r.close();
     dir.close();
   }
