Buggy code:
final class SegmentMerger { static final byte [ ] NORMS_HEADER = new byte [ ] { 'N' , 'R' , 'M' , - 1 } ; private Directory directory ; private String segment ; private int termIndexInterval = IndexWriter . DEFAULT_TERM_INDEX_INTERVAL ; private Vector readers = new Vector ( ) ; private FieldInfos fieldInfos ; private int mergedDocs ; private boolean mergeDocStores ; private static final int MAX_RAW_MERGE_DOCS = 16384 ; SegmentMerger ( Directory dir , String name ) { } SegmentMerger ( IndexWriter writer , String name ) { } final void add ( IndexReader reader ) { } final IndexReader segmentReader ( int i ) { } final int merge ( ) throws IOException , CorruptIndexException { } final int merge ( boolean mergeDocStores ) throws IOException , CorruptIndexException { } final void closeReaders ( ) throws IOException { } final Vector createCompoundFile ( String fileName ) throws IOException { } private void addIndexed ( IndexReader reader , FieldInfos fieldInfos , Collection names , boolean storeTermVectors , boolean storePositionWithTermVector , boolean storeOffsetWithTermVector , boolean storePayloads ) throws IOException { } private final int mergeFields ( ) throws IOException , CorruptIndexException { if ( ! ( mergeDocStores ) ) { final SegmentReader sr = ( ( SegmentReader ) ( readers . elementAt ( ( ( readers . size ( ) ) - 1 ) ) ) ) ; fieldInfos = ( ( FieldInfos ) ( sr . fieldInfos . clone ( ) ) ) ; } else { fieldInfos = new FieldInfos ( ) ; } for ( int i = 0 ; i < ( readers . size ( ) ) ; i ++ ) { IndexReader reader = ( ( IndexReader ) ( readers . elementAt ( i ) ) ) ; if ( reader instanceof SegmentReader ) { SegmentReader segmentReader = ( ( SegmentReader ) ( reader ) ) ; for ( int j = 0 ; j < ( segmentReader . getFieldInfos ( ) . size ( ) ) ; j ++ ) { FieldInfo fi = segmentReader . getFieldInfos ( ) . fieldInfo ( j ) ; <START_BUG> fieldInfos . add ( fi . name , fi . isIndexed , fi . storeTermVector , fi . storePositionWithTermVector , fi . storeOffsetWithTermVector , ( ! ( reader . hasNorms ( fi . name ) ) ) ) ; <END_BUG> } } else { addIndexed ( reader , fieldInfos , reader . getFieldNames ( TERMVECTOR_WITH_POSITION_OFFSET ) , true , true , true , false ) ; addIndexed ( reader , fieldInfos , reader . getFieldNames ( TERMVECTOR_WITH_POSITION ) , true , true , false , false ) ; addIndexed ( reader , fieldInfos , reader . getFieldNames ( TERMVECTOR_WITH_OFFSET ) , true , false , true , false ) ; addIndexed ( reader , fieldInfos , reader . getFieldNames ( TERMVECTOR ) , true , false , false , false ) ; addIndexed ( reader , fieldInfos , reader . getFieldNames ( STORES_PAYLOADS ) , false , false , false , true ) ; addIndexed ( reader , fieldInfos , reader . getFieldNames ( INDEXED ) , false , false , false , false ) ; fieldInfos . add ( reader . getFieldNames ( UNINDEXED ) , false ) ; } } fieldInfos . write ( directory , ( ( segment ) + ".fnm" ) ) ; int docCount = 0 ; if ( mergeDocStores ) { SegmentReader [ ] matchingSegmentReaders = new SegmentReader [ readers . size ( ) ] ; for ( int i = 0 ; i < ( readers . size ( ) ) ; i ++ ) { IndexReader reader = ( ( IndexReader ) ( readers . elementAt ( i ) ) ) ; boolean same = ( ( reader . getFieldNames ( ALL ) . size ( ) ) == ( fieldInfos . size ( ) ) ) && ( reader instanceof SegmentReader ) ; if ( same ) { SegmentReader segmentReader = ( ( SegmentReader ) ( reader ) ) ; for ( int j = 0 ; same && ( j < ( fieldInfos . size ( ) ) ) ; j ++ ) same = fieldInfos . fieldName ( j ) . equals ( segmentReader . getFieldInfos ( ) . fieldName ( j ) ) ; if ( same ) matchingSegmentReaders [ i ] = segmentReader ; } } final int [ ] rawDocLengths = new int [ SegmentMerger . MAX_RAW_MERGE_DOCS ] ; final FieldsWriter fieldsWriter = new FieldsWriter ( directory , segment , fieldInfos ) ; FieldSelector fieldSelectorMerge = new FieldSelector ( ) { public FieldSelectorResult accept ( String fieldName ) { return FieldSelectorResult . LOAD_FOR_MERGE ; } } ; try { for ( int i = 0 ; i < ( readers . size ( ) ) ; i ++ ) { final IndexReader reader = ( ( IndexReader ) ( readers . elementAt ( i ) ) ) ; final SegmentReader matchingSegmentReader = matchingSegmentReaders [ i ] ; final FieldsReader matchingFieldsReader ; if ( matchingSegmentReader != null ) matchingFieldsReader = matchingSegmentReader . getFieldsReader ( ) ; else matchingFieldsReader = null ; final int maxDoc = reader . maxDoc ( ) ; for ( int j = 0 ; j < maxDoc ; ) { if ( ! ( reader . isDeleted ( j ) ) ) { if ( matchingSegmentReader != null ) { int start = j ; int numDocs = 0 ; do { j ++ ; numDocs ++ ; } while ( ( ( j < maxDoc ) && ( ! ( matchingSegmentReader . isDeleted ( j ) ) ) ) && ( numDocs < ( SegmentMerger . MAX_RAW_MERGE_DOCS ) ) ) ; IndexInput stream = matchingFieldsReader . rawDocs ( rawDocLengths , start , numDocs ) ; fieldsWriter . addRawDocuments ( stream , rawDocLengths , numDocs ) ; docCount += numDocs ; } else { fieldsWriter . addDocument ( reader . document ( j , fieldSelectorMerge ) ) ;

Fix:
fieldInfos . add ( fi . name , fi . isIndexed , fi . storeTermVector , fi . storePositionWithTermVector , fi . storeOffsetWithTermVector , ( ! ( reader . hasNorms ( fi . name ) ) ) , fi . storePayloads ) ;