Index: contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java
===================================================================
--- contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java	(revision 764343)
+++ contrib/queries/src/java/org/apache/lucene/search/trie/TrieUtils.java	(working copy)
@@ -18,6 +18,8 @@
  */
 
 import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.ValueSource;
+import org.apache.lucene.search.CachingValueSource;
 import org.apache.lucene.search.FieldCache;
 import org.apache.lucene.search.ExtendedFieldCache;
 
@@ -64,57 +66,12 @@
 
   /** internal: maximum needed <code>char[]</code> buffer size for encoding */
   static final int INT_BUF_SIZE = 31/7 + 2;
-
-  /**
-   * A parser instance for filling a {@link ExtendedFieldCache}, that parses prefix encoded fields as longs.
-   */
-  public static final ExtendedFieldCache.LongParser FIELD_CACHE_LONG_PARSER=new ExtendedFieldCache.LongParser(){
-    public final long parseLong(final String val) {
-      final int shift = val.charAt(0)-SHIFT_START_LONG;
-      if (shift>0 && shift<=63)
-        throw new FieldCache.StopFillCacheException();
-      return prefixCodedToLong(val);
-    }
-  };
   
   /**
-   * A parser instance for filling a {@link FieldCache}, that parses prefix encoded fields as ints.
+   * A value source for the field cache, that parses prefix encoded fields.
    */
-  public static final FieldCache.IntParser FIELD_CACHE_INT_PARSER=new FieldCache.IntParser(){
-    public final int parseInt(final String val) {
-      final int shift = val.charAt(0)-SHIFT_START_INT;
-      if (shift>0 && shift<=31)
-        throw new FieldCache.StopFillCacheException();
-      return prefixCodedToInt(val);
-    }
-  };
+  public static final ValueSource TRIE_VALUE_SOURCE = new CachingValueSource(new TrieValueSource());
 
