LUCENE-5012: don't separate interface from impl for attributes

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene5012@1694511 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/AutomatonStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/AutomatonStage.java
index 9236c9f..3f3d16f 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/AutomatonStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/AutomatonStage.java
@@ -17,18 +17,18 @@
 * limitations under the License.
 */
 
-import java.io.IOException;
-import java.io.Reader;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.TermToBytesRefAttribute;
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.automaton.Automaton;
 import org.apache.lucene.util.automaton.State;
 import org.apache.lucene.util.automaton.Transition;
 
+import java.io.IOException;
+import java.io.Reader;
+import java.util.HashMap;
+import java.util.Map;
+
 /** Pass-through stage that builds an Automaton from the
  *  input tokens it sees. */
 
@@ -44,12 +44,12 @@
   private Map<Integer,State> toStates;
   private Map<Integer,State> fromStates;
   private final ArcAttribute arcAtt;
-  private final TermToBytesRefAttribute termAtt;
+  private final TermAttribute termAtt;
 
   public AutomatonStage(Stage prevStage) {
     super(prevStage);
     arcAtt = prevStage.get(ArcAttribute.class);
-    termAtt = prevStage.get(TermToBytesRefAttribute.class);
+    termAtt = prevStage.get(TermAttribute.class);
   }
 
   @Override
