Index: lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/BlockTermsReader.java (working copy) @@ -18,6 +18,7 @@ */ import java.io.IOException; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.TreeMap; @@ -39,7 +40,6 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.DoubleBarrelLRUCache; -import org.apache.lucene.util.UnmodifiableIterator; /** Handles a terms dict, but decouples all details of * doc/freqs/positions reading to an instance of {@link @@ -185,7 +185,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override Index: lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/BlockTreeTermsReader.java (working copy) @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.Locale; @@ -45,7 +46,6 @@ import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.RamUsageEstimator; import org.apache.lucene.util.StringHelper; -import org.apache.lucene.util.UnmodifiableIterator; import org.apache.lucene.util.automaton.CompiledAutomaton; import org.apache.lucene.util.automaton.RunAutomaton; import org.apache.lucene.util.automaton.Transition; @@ -200,7 +200,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override Index: lucene/core/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/bloom/BloomFilteringPostingsFormat.java (working copy) @@ -207,7 +207,7 @@ } } - public int size() throws IOException { + public int size() { return delegateFieldsProducer.size(); } Index: lucene/core/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/memory/DirectPostingsFormat.java (working copy) @@ -18,6 +18,7 @@ */ import java.io.IOException; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.Map; @@ -43,7 +44,6 @@ import org.apache.lucene.util.ArrayUtil; import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.UnmodifiableIterator; import org.apache.lucene.util.automaton.CompiledAutomaton; import org.apache.lucene.util.automaton.RunAutomaton; import org.apache.lucene.util.automaton.Transition; @@ -131,7 +131,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override Index: lucene/core/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/memory/MemoryPostingsFormat.java (working copy) @@ -18,6 +18,7 @@ */ import java.io.IOException; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.SortedMap; @@ -48,7 +49,6 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IntsRef; -import org.apache.lucene.util.UnmodifiableIterator; import org.apache.lucene.util.fst.Builder; import org.apache.lucene.util.fst.ByteSequenceOutputs; import org.apache.lucene.util.fst.BytesRefFSTEnum; @@ -863,7 +863,7 @@ return new FieldsProducer() { @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override Index: lucene/core/src/java/org/apache/lucene/codecs/perfield/PerFieldPostingsFormat.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/perfield/PerFieldPostingsFormat.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/perfield/PerFieldPostingsFormat.java (working copy) @@ -19,6 +19,7 @@ import java.io.Closeable; import java.io.IOException; +import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -34,7 +35,6 @@ import org.apache.lucene.index.SegmentWriteState; import org.apache.lucene.index.Terms; import org.apache.lucene.util.IOUtils; -import org.apache.lucene.util.UnmodifiableIterator; /** * Enables per field format support. @@ -199,7 +199,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override Index: lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextFieldsReader.java (working copy) @@ -18,6 +18,7 @@ */ import java.io.IOException; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; @@ -43,7 +44,6 @@ import org.apache.lucene.util.OpenBitSet; import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.UnicodeUtil; -import org.apache.lucene.util.UnmodifiableIterator; import org.apache.lucene.util.fst.Builder; import org.apache.lucene.util.fst.BytesRefFSTEnum; import org.apache.lucene.util.fst.FST; @@ -608,7 +608,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } private final Map termsCache = new HashMap(); Index: lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/simpletext/SimpleTextTermVectorsReader.java (working copy) @@ -19,6 +19,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.Map; @@ -44,8 +45,6 @@ import org.apache.lucene.util.IOUtils; import org.apache.lucene.util.StringHelper; import org.apache.lucene.util.UnicodeUtil; -import org.apache.lucene.util.UnmodifiableIterator; - import static org.apache.lucene.codecs.simpletext.SimpleTextTermVectorsWriter.*; /** @@ -241,7 +240,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override @@ -250,7 +249,7 @@ } @Override - public int size() throws IOException { + public int size() { return fields.size(); } } Index: lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java =================================================================== --- lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/codecs/TermVectorsWriter.java (working copy) @@ -20,6 +20,7 @@ import java.io.Closeable; import java.io.IOException; import java.util.Comparator; +import java.util.Iterator; import org.apache.lucene.index.AtomicReader; import org.apache.lucene.index.DocsAndPositionsEnum; @@ -187,19 +188,21 @@ } /** Safe (but, slowish) default method to write every - * vector field in the document. This default - * implementation requires that the vectors implement - * both Fields.size and - * Terms.size. */ + * vector field in the document. */ protected final void addAllDocVectors(Fields vectors, MergeState mergeState) throws IOException { if (vectors == null) { startDocument(0); return; } - final int numFields = vectors.size(); + int numFields = vectors.size(); if (numFields == -1) { - throw new IllegalStateException("vectors.size() must be implemented (it returned -1)"); + // count manually! TODO: Maybe enforce that Fields.size() returns something valid? + numFields = 0; + for (final Iterator it = vectors.iterator(); it.hasNext(); ) { + it.next(); + numFields++; + } } startDocument(numFields); @@ -208,7 +211,9 @@ TermsEnum termsEnum = null; DocsAndPositionsEnum docsAndPositionsEnum = null; + int fieldCount = 0; for(String fieldName : vectors) { + fieldCount++; final FieldInfo fieldInfo = mergeState.fieldInfos.fieldInfo(fieldName); assert lastFieldName == null || fieldName.compareTo(lastFieldName) > 0: "lastFieldName=" + lastFieldName + " fieldName=" + fieldName; @@ -225,9 +230,14 @@ final boolean hasPayloads = terms.hasPayloads(); assert !hasPayloads || hasPositions; - final int numTerms = (int) terms.size(); + int numTerms = (int) terms.size(); if (numTerms == -1) { - throw new IllegalStateException("terms.size() must be implemented (it returned -1)"); + // count manually. It is stupid, but needed, as Terms.size() is not a mandatory statistics function + numTerms = 0; + termsEnum = terms.iterator(termsEnum); + while(termsEnum.next() != null) { + numTerms++; + } } startField(fieldInfo, numTerms, hasPositions, hasOffsets, hasPayloads); @@ -263,6 +273,7 @@ } assert termCount == numTerms; } + assert fieldCount == numFields; } /** Return the BytesRef Comparator used to sort terms Index: lucene/core/src/java/org/apache/lucene/index/Fields.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/Fields.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/index/Fields.java (working copy) @@ -36,7 +36,7 @@ /** Returns the number of fields or -1 if the number of * distinct field names is unknown. If >= 0, * {@link #iterator} will return as many field names. */ - public abstract int size() throws IOException; + public abstract int size(); /** Returns the number of terms for all fields, or -1 if this * measure isn't stored by the codec. Note that, just like Index: lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/index/FilterAtomicReader.java (working copy) @@ -57,7 +57,7 @@ } @Override - public int size() throws IOException { + public int size() { return in.size(); } Index: lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java =================================================================== --- lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/index/ParallelAtomicReader.java (working copy) @@ -27,7 +27,6 @@ import java.util.TreeMap; import org.apache.lucene.util.Bits; -import org.apache.lucene.util.UnmodifiableIterator; /** An {@link AtomicReader} which reads multiple, parallel indexes. Each index @@ -163,7 +162,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fields.keySet().iterator()); + return Collections.unmodifiableSet(fields.keySet()).iterator(); } @Override Index: lucene/core/src/java/org/apache/lucene/util/UnmodifiableIterator.java =================================================================== --- lucene/core/src/java/org/apache/lucene/util/UnmodifiableIterator.java (revision 1375034) +++ lucene/core/src/java/org/apache/lucene/util/UnmodifiableIterator.java (working copy) @@ -1,46 +0,0 @@ -package org.apache.lucene.util; - -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import java.util.Iterator; - -/** - * Wraps an iterator to ensure its unmodifiable - */ -public class UnmodifiableIterator implements Iterator { - private final Iterator in; - - public UnmodifiableIterator(Iterator in) { - this.in = in; - } - - @Override - public boolean hasNext() { - return in.hasNext(); - } - - @Override - public T next() { - return in.next(); - } - - @Override - public void remove() { - throw new UnsupportedOperationException(); - } -} Index: lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPostingsFormat.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPostingsFormat.java (revision 1375034) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/asserting/AssertingPostingsFormat.java (working copy) @@ -83,7 +83,7 @@ } @Override - public int size() throws IOException { + public int size() { return in.size(); } Index: lucene/test-framework/src/java/org/apache/lucene/codecs/ramonly/RAMOnlyPostingsFormat.java =================================================================== --- lucene/test-framework/src/java/org/apache/lucene/codecs/ramonly/RAMOnlyPostingsFormat.java (revision 1375034) +++ lucene/test-framework/src/java/org/apache/lucene/codecs/ramonly/RAMOnlyPostingsFormat.java (working copy) @@ -19,6 +19,7 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.Iterator; @@ -49,7 +50,6 @@ import org.apache.lucene.util.Bits; import org.apache.lucene.util.BytesRef; import org.apache.lucene.util.IOUtils; -import org.apache.lucene.util.UnmodifiableIterator; /** Stores all postings data in RAM, but writes a small * token (header + single int) to identify which "slot" the @@ -113,7 +113,7 @@ @Override public Iterator iterator() { - return new UnmodifiableIterator(fieldToTerms.keySet().iterator()); + return Collections.unmodifiableSet(fieldToTerms.keySet()).iterator(); } @Override