-  /**
-   * A parser instance for filling a {@link ExtendedFieldCache}, that parses prefix encoded fields as doubles.
-   * This uses {@link #sortableLongToDouble} to convert the encoded long to a double.
-   */
-  public static final ExtendedFieldCache.DoubleParser FIELD_CACHE_DOUBLE_PARSER=new ExtendedFieldCache.DoubleParser(){
-    public final double parseDouble(final String val) {
-      final int shift = val.charAt(0)-SHIFT_START_LONG;
-      if (shift>0 && shift<=63)
-        throw new FieldCache.StopFillCacheException();
-      return sortableLongToDouble(prefixCodedToLong(val));
-    }
-  };
-  
-  /**
-   * A parser instance for filling a {@link FieldCache}, that parses prefix encoded fields as floats.
-   * This uses {@link #sortableIntToFloat} to convert the encoded int to a float.
-   */
-  public static final FieldCache.FloatParser FIELD_CACHE_FLOAT_PARSER=new FieldCache.FloatParser(){
-    public final float parseFloat(final String val) {
-      final int shift = val.charAt(0)-SHIFT_START_INT;
-      if (shift>0 && shift<=31)
-        throw new FieldCache.StopFillCacheException();
-      return sortableIntToFloat(prefixCodedToInt(val));
-    }
-  };
-  
   /** internal */
   static int longToPrefixCoded(final long val, final int shift, final char[] buffer) {
     int nChars = (63-shift)/7 + 1, len = nChars+1;
@@ -291,12 +248,12 @@
 
   /** A factory method, that generates a {@link SortField} instance for sorting prefix encoded long values. */
   public static SortField getLongSortField(final String field, final boolean reverse) {
-    return new SortField(field, FIELD_CACHE_LONG_PARSER, reverse);
+    return new SortField(field, SortField.LONG, TRIE_VALUE_SOURCE, reverse);
   }
   
   /** A factory method, that generates a {@link SortField} instance for sorting prefix encoded int values. */
   public static SortField getIntSortField(final String field, final boolean reverse) {
-    return new SortField(field, FIELD_CACHE_INT_PARSER, reverse);
+    return new SortField(field, SortField.INT, TRIE_VALUE_SOURCE, reverse);
   }
 
   /**
Index: contrib/queries/src/java/org/apache/lucene/search/trie/TrieValueSource.java
===================================================================
--- contrib/queries/src/java/org/apache/lucene/search/trie/TrieValueSource.java	(revision 0)
+++ contrib/queries/src/java/org/apache/lucene/search/trie/TrieValueSource.java	(revision 0)
@@ -0,0 +1,115 @@
+package org.apache.lucene.search.trie;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.ValueSource;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.index.TermEnum;
+
+public class TrieValueSource extends ValueSource {
+
+  public double[] getDoubles(final IndexReader reader, String field) throws IOException {
+    final double[] retArray = new double[reader.maxDoc()];
+    new TrieUninverter() {
+      private double doubleVal;
+
+      protected void handleDoc(int index) {
+        retArray[index] = doubleVal;
+      }
+
+      protected boolean newTerm(String value) {
+        final int shift = value.charAt(0)-TrieUtils.SHIFT_START_LONG;
+        if (shift>0 && shift<=63) return true;
+        this.doubleVal = TrieUtils.sortableLongToDouble(TrieUtils.prefixCodedToLong(value));
+        return false;
+      }
+    }.go(reader, field);
+    return retArray;
+  }
+
+  public float[] getFloats(final IndexReader reader, String field) throws IOException {
+    final float[] retArray = new float[reader.maxDoc()];
+    new TrieUninverter() {
+      private float floatVal;
+
+      protected void handleDoc(int index) {
+        retArray[index] = floatVal;
+      }
+
+      protected boolean newTerm(String value) {
+        final int shift = value.charAt(0)-TrieUtils.SHIFT_START_INT;
+        if (shift>0 && shift<=63) return true;
+        this.floatVal = TrieUtils.sortableIntToFloat(TrieUtils.prefixCodedToInt(value));
+        return false;
+      }
+    }.go(reader, field);
+    return retArray;
+  }
+
+  public int[] getInts(final IndexReader reader, String field) throws IOException {
+    final int[] retArray = new int[reader.maxDoc()];
+    new TrieUninverter() {
+      private int intVal;
+
+      protected void handleDoc(int index) {
+        retArray[index] = intVal;
+      }
+
+      protected boolean newTerm(String value) {
+        final int shift = value.charAt(0)-TrieUtils.SHIFT_START_INT;
+        if (shift>0 && shift<=31) return true;
+        this.intVal = TrieUtils.prefixCodedToInt(value);
+        return false;
+      }
+    }.go(reader, field);
+    return retArray;
+  }
+
+  public long[] getLongs(final IndexReader reader, String field) throws IOException {
+    final long[] retArray = new long[reader.maxDoc()];
+    new TrieUninverter() {
+      private long longVal;
+
+      protected void handleDoc(int index) {
+        retArray[index] = longVal;
+      }
+
+      protected boolean newTerm(String value) {
+        final int shift = value.charAt(0)-TrieUtils.SHIFT_START_LONG;
+        if (shift>0 && shift<=63) return true;
+        this.longVal = TrieUtils.prefixCodedToLong(value);
+        return false;
+      }
+    }.go(reader, field);
+    return retArray;
+  }
+
+  protected static abstract class TrieUninverter {
+    public void go(IndexReader reader, String field) throws IOException {
+      TermDocs termDocs = reader.termDocs();
+      TermEnum termEnum = reader.terms(new Term(field, ""));
+      try {
+        do {
+          Term term = termEnum.term();
+          if (term == null || term.field() != field)
+            break;
+          if (newTerm(term.text())) break;
+          termDocs.seek(termEnum);
+          while (termDocs.next()) {
+            handleDoc(termDocs.doc());
+          }
+        } while (termEnum.next());
+      } finally {
+        termDocs.close();
+        termEnum.close();
+      }
+    }
+
+    protected abstract void handleDoc(int docID);
+
+    /** returns true, if parsing should be stopped */
+    protected abstract boolean newTerm(String text);
+  }
+}