@@ -96,20 +96,19 @@
   @Override
   public boolean next() throws IOException {
     if (prevStage.next()) {
-      BytesRef term = termAtt.getBytesRef();
-      termAtt.fillBytesRef();
-      if (term.length == 0) {
+      String term = termAtt.get();
+      if (term.length() == 0) {
         throw new IllegalStateException("cannot handle empty-string term");
       }
       State lastState = getFromState(arcAtt.from());
-      for(int i=0;i<term.length;i++) {
+      for(int i=0;i<term.length();i++) {
         State toState;
-        if (i == term.length-1) {
+        if (i == term.length()-1) {
           toState = getToState(arcAtt.to());
         } else {
           toState = new State();
         }
-        lastState.addTransition(new Transition(term.bytes[term.offset + i], toState));
+        lastState.addTransition(new Transition(term.charAt(i), toState));
         lastState = toState;
       }    
       return true;
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/CharTokenizerStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/CharTokenizerStage.java
index dce2f0d..08ed514 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/CharTokenizerStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/CharTokenizerStage.java
@@ -17,24 +17,25 @@
  * limitations under the License.
  */
 
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.OffsetAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
+import org.apache.lucene.analysis.util.CharacterUtils.CharacterBuffer;
+import org.apache.lucene.analysis.util.CharacterUtils;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.Attribute;
+import org.apache.lucene.util.Version;
+
 import java.io.IOException;
 import java.io.Reader;
 import java.util.Arrays;
 
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
-import org.apache.lucene.analysis.util.CharacterUtils.CharacterBuffer;
-import org.apache.lucene.analysis.util.CharacterUtils;
-import org.apache.lucene.util.Attribute;
-import org.apache.lucene.util.Version;
-
 public abstract class CharTokenizerStage extends Stage {
   private static final int MAX_WORD_LEN = 255;
   private static final int IO_BUFFER_SIZE = 4096;
 
   private Reader input;
-  private final CharTermAttribute termAtt;
+  private final TermAttribute termAtt;
   private final OffsetAttribute offsetAtt;
   private final ArcAttribute arcAtt;
 
@@ -52,9 +53,11 @@
 
   private int lastNode;
 
+  private char[] buffer = new char[10];
+
   public CharTokenizerStage() {
     super(null);
-    termAtt = create(CharTermAttribute.class);
+    termAtt = create(TermAttribute.class);
     offsetAtt = create(OffsetAttribute.class);
     arcAtt = create(ArcAttribute.class);
   }
@@ -75,7 +78,6 @@
     int length = 0;
     int start = -1; // this variable is always initialized
     int end = -1;
-    char[] buffer = termAtt.buffer();
     while (true) {
       if (bufferIndex >= dataLen) {
         offset += dataLen;
@@ -105,7 +107,7 @@
           start = offset + bufferIndex - charCount;
           end = start;
         } else if (length >= buffer.length-1) { // check if a supplementary could run out of bounds
-          buffer = termAtt.resizeBuffer(2+length); // make sure a supplementary fits in the buffer
+          buffer = ArrayUtil.grow(buffer, 2+length); // make sure a supplementary fits in the buffer
         }
         end += charCount;
         length += Character.toChars(normalize(c), buffer, length); // buffer it, normalized
@@ -117,7 +119,7 @@
       }
     }
 
-    termAtt.setLength(length);
+    termAtt.set(new String(buffer, 0, length));
 
     offsetAtt.setOffset(correctOffset(start), correctOffset(start+length));
 
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/InsertDeletedPunctuationStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/InsertDeletedPunctuationStage.java
index 20c8e1e..d4a3f8c 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/InsertDeletedPunctuationStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/InsertDeletedPunctuationStage.java
@@ -17,18 +17,18 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.io.Reader;
-
 import org.apache.lucene.analysis.CharFilter;
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.DeletedAttribute;
-import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.DeletedAttribute;
+import org.apache.lucene.analysis.stages.attributes.OffsetAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
 import org.apache.lucene.util.ArrayUtil;
 import org.apache.lucene.util.FixedBitSet;
 
-/** Uses a CharFilter to detect when punction occurs in the
+import java.io.IOException;
+import java.io.Reader;
+
+/** Uses a CharFilter to detect when punctuation occurs in the
  *  input in between two tokens, and then as a Stage it will
  *  re-insert [deleted] tokens when it notices the tokenizer
  *  had deleted the punctuation.  E.g. this can be used to
@@ -38,12 +38,12 @@
 
   private final DeletedAttribute delAttIn;
   private final ArcAttribute arcAttIn;
-  private final CharTermAttribute termAttIn;
+  private final TermAttribute termAttIn;
   private final OffsetAttribute offsetAttIn;
 
   private final ArcAttribute arcAttOut;
   private final DeletedAttribute delAttOut;
-  private final CharTermAttribute termAttOut;
+  private final TermAttribute termAttOut;
   private final OffsetAttribute offsetAttOut;
 
   private final String punctToken;
@@ -55,12 +55,12 @@
     delAttIn = prevStage.get(DeletedAttribute.class);
     offsetAttIn = prevStage.get(OffsetAttribute.class);
     arcAttIn = prevStage.get(ArcAttribute.class);
-    termAttIn = prevStage.get(CharTermAttribute.class);
+    termAttIn = prevStage.get(TermAttribute.class);
 
     delAttOut = create(DeletedAttribute.class);
     offsetAttOut = create(OffsetAttribute.class);
     arcAttOut = create(ArcAttribute.class);
-    termAttOut = create(CharTermAttribute.class);
+    termAttOut = create(TermAttribute.class);
   }
 
   private static class FindPunctuationCharFilter extends CharFilter {
@@ -146,8 +146,7 @@
         delAttOut.set(true);
         offsetAttOut.setOffset(lastEndOffset, startOffset);
         // nocommit: should we copy over the actual punct chars...?
-        termAttOut.setEmpty();
-        termAttOut.append(punctToken);
+        termAttOut.set(punctToken);
         nodeOffset++;
       } else {
         copyToken();
@@ -165,8 +164,7 @@
     } else {
       delAttOut.set(false);
     }
-    termAttOut.setEmpty();
-    termAttOut.append(termAttIn);
+    termAttOut.set(termAttIn.get());
     offsetAttOut.setOffset(offsetAttIn.startOffset(), offsetAttIn.endOffset());
     arcAttOut.set(arcAttIn.from()+nodeOffset, arcAttIn.to() + nodeOffset);
   }
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/LowerCaseFilterStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/LowerCaseFilterStage.java
index 29922c0..faf1eeb 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/LowerCaseFilterStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/LowerCaseFilterStage.java
@@ -19,37 +19,36 @@
 
 import java.io.IOException;
 
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttributeImpl;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
 import org.apache.lucene.analysis.util.CharacterUtils;
 import org.apache.lucene.util.Attribute;
 import org.apache.lucene.util.Version;
 
 public class LowerCaseFilterStage extends Stage {
   private final CharacterUtils charUtils;
-  private final CharTermAttribute termAttOut;
-  private final CharTermAttribute termAttIn;
+  private final TermAttribute termAttOut;
+  private final TermAttribute termAttIn;
 
   public LowerCaseFilterStage(Version version, Stage prevStage) {
     super(prevStage);
     charUtils = CharacterUtils.getInstance(version);
-    termAttIn = prevStage.get(CharTermAttribute.class);
-    termAttOut = create(CharTermAttribute.class);
+    termAttIn = prevStage.get(TermAttribute.class);
+    termAttOut = create(TermAttribute.class);
   }
   
   @Override
   public final boolean next() throws IOException {
     if (prevStage.next()) {
-      final char[] buffer = termAttIn.buffer();
-      final int length = termAttIn.length();
-      final char[] bufferOut = termAttOut.resizeBuffer(length);
+      final String term = termAttIn.get();
+      int length = term.length();
+      final char[] bufferOut = new char[length];
       for (int i = 0; i < length;) {
         // nocommit correct?
         i += Character.toChars(
                 Character.toLowerCase(
-                   charUtils.codePointAt(buffer, i, length)), bufferOut, i);
+                   charUtils.codePointAt(term, i)), bufferOut, i);
       }
-      termAttOut.setLength(length);
+      termAttOut.set(new String(bufferOut));
       return true;
     } else {
       return false;
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SplitOnDashFilterStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SplitOnDashFilterStage.java
index 88c4c01..1b81264 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SplitOnDashFilterStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SplitOnDashFilterStage.java
@@ -17,23 +17,21 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.io.Reader;
-
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.ArcAttributeImpl;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttributeImpl;
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
 import org.apache.lucene.analysis.util.CharacterUtils;
 import org.apache.lucene.util.Attribute;
 
+import java.io.IOException;
+import java.io.Reader;
+
 /** Simple example of decompounder-as-filter, just dividing
  *  a word at its dashes and keeping the original. */
 public class SplitOnDashFilterStage extends Stage {
 
   // We change the term:
-  private final CharTermAttribute termAttIn;
-  private final CharTermAttribute termAttOut;
+  private final TermAttribute termAttIn;
+  private final TermAttribute termAttOut;
 
   // We change the to/from:
   private final ArcAttribute arcAttIn;
@@ -44,8 +42,8 @@
 
   public SplitOnDashFilterStage(Stage prevStage) {
     super(prevStage);
-    termAttIn = prevStage.get(CharTermAttribute.class);
-    termAttOut = create(CharTermAttribute.class);
+    termAttIn = prevStage.get(TermAttribute.class);
+    termAttOut = create(TermAttribute.class);
     arcAttIn = prevStage.get(ArcAttribute.class);
     arcAttOut = create(ArcAttribute.class);
   }
@@ -60,8 +58,7 @@
   public boolean next() throws IOException {
     if (parts != null) {
 
-      termAttOut.setEmpty();
-      termAttOut.append(parts[nextPart]);
+      termAttOut.set(parts[nextPart]);
       int from;
       if (nextPart == 0) {
         from = arcAttIn.from();
@@ -90,8 +87,7 @@
     if (prevStage.next()) {
 
       // nocommit copyTo?
-      termAttOut.setEmpty();
-      termAttOut.append(termAttIn);
+      termAttOut.set(termAttIn.get());
       arcAttOut.set(arcAttIn.from(), arcAttIn.to());
       
       parts = termAttIn.toString().split("-");
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/Stage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/Stage.java
index f6c5d87..c842355 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/Stage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/Stage.java
@@ -37,17 +37,8 @@
   // stages:
   protected final NodeTracker nodes;
 
-  // nocommit is all this hair really worth the separation
-  // of interface from impl?  can we just have concrete
-  // attrs?
-
-  private static final WeakIdentityMap<Class<? extends Attribute>, WeakReference<Class<? extends AttributeImpl>>> attClassImplMap =
-    WeakIdentityMap.newConcurrentHashMap(false);
-
-
   /** Which Attributes this stage defines */
-  private final Map<Class<? extends AttributeImpl>, AttributeImpl> attImpls = new LinkedHashMap<Class<? extends AttributeImpl>, AttributeImpl>();
-  private final Map<Class<? extends Attribute>, AttributeImpl> atts = new LinkedHashMap<Class<? extends Attribute>, AttributeImpl>();
+  private final Map<Class<? extends Attribute>, Attribute> atts = new LinkedHashMap<Class<? extends Attribute>, Attribute>();
 
   protected Stage(Stage prevStage) {
     this.prevStage = prevStage;
@@ -58,112 +49,30 @@
     }
   }
 
-  /** a cache that stores all interfaces for known implementation classes for performance (slow reflection) */
-  private static final WeakIdentityMap<Class<? extends AttributeImpl>,LinkedList<WeakReference<Class<? extends Attribute>>>> knownImplClasses =
-    WeakIdentityMap.newConcurrentHashMap(false);
-  
-  static LinkedList<WeakReference<Class<? extends Attribute>>> getAttributeInterfaces(final Class<? extends AttributeImpl> clazz) {
-    LinkedList<WeakReference<Class<? extends Attribute>>> foundInterfaces = knownImplClasses.get(clazz);
-    if (foundInterfaces == null) {
-      // we have the slight chance that another thread may do the same, but who cares?
-      foundInterfaces = new LinkedList<WeakReference<Class<? extends Attribute>>>();
-      // find all interfaces that this attribute instance implements
-      // and that extend the Attribute interface
-      Class<?> actClazz = clazz;
-      do {
-        for (Class<?> curInterface : actClazz.getInterfaces()) {
-          if (curInterface != Attribute.class && Attribute.class.isAssignableFrom(curInterface)) {
-            foundInterfaces.add(new WeakReference<Class<? extends Attribute>>(curInterface.asSubclass(Attribute.class)));
-          }
-        }
-        actClazz = actClazz.getSuperclass();
-      } while (actClazz != null);
-      knownImplClasses.put(clazz, foundInterfaces);
-    }
-    return foundInterfaces;
-  }
-
-  /** <b>Expert:</b> Adds a custom AttributeImpl instance with one or more Attribute interfaces.
-   * <p><font color="red"><b>Please note:</b> It is not guaranteed, that <code>att</code> is added to
-   * the <code>AttributeSource</code>, because the provided attributes may already exist.
-   * You should always retrieve the wanted attributes using {@link #getAttribute} after adding
-   * with this method and cast to your class.
-   * The recommended way to use custom implementations is using an {@link AttributeFactory}.
-   * </font></p>
-   */
-  public final void addAttributeImpl(final AttributeImpl att) {
-    final Class<? extends AttributeImpl> clazz = att.getClass();
-    if (attImpls.containsKey(clazz)) return;
-    
-    // add all interfaces of this AttributeImpl to the maps
-    for (WeakReference<Class<? extends Attribute>> curInterfaceRef : getAttributeInterfaces(clazz)) {
-      final Class<? extends Attribute> curInterface = curInterfaceRef.get();
-      assert (curInterface != null) :
-        "We have a strong reference on the class holding the interfaces, so they should never get evicted";
-      // Attribute is a superclass of this interface
-      if (!atts.containsKey(curInterface)) {
-        atts.put(curInterface, att);
-        attImpls.put(clazz, att);
-      }
-    }
-  }
-  
-  private static Class<? extends AttributeImpl> getClassForInterface(Class<? extends Attribute> attClass) {
-    final WeakReference<Class<? extends AttributeImpl>> ref = attClassImplMap.get(attClass);
-    Class<? extends AttributeImpl> clazz = (ref == null) ? null : ref.get();
-    if (clazz == null) {
-      // we have the slight chance that another thread may do the same, but who cares?
-      try {
-        attClassImplMap.put(attClass,
-                            new WeakReference<Class<? extends AttributeImpl>>(
-                                clazz = Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader())
-                                .asSubclass(AttributeImpl.class))
-                            );
-      } catch (ClassNotFoundException e) {
-        throw new IllegalArgumentException("Could not find implementing class for " + attClass.getName());
-      }
-    }
-    return clazz;
-  }
-
-  /**
-   * The caller must pass in a Class&lt;? extends Attribute&gt; value.
-   * This method first checks if an instance of that class is 
-   * already in this AttributeSource and returns it. Otherwise a
-   * new instance is created, added to this AttributeSource and returned. 
-   */
   protected final <A extends Attribute> A create(Class<A> attClass) {
-    AttributeImpl attImpl = atts.get(attClass);
-    if (attImpl == null) {
-      if (!(attClass.isInterface() && Attribute.class.isAssignableFrom(attClass))) {
-        throw new IllegalArgumentException(
-          "addAttribute() only accepts an interface that extends Attribute, but " +
-          attClass.getName() + " does not fulfil this contract."
-        );
-      }
-
+    Attribute att = atts.get(attClass);
+    if (att == null) {
       try {
-        attImpl = getClassForInterface(attClass).newInstance();
+        att = attClass.newInstance();
       } catch (InstantiationException e) {
         throw new IllegalArgumentException("Could not instantiate implementing class for " + attClass.getName());
       } catch (IllegalAccessException e) {
         throw new IllegalArgumentException("Could not instantiate implementing class for " + attClass.getName());
       }
 
-      addAttributeImpl(attImpl);
-      return attClass.cast(attImpl);
+      atts.put(attClass, att);
+      return attClass.cast(att);
     } else {
       throw new IllegalArgumentException(attClass + " was already added");
     }
   }
 
   public final <A extends Attribute> A get(Class<A> attClass) {
-    AttributeImpl attImpl = atts.get(attClass);
+    Attribute attImpl = atts.get(attClass);
     if (attImpl == null) {
       if (prevStage != null) {
         return prevStage.get(attClass);
       } else {
-        //throw new IllegalArgumentException("This AttributeSource does not have the attribute '" + attClass.getName() + "'.");
         return null;
       }
     }
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StageToTokenStream.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StageToTokenStream.java
index e9bbe7f..a9f6e91 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StageToTokenStream.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StageToTokenStream.java
@@ -17,20 +17,20 @@
  * limitations under the License.
  */
 
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.DeletedAttribute;
+import org.apache.lucene.analysis.stages.attributes.OffsetAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.util.ArrayUtil;
+
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
-import org.apache.lucene.analysis.TokenStream;
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.DeletedAttribute;
-import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
-import org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute;
-import org.apache.lucene.util.ArrayUtil;
-
 // TODO
 //   - is there an adversary here?  that can cause
 //     indefinite buffering?
@@ -41,21 +41,27 @@
 // current indexer ... eg use captureState/restoreState to
 // pass through any custom atts too
 
-/** Takes a Stage as input and produces a TokenStream as
- *  output that can be consumed for indexing.  This is not
- *  general purpose: it currently only sets the attributes
- *  that the (core, no custom indexing chain) indexer
+/** This is a compatibility class, to map the new {@link Stage} API to
+ *  the legacy {@link TokenStream} API currently used/required by
+ *  consumers like {@link IndexWriter} and query parsers.  It takes
+ *  a {@link Stage} as input and produces a {@link TokenStream} as
+ *  output.  This is not general purpose: it currently only sets
+ *  the attributes that the (core, no custom indexing chain) indexer 
  *  requires. */
+
 public class StageToTokenStream extends TokenStream {
 
-  private final Stage prevStage;
+  // nocommit: cutover to the approach from SausageGraphFilter
+
+  private final Stage stage;
   private final DeletedAttribute delAtt;
-  private final CharTermAttribute termAttIn;
-  private final CharTermAttribute termAttOut;
+  private final TermAttribute termAttIn;
   private final ArcAttribute arcAttIn;
-  private final PositionIncrementAttribute posIncAttOut;
   private final OffsetAttribute offsetAttIn;
-  private final OffsetAttribute offsetAttOut;
+
+  private final org.apache.lucene.analysis.tokenattributes.CharTermAttribute termAttOut;
+  private final org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute posIncAttOut;
+  private final org.apache.lucene.analysis.tokenattributes.OffsetAttribute offsetAttOut;
 
   protected boolean resetCalled;
   protected boolean closeCalled = true;
@@ -99,15 +105,15 @@
     }
   }
 
-  public StageToTokenStream(Stage prevStage) {
-    this.prevStage = prevStage;
-    termAttIn = prevStage.get(CharTermAttribute.class);
-    termAttOut = addAttribute(CharTermAttribute.class);
-    posIncAttOut = addAttribute(PositionIncrementAttribute.class);
-    offsetAttIn = prevStage.get(OffsetAttribute.class);
-    offsetAttOut = addAttribute(OffsetAttribute.class);
-    arcAttIn = prevStage.get(ArcAttribute.class);
-    delAtt = prevStage.get(DeletedAttribute.class);
+  public StageToTokenStream(Stage stage) {
+    this.stage = stage;
+    termAttIn = stage.get(TermAttribute.class);
+    termAttOut = addAttribute(org.apache.lucene.analysis.tokenattributes.CharTermAttribute.class);
+    posIncAttOut = addAttribute(org.apache.lucene.analysis.tokenattributes.PositionIncrementAttribute.class);
+    offsetAttIn = stage.get(OffsetAttribute.class);
+    offsetAttOut = addAttribute(org.apache.lucene.analysis.tokenattributes.OffsetAttribute.class);
+    arcAttIn = stage.get(ArcAttribute.class);
+    delAtt = stage.get(DeletedAttribute.class);
   }
 
   private Node getNode(Map<Integer,Node> nodes, int node) {
@@ -205,8 +211,8 @@
       // buffered token(s) were deleted (holes)
     }
 
-    if (prevStage.next()) {
-      if (prevStage.nodes.anyNodesCanChange()) {
+    if (stage.next()) {
+      if (stage.nodes.anyNodesCanChange()) {
         System.out.println("  now buffer: " + termAttIn);
         Map<Integer,Node> nodes = new HashMap<Integer,Node>();
         nodes.put(arcAttIn.from(), new Node());
@@ -216,14 +222,14 @@
         // until it un-clumps itself:
         saveToken(nodes);
         while (true) {
-          boolean result = prevStage.next();
+          boolean result = stage.next();
           // So long as there are still nodes that can
           // change, there must be more tokens (hmm is this
           // really true...):
           assert result: "Stage.next ended without freezing all nodes";
           saveToken(nodes);
-          System.out.println("  buffer again: " + termAttIn + "; " + prevStage.anyNodesCanChange() + " " + frontierNodeCount);
-          if (!prevStage.anyNodesCanChange() && frontierNodeCount == 1) {
+          System.out.println("  buffer again: " + termAttIn + "; " + stage.anyNodesCanChange() + " " + frontierNodeCount);
+          if (!stage.anyNodesCanChange() && frontierNodeCount == 1) {
             System.out.println("  clump done");
             break;
           }
@@ -247,7 +253,7 @@
         System.out.println("  pass through");
         // Fast path (pass through): no buffering necessary:
         termAttOut.setEmpty();
-        termAttOut.append(termAttIn);
+        termAttOut.append(termAttIn.get());
         offsetAttOut.setOffset(offsetAttIn.startOffset(),
                                offsetAttIn.endOffset());
         posIncAttOut.setPositionIncrement(1 + pendingPosInc);
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StopFilterStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StopFilterStage.java
index 3b55bbc..2f5ee01 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StopFilterStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/StopFilterStage.java
@@ -19,22 +19,22 @@
 
 import java.io.IOException;
 
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.DeletedAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
+import org.apache.lucene.analysis.stages.attributes.DeletedAttribute;
 import org.apache.lucene.analysis.util.CharArraySet;
 
 /** Marks stop words as deleted */
 public class StopFilterStage extends Stage {
 
   private final CharArraySet stopWords;
-  private final CharTermAttribute termAtt;
+  private final TermAttribute termAtt;
   private final DeletedAttribute delAttIn;
   private final DeletedAttribute delAttOut;
 
   public StopFilterStage(Stage prevStage, CharArraySet stopWords) {
     super(prevStage);
     this.stopWords = stopWords;
-    termAtt = prevStage.get(CharTermAttribute.class);
+    termAtt = prevStage.get(TermAttribute.class);
     delAttIn = prevStage.get(DeletedAttribute.class);
     delAttOut = create(DeletedAttribute.class);
   }
@@ -42,7 +42,7 @@
   @Override
   public boolean next() throws IOException {
     if (prevStage.next()) {
-      if ((delAttIn != null && delAttIn.deleted()) || stopWords.contains(termAtt.buffer(), 0, termAtt.length())) {
+      if ((delAttIn != null && delAttIn.deleted()) || stopWords.contains(termAtt.get())) {
         delAttOut.set(true);
       } else {
         delAttOut.set(false);
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SynonymFilterStage.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SynonymFilterStage.java
index 42ccb62..fa236d3 100644
--- a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SynonymFilterStage.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/SynonymFilterStage.java
@@ -17,16 +17,10 @@
  * limitations under the License.
  */
 
-import java.io.IOException;
-import java.io.Reader;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.OffsetAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
 import org.apache.lucene.analysis.synonym.SynonymMap;
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
 import org.apache.lucene.store.ByteArrayDataInput;
 import org.apache.lucene.util.Attribute;
 import org.apache.lucene.util.BytesRef;
@@ -34,6 +28,12 @@
 import org.apache.lucene.util.UnicodeUtil;
 import org.apache.lucene.util.fst.FST;
 
+import java.io.IOException;
+import java.io.Reader;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
 // nocommit does not do keepOrig
 
 // nocommit should we ... allow recursing on ourselves?  ie
@@ -47,8 +47,8 @@
 public class SynonymFilterStage extends Stage {
 
   // We change the term:
-  private final CharTermAttribute termAttIn;
-  private final CharTermAttribute termAttOut;
+  private final TermAttribute termAttIn;
+  private final TermAttribute termAttOut;
 
   // We change the to/from:
   private final ArcAttribute arcAttIn;
@@ -113,8 +113,8 @@
 
   public SynonymFilterStage(Stage prevStage, SynonymMap synonyms, boolean ignoreCase) {
     super(prevStage);
-    termAttIn = prevStage.get(CharTermAttribute.class);
-    termAttOut = create(CharTermAttribute.class);
+    termAttIn = prevStage.get(TermAttribute.class);
+    termAttOut = create(TermAttribute.class);
     arcAttIn = prevStage.get(ArcAttribute.class);
     arcAttOut = create(ArcAttribute.class);
     offsetAttIn = prevStage.get(OffsetAttribute.class);
@@ -151,11 +151,10 @@
       output = fst.outputs.getNoOutput();
     }
 
-    char[] buffer = termAttIn.buffer();
-    int bufferLen = termAttIn.length();
+    int bufferLen = termAttIn.get().length();
     int bufUpto = 0;
     while(bufUpto < bufferLen) {
-      final int codePoint = Character.codePointAt(buffer, bufUpto, bufferLen);
+      final int codePoint = Character.codePointAt(termAttIn.get(), bufUpto);
       if (fst.findTargetArc(ignoreCase ? Character.toLowerCase(codePoint) : codePoint, scratchArc, scratchArc, fstReader) == null) {
         return;
       }
@@ -297,8 +296,7 @@
     if (token != null) {
       //System.out.println("  insert output token! text=" + token.text + " offset=" + token.startOffset + "/" + token.endOffset);
       // We still have outputs pending from previous match:
-      termAttOut.setEmpty();
-      termAttOut.append(token.text);
+      termAttOut.set(token.text);
       offsetAttOut.setOffset(token.startOffset, token.endOffset);
       arcAttOut.set(token.fromNode, token.toNode);
       return true;
@@ -319,8 +317,7 @@
       match();
       
       // nocommit copy?
-      termAttOut.setEmpty();
-      termAttOut.append(termAttIn);
+      termAttOut.set(termAttIn.get());
 
       offsetAttOut.setOffset(offsetAttIn.startOffset(),
                              offsetAttIn.endOffset());
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/ArcAttributeImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/ArcAttribute.java
similarity index 72%
rename from lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/ArcAttributeImpl.java
rename to lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/ArcAttribute.java
index 48382bf..994fe7f 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/ArcAttributeImpl.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/ArcAttribute.java
@@ -1,4 +1,4 @@
-package org.apache.lucene.analysis.tokenattributes;
+package org.apache.lucene.analysis.stages.attributes;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,33 +17,28 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.Attribute;
 
-/** Default implementation of {@link ArcAttribute}. */
-public class ArcAttributeImpl extends AttributeImpl implements ArcAttribute, Cloneable {
+public class ArcAttribute implements Attribute, Cloneable {
   private int from;
   private int to;
   
-  /** Initialize this attribute with from=0, to=0. */
-  public ArcAttributeImpl() {}
+  public ArcAttribute() {
+  }
 
-  @Override
   public int from() {
     return from;
   }
 
-  @Override
   public int to() {
     return to;
   }
 
-  @Override
   public void set(int from, int to) {
     this.from = from;
     this.to = to;
   }
 
-  @Override
   public void clear() {
     from = 0;
     to = 0;
@@ -55,8 +50,8 @@
       return true;
     }
     
-    if (other instanceof ArcAttributeImpl) {
-      ArcAttributeImpl o = (ArcAttributeImpl) other;
+    if (other instanceof ArcAttribute) {
+      ArcAttribute o = (ArcAttribute) other;
       return o.from == from && o.to == to;
     }
     
@@ -70,8 +65,7 @@
     return code;
   } 
   
-  @Override
-  public void copyTo(AttributeImpl target) {
+  public void copyTo(Attribute target) {
     ArcAttribute t = (ArcAttribute) target;
     t.set(from, to);
   }  
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/DeletedAttributeImpl.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/DeletedAttribute.java
similarity index 72%
rename from lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/DeletedAttributeImpl.java
rename to lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/DeletedAttribute.java
index b32fe91..c7db32d 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/DeletedAttributeImpl.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/DeletedAttribute.java
@@ -1,4 +1,4 @@
-package org.apache.lucene.analysis.tokenattributes;
+package org.apache.lucene.analysis.stages.attributes;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -17,25 +17,22 @@
  * limitations under the License.
  */
 
-import org.apache.lucene.util.AttributeImpl;
+import org.apache.lucene.util.Attribute;
 
-/** Default implementation of {@link DeletedAttribute}. */
-public class DeletedAttributeImpl extends AttributeImpl implements DeletedAttribute, Cloneable {
+public class DeletedAttribute implements Attribute, Cloneable {
   private boolean deleted;
   
-  public DeletedAttributeImpl() {}
+  public DeletedAttribute() {
+  }
 
-  @Override
   public boolean deleted() {
     return deleted;
   }
 
-  @Override
   public void set(boolean deleted) {
     this.deleted = deleted;
   }
 
-  @Override
   public void clear() {
     deleted = false;
   }
@@ -46,8 +43,8 @@
       return true;
     }
     
-    if (other instanceof DeletedAttributeImpl) {
-      DeletedAttributeImpl o = (DeletedAttributeImpl) other;
+    if (other instanceof DeletedAttribute) {
+      DeletedAttribute o = (DeletedAttribute) other;
       return o.deleted == deleted;
     }
     
@@ -59,8 +56,7 @@
     return deleted ? 31 : 57;
   } 
   
-  @Override
-  public void copyTo(AttributeImpl target) {
+  public void copyTo(Attribute target) {
     DeletedAttribute t = (DeletedAttribute) target;
     t.set(deleted);
   }  
diff --git a/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/OffsetAttribute.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/OffsetAttribute.java
new file mode 100644
index 0000000..64c7d98
--- /dev/null
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/OffsetAttribute.java
@@ -0,0 +1,87 @@
+package org.apache.lucene.analysis.stages.attributes;
+
+/*
+ * 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 org.apache.lucene.util.Attribute;
+
+public class OffsetAttribute implements Attribute, Cloneable {
+  private int startOffset;
+  private int endOffset;
+  
+  /** Initialize this attribute with startOffset and endOffset of 0. */
+  public OffsetAttribute() {
+  }
+
+  public int startOffset() {
+    return startOffset;
+  }
+
+  public void setOffset(int startOffset, int endOffset) {
+
+    // TODO: we could assert that this is set-once, ie,
+    // current values are -1?  Very few token filters should
+    // change offsets once set by the tokenizer... and
+    // tokenizer should call clearAtts before re-using
+    // OffsetAtt
+
+    if (startOffset < 0 || endOffset < startOffset) {
+      throw new IllegalArgumentException("startOffset must be non-negative, and endOffset must be >= startOffset, "
+          + "startOffset=" + startOffset + ",endOffset=" + endOffset);
+    }
+
+    this.startOffset = startOffset;
+    this.endOffset = endOffset;
+  }
+  
+  public int endOffset() {
+    return endOffset;
+  }
+
+  public void clear() {
+    // TODO: we could use -1 as default here?  Then we can
+    // assert in setOffset...
+    startOffset = 0;
+    endOffset = 0;
+  }
+  
+  @Override
+  public boolean equals(Object other) {
+    if (other == this) {
+      return true;
+    }
+    
+    if (other instanceof OffsetAttribute) {
+      OffsetAttribute o = (OffsetAttribute) other;
+      return o.startOffset == startOffset && o.endOffset == endOffset;
+    }
+    
+    return false;
+  }
+
+  @Override
+  public int hashCode() {
+    int code = startOffset;
+    code = code * 31 + endOffset;
+    return code;
+  } 
+  
+  public void copyTo(Attribute target) {
+    OffsetAttribute t = (OffsetAttribute) target;
+    t.setOffset(startOffset, endOffset);
+  }  
+}
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/DeletedAttribute.java b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/TermAttribute.java
similarity index 72%
rename from lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/DeletedAttribute.java
rename to lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/TermAttribute.java
index ba5a767..5431a6d 100644
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/DeletedAttribute.java
+++ b/lucene/analysis/common/src/java/org/apache/lucene/analysis/stages/attributes/TermAttribute.java
@@ -1,4 +1,4 @@
-package org.apache.lucene.analysis.tokenattributes;
+package org.apache.lucene.analysis.stages.attributes;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -19,17 +19,20 @@
 
 import org.apache.lucene.util.Attribute;
 
-/**
- * Records that the token is deleted (a hole).
- */
-public interface DeletedAttribute extends Attribute {
-  /** 
-   * Returns deleted
-   */
-  public boolean deleted();
+// TODO: CharSequence again?
+public class TermAttribute implements Attribute {
+  private String term;
 
-  /** 
-   * Set deleted
-   */
-  public void set(boolean deleted);
+  public void set(String term) {
+    this.term = term;
+  }
+
+  public String get() {
+    return term;
+  }
+
+  @Override
+  public String toString() {
+    return term;
+  }
 }
diff --git a/lucene/analysis/common/src/test/org/apache/lucene/analysis/stages/AssertingStage.java b/lucene/analysis/common/src/test/org/apache/lucene/analysis/stages/AssertingStage.java
index a90761c..09b0adb 100644
--- a/lucene/analysis/common/src/test/org/apache/lucene/analysis/stages/AssertingStage.java
+++ b/lucene/analysis/common/src/test/org/apache/lucene/analysis/stages/AssertingStage.java
@@ -17,17 +17,17 @@
  * limitations under the License.
  */
 
+import org.apache.lucene.analysis.stages.attributes.ArcAttribute;
+import org.apache.lucene.analysis.stages.attributes.TermAttribute;
+
 import java.io.IOException;
 import java.io.Reader;
 import java.util.HashSet;
 import java.util.Set;
 
-import org.apache.lucene.analysis.tokenattributes.ArcAttribute;
-import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
-
 class AssertingStage extends Stage {
   final ArcAttribute arcAtt;
-  final CharTermAttribute termAtt;
+  final TermAttribute termAtt;
   private int lastFrom;
   private int lastTo;
 
@@ -37,7 +37,7 @@
   public AssertingStage(Stage prevStage) {
     super(prevStage);
     arcAtt = prevStage.get(ArcAttribute.class);
-    termAtt = prevStage.get(CharTermAttribute.class);
+    termAtt = prevStage.get(TermAttribute.class);
   }
 
   @Override
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectDocValuesProducer.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectDocValuesProducer.java
index 32cd3b9..d7defa9 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectDocValuesProducer.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/DirectDocValuesProducer.java
@@ -106,9 +106,9 @@
     }
 
     success = false;
+    String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
+    data = state.directory.openInput(dataName, state.context);
     try {
-      String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
-      data = state.directory.openInput(dataName, state.context);
       final int version2 = CodecUtil.checkHeader(data, dataCodec, 
                                                  VERSION_START,
                                                  VERSION_CURRENT);
diff --git a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
index 815bad5..ec85b78 100644
--- a/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
+++ b/lucene/codecs/src/java/org/apache/lucene/codecs/memory/MemoryDocValuesProducer.java
@@ -127,9 +127,9 @@
     }
 
     success = false;
+    String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
+    data = state.directory.openInput(dataName, state.context);
     try {
-      String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
-      data = state.directory.openInput(dataName, state.context);
       final int version2 = CodecUtil.checkHeader(data, dataCodec, 
                                                  VERSION_START,
                                                  VERSION_CURRENT);
diff --git a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/ArcAttribute.java b/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/ArcAttribute.java
deleted file mode 100644
index 2d660b0..0000000
--- a/lucene/core/src/java/org/apache/lucene/analysis/tokenattributes/ArcAttribute.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package org.apache.lucene.analysis.tokenattributes;
-
-/*
- * 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 org.apache.lucene.util.Attribute;
-
-/**
- * The from/to nodes for a token: every token is one edge in
- * the growing graph.  All leaving tokens for a given node
- * must be enumerated at once; once the tokenizer moves
- * beyond that node then it's done.  Nodes are numbered with
- * integers, but these are not positions!  Positions are
- * assigned at the end of tokenization.
- */
-public interface ArcAttribute extends Attribute {
-  /** 
-   * Returns this Token's from node.
-   */
-  public int from();
-
-  /** 
-   * Returns this Token's to node.
-   */
-  public int to();
-
-  /** 
-   * Set the dest.
-   */
-  public void set(int from, int to);
-}
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene42/Lucene42DocValuesProducer.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene42/Lucene42DocValuesProducer.java
index d38fff0..969ab18 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene42/Lucene42DocValuesProducer.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene42/Lucene42DocValuesProducer.java
@@ -127,9 +127,9 @@
     }
 
     success = false;
+    String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
+    data = state.directory.openInput(dataName, state.context);
     try {
-      String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
-      data = state.directory.openInput(dataName, state.context);
       final int version2 = CodecUtil.checkHeader(data, dataCodec, 
                                                  VERSION_START,
                                                  VERSION_CURRENT);
diff --git a/lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java b/lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java
index 54a75d5..a4d92cf 100644
--- a/lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java
+++ b/lucene/core/src/java/org/apache/lucene/codecs/lucene45/Lucene45DocValuesProducer.java
@@ -128,9 +128,9 @@
     }
 
     success = false;
+    String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
+    data = state.directory.openInput(dataName, state.context);
     try {
-      String dataName = IndexFileNames.segmentFileName(state.segmentInfo.name, state.segmentSuffix, dataExtension);
-      data = state.directory.openInput(dataName, state.context);
       final int version2 = CodecUtil.checkHeader(data, dataCodec, 
                                                  Lucene45DocValuesFormat.VERSION_START,
                                                  Lucene45DocValuesFormat.VERSION_CURRENT);