Index: lucene/misc/src/java/org/apache/lucene/index/sorter/Doc.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/Doc.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/Doc.java	(working copy)
@@ -0,0 +1,54 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.Arrays;
+
+/**
+ *  This class represents a document that is to be sorted in the index.
+ *  @param <T> A comparable  type according to which the document should be sorted.  
+ *  
+ * @lucene.experimental
+ */
+
+public class Doc<T extends Comparable<T>> implements Comparable<Doc<T>> {
+  private final T comparable;
+  private final int id;
+
+  /** Returns a permutation on the list of documents from their id's to 
+   *  their order when sorted according to T */
+  public static int[] old2new(final Doc<?>[] docs) {
+    Arrays.sort(docs);
+    final int[] oldToNew = new int[docs.length];
+    for (int i = 0; i < docs.length; i++)
+      oldToNew[docs[i].id] = i;
+    return oldToNew;
+  }
+
+  public Doc(final T comparable, final int docId) {
+    this.comparable = comparable;
+    this.id = docId;
+  }
+
+  @Override
+  public int compareTo(final Doc<T> doc) {
+    final int compareTo = comparable.compareTo(doc.comparable);
+    if (compareTo != 0) return compareTo;
+    return id - doc.id;
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/DocValuesSorter.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/DocValuesSorter.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/DocValuesSorter.java	(working copy)
@@ -0,0 +1,56 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ *  
+ * A {@link Sorter} which sorts documents according to their DocValues.
+ * 
+ * @lucene.experimental
+ */
+public class DocValuesSorter<T extends Comparable<T>> implements Sorter {
+
+  private final To<BytesRef, T> to;
+  private final String fieldName;
+
+  public DocValuesSorter(final String fieldName, final To<BytesRef, T> to) {
+    this.to = to;
+    this.fieldName = fieldName;
+  }
+
+  @Override
+  public int[] oldToNew(final Directory dir) throws IOException {
+    final DirectoryReader reader = DirectoryReader.open(dir);
+    final AtomicReader atomicReader = new SlowCompositeReaderWrapper(reader); // TODO: consider optimizing later
+    final int maxDoc = reader.maxDoc();
+    final Doc<?>[] docs = new Doc<?>[maxDoc];
+    BytesRef bytes = new BytesRef();
+    for (int i = 0; i < maxDoc; i++) {
+      bytes = atomicReader.docValues(fieldName).getSource().getBytes(i, bytes);
+      docs[i] = new Doc<T>(to.from(bytes), i);
+    }
+    atomicReader.close();
+    return Doc.old2new(docs);
+  }
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/DocumentSorter.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/DocumentSorter.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/DocumentSorter.java	(working copy)
@@ -0,0 +1,48 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.store.Directory;
+
+/**
+ * A {@link Sorter} which sorts documents according to their stored fields.
+ * 
+ * @lucene.experimental
+ */
+public class DocumentSorter<T extends Comparable<T>> implements Sorter {
+
+  private final To<Document, T> to;
+
+  public DocumentSorter(final To<Document, T> to) {
+    this.to = to;
+  }
+
+  @Override
+  public int[] oldToNew(final Directory dir) throws IOException {
+    final DirectoryReader reader = DirectoryReader.open(dir);
+    final int maxDoc = reader.maxDoc();
+    final Doc<?>[] docs = new Doc<?>[maxDoc];
+    for (int i = 0; i < maxDoc; i++)
+      docs[i] = new Doc<T>(to.from(reader.document(i)), i);
+    reader.close();
+    return Doc.old2new(docs);
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/PayloadSorter.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/PayloadSorter.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/PayloadSorter.java	(working copy)
@@ -0,0 +1,58 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.MultiFields;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ * A {@link Sorter} which sorts a document according to it's payload.
+ * 
+ * @lucene.experimental
+ */
+public class PayloadSorter<T extends Comparable<T>> implements Sorter {
+
+  private final To<BytesRef, T> to;
+  private final BytesRef term;
+  private final String field;
+
+  public PayloadSorter(final BytesRef term, final String field, final To<BytesRef, T> to) {
+    this.to = to;
+    this.field = field;
+    this.term = term;
+  }
+
+  @Override
+  public int[] oldToNew(final Directory dir) throws IOException {
+    final DirectoryReader reader = DirectoryReader.open(dir);
+    final DocsAndPositionsEnum it = MultiFields.getTermPositionsEnum(reader, null, field, term);
+    final int maxDoc = reader.maxDoc();
+    final Doc<?>[] docs = new Doc<?>[maxDoc];
+    int i = 0;
+    while (it.nextDoc() != DocsAndPositionsEnum.NO_MORE_DOCS) {
+      it.nextPosition();
+      docs[i] = new Doc<T>(to.from(it.getPayload()), i);
+      i++;
+    }
+    reader.close();
+    return Doc.old2new(docs);
+  }
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/ReverseDocIdSorter.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/ReverseDocIdSorter.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/ReverseDocIdSorter.java	(working copy)
@@ -0,0 +1,41 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.store.Directory;
+
+/**
+ *  A {@link Sorter} which sorts document in a reverse order to their doc id's
+ * 
+ * @lucene.experimental
+ */
+public class ReverseDocIdSorter implements Sorter {
+
+  @Override
+  public int[] oldToNew(final Directory dir) throws IOException {
+    final DirectoryReader reader = DirectoryReader.open(dir);
+    final int maxDoc = reader.maxDoc();
+    int[] reverseDocs = new int[maxDoc];
+    for (int i = 0; i < maxDoc; i++)
+      reverseDocs[i] = maxDoc - (i + 1);
+    reader.close();
+    return reverseDocs;
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/Sorter.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/Sorter.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/Sorter.java	(working copy)
@@ -0,0 +1,31 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.store.Directory;
+/**
+ * An interface for sorting documents in a directory.   
+ * 
+ * @lucene.experimental
+ */
+public interface Sorter {
+  
+  /** Returns a list of document id's of the document in the received directory,
+   * sorted according to their new order. */
+  int[] oldToNew(Directory dir) throws IOException;
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SorterUtil.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SorterUtil.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SorterUtil.java	(working copy)
@@ -0,0 +1,52 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.analysis.standard.StandardAnalyzer;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.Version;
+
+/***
+ * A utility class for index sorting. 
+ * 
+ * @lucene.experimental
+ */
+public class SorterUtil {
+
+  /**
+   * 
+   * @param in A directory of documents to be sorted
+   * @param out The directory to which the sorted documents will be added  
+   * @param sorter An object that knows how to sort the documents. 
+   * @throws IOException
+   */
+  public static void sort(Directory in, Directory out, Sorter sorter) throws IOException {
+    int[] old2new = sorter.oldToNew(in);
+    final IndexWriter writer = new IndexWriter(out, new IndexWriterConfig(Version.LUCENE_40, new StandardAnalyzer(Version.LUCENE_40)));
+    final DirectoryReader reader = DirectoryReader.open(in);
+    final SortingIndexReader sortingReader = new SortingIndexReader(reader, old2new);
+    for (int i = 0; i < old2new.length; i++)
+      writer.addDocument(sortingReader.document(i));
+    sortingReader.close();
+    writer.close();
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocValues.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocValues.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocValues.java	(working copy)
@@ -0,0 +1,65 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.DocValues.Source;
+import org.apache.lucene.index.DocValues.Type;
+
+/**
+ *  Allow {@link DocValues} to be read according to old2new permutation.
+ * 
+ * @lucene.experimental
+ */
+public class SortingDocValues extends DocValues {
+
+  private final DocValues oldDocValues;
+  private final int[] old2new;
+
+  public SortingDocValues(final DocValues oldDocValues, final int[] old2new) {
+    this.oldDocValues = oldDocValues;
+    this.old2new = old2new;
+  }
+
+  @Override
+  public Source getDirectSource() throws IOException {
+    return new SortingSource(oldDocValues.getDirectSource(), old2new);
+  }
+
+  /***
+   *  This operation is not supported.
+   */
+  @Override
+  public Source getSource() throws IOException {
+    throw new UnsupportedOperationException("getSource is not supported");
+  }
+
+  @Override
+  public Type getType() {
+    return oldDocValues.getType();
+  }
+
+  /***
+   *  This operation is not supported.
+   */
+  @Override
+  public Source load() throws IOException {
+    throw new UnsupportedOperationException("load is not supported");
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocsAndPositionsEnum.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocsAndPositionsEnum.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocsAndPositionsEnum.java	(working copy)
@@ -0,0 +1,190 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.store.ByteArrayDataInput;
+import org.apache.lucene.store.ByteArrayDataOutput;
+import org.apache.lucene.store.IOContext;
+import org.apache.lucene.store.IndexInput;
+import org.apache.lucene.store.IndexOutput;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.store.RAMInputStream;
+import org.apache.lucene.store.RAMOutputStream;
+import org.apache.lucene.util.ArrayUtil;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.RamUsageEstimator;
+import sun.jdbc.odbc.OdbcDef;
+/**
+ * 
+ * Allow {@link DocsAndPositionsEnum} to be read according to old2new permutation.
+ * @lucene.experimental
+ */
+public class SortingDocsAndPositionsEnum extends DocsAndPositionsEnum {
+
+	static class Position {
+		final int pos;
+		final int startOffset;
+		final int endOffset;
+		final BytesRef payload;
+
+		public Position(final int pos, final int startOffset, final int endOffset, final BytesRef payload) {
+			this.pos = pos;
+			this.startOffset = startOffset;
+			this.endOffset = endOffset;
+			this.payload = payload;
+		}
+	}
+
+	private static class PostingMap implements Comparable<PostingMap> {
+		private final int newDocId;
+		private final long offset;
+
+		PostingMap(final int newDocId, final long offset) {
+			this.newDocId = newDocId;
+			this.offset = offset;
+		}
+		@Override
+		public int compareTo(PostingMap pm) {              // order by newDoc id
+			return this.newDocId - pm.newDocId;
+		}
+	}
+
+	private static final int OFFSETS_INIT_LENGTH = 0;
+	private static final int OFFSETS_GROW_LENGTH = 1;
+
+	private PostingMap[] postingMaps = new PostingMap[OFFSETS_INIT_LENGTH];
+	private final int upto;
+
+	private static final String TEMP_FILE = "temp";
+	private final RAMDirectory tempDir = new RAMDirectory();
+	private final IndexOutput out;
+	private final IndexInput in;
+
+	int docIt = -1, posIt = -1;
+	private Position currentPosition;
+	private int currFreq;
+
+	public SortingDocsAndPositionsEnum(final DocsAndPositionsEnum oldDocsAndPositions, final int[] old2new) throws IOException {
+		int i = 0;
+		out = tempDir.createOutput(TEMP_FILE, null);
+
+		while (oldDocsAndPositions.nextDoc() != DocsAndPositionsEnum.NO_MORE_DOCS) {
+			if ( i >= postingMaps.length) {
+				PostingMap[] newArray = new PostingMap[ArrayUtil.oversize(
+						postingMaps.length + OFFSETS_GROW_LENGTH, RamUsageEstimator.NUM_BYTES_SHORT)];
+				System.arraycopy(postingMaps, 0, newArray, 0, postingMaps.length);
+				postingMaps = newArray;
+			}
+			postingMaps[i] = new PostingMap(old2new[oldDocsAndPositions.docID()],out.getFilePointer());
+			addPositions(oldDocsAndPositions);
+			i++;
+		}
+		upto = i;
+		Arrays.sort(postingMaps, 0, upto);
+
+		out.flush();
+		in = tempDir.openInput(TEMP_FILE, IOContext.READ);
+	}
+
+	/***
+	 *  This operation is not supported.
+	 */
+	@Override
+	public int advance(final int target) throws IOException {
+		throw new UnsupportedOperationException("advance is not supported");
+	}
+
+	/***
+	 *  This operation is not supported.
+	 */
+	@Override
+	public int docID() {
+		throw new UnsupportedOperationException("docID is not supported");
+	}
+
+	@Override
+	public int endOffset() throws IOException {
+		return currentPosition.endOffset;
+	}
+
+	@Override
+	public int freq() throws IOException {
+		return currFreq;
+	}
+
+	@Override
+	public BytesRef getPayload() throws IOException {
+		return currentPosition.payload;
+	}
+
+	@Override
+	public int nextDoc() throws IOException {
+		posIt = -1;
+		if (++docIt >= upto) return DocsAndPositionsEnum.NO_MORE_DOCS;
+		in.seek(postingMaps[docIt].offset);
+		currFreq = in.readVInt();
+		return postingMaps[docIt].newDocId;
+	}
+
+	@Override
+	public int nextPosition() throws IOException {
+		final int pos = in.readVInt();
+		final int startOffset = in.readVInt();
+		final int endOffset = in.readVInt();
+		final int offset = in.readVInt();
+		final int length = in.readVInt();
+		byte[] bytes = new byte[length];
+		in.readBytes(bytes, offset,length);
+		final BytesRef payload = new BytesRef(bytes, offset, length);
+		currentPosition = new Position(pos, startOffset, endOffset, payload);
+		return currentPosition.pos;
+	}
+
+	@Override
+	public int startOffset() throws IOException {
+		return currentPosition.startOffset;
+	}
+
+	private void addPositions(final DocsAndPositionsEnum oldDocsAndPositions) throws IOException {
+
+		out.writeVInt(oldDocsAndPositions.freq());
+		for (int i = 0; i < oldDocsAndPositions.freq(); i++) {
+			final int oldPos = oldDocsAndPositions.nextPosition();
+
+			out.writeVInt(oldPos);
+			out.writeVInt(oldDocsAndPositions.startOffset());
+			out.writeVInt(oldDocsAndPositions.endOffset());
+
+			BytesRef oldPayload = oldDocsAndPositions.getPayload();
+			if (oldPayload != null) {
+				oldPayload = BytesRef.deepCopyOf(oldPayload);
+				out.writeVInt(oldPayload.offset);
+				out.writeVInt(oldPayload.length);
+				out.writeBytes(oldPayload.bytes, oldPayload.offset, oldPayload.length);
+			} else {
+				out.writeBytes(BytesRef.EMPTY_BYTES, 0, 0);
+			}
+		}
+	}
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocsEnum.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocsEnum.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingDocsEnum.java	(working copy)
@@ -0,0 +1,83 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.util.ArrayUtil;
+
+/**
+ * Allow {@link DocsEnum} to be read according to old2new permutation.
+ * @lucene.experimental
+ */
+
+
+public class SortingDocsEnum extends DocsEnum {
+
+	private static final int NEW_DOC_ID_INIT_LENGTH = 0;
+	private static final int NEW_DOC_ID_GROW_LENGTH = 1;
+	
+	private int[] newDocIds = new int[NEW_DOC_ID_INIT_LENGTH];
+	private int docIt = -1;
+	private final int upto;
+	
+	public SortingDocsEnum(final DocsEnum docs, final int[] old2new) throws IOException {
+		int i = 0;
+		while (docs.nextDoc() != DocsEnum.NO_MORE_DOCS){
+			if ( i >= newDocIds.length) {
+				newDocIds = ArrayUtil.grow(newDocIds, newDocIds.length + NEW_DOC_ID_GROW_LENGTH);
+			}
+			newDocIds[i++] = old2new[docs.docID()];
+		}
+		upto = i;	
+		Arrays.sort(this.newDocIds, 0, upto);
+	}
+
+	/***
+	 *  This operation is not supported.
+	 */
+	@Override
+	public int advance(final int target) throws IOException {
+		throw new UnsupportedOperationException("advance is not supported");
+	}
+
+	/***
+	 *  This operation is not supported.
+	 */
+	@Override
+	public int docID() {
+		throw new UnsupportedOperationException("docID is not supported");
+	}
+
+	/***
+	 *  This operation is not supported.
+	 */
+	@Override
+	public int freq() throws IOException {
+		throw new UnsupportedOperationException("freq is not supported");
+	}
+
+	@Override
+	public int nextDoc() throws IOException {
+		if (++docIt >= upto) return NO_MORE_DOCS;
+		return newDocIds[docIt];
+	}
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingFields.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingFields.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingFields.java	(working copy)
@@ -0,0 +1,55 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Iterator;
+import org.apache.lucene.index.Fields;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.sorter.SortingTerms;
+
+/**
+ *  
+ * Allow {@link Fields} to be read according to old2new permutation.
+ * @lucene.experimental
+ */
+public class SortingFields extends Fields {
+
+  private final Fields oldFields;
+  private final int[] old2new;
+
+  public SortingFields(final Fields oldFields, final int[] old2new) {
+    this.oldFields = oldFields;
+    this.old2new = old2new;
+  }
+
+  @Override
+  public Iterator<String> iterator() {
+    return oldFields.iterator();
+  }
+
+  @Override
+  public int size() {
+    return oldFields.size();
+  }
+
+  @Override
+  public Terms terms(final String field) throws IOException {
+    return new SortingTerms(oldFields.terms(field), old2new);
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingIndexReader.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingIndexReader.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingIndexReader.java	(working copy)
@@ -0,0 +1,112 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.CompositeReader;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.FieldInfos;
+import org.apache.lucene.index.Fields;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.StoredFieldVisitor;
+import org.apache.lucene.util.Bits;
+
+
+/**
+ * Allow {@link AtomicReader} to be read according to old2new permutation.
+ * Note that at  this point deletion of document is not supported
+ * @lucene.experimental
+ */
+public class SortingIndexReader extends AtomicReader {
+
+  private final AtomicReader oldReader;
+  private final int[] old2new;
+
+  /**
+   * 
+   * @param dirReader
+   * @param old2new
+   * @throws IOException
+   */
+  public SortingIndexReader(final CompositeReader dirReader, final int[] old2new) throws IOException {
+    oldReader = new SlowCompositeReaderWrapper(dirReader);
+    this.old2new = old2new;
+  }
+
+  @Override
+  public void document(final int docID, final StoredFieldVisitor visitor) throws IOException {
+    oldReader.document(old2new[docID], visitor);
+  }
+
+  @Override
+  public DocValues docValues(final String field) throws IOException {
+    final DocValues oldDocValues = oldReader.docValues(field);
+    if (oldDocValues == null) return null;
+    return new SortingDocValues(oldDocValues, old2new);
+  }
+
+  @Override
+  public Fields fields() throws IOException {
+    return new SortingFields(oldReader.fields(), old2new);
+  }
+
+  @Override
+  public FieldInfos getFieldInfos() {
+    return oldReader.getFieldInfos();
+  }
+
+  @Override
+  public Bits getLiveDocs() {
+    return null; // default - no deleted docs
+  }
+
+  @Override
+  public Fields getTermVectors(final int docID) throws IOException {
+    return oldReader.getTermVectors(old2new[docID]);
+  }
+
+  /***
+   *  This operation is not supported.
+   */
+  @Override
+  public boolean hasDeletions() {
+    throw new UnsupportedOperationException("hasDeletions is not supported");
+  }
+
+  @Override
+  public int maxDoc() {
+    return oldReader.maxDoc();
+  }
+
+  @Override
+  public DocValues normValues(final String field) throws IOException {
+    final DocValues oldDocValues = oldReader.normValues(field);
+    if (oldDocValues == null) return null;
+    return new SortingDocValues(oldDocValues, old2new);
+  }
+
+  @Override
+  public int numDocs() {
+    return oldReader.numDocs();
+  }
+
+  @Override
+  protected void doClose() throws IOException {
+    oldReader.close();
+  }
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingSource.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingSource.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingSource.java	(working copy)
@@ -0,0 +1,54 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.index.DocValues.Source;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ *  
+ * Allow {@link Source} to be read according to old2new permutation.
+ * @lucene.experimental
+ */
+public class SortingSource extends Source {
+
+  private final Source oldSource;
+  private final int[] old2new;
+
+  public SortingSource(final Source oldSource, final int[] old2new) {
+    super(oldSource.getType());
+    this.oldSource = oldSource;
+    this.old2new = old2new;
+  }
+
+  @Override
+  public BytesRef getBytes(final int docID, final BytesRef ref) {
+    return oldSource.getBytes(old2new[docID], ref);
+  }
+
+  @Override
+  public double getFloat(final int docID) {
+    return oldSource.getFloat(old2new[docID]);
+  }
+
+  @Override
+  public long getInt(final int docID) {
+    return oldSource.getInt(old2new[docID]);
+  }
+
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingTermEnum.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingTermEnum.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingTermEnum.java	(working copy)
@@ -0,0 +1,99 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Comparator;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.index.TermsEnum.SeekStatus;
+import org.apache.lucene.index.sorter.SortingDocsAndPositionsEnum;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ *  
+ * Allow {@link TermsEnum} to be read according to old2new permutation.
+ * @lucene.experimental
+ */
+public class SortingTermEnum extends TermsEnum {
+
+  private final TermsEnum oldIterator;
+  private final int[] old2new;
+
+  public SortingTermEnum(final TermsEnum oldIterator, final int[] old2new) {
+    this.oldIterator = oldIterator;
+    this.old2new = old2new;
+  }
+
+  @Override
+  public int docFreq() throws IOException {
+    return oldIterator.docFreq();
+  }
+
+  @Override
+  public DocsEnum docs(final Bits liveDocs, final DocsEnum reuse, final int flags) throws IOException {
+    return new SortingDocsEnum(oldIterator.docs(liveDocs, reuse, flags), old2new);
+  }
+
+  @Override
+  public DocsAndPositionsEnum docsAndPositions(final Bits liveDocs, final DocsAndPositionsEnum reuse, final int flags) throws IOException {
+    return new SortingDocsAndPositionsEnum(oldIterator.docsAndPositions(liveDocs, reuse, flags), old2new);
+  }
+
+  @Override
+  public Comparator<BytesRef> getComparator() {
+    return oldIterator.getComparator();
+  }
+
+  @Override
+  public BytesRef next() throws IOException {
+    return oldIterator.next();
+  }
+
+  /***
+   *  This operation is not supported.
+   */
+  @Override
+  public long ord() throws IOException {
+    throw new UnsupportedOperationException("ord is not supported");
+  }
+
+  @Override
+  public SeekStatus seekCeil(final BytesRef text, final boolean useCache) throws IOException {
+    return oldIterator.seekCeil(text, useCache);
+  }
+
+  /***
+   *  This operation is not supported.
+   */
+  @Override
+  public void seekExact(final long ord) throws IOException {
+    throw new UnsupportedOperationException("seekExact is not supported");
+  }
+
+  @Override
+  public BytesRef term() throws IOException {
+    return oldIterator.term();
+  }
+
+  @Override
+  public long totalTermFreq() throws IOException {
+    return oldIterator.totalTermFreq();
+  }
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/SortingTerms.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/SortingTerms.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/SortingTerms.java	(working copy)
@@ -0,0 +1,84 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Comparator;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.util.BytesRef;
+
+/**
+ *  
+ * Allow {@link Terms} to be read according to old2new permutation.
+ * @lucene.experimental
+ */
+public class SortingTerms extends Terms {
+
+  private final Terms oldTerms;
+  private final int[] old2new;
+
+  public SortingTerms(final Terms oldTerms, final int[] old2new) {
+    this.oldTerms = oldTerms;
+    this.old2new = old2new;
+  }
+
+  @Override
+  public Comparator<BytesRef> getComparator() throws IOException {
+    return oldTerms.getComparator();
+  }
+
+  @Override
+  public int getDocCount() throws IOException {
+    return oldTerms.getDocCount();
+  }
+
+  @Override
+  public long getSumDocFreq() throws IOException {
+    return oldTerms.getSumDocFreq();
+  }
+
+  @Override
+  public long getSumTotalTermFreq() throws IOException {
+    return oldTerms.getSumTotalTermFreq();
+  }
+
+  @Override
+  public boolean hasOffsets() {
+    return oldTerms.hasOffsets();
+  }
+
+  @Override
+  public boolean hasPayloads() {
+    return oldTerms.hasPayloads();
+  }
+
+  @Override
+  public boolean hasPositions() {
+    return oldTerms.hasPositions();
+  }
+
+  @Override
+  public TermsEnum iterator(final TermsEnum reuse) throws IOException {
+    return new SortingTermEnum(oldTerms.iterator(reuse), old2new);
+  }
+
+  @Override
+  public long size() throws IOException {
+    return oldTerms.size();
+  }
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/To.java
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/To.java	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/To.java	(working copy)
@@ -0,0 +1,32 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.
+ */
+
+/***
+ * 
+ * Interface used by index {@link Sorter} 
+ *
+ * @param <S> Object to be sorted.
+ * @param <T> Field according to which the sorting will be done. 
+ * 
+ * @lucene.experimental
+ */
+public interface To<S, T> {
+  /** Retrieves from S the field according to which the sorting will be done*/
+  public T from(S s);
+}
Index: lucene/misc/src/java/org/apache/lucene/index/sorter/package.html
===================================================================
--- lucene/misc/src/java/org/apache/lucene/index/sorter/package.html	(revision 0)
+++ lucene/misc/src/java/org/apache/lucene/index/sorter/package.html	(working copy)
@@ -0,0 +1,91 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<!--
+ 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.
+-->
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+</head>
+<body>
+Code to sort indices.
+<h2>Table Of Contents</h2>
+<p>
+    <ol>
+        <li><a href="#sorters">Sorters API</a></li>
+        <li><a href="#sortingClasses">Sorting classes</a></li>
+    </ol>
+</p>
+<a name="sorters"></a>
+<h2>Sorters API</h2>
+<p>
+All sorters implement the {@link org.apache.lucene.index.sorter.Sorter} interface. 
+Each sorter implementation sorts the documents in a directory according to the values of a document component such as
+StoredFields, DocValues, Payload etc`. The relevant component is evident from the name of the sorter class. 
+Most sorter classes are generic and take in a parameter <i>T</i> which defines the type of the component 
+according to which the sorting should be done. This type must be comparable. 
+For example we can have an integer DocValues sorter, a double DocValues sorters and so on.  
+In order to use a generic sorter the user must supply the sorter with a {@link org.apache.lucene.index.sorter.To} object.
+that can extract an object of a comparable type <i>T</i> according to which the sorting will be done.
+
+For example, sorting a directory according to an integer DocValues field will be done as follow:
+<pre class="prettyprint">
+  int[] docValuesSort(Directory dir) throws IOException{
+    final DocValuesSorter&lt;Integer&gt; docValSorter = new DocValuesSorter&lt;Integer&gt;("someField", new To&lt;BytesRef, Integer&gt;() {
+
+      @Override
+      public Integer from(final BytesRef bytes) {
+        return DocValuesArraySource.asInt(bytes);
+      }
+    });
+    return docValSorter.oldToNew(dir);    
+  }
+</pre> 
+Currently the following sorters are implemented:
+   <ol>
+        <li>{@link org.apache.lucene.index.sorter.DocumentSorter}</li>
+        <li>{@link org.apache.lucene.index.sorter.DocValuesSorter}</li>
+        <li>{@link org.apache.lucene.index.sorter.PayloadSorter}</li>
+        <li>{@link org.apache.lucene.index.sorter.ReverseDocIdSorter}</li>
+    </ol>
+In addition, once a sorter is defined, the utility class {@link org.apache.lucene.index.sorter.SorterUtil} supplies 
+a convenient interface to read documents from an input directory, sort them and add them to an output
+directory according to their new order.     
+</p>
+<a name="sortingClasses"></a>
+<h2>Sorting classes</h2>
+<p>
+A sorting class is a class that extends a previously existing index class  
+and allows the index to be accessed according to a permutation on its original order.
+Each sorting class received in its constructor an instance of its superclass
+and a permutation
+that defines the new order of the index. A sorting class exposes the same interface as its superclass
+although not all of the superclasses functionality is currently supported. 
+<br/>
+The following sorting classes are available:
+   <ol>
+        <li>{@link org.apache.lucene.index.sorter.SortingDocsAndPositionsEnum}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingDocsEnum}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingDocValues}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingFields}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingIndexReader}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingSource}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingTermEnum}</li>
+        <li>{@link org.apache.lucene.index.sorter.SortingTerms}</li>
+    </ol>
+</p>
+
+</body>
+</html>
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/DocValuesSorterTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/DocValuesSorterTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/DocValuesSorterTest.java	(working copy)
@@ -0,0 +1,70 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.codecs.DocValuesArraySource;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.IntDocValuesField;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DocValuesSorterTest extends LuceneTestCase{
+	private static final String DOC_VAL = "docVal";
+	private RAMDirectory dir;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		dir = new RAMDirectory();
+		final IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random())));
+		writer.addDocument(doc(3));
+		writer.addDocument(doc(2));
+		writer.addDocument(doc(1));
+		writer.close();
+	}
+
+	@Test
+	public void test() throws IOException {
+		final DocValuesSorter<Integer> docValSorter = new DocValuesSorter<Integer>(DOC_VAL, new To<BytesRef, Integer>() {
+
+			@Override
+			public Integer from(final BytesRef bytes) {
+				return DocValuesArraySource.asInt(bytes);
+			}
+		});
+
+		assertArrayEquals(new int[] { 2, 1, 0 }, docValSorter.oldToNew(dir));
+	}
+
+	private Iterable<? extends IndexableField> doc(final int val) {
+		final Document doc = new Document();
+		doc.add(new IntDocValuesField(DOC_VAL, val));
+		return doc;
+	}
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/DocumentSorterTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/DocumentSorterTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/DocumentSorterTest.java	(working copy)
@@ -0,0 +1,71 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class DocumentSorterTest extends LuceneTestCase {
+
+  private static final String VAL = "val";
+  private RAMDirectory dir;
+
+  @Override
+@Before
+  public void setUp() throws Exception {
+	super.setUp();
+    dir = new RAMDirectory();
+    final IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random())));
+    writer.addDocument(doc(1));
+    writer.addDocument(doc(3));
+    writer.addDocument(doc(2));
+    writer.addDocument(doc(1));
+    writer.close();
+  }
+
+  @Test
+  public void test() throws IOException {
+    final DocumentSorter<Integer> documentSorter = new DocumentSorter<Integer>(new To<Document, Integer>() {
+
+      @Override
+      public Integer from(final Document doc) {
+        return doc.getField(VAL).numericValue().intValue();
+      }
+    });
+
+    assertArrayEquals(new int[] { 0, 3, 2, 1 }, documentSorter.oldToNew(dir));
+  }
+
+  private Iterable<? extends IndexableField> doc(final int val) {
+    final Document doc = new Document();
+    doc.add(new IntField(VAL, val, Store.YES));
+    return doc;
+  }
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/PayloadSorterTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/PayloadSorterTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/PayloadSorterTest.java	(working copy)
@@ -0,0 +1,112 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.payloads.PayloadHelper;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
+import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.index.FieldInfo.IndexOptions;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PayloadSorterTest extends LuceneTestCase{
+	private static final String PAYLOAD_FIELD = "payloadField";
+	private static final String TERM = "term";
+	private RAMDirectory dir;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		dir = new RAMDirectory();
+		final IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random())));
+		writer.addDocument(doc(3));
+		writer.addDocument(doc(2));
+		writer.addDocument(doc(1));
+		writer.close();
+	}
+
+	@Test
+	public void test() throws IOException {
+		Term term = new Term(PAYLOAD_FIELD, TERM);
+		final PayloadSorter<Integer> payloadSorter = new PayloadSorter<Integer>(term.bytes(), term.field(), new To<BytesRef, Integer>() {
+
+			@Override
+			public Integer from(final BytesRef bytes) {
+				return PayloadHelper.decodeInt(bytes.bytes, bytes.offset);
+
+			}
+		});
+
+		assertArrayEquals(new int[] { 2, 1, 0 }, payloadSorter.oldToNew(dir));
+	}
+
+	// TODO write a util that grab all the information for a particular document (terms, positions, payloads, etc....)
+	// TODO sort the index and then sort it back, use Lucen's util to compare the original index to the result one.
+	private void addPayload(final Document doc, final Integer id) {
+		final FieldType fieldType = new FieldType();
+		fieldType.setIndexed(true);
+		fieldType.freeze();
+
+		doc.add(new Field(PAYLOAD_FIELD, new TokenStream() {
+			int positionsCount = 2;
+			private final CharTermAttribute attCharTerm = addAttribute(CharTermAttribute.class);
+			private final PayloadAttribute attPayload = addAttribute(PayloadAttribute.class);
+			private final OffsetAttribute attOffset = addAttribute(OffsetAttribute.class);
+
+			@Override
+			public boolean incrementToken() throws IOException {
+				if (positionsCount-- == 0) return false;
+				attCharTerm.setEmpty().append(TERM);
+				attPayload.setPayload(new BytesRef(PayloadHelper.encodeInt(id)));
+				attOffset.setOffset(id, id);
+				return true;
+			}
+
+		}, fieldType));
+	}
+
+	private Iterable<? extends IndexableField> doc(final Integer val) {
+		final Document doc = new Document();
+
+		doc.add(new StringField("stringFields", val.toString(), Store.YES));
+		doc.add(new IntField("intField", val, Store.YES));
+		addPayload(doc, val);
+
+		return doc;
+	}
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/ReverseDocIdSorterTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/ReverseDocIdSorterTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/ReverseDocIdSorterTest.java	(working copy)
@@ -0,0 +1,63 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ReverseDocIdSorterTest extends LuceneTestCase{
+
+	private static final String VAL = "val";
+	private RAMDirectory dir;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		dir = new RAMDirectory();
+		final IndexWriter writer = new IndexWriter(dir, new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random())));
+		writer.addDocument(doc(3));
+		writer.addDocument(doc(2));
+		writer.addDocument(doc(1));
+		writer.close();
+	}
+
+	@Test
+	public void test() throws IOException {
+		final ReverseDocIdSorter documentSorter = new ReverseDocIdSorter();
+		assertArrayEquals(new int[] { 2, 1, 0 }, documentSorter.oldToNew(dir));
+	}
+
+	private Iterable<? extends IndexableField> doc(final int val) {
+		final Document doc = new Document();
+		doc.add(new IntField(VAL, val, Store.YES));
+		return doc;
+	}
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SorterUtilTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SorterUtilTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SorterUtilTest.java	(working copy)
@@ -0,0 +1,78 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SorterUtilTest extends LuceneTestCase{
+
+	private static final String VAL = "val";
+	private RAMDirectory in;
+	private RAMDirectory out;
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		in = new RAMDirectory();
+		final IndexWriter writer = new IndexWriter(in, new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random())));
+		writer.addDocument(doc(1));
+		writer.addDocument(doc(3));
+		writer.addDocument(doc(2));
+		writer.close();
+		out = new RAMDirectory();
+	}
+
+	@Test
+	public void test() throws IOException {
+		final DocumentSorter<Integer> documentSorter = new DocumentSorter<Integer>(new To<Document, Integer>() {
+
+			@Override
+			public Integer from(final Document doc) {
+				return doc.getField(VAL).numericValue().intValue();
+			}
+		});
+		SorterUtil.sort(in, out, documentSorter);
+		final int[] expected = { 1, 2, 3 };
+		final DirectoryReader outReader = DirectoryReader.open(out);
+		for (int i = 0; i < outReader.maxDoc(); i++) {
+			assertEquals(expected[i], outReader.document(i).getField(VAL).numericValue().intValue());
+		}
+
+	}
+
+	private Iterable<? extends IndexableField> doc(final int val) {
+		final Document doc = new Document();
+		doc.add(new IntField(VAL, val, Store.YES));
+		return doc;
+	}
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocValuesTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocValuesTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocValuesTest.java	(working copy)
@@ -0,0 +1,98 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.IntDocValuesField;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.DocValues.Source;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingDocValuesTest extends LuceneTestCase{
+
+  AtomicReader atomicReader;
+
+  static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+  private final int[] oldToNew = { 2, 1, 0 };
+
+  private static final String VAL = "Val";
+  private SortingDocValues sortingDocValues;
+  private DocValues unsortedDocValues;
+
+  private Document doc(final Integer id) {
+    final Document doc = new Document();
+
+    doc.add(new IntDocValuesField(VAL, id));
+    return doc;
+    
+  }
+
+@Override
+@Before
+  public void setUp() throws Exception {
+	super.setUp();
+    Directory dir = new RAMDirectory();
+    final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+    indexWriter.addDocument(doc(0));
+    indexWriter.addDocument(doc(1));
+    indexWriter.addDocument(doc(2));
+    indexWriter.close();
+
+    final DirectoryReader dirReader = DirectoryReader.open(dir);
+    atomicReader = new SlowCompositeReaderWrapper(dirReader);
+    unsortedDocValues = atomicReader.docValues(VAL);
+    sortingDocValues = new SortingDocValues(unsortedDocValues, oldToNew);
+  }
+
+  @Test
+  public void testGetDirectSource() {
+    try {
+      Source unsortedSource = unsortedDocValues.getDirectSource();
+      Source sortedSource = sortingDocValues.getDirectSource();
+
+      assertEquals(unsortedSource.getInt(2), sortedSource.getInt(0));
+      assertEquals(unsortedSource.getInt(1), sortedSource.getInt(1));
+      assertEquals(unsortedSource.getInt(0), sortedSource.getInt(2));
+      
+    } catch (IOException e) {
+      // TODO Auto-generated catch block
+      e.printStackTrace();
+      fail("Exception");
+    }
+  }
+
+
+  @Test
+  public void testGetType() {
+    assertEquals(unsortedDocValues.getType(), sortingDocValues.getType());
+  }
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocsAndPositionsEnumTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocsAndPositionsEnumTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocsAndPositionsEnumTest.java	(working copy)
@@ -0,0 +1,268 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
+import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.FieldInfo.IndexOptions;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.MultiFields;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingDocsAndPositionsEnumTest extends LuceneTestCase{
+  AtomicReader atomicReader;
+  DirectoryReader dirReader;
+
+  static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+  private final int[] oldToNew = { 2, 1, 0 };
+
+  private static final String PAYLOAD_TEST_CONTENT = "payload";
+
+  private SortingDocsAndPositionsEnum sortingEnum;
+  private DocsAndPositionsEnum unSortedEnum;
+
+  private void addPayload(final Document doc, final Integer id) {
+    final FieldType fieldType = new FieldType();
+    fieldType.setIndexed(true);
+    fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
+    fieldType.freeze();
+
+    doc.add(new Field(PAYLOAD_TEST_CONTENT, new TokenStream() {
+      int positionsCount = id+1;
+      private final CharTermAttribute attCharTerm = addAttribute(CharTermAttribute.class);
+      private final PayloadAttribute attPayload = addAttribute(PayloadAttribute.class);
+      private final OffsetAttribute attOffset = addAttribute(OffsetAttribute.class);
+
+      @Override
+      public boolean incrementToken() throws IOException {
+        if (positionsCount-- == 0) return false;
+
+        attCharTerm.setEmpty().append(PAYLOAD_TEST_CONTENT);
+        attPayload.setPayload(new BytesRef(id.toString()));
+        attOffset.setOffset(id, id);
+        return true;
+      }
+
+    }, fieldType));
+  }
+
+  private Document doc(final Integer id) {
+    final Document doc = new Document();
+    addPayload(doc, id);
+    return doc;
+  }
+
+@Override
+@Before
+  public void setUp() throws Exception {
+	super.setUp();
+    Directory dir = new RAMDirectory();
+    final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+    indexWriter.addDocument(doc(0));
+    indexWriter.addDocument(doc(1));
+    indexWriter.addDocument(doc(2));
+    indexWriter.close();
+
+    dirReader = DirectoryReader.open(dir);
+    atomicReader = new SlowCompositeReaderWrapper(dirReader);
+    unSortedEnum = MultiFields.getTermPositionsEnum(dirReader,
+        null, PAYLOAD_TEST_CONTENT, new BytesRef(PAYLOAD_TEST_CONTENT));
+    
+    DocsAndPositionsEnum oldEnum = MultiFields
+        .getTermPositionsEnum(dirReader, null, PAYLOAD_TEST_CONTENT, new BytesRef(PAYLOAD_TEST_CONTENT));
+    sortingEnum = new SortingDocsAndPositionsEnum(oldEnum, oldToNew);
+
+  }
+
+  @Test
+  public void testNextDoc() {
+    try {
+      assertEquals(sortingEnum.nextDoc(), 0);
+      assertEquals(sortingEnum.nextDoc(), 1);
+      assertEquals(sortingEnum.nextDoc(), 2);
+      assertEquals(sortingEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+    } catch (IOException e) {
+      fail("Exception");
+    }
+
+  }
+
+  @Test
+  public void testFreq() {
+    try {
+      assertEquals(sortingEnum.nextDoc(), 0);
+      assertEquals(sortingEnum.freq(), 3);
+      assertEquals(sortingEnum.nextDoc(), 1);
+      assertEquals(sortingEnum.freq(), 2);
+      assertEquals(sortingEnum.nextDoc(), 2);
+      assertEquals(sortingEnum.freq(), 1);
+    } catch (IOException e) {
+      fail("Exception");
+    }
+  }
+
+  @Test
+  public void testNextPosition() {
+    try {
+      int[][] unsortedPositions = new int[3][];
+      int[][] sortedPositions = new int[3][];
+      for ( int i=0; i < 3; i++) {
+        unSortedEnum.nextDoc();
+        unsortedPositions[i] = new int[unSortedEnum.freq()];
+        for (int j = 0; j < unsortedPositions[i].length; j++) {
+          unsortedPositions[i][j] = unSortedEnum.nextPosition();
+        }
+
+        sortingEnum.nextDoc();
+        sortedPositions[i] = new int[sortingEnum.freq()];
+        for (int j = 0; j < sortedPositions[i].length; j++) {
+          sortedPositions[i][j] = sortingEnum.nextPosition();
+        }
+      }
+      assertEquals(unSortedEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+      assertEquals(sortingEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+
+      for (int i=0; i < sortedPositions.length; i++) {
+        assertArrayEquals(sortedPositions[i], unsortedPositions[2-i]);
+      }
+    } catch (IOException e) {
+      fail("Exception");
+    }
+  }
+
+  @Test
+  public void testStartOffset() {
+    try {
+      int[][] unsortedOffsets = new int[3][];
+      int[][] sortedOffsets = new int[3][];
+
+      for ( int i=0; i < 3; i++) {
+        unSortedEnum.nextDoc();
+        unsortedOffsets[i] = new int[unSortedEnum.freq()];
+        for (int j = 0; j < unsortedOffsets[i].length; j++) {
+          unSortedEnum.nextPosition();
+          unsortedOffsets[i][j] = unSortedEnum.startOffset();
+        }
+
+        sortingEnum.nextDoc();
+        sortedOffsets[i] = new int[sortingEnum.freq()];
+        for (int j = 0; j < sortedOffsets[i].length; j++) {
+          sortingEnum.nextPosition();
+          sortedOffsets[i][j] = sortingEnum.startOffset();
+        }
+      }
+      assertEquals(unSortedEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+      assertEquals(sortingEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+
+      for (int i=0; i < sortedOffsets.length; i++) {
+        assertArrayEquals(sortedOffsets[i], unsortedOffsets[2-i]);
+      }
+
+    } catch (IOException e) {
+      fail("Exception");
+    }
+  }
+
+  @Test
+  public void testEndOffset() {
+    try {
+      int[][] unsortedOffsets = new int[3][];
+      int[][] sortedOffsets = new int[3][];
+
+      for ( int i=0; i < 3; i++) {
+        unSortedEnum.nextDoc();
+        unsortedOffsets[i] = new int[unSortedEnum.freq()];
+        for (int j = 0; j < unsortedOffsets[i].length; j++) {
+          unSortedEnum.nextPosition();
+          unsortedOffsets[i][j] = unSortedEnum.endOffset();
+        }
+
+        sortingEnum.nextDoc();
+        sortedOffsets[i] = new int[sortingEnum.freq()];
+        for (int j = 0; j < sortedOffsets[i].length; j++) {
+          sortingEnum.nextPosition();
+          sortedOffsets[i][j] = sortingEnum.endOffset();
+        }
+      }
+      assertEquals(unSortedEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+      assertEquals(sortingEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+
+      for (int i=0; i < sortedOffsets.length; i++) {
+        assertArrayEquals(sortedOffsets[i], unsortedOffsets[2-i]);
+      }
+
+    } catch (IOException e) {
+      fail("Exception");
+    }
+
+  }
+
+  @Test
+  public void testGetPayload() {
+    try {
+      BytesRef[][] unsortedPayloads = new BytesRef[3][];
+      BytesRef[][] sortedPayloads = new BytesRef[3][];
+
+      for ( int i=0; i < 3; i++) {
+        unSortedEnum.nextDoc();
+        unsortedPayloads[i] = new BytesRef[unSortedEnum.freq()];
+        for (int j = 0; j < unsortedPayloads[i].length; j++) {
+          unSortedEnum.nextPosition();
+          unsortedPayloads[i][j] = BytesRef.deepCopyOf(unSortedEnum.getPayload());
+        }
+
+        sortingEnum.nextDoc();
+        sortedPayloads[i] = new BytesRef[sortingEnum.freq()];
+        for (int j = 0; j < sortedPayloads[i].length; j++) {
+          sortingEnum.nextPosition();
+          sortedPayloads[i][j] = BytesRef.deepCopyOf(sortingEnum.getPayload());
+        }
+      }
+      assertEquals(unSortedEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+      assertEquals(sortingEnum.nextDoc(), DocsAndPositionsEnum.NO_MORE_DOCS);
+
+      for (int i=0; i < sortedPayloads.length; i++) {
+        assertArrayEquals(sortedPayloads[i], unsortedPayloads[2-i]);
+      }
+
+    } catch (IOException e) {
+      fail("Exception");
+    }
+
+
+  }
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocsEnumTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocsEnumTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingDocsEnumTest.java	(working copy)
@@ -0,0 +1,118 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.analysis.TokenStream;
+import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
+import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
+import org.apache.lucene.analysis.tokenattributes.PayloadAttribute;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.FieldInfo.IndexOptions;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.MultiFields;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingDocsEnumTest extends LuceneTestCase{
+
+  private SortingDocsEnum sortingDocsEnum;
+
+  static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+  private final int[] oldToNew = { 2, 1, 0 };
+
+  private static final String PAYLOAD_TEST_CONTENT = "payload";
+  private static final String VAL = "Val";
+
+  private void addPayload(final Document doc, final Integer id) {
+    final FieldType fieldType = new FieldType();
+    fieldType.setIndexed(true);
+    fieldType.setIndexOptions(IndexOptions.DOCS_AND_FREQS_AND_POSITIONS_AND_OFFSETS);
+    fieldType.freeze();
+
+    doc.add(new Field(PAYLOAD_TEST_CONTENT, new TokenStream() {
+      int positionsCount = id+1;
+      private final CharTermAttribute attCharTerm = addAttribute(CharTermAttribute.class);
+      private final PayloadAttribute attPayload = addAttribute(PayloadAttribute.class);
+      private final OffsetAttribute attOffset = addAttribute(OffsetAttribute.class);
+
+      @Override
+      public boolean incrementToken() throws IOException {
+        if (positionsCount-- == 0) return false;
+
+        attCharTerm.setEmpty().append(PAYLOAD_TEST_CONTENT);
+        attPayload.setPayload(new BytesRef(id.toString()));
+        attOffset.setOffset(id, id);
+        return true;
+      }
+
+    }, fieldType));
+  }
+  
+  private Document doc(final Integer id) {
+    final Document doc = new Document();
+
+    doc.add(new IntField(VAL, id, Store.YES));
+    addPayload(doc, id);
+    return doc;
+  }
+
+@Override
+@Before
+  public void setUp() throws Exception {
+	super.setUp();
+    Directory dir = new RAMDirectory();
+    final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+    indexWriter.addDocument(doc(0));
+    indexWriter.addDocument(doc(1));
+    indexWriter.addDocument(doc(2));
+    indexWriter.close();
+
+    final DirectoryReader dirReader = DirectoryReader.open(dir);
+    DocsEnum docsEnum = MultiFields.getTermDocsEnum(dirReader, null, PAYLOAD_TEST_CONTENT, new BytesRef(PAYLOAD_TEST_CONTENT));
+    sortingDocsEnum = new SortingDocsEnum(docsEnum, oldToNew);
+  }
+
+
+  @Test
+  public void testNextDoc() {
+    try {
+      assertEquals(0, sortingDocsEnum.nextDoc());
+      assertEquals(1, sortingDocsEnum.nextDoc());
+      assertEquals(2, sortingDocsEnum.nextDoc());
+    } catch (IOException e) {
+      fail("Exception");
+    }
+    
+  }
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingFieldsTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingFieldsTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingFieldsTest.java	(working copy)
@@ -0,0 +1,101 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Iterator;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.Fields;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingFieldsTest extends LuceneTestCase{
+
+  AtomicReader atomicReader;
+
+  static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+  private final int[] oldToNew = { 2, 1, 0 };
+
+  private static final String VAL = "Val";
+  private SortingFields sortingFields;
+
+  private Fields unsortedFields;
+
+  private Document doc(final Integer id) {
+    final Document doc = new Document();
+    doc.add(new IntField(VAL, id, Store.YES));
+    return doc;
+  }
+
+  @Override
+@Before
+  public void setUp() throws Exception {
+	super.setUp();
+    Directory dir = new RAMDirectory();
+    final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+    indexWriter.addDocument(doc(0));
+    indexWriter.addDocument(doc(1));
+    indexWriter.addDocument(doc(2));
+    indexWriter.close();
+
+    final DirectoryReader dirReader = DirectoryReader.open(dir);
+    atomicReader = new SlowCompositeReaderWrapper(dirReader);
+    unsortedFields = atomicReader.fields();
+    sortingFields = new SortingFields(unsortedFields, oldToNew);
+
+  }
+
+  @Test
+  public void testSize() {
+    assertEquals(unsortedFields.size(), sortingFields.size());
+  }
+
+  @Test
+  public void testIterator() {
+    Iterator<String> i1 = unsortedFields.iterator();
+    Iterator<String> i2 = sortingFields.iterator();
+    while (i1.hasNext()) {
+      assertEquals(i1.next(), i2.next());
+    }
+    assertFalse(i1.hasNext());
+    assertFalse(i2.hasNext());
+  }
+
+  @Test
+  public void testTermsString() {
+    try {
+      TestUtils.compareTerms(unsortedFields.terms(VAL), sortingFields.terms(VAL));
+    } catch (IOException e) {
+      fail("Exception");
+    }
+
+  }
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingIndexReaderTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingIndexReaderTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingIndexReaderTest.java	(working copy)
@@ -0,0 +1,286 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Iterator;
+import java.util.Map.Entry;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.DocumentStoredFieldVisitor;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.document.FieldType.NumericType;
+import org.apache.lucene.document.IntDocValuesField;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.CompositeReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.FieldInfo;
+import org.apache.lucene.index.FieldInfos;
+import org.apache.lucene.index.Fields;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexReader.ReaderClosedListener;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.search.similarities.DefaultSimilarity;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingIndexReaderTest extends LuceneTestCase{
+
+	AtomicReader atomicReader;
+
+	static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+	private final int[] oldToNew = { 2, 1, 0 };
+
+	private static final String VAL = "val";
+	private static final String DOC_VAL = "docVal";
+
+	private SortingIndexReader sortingIndexReader;
+	private CompositeReader unsortedIndexReader;
+	private CompositeReader oldIndexReader;
+
+	private Document doc(final Integer id) {
+		final Document doc = new Document();
+
+		FieldType ft = new FieldType();
+
+		doc.add(new IntDocValuesField(DOC_VAL, id));
+
+		// for the norm values test. We want each doc to have a different norm value
+		// therefore we add a different number of terms to each doc.
+		for (int i = 0; i <= id; i++) {
+			ft = new FieldType();
+
+			ft.setIndexed(true);
+			ft.setStored(true);
+			ft.setStoreTermVectors(true);
+			ft.setOmitNorms(false);
+			ft.setNumericType(NumericType.INT);
+
+			doc.add(new IntField(VAL, id, ft));
+		}
+
+		return doc;
+	}
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		Directory dir = new RAMDirectory();
+		INDEX_WRITER_CONFIG.setSimilarity(new DefaultSimilarity());
+		final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+		indexWriter.addDocument(doc(0));
+		indexWriter.addDocument(doc(1));
+		indexWriter.addDocument(doc(2));
+		indexWriter.close();
+
+		final DirectoryReader dirReader = DirectoryReader.open(dir);
+		atomicReader = new SlowCompositeReaderWrapper(dirReader);
+		unsortedIndexReader = DirectoryReader.open(dir);
+		oldIndexReader = DirectoryReader.open(dir);
+		sortingIndexReader = new SortingIndexReader(oldIndexReader, oldToNew);
+	}
+
+	@Test
+	public void testNumDocs() {
+		assertEquals(unsortedIndexReader.numDocs(), sortingIndexReader.numDocs());
+	}
+
+	@Test
+	public void testMaxDoc() {
+		assertEquals(unsortedIndexReader.maxDoc(), sortingIndexReader.maxDoc());
+	}
+
+
+	@Test
+	public void testDoClose() {
+
+		class MyReaderClosedListener implements ReaderClosedListener {
+
+			boolean closed;
+
+			@Override
+			public void onClose(IndexReader arg0) {
+				closed = true;
+
+			}
+
+		}
+
+		MyReaderClosedListener closedListener = new MyReaderClosedListener();
+
+		try {
+			oldIndexReader.addReaderClosedListener(closedListener);
+			sortingIndexReader.doClose();
+			// wait for the listener
+			for (int i = 0; i < 1000; i++) {
+				if (closedListener.closed) {
+					assertTrue(true);
+					return;
+				}
+				Thread.sleep(1000);
+			}
+			fail("Reader not closed");
+		} catch (IOException e) {
+			fail("Exception");
+		} catch (InterruptedException e) {
+			fail("Exception");
+		}
+		fail("Reader Not Closed");
+
+	}
+
+	@Test
+	public void testDocumentIntStoredFieldVisitor() {
+		DocumentStoredFieldVisitor sortedVisitor = new DocumentStoredFieldVisitor();
+		DocumentStoredFieldVisitor oldVisitor = new DocumentStoredFieldVisitor();
+		try {
+			unsortedIndexReader.document(0, oldVisitor);
+			sortingIndexReader.document(2, sortedVisitor);
+			assertEquals(oldVisitor.getDocument().toString(), sortedVisitor.getDocument().toString());
+
+			unsortedIndexReader.document(1, oldVisitor);
+			sortingIndexReader.document(1, sortedVisitor);
+			assertEquals(oldVisitor.getDocument().toString(), sortedVisitor.getDocument().toString());
+
+			unsortedIndexReader.document(2, oldVisitor);
+			sortingIndexReader.document(0, sortedVisitor);
+			assertEquals(oldVisitor.getDocument().toString(), sortedVisitor.getDocument().toString());
+
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testDocValues() {
+		try {
+			assertNull(sortingIndexReader.docValues(""));
+			final DocValues docValues = sortingIndexReader.docValues(DOC_VAL);
+			assertEquals(2, docValues.getDirectSource().getInt(0));
+			assertEquals(1, docValues.getDirectSource().getInt(1));
+			assertEquals(0, docValues.getDirectSource().getInt(2));
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+	@Test
+	public void testFields() {
+		Fields sortedFields;
+		try {
+			sortedFields = sortingIndexReader.fields();
+			Terms sortedTerms = sortedFields.terms(VAL);
+			Terms oldTerms = atomicReader.fields().terms(VAL);
+			TermsEnum sortedTermsIt = sortedTerms.iterator(null);
+			TermsEnum oldTermsIt = oldTerms.iterator(null);
+			assertEquals(oldTerms.size(), sortedTerms.size());
+			for (int i = 0; i < oldTerms.size(); i++) {
+				assertEquals(oldTermsIt.next(), sortedTermsIt.next());
+			}
+
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+	@Test
+	public void testGetLiveDocs() {
+		assertNull(sortingIndexReader.getLiveDocs());
+	}
+
+	@Test
+	public void testGetFieldInfos() {
+		FieldInfos oldReaderInfo = atomicReader.getFieldInfos();
+		FieldInfos sortingReaderInfo = sortingIndexReader.getFieldInfos();
+		Iterator<FieldInfo> oldInfoIt = oldReaderInfo.iterator();
+		Iterator<FieldInfo> sortingInfoIt = sortingReaderInfo.iterator();
+		while (sortingInfoIt.hasNext()) {
+			FieldInfo oldF = oldInfoIt.next();
+			FieldInfo sortedF = sortingInfoIt.next();
+			assertEquals(oldF.name, sortedF.name);
+			assertEquals(oldF.number, sortedF.number);
+			assertEquals(oldF.hasDocValues(), sortedF.hasDocValues());
+			assertEquals(oldF.hasNorms(), sortedF.hasNorms());
+			assertEquals(oldF.hasPayloads(), sortedF.hasPayloads());
+			assertEquals(oldF.hasVectors(), sortedF.hasVectors());
+			assertEquals(oldF.isIndexed(), sortedF.isIndexed());
+			assertEquals(oldF.omitsNorms(), sortedF.omitsNorms());
+			assertEquals(oldF.getDocValuesType(), sortedF.getDocValuesType());
+			assertEquals(oldF.getIndexOptions(), sortedF.getIndexOptions());
+			assertEquals(oldF.getNormType(), sortedF.getNormType());
+			if (sortedF.attributes() == null) {
+				assertNull(oldF.attributes());
+			} else {
+				Iterator<Entry<String, String>> sortedMap = sortedF.attributes().entrySet().iterator();
+				Iterator<Entry<String, String>> oldMap = oldF.attributes().entrySet().iterator();
+
+				while (sortedMap.hasNext()) {
+					Entry<String, String> sortedEntry = sortedMap.next();
+					Entry<String, String> oldEntry = oldMap.next();
+					assertEquals(sortedEntry.getKey(), oldEntry.getKey());
+					assertEquals(sortedEntry.getValue(), oldEntry.getValue());
+				}
+				assertFalse(oldMap.hasNext());
+			}
+		}
+		assertFalse(oldInfoIt.hasNext());
+	}
+
+	@Test
+	public void testGetTermVectorsInt() {
+		try {
+			TestUtils.compareTerms(unsortedIndexReader.getTermVector(2, VAL), sortingIndexReader.getTermVector(0, VAL));
+			TestUtils.compareTerms(unsortedIndexReader.getTermVector(1, VAL), sortingIndexReader.getTermVector(1, VAL));
+			TestUtils.compareTerms(unsortedIndexReader.getTermVector(0, VAL), sortingIndexReader.getTermVector(2, VAL));
+
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+	@Test
+	public void testNormValuesString() {
+		try {
+			assertNull(sortingIndexReader.normValues(""));
+			final DocValues sortedNormValues = sortingIndexReader.normValues(VAL);
+			final DocValues oldNormValues = atomicReader.normValues(VAL);
+			assertEquals(oldNormValues.getDirectSource().getInt(2), sortedNormValues.getDirectSource().getInt(0));
+			assertEquals(oldNormValues.getDirectSource().getInt(1), sortedNormValues.getDirectSource().getInt(1));
+			assertEquals(oldNormValues.getDirectSource().getInt(0), sortedNormValues.getDirectSource().getInt(2));
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingSourceTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingSourceTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingSourceTest.java	(working copy)
@@ -0,0 +1,131 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.FloatDocValuesField;
+import org.apache.lucene.document.IntDocValuesField;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocValues;
+import org.apache.lucene.index.DocValues.Source;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingSourceTest extends LuceneTestCase{
+
+	static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+
+	private SortingSource sortingSource;
+	private final int[] oldToNew = { 2, 1, 0 };
+	AtomicReader atomicReader;
+
+	private static final String I_VAL = "iVal";
+	private static final String F_VAL = "fVal";
+
+	private Document doc(final Integer id) {
+		final Document doc = new Document();
+
+		doc.add(new IntDocValuesField(I_VAL, id));
+		doc.add(new FloatDocValuesField(F_VAL, id));
+
+		return doc;
+	}
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		Directory dir = new RAMDirectory();
+		final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+		indexWriter.addDocument(doc(0));
+		indexWriter.addDocument(doc(1));
+		indexWriter.addDocument(doc(2));
+		indexWriter.close();
+
+		final DirectoryReader dirReader = DirectoryReader.open(dir);
+		atomicReader = new SlowCompositeReaderWrapper(dirReader);
+
+	}
+
+	@Test
+	public void testGetInt() {
+		try {
+			DocValues docValues = atomicReader.docValues(I_VAL);
+			Source unsortedSource = docValues.getSource();
+			sortingSource = new SortingSource(docValues.getSource(), oldToNew);
+
+			assertEquals(unsortedSource.getInt(2), sortingSource.getInt(0));
+			assertEquals(unsortedSource.getInt(1), sortingSource.getInt(1));
+			assertEquals(unsortedSource.getInt(0), sortingSource.getInt(2));
+
+			atomicReader.close();
+
+		} catch (IOException e) {
+			fail("exception");
+		}
+
+	}
+
+	@Test
+	public void testGetFloat() {
+		try {
+			DocValues docValues = atomicReader.docValues(F_VAL);
+			Source unsortedSource = docValues.getSource();
+			sortingSource = new SortingSource(docValues.getSource(), oldToNew);
+			atomicReader.close();
+
+			assertTrue(Double.compare(unsortedSource.getFloat(2), sortingSource.getFloat(0)) == 0);
+			assertTrue(Double.compare(unsortedSource.getFloat(1), sortingSource.getFloat(1)) == 0);
+			assertTrue(Double.compare(unsortedSource.getFloat(0), sortingSource.getFloat(2)) == 0);
+
+		} catch (IOException e) {
+			fail("exception");
+		}
+
+	}
+
+	@Test
+	public void testGetByteRef() {
+		try {
+			DocValues docValues = atomicReader.docValues(F_VAL);
+			Source unsortedSource = docValues.getSource();
+			sortingSource = new SortingSource(docValues.getSource(), oldToNew);
+			atomicReader.close();
+
+			assertEquals(unsortedSource.getBytes(2, new BytesRef()), sortingSource.getBytes(0, new BytesRef()));
+			assertEquals(unsortedSource.getBytes(1, new BytesRef()), sortingSource.getBytes(1, new BytesRef()));
+			assertEquals(unsortedSource.getBytes(0, new BytesRef()), sortingSource.getBytes(2, new BytesRef()));
+
+		} catch (IOException e) {
+			fail("exception");
+		}
+
+	}
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingTermEnumTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingTermEnumTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingTermEnumTest.java	(working copy)
@@ -0,0 +1,195 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.FieldType;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.DocsEnum;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.index.TermsEnum.SeekStatus;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.BytesRef;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+/***
+ * 
+ * 
+ *@lucene.experimental
+ */
+public class SortingTermEnumTest extends LuceneTestCase{
+
+	static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+
+	private TermsEnum unsortedTermsEnum;
+	private SortingTermEnum sortingTermEnum;
+	private final int[] oldToNew = { 2, 1, 0 };
+	AtomicReader atomicReader;
+
+	private static final String VAL = "Val";
+
+
+	private Document doc(final Integer id) {
+		final Document doc = new Document();
+		FieldType ft = new FieldType();
+		ft.setIndexed(true);
+		ft.setStored(true);
+		for ( int i=0; i <= id; i++) {
+			doc.add(new Field(VAL,Integer.toString(i), ft));
+		}
+		return doc;
+	}
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		Directory dir = new RAMDirectory();
+		final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+		indexWriter.addDocument(doc(0));
+		indexWriter.addDocument(doc(1));
+		indexWriter.addDocument(doc(2));
+		indexWriter.close();
+
+		final DirectoryReader dirReader = DirectoryReader.open(dir);
+		atomicReader = new SlowCompositeReaderWrapper(dirReader);
+		unsortedTermsEnum = atomicReader.terms(VAL).iterator(null);
+		sortingTermEnum = new SortingTermEnum(atomicReader.terms(VAL).iterator(null), oldToNew);
+	}
+
+
+	@Test
+	public void testDocFreq() throws IOException {
+		TermsEnum unsortedEnum = atomicReader.fields().terms(VAL).iterator(null);
+		for (int i = 0; i < 3 ; i++) {
+			sortingTermEnum.next();
+			unsortedEnum.next();
+			assertEquals(unsortedEnum.docFreq(), sortingTermEnum.docFreq());
+		}
+		assertNull(sortingTermEnum.next());
+		assertNull(unsortedEnum.next());
+	}
+
+	@Test
+	public void testTotalTermFreq() {
+		try {
+			TermsEnum unsortedTermEnum = atomicReader.terms(VAL).iterator(null);
+			unsortedTermEnum.next();
+			sortingTermEnum.next();
+			assertEquals(unsortedTermEnum.totalTermFreq(), sortingTermEnum.totalTermFreq());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+
+	@Test
+	public void testDocs() {
+		try {
+			BytesRef term = sortingTermEnum.next();
+			while  (term != null) {
+				DocsEnum sortedDocs = sortingTermEnum.docs(null, null);
+				for ( int j = 0; j <sortingTermEnum.docFreq() ; j++) {
+					assertEquals(j, sortedDocs.nextDoc());
+				}
+				term = sortingTermEnum.next();
+			}
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+	@Test
+	public void testDocsAndPositions() {
+		try {
+			BytesRef term = sortingTermEnum.next();
+			while  (term != null) {
+				DocsAndPositionsEnum docsAndpoistions = sortingTermEnum.docsAndPositions(null, null);
+				for ( int j = 0; j <sortingTermEnum.docFreq() ; j++) {
+					assertEquals(j, docsAndpoistions.nextDoc());
+				}
+				term = sortingTermEnum.next();
+			}
+		} catch (IOException e) {
+
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testGetComparator() {
+		assertEquals(unsortedTermsEnum.getComparator(), sortingTermEnum.getComparator());
+	}
+
+	@Test
+	public void testNext() {
+		try {
+			TermsEnum unsortedIterator = atomicReader.terms(VAL).iterator(null);
+			BytesRef expectedNext;
+			while ((expectedNext= unsortedIterator.next()) != null) {
+				assertEquals(expectedNext, sortingTermEnum.next());
+			}
+			assertNull(sortingTermEnum.next());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testSeekCeil() {
+
+		try {
+			TermsEnum unsortedIterator = atomicReader.terms(VAL).iterator(null);
+			while (unsortedIterator.next() != null) {
+				assertEquals(SeekStatus.FOUND, sortingTermEnum.seekCeil(unsortedIterator.term()));
+			}
+			assertEquals(SeekStatus.END, sortingTermEnum.seekCeil(new BytesRef("THE END")));
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testTerm() {
+		try {
+			TermsEnum unsortedIterator = atomicReader.terms(VAL).iterator(null);
+			while (unsortedIterator.next() != null) {
+				sortingTermEnum.next();
+				assertEquals(unsortedIterator.term(), sortingTermEnum.term());
+			}
+			assertNull(sortingTermEnum.next());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/SortingTermsTest.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/SortingTermsTest.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/SortingTermsTest.java	(working copy)
@@ -0,0 +1,146 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import java.util.Random;
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field.Store;
+import org.apache.lucene.document.IntField;
+import org.apache.lucene.index.AtomicReader;
+import org.apache.lucene.index.DirectoryReader;
+import org.apache.lucene.index.IndexWriter;
+import org.apache.lucene.index.IndexWriterConfig;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.RAMDirectory;
+import org.apache.lucene.util.LuceneTestCase;
+import org.apache.lucene.util.Version;
+import org.junit.Before;
+import org.junit.Test;
+
+public class SortingTermsTest extends LuceneTestCase{
+
+	private Terms unsortedTerms;
+	private SortingTerms sortingTerms;
+	private final int[] oldToNew = { 2, 1, 0 };
+	AtomicReader atomicReader;
+	static final IndexWriterConfig INDEX_WRITER_CONFIG = new IndexWriterConfig(Version.LUCENE_40, new MockAnalyzer(new Random()));
+
+	private static final String VAL = "Val";
+
+	private Document doc(final Integer id) {
+		final Document doc = new Document();
+
+		doc.add(new IntField(VAL, id, Store.YES));
+
+		return doc;
+	}
+
+	@Override
+	@Before
+	public void setUp() throws Exception {
+		super.setUp();
+		Directory dir = new RAMDirectory();
+		final IndexWriter indexWriter = new IndexWriter(dir, INDEX_WRITER_CONFIG);
+
+		indexWriter.addDocument(doc(0));
+		indexWriter.addDocument(doc(1));
+		indexWriter.addDocument(doc(2));
+		indexWriter.close();
+
+		final DirectoryReader dirReader = DirectoryReader.open(dir);
+		atomicReader = new SlowCompositeReaderWrapper(dirReader);
+		unsortedTerms = atomicReader.terms(VAL);
+		sortingTerms = new SortingTerms(unsortedTerms, oldToNew);
+
+	}
+
+	@Test
+	public void testSize() {
+		try {
+			assertEquals(unsortedTerms.size(), sortingTerms.size());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testGetSumTotalTermFreq() {
+		try {
+			assertEquals(unsortedTerms.getSumTotalTermFreq(), sortingTerms.getSumTotalTermFreq());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+
+	@Test
+	public void testGetSumDocFreq() {
+		try {
+			assertEquals(unsortedTerms.getSumDocFreq(), sortingTerms.getSumDocFreq());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testGetDocCount() {
+		try {
+			assertEquals(unsortedTerms.getDocCount(), sortingTerms.getDocCount());
+		} catch (IOException e) {
+			fail("Exception");
+		}
+	}
+
+	@Test
+	public void testHasOffsets() {
+		assertEquals(unsortedTerms.hasOffsets(), sortingTerms.hasOffsets());
+	}
+
+	@Test
+	public void testHasPositions() {
+		assertEquals(unsortedTerms.hasPositions(), sortingTerms.hasPositions());
+	}
+
+	@Test
+	public void testHasPayloads() {
+		assertEquals(unsortedTerms.hasPayloads(), sortingTerms.hasPayloads());
+	}
+
+	@Test
+	public void testGetComparator() {
+		try {
+			assertEquals(unsortedTerms.getComparator(), sortingTerms.getComparator());
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			fail("Excception");
+		}
+	}
+
+	@Test
+	public void testIteratorTermsEnum() {
+		try {
+			TestUtils.compareTerms(unsortedTerms, sortingTerms);
+		} catch (IOException e) {
+			fail("Exception");
+		}
+
+	}
+}
Index: lucene/misc/src/test/org/apache/lucene/index/sorter/TestUtils.java
===================================================================
--- lucene/misc/src/test/org/apache/lucene/index/sorter/TestUtils.java	(revision 0)
+++ lucene/misc/src/test/org/apache/lucene/index/sorter/TestUtils.java	(working copy)
@@ -0,0 +1,36 @@
+package org.apache.lucene.index.sorter;
+
+/*
+ * 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.io.IOException;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
+import static org.junit.Assert.*;
+
+public class TestUtils {
+
+  public static void compareTerms(Terms unsortedTerms, Terms sortingTerms) throws IOException {
+    assertEquals(unsortedTerms.size(), sortingTerms.size());
+    TermsEnum oldTermsIt = unsortedTerms.iterator(null);
+    TermsEnum sortingTermsIt = sortingTerms.iterator(null);
+    for (int i = 0; i < unsortedTerms.size(); i++) {
+      assertEquals(sortingTermsIt.next(), oldTermsIt.next());
+    }
+    assertNull(sortingTermsIt.next());
+    assertNull(oldTermsIt.next());
+  }
+}
Index: lucene/module-build.xml
===================================================================
--- lucene/module-build.xml	(revision 1436328)
+++ lucene/module-build.xml	(working copy)
@@ -1,556 +0,0 @@
-<?xml version="1.0"?>
-
-<!--
-    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.
- -->
-
-<project name="module-build" xmlns:artifact="antlib:org.apache.maven.artifact.ant">
-  <echo>Building ${ant.project.name}...</echo>
-
-  <!-- TODO: adjust build.dir/dist.dir appropriately when a module is run individually -->
-  <dirname file="${ant.file.module-build}" property="module-build.dir"/>
-  <property name="build.dir" location="${module-build.dir}/build/${ant.project.name}"/>
-  <property name="dist.dir" location="${module-build.dir}/dist/${ant.project.name}"/>
-  <property name="maven.dist.dir" location="${module-build.dir}/dist/maven"/>
-
-  <import file="common-build.xml"/>
-
-  <!-- if you extend the classpath refid in one contrib's build.xml (add JARs), use this as basis: -->
-  <path id="base.classpath">
-   <pathelement location="${common.dir}/build/core/classes/java"/>
-   <pathelement path="${project.classpath}"/>
-  </path>
-  
-  <!-- default classpath refid, can be overridden by contrib's build.xml (use the above base.classpath as basis): -->
-  <path id="classpath" refid="base.classpath"/>
-  
-  <path id="test.base.classpath">
-    <pathelement location="${common.dir}/build/test-framework/classes/java"/>
-    <pathelement location="${common.dir}/build/codecs/classes/java"/>
-    <path refid="classpath"/>
-    <path refid="junit-path"/>
-    <pathelement location="${build.dir}/classes/java"/>
-  </path>
-
-  <path id="test.classpath" refid="test.base.classpath"/>
-
-  <path id="junit.classpath">
-    <pathelement location="${build.dir}/classes/test"/>
-    <path refid="test.classpath"/>
-    <pathelement path="${java.class.path}"/>
-  </path>
-
-  <target name="init" depends="common.init,compile-lucene-core"/>
-  <target name="compile-test" depends="init" if="module.has.tests">
-    <antcall target="common.compile-test" inheritRefs="true" />
-  </target>
-  <target name="test" depends="init" if="module.has.tests">
-    <antcall target="common.test" inheritRefs="true" />
-  </target>
-  <target name="build-artifacts-and-tests" depends="jar, compile-test" />
-	
-  <!-- TODO: why does this previous depend on compile-core? -->
-  <target name="javadocs" depends="compile-core,javadocs-lucene-core">
-    <invoke-module-javadoc/>
-  </target>	
-
-  <macrodef name="invoke-module-javadoc">
-    <!-- additional links for dependencies to other modules -->
-      <element name="links" optional="yes"/>
-    <!-- link source (don't do this unless its example code) -->
-      <attribute name="linksource" default="no"/>
-    <sequential>
-      <mkdir dir="${javadoc.dir}/${name}"/>
-      <invoke-javadoc
-         destdir="${javadoc.dir}/${name}"
-       	 title="${Name} ${version} ${name} API"
-         linksource="@{linksource}">
-         <sources>
-           <link href="../core/"/>
-           <links/>
-           <link href=""/>
-           <packageset dir="${src.dir}"/>
-        </sources>
-      </invoke-javadoc>
-      <jarify basedir="${javadoc.dir}/${name}" destfile="${build.dir}/${final.name}-javadoc.jar"/>
-    </sequential>
-  </macrodef>
-
-  <property name="test-framework.jar" value="${common.dir}/build/test-framework/lucene-test-framework-${version}.jar"/>
-  <target name="check-test-framework-uptodate" unless="test-framework.uptodate">
-    <module-uptodate name="test-framework" jarfile="${test-framework.jar}" property="test-framework.uptodate"/>
-  </target>
-  <target name="jar-test-framework" unless="test-framework.uptodate" depends="check-test-framework-uptodate">
-    <ant dir="${common.dir}/test-framework" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="test-framework.uptodate" value="true"/>
-  </target>
-
-  <property name="test-framework-javadoc.jar" value="${common.dir}/build/test-framework/lucene-test-framework-${version}-javadoc.jar"/>
-  <target name="check-test-framework-javadocs-uptodate" unless="test-framework-javadocs.uptodate">
-    <module-uptodate name="test-framework" jarfile="${test-framework-javadoc.jar}" property="test-framework-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-test-framework" unless="test-framework-javadocs.uptodate" depends="check-test-framework-javadocs-uptodate">
-    <ant dir="${common.dir}/test-framework" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="test-framework-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="queryparser.jar" value="${common.dir}/build/queryparser/lucene-queryparser-${version}.jar"/>
-  <target name="check-queryparser-uptodate" unless="queryparser.uptodate">
-    <module-uptodate name="queryparser" jarfile="${queryparser.jar}" property="queryparser.uptodate"/>
-  </target>
-  <target name="jar-queryparser" unless="queryparser.uptodate" depends="check-queryparser-uptodate">
-    <ant dir="${common.dir}/queryparser" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="queryparser.uptodate" value="true"/>
-  </target>
-
-  <property name="queryparser-javadoc.jar" value="${common.dir}/build/queryparser/lucene-queryparser-${version}-javadoc.jar"/>
-  <target name="check-queryparser-javadocs-uptodate" unless="queryparser-javadocs.uptodate">
-    <module-uptodate name="queryparser" jarfile="${queryparser-javadoc.jar}" property="queryparser-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-queryparser" unless="queryparser-javadocs.uptodate" depends="check-queryparser-javadocs-uptodate">
-    <ant dir="${common.dir}/queryparser" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="queryparser-javadocs.uptodate" value="true"/>
-  </target>
-  
-  <property name="analyzers-common.jar" value="${common.dir}/build/analysis/common/lucene-analyzers-common-${version}.jar"/>
-  <target name="check-analyzers-common-uptodate" unless="analyzers-common.uptodate">
-    <module-uptodate name="analysis/common" jarfile="${analyzers-common.jar}" property="analyzers-common.uptodate"/>
-  </target>
-  <target name="jar-analyzers-common" unless="analyzers-common.uptodate" depends="check-analyzers-common-uptodate">
-    <ant dir="${common.dir}/analysis/common" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-common.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-common-javadoc.jar" value="${common.dir}/build/analysis/common/lucene-analyzers-common-${version}-javadoc.jar"/>
-  <target name="check-analyzers-common-javadocs-uptodate" unless="analyzers-common-javadocs.uptodate">
-    <module-uptodate name="analysis/common" jarfile="${analyzers-common-javadoc.jar}" property="analyzers-common-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-common" unless="analyzers-common-javadocs.uptodate" depends="check-analyzers-common-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/common" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-common-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="queries.jar" value="${common.dir}/build/queries/lucene-queries-${version}.jar"/>
-  <target name="check-queries-uptodate" unless="queries.uptodate">
-    <module-uptodate name="queries" jarfile="${queries.jar}" property="queries.uptodate"/>
-  </target>
-  <target name="jar-queries" unless="queries.uptodate" depends="check-queries-uptodate">
-  	<ant dir="${common.dir}/queries" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="queries.uptodate" value="true"/>
-  </target>
-
-  <property name="queries-javadoc.jar" value="${common.dir}/build/queries/lucene-queries-${version}-javadoc.jar"/>
-  <target name="check-queries-javadocs-uptodate" unless="queries-javadocs.uptodate">
-    <module-uptodate name="queries" jarfile="${queries-javadoc.jar}" property="queries-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-queries" unless="queries-javadocs.uptodate" depends="check-queries-javadocs-uptodate">
-    <ant dir="${common.dir}/queries" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="queries-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="classification.jar" value="${common.dir}/build/classification/lucene-classification-${version}.jar"/>
-  <target name="check-classification-uptodate" unless="classification.uptodate">
-    <module-uptodate name="classification" jarfile="${classification.jar}" property="classification.uptodate"/>
-  </target>
-  <target name="jar-classification" unless="classification.uptodate" depends="check-classification-uptodate">
-    <ant dir="${common.dir}/classification" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="classification.uptodate" value="true"/>
-  </target>
-
-  <property name="classification-javadoc.jar" value="${common.dir}/build/classification/lucene-classification-${version}-javadoc.jar"/>
-  <target name="check-classification-javadocs-uptodate" unless="classification-javadocs.uptodate">
-    <module-uptodate name="classification" jarfile="${classification-javadoc.jar}" property="classification-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-classification" unless="classification-javadocs.uptodate" depends="check-classification-javadocs-uptodate">
-    <ant dir="${common.dir}/classification" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="classification-javadocs.uptodate" value="true"/>
-  </target>
-  
-  <property name="facet.jar" value="${common.dir}/build/facet/lucene-facet-${version}.jar"/>
-  <target name="check-facet-uptodate" unless="facet.uptodate">
-    <module-uptodate name="facet" jarfile="${facet.jar}" property="facet.uptodate"/>
-  </target>
-  <target name="jar-facet" unless="facet.uptodate" depends="check-facet-uptodate">
-    <ant dir="${common.dir}/facet" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="facet.uptodate" value="true"/>
-  </target>
-
-  <property name="facet-javadoc.jar" value="${common.dir}/build/facet/lucene-facet-${version}-javadoc.jar"/>
-  <target name="check-facet-javadocs-uptodate" unless="facet-javadocs.uptodate">
-    <module-uptodate name="facet" jarfile="${facet-javadoc.jar}" property="facet-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-facet" unless="facet-javadocs.uptodate" depends="check-facet-javadocs-uptodate">
-    <ant dir="${common.dir}/facet" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="facet-javadocs.uptodate" value="true"/>
-  </target>
- 
-  <property name="analyzers-icu.jar" value="${common.dir}/build/analysis/icu/lucene-analyzers-icu-${version}.jar"/>
-  <target name="check-analyzers-icu-uptodate" unless="analyzers-icu.uptodate">
-    <module-uptodate name="analysis/icu" jarfile="${analyzers-icu.jar}" property="analyzers-icu.uptodate"/>
-  </target>
-  <target name="jar-analyzers-icu" unless="analyzers-icu.uptodate" depends="check-analyzers-icu-uptodate">
-  	<ant dir="${common.dir}/analysis/icu" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-icu.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-icu-javadoc.jar" value="${common.dir}/build/analysis/icu/lucene-analyzers-icu-${version}-javadoc.jar"/>
-  <target name="check-analyzers-icu-javadocs-uptodate" unless="analyzers-icu-javadocs.uptodate">
-    <module-uptodate name="analysis/icu" jarfile="${analyzers-icu-javadoc.jar}" property="analyzers-icu-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-icu" unless="analyzers-icu-javadocs.uptodate" depends="check-analyzers-icu-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/icu" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-icu-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-phonetic.jar" value="${common.dir}/build/analysis/phonetic/lucene-analyzers-phonetic-${version}.jar"/>
-  <target name="check-analyzers-phonetic-uptodate" unless="analyzers-phonetic.uptodate">
-    <module-uptodate name="analysis/phonetic" jarfile="${analyzers-phonetic.jar}" property="analyzers-phonetic.uptodate"/>
-  </target>
-  <target name="jar-analyzers-phonetic" unless="analyzers-phonetic.uptodate" depends="check-analyzers-phonetic-uptodate">
-  	<ant dir="${common.dir}/analysis/phonetic" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-  </target>
-
-  <property name="analyzers-phonetic-javadoc.jar" value="${common.dir}/build/analysis/phonetic/lucene-analyzers-phonetic-${version}-javadoc.jar"/>
-  <target name="check-analyzers-phonetic-javadocs-uptodate" unless="analyzers-phonetic-javadocs.uptodate">
-    <module-uptodate name="analysis/phonetic" jarfile="${analyzers-phonetic-javadoc.jar}" property="analyzers-phonetic-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-phonetic" unless="analyzers-phonetic-javadocs.uptodate" depends="check-analyzers-phonetic-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/phonetic" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-phonetic-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-smartcn.jar" value="${common.dir}/build/analysis/smartcn/lucene-analyzers-smartcn-${version}.jar"/>
-  <target name="check-analyzers-smartcn-uptodate" unless="analyzers-smartcn.uptodate">
-    <module-uptodate name="analysis/smartcn" jarfile="${analyzers-smartcn.jar}" property="analyzers-smartcn.uptodate"/>
-  </target>
-  <target name="jar-analyzers-smartcn" unless="analyzers-smartcn.uptodate" depends="check-analyzers-smartcn-uptodate">
-  	<ant dir="${common.dir}/analysis/smartcn" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-smartcn.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-smartcn-javadoc.jar" value="${common.dir}/build/analysis/smartcn/lucene-analyzers-smartcn-${version}-javadoc.jar"/>
-  <target name="check-analyzers-smartcn-javadocs-uptodate" unless="analyzers-smartcn-javadocs.uptodate">
-    <module-uptodate name="analysis/smartcn" jarfile="${analyzers-smartcn-javadoc.jar}" property="analyzers-smartcn-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-smartcn" unless="analyzers-smartcn-javadocs.uptodate" depends="check-analyzers-smartcn-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/smartcn" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-smartcn-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-stempel.jar" value="${common.dir}/build/analysis/stempel/lucene-analyzers-stempel-${version}.jar"/>
-  <target name="check-analyzers-stempel-uptodate" unless="analyzers-stempel.uptodate">
-    <module-uptodate name="analysis/stempel" jarfile="${analyzers-stempel.jar}" property="analyzers-stempel.uptodate"/>
-  </target>
-  <target name="jar-analyzers-stempel" unless="analyzers-stempel.uptodate" depends="check-analyzers-stempel-uptodate">
-  	<ant dir="${common.dir}/analysis/stempel" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-stempel.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-stempel-javadoc.jar" value="${common.dir}/build/analysis/stempel/lucene-analyzers-stempel-${version}-javadoc.jar"/>
-  <target name="check-analyzers-stempel-javadocs-uptodate" unless="analyzers-stempel-javadocs.uptodate">
-    <module-uptodate name="analysis/stempel" jarfile="${analyzers-stempel-javadoc.jar}" property="analyzers-stempel-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-stempel" unless="analyzers-stempel-javadocs.uptodate" depends="check-analyzers-stempel-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/stempel" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-stempel-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-kuromoji.jar" value="${common.dir}/build/analysis/kuromoji/lucene-analyzers-kuromoji-${version}.jar"/>
-  <target name="check-analyzers-kuromoji-uptodate" unless="analyzers-kuromoji.uptodate">
-    <module-uptodate name="analysis/kuromoji" jarfile="${analyzers-kuromoji.jar}" property="analyzers-kuromoji.uptodate"/>
-  </target>
-  <target name="jar-analyzers-kuromoji" unless="analyzers-kuromoji.uptodate" depends="check-analyzers-kuromoji-uptodate">
-  	<ant dir="${common.dir}/analysis/kuromoji" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-kuromoji.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-kuromoji-javadoc.jar" value="${common.dir}/build/analysis/kuromoji/lucene-analyzers-kuromoji-${version}-javadoc.jar"/>
-  <target name="check-analyzers-kuromoji-javadocs-uptodate" unless="analyzers-kuromoji-javadocs.uptodate">
-    <module-uptodate name="analysis/kuromoji" jarfile="${analyzers-kuromoji-javadoc.jar}" property="analyzers-kuromoji-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-kuromoji" unless="analyzers-kuromoji-javadocs.uptodate" depends="check-analyzers-kuromoji-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/kuromoji" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-kuromoji-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-uima.jar" value="${common.dir}/build/analysis/uima/lucene-analyzers-uima-${version}.jar"/>
-  <target name="check-analyzers-uima-uptodate" unless="analyzers-uima.uptodate">
-    <module-uptodate name="analysis/uima" jarfile="${analyzers-uima.jar}" property="analyzers-uima.uptodate"/>
-  </target>
-  <target name="jar-analyzers-uima" unless="analyzers-uima.uptodate" depends="check-analyzers-uima-uptodate">
-    <ant dir="${common.dir}/analysis/uima" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-uima.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-uima-javadoc.jar" value="${common.dir}/build/analysis/uima/lucene-analyzers-uima-${version}-javadoc.jar"/>
-  <target name="check-analyzers-uima-javadocs-uptodate" unless="analyzers-uima-javadocs.uptodate">
-    <module-uptodate name="analysis/uima" jarfile="${analyzers-uima-javadoc.jar}" property="analyzers-uima-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-uima" unless="analyzers-uima-javadocs.uptodate" depends="check-analyzers-uima-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/uima" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-uima-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-morfologik.jar" value="${common.dir}/build/analysis/morfologik/lucene-analyzers-morfologik-${version}.jar"/>
-  <fileset id="analyzers-morfologik.fileset" dir="${common.dir}">
-    <include name="build/analysis/morfologik/lucene-analyzers-morfologik-${version}.jar" />
-    <include name="analysis/morfologik/lib/morfologik-*.jar" />
-  </fileset>
-  <target name="check-analyzers-morfologik-uptodate" unless="analyzers-morfologik.uptodate">
-    <module-uptodate name="analysis/morfologik" jarfile="${analyzers-morfologik.jar}" property="analyzers-morfologik.uptodate"/>
-  </target>
-  <target name="jar-analyzers-morfologik" unless="analyzers-morfologik.uptodate" depends="check-analyzers-morfologik-uptodate">
-    <ant dir="${common.dir}/analysis/morfologik" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-morfologik.uptodate" value="true"/>
-  </target>
-
-  <property name="analyzers-morfologik-javadoc.jar" value="${common.dir}/build/analysis/morfologik/lucene-analyzers-morfologik-${version}-javadoc.jar"/>
-  <target name="check-analyzers-morfologik-javadocs-uptodate" unless="analyzers-morfologik-javadocs.uptodate">
-    <module-uptodate name="analysis/morfologik" jarfile="${analyzers-morfologik-javadoc.jar}" property="analyzers-morfologik-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-analyzers-morfologik" unless="analyzers-morfologik-javadocs.uptodate" depends="check-analyzers-morfologik-javadocs-uptodate">
-    <ant dir="${common.dir}/analysis/morfologik" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="analyzers-morfologik-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="codecs.jar" value="${common.dir}/build/codecs/lucene-codecs-${version}.jar"/>
-  <target name="check-codecs-uptodate" unless="codecs.uptodate">
-    <module-uptodate name="codecs" jarfile="${codecs.jar}" property="codecs.uptodate"/>
-  </target>
-  <target name="jar-codecs" unless="codecs.uptodate" depends="check-codecs-uptodate">
-    <ant dir="${common.dir}/codecs" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="codecs.uptodate" value="true"/>
-  </target>
-
-  <property name="codecs-javadoc.jar" value="${common.dir}/build/codecs/lucene-codecs-${version}-javadoc.jar"/>
-  <target name="check-codecs-javadocs-uptodate" unless="codecs-javadocs.uptodate">
-    <module-uptodate name="codecs" jarfile="${codecs-javadoc.jar}" property="codecs-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-codecs" unless="codecs-javadocs.uptodate" depends="check-codecs-javadocs-uptodate">
-    <ant dir="${common.dir}/codecs" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="codecs-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="grouping.jar" value="${common.dir}/build/grouping/lucene-grouping-${version}.jar"/>
-  <target name="check-grouping-uptodate" unless="grouping.uptodate">
-    <module-uptodate name="grouping" jarfile="${grouping.jar}" property="grouping.uptodate"/>
-  </target>
-  <target name="jar-grouping" unless="grouping.uptodate" depends="check-grouping-uptodate">
-  	<ant dir="${common.dir}/grouping" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="grouping.uptodate" value="true"/>
-  </target>
-
-  <property name="grouping-javadoc.jar" value="${common.dir}/build/grouping/lucene-grouping-${version}-javadoc.jar"/>
-  <target name="check-grouping-javadocs-uptodate" unless="grouping-javadocs.uptodate">
-    <module-uptodate name="grouping" jarfile="${grouping-javadoc.jar}" property="grouping-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-grouping" unless="grouping-javadocs.uptodate" depends="check-grouping-javadocs-uptodate">
-    <ant dir="${common.dir}/grouping" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="grouping-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="highlighter.jar" value="${common.dir}/build/highlighter/lucene-highlighter-${version}.jar"/>
-  <target name="check-highlighter-uptodate" unless="highlighter.uptodate">
-    <module-uptodate name="highlighter" jarfile="${highlighter.jar}" property="highlighter.uptodate"/>
-  </target>
-  <target name="jar-highlighter" unless="highlighter.uptodate" depends="check-highlighter-uptodate">
-    <ant dir="${common.dir}/highlighter" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="highlighter.uptodate" value="true"/>
-  </target>
-
-  <property name="highlighter-javadoc.jar" value="${common.dir}/build/highlighter/lucene-highlighter-${version}-javadoc.jar"/>
-  <target name="check-highlighter-javadocs-uptodate" unless="highlighter-javadocs.uptodate">
-    <module-uptodate name="highlighter" jarfile="${highlighter-javadoc.jar}" property="highlighter-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-highlighter" unless="highlighter-javadocs.uptodate" depends="check-highlighter-javadocs-uptodate">
-    <ant dir="${common.dir}/highlighter" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="highlighter-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="memory.jar" value="${common.dir}/build/memory/lucene-memory-${version}.jar"/>
-  <target name="check-memory-uptodate" unless="memory.uptodate">
-    <module-uptodate name="memory" jarfile="${memory.jar}" property="memory.uptodate"/>
-  </target>
-  <target name="jar-memory" unless="memory.uptodate" depends="check-memory-uptodate">
-    <ant dir="${common.dir}/memory" target="jar-core" inheritall="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="memory.uptodate" value="true"/>
-  </target>
-
-  <property name="memory-javadoc.jar" value="${common.dir}/build/memory/lucene-memory-${version}-javadoc.jar"/>
-  <target name="check-memory-javadocs-uptodate" unless="memory-javadocs.uptodate">
-    <module-uptodate name="memory" jarfile="${memory-javadoc.jar}" property="memory-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-memory" unless="memory-javadocs.uptodate" depends="check-memory-javadocs-uptodate">
-    <ant dir="${common.dir}/memory" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="memory-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="misc.jar" value="${common.dir}/build/misc/lucene-misc-${version}.jar"/>
-  <target name="check-misc-uptodate" unless="misc.uptodate">
-    <module-uptodate name="misc" jarfile="${misc.jar}" property="misc.uptodate"/>
-  </target>
-  <target name="jar-misc" unless="misc.uptodate" depends="check-misc-uptodate">
-  	<ant dir="${common.dir}/misc" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="misc.uptodate" value="true"/>
-  </target>
-
-  <property name="misc-javadoc.jar" value="${common.dir}/build/misc/lucene-misc-${version}-javadoc.jar"/>
-  <target name="check-misc-javadocs-uptodate" unless="misc-javadocs.uptodate">
-    <module-uptodate name="misc" jarfile="${misc-javadoc.jar}" property="misc-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-misc" unless="misc-javadocs.uptodate" depends="check-misc-javadocs-uptodate">
-    <ant dir="${common.dir}/misc" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="misc-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="sandbox.jar" value="${common.dir}/build/sandbox/lucene-sandbox-${version}.jar"/>
-  <target name="check-sandbox-uptodate" unless="sandbox.uptodate">
-    <module-uptodate name="sandbox" jarfile="${sandbox.jar}" property="sandbox.uptodate"/>
-  </target>
-  <target name="jar-sandbox" unless="sandbox.uptodate" depends="check-sandbox-uptodate">
-  	<ant dir="${common.dir}/sandbox" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="sandbox.uptodate" value="true"/>
-  </target>
-
-  <property name="sandbox-javadoc.jar" value="${common.dir}/build/sandbox/lucene-sandbox-${version}-javadoc.jar"/>
-  <target name="check-sandbox-javadocs-uptodate" unless="sandbox-javadocs.uptodate">
-    <module-uptodate name="sandbox" jarfile="${sandbox-javadoc.jar}" property="sandbox-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-sandbox" unless="sandbox-javadocs.uptodate" depends="check-sandbox-javadocs-uptodate">
-    <ant dir="${common.dir}/sandbox" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="sandbox-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="spatial.jar" value="${common.dir}/build/spatial/lucene-spatial-${version}.jar"/>
-  <target name="check-spatial-uptodate" unless="spatial.uptodate">
-    <module-uptodate name="spatial" jarfile="${spatial.jar}" property="spatial.uptodate"/>
-  </target>
-  <target name="jar-spatial" unless="spatial.uptodate" depends="check-spatial-uptodate">
-  	<ant dir="${common.dir}/spatial" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="spatial.uptodate" value="true"/>
-  </target>
-
-  <property name="spatial-javadoc.jar" value="${common.dir}/build/spatial/lucene-spatial-${version}-javadoc.jar"/>
-  <target name="check-spatial-javadocs-uptodate" unless="spatial-javadocs.uptodate">
-    <module-uptodate name="spatial" jarfile="${spatial-javadoc.jar}" property="spatial-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-spatial" unless="spatial-javadocs.uptodate" depends="check-spatial-javadocs-uptodate">
-    <ant dir="${common.dir}/spatial" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="spatial-javadocs.uptodate" value="true"/>
-  </target>
-
-  <property name="suggest.jar" value="${common.dir}/build/suggest/lucene-suggest-${version}.jar"/>
-  <target name="check-suggest-uptodate" unless="suggest.uptodate">
-    <module-uptodate name="suggest" jarfile="${suggest.jar}" property="suggest.uptodate"/>
-  </target>
-  <target name="jar-suggest" unless="suggest.uptodate" depends="check-suggest-uptodate">
-  	<ant dir="${common.dir}/suggest" target="jar-core" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="suggest.uptodate" value="true"/>
-  </target>
-
-  <property name="suggest-javadoc.jar" value="${common.dir}/build/suggest/lucene-suggest-${version}-javadoc.jar"/>
-  <target name="check-suggest-javadocs-uptodate" unless="suggest-javadocs.uptodate">
-    <module-uptodate name="suggest" jarfile="${suggest-javadoc.jar}" property="suggest-javadocs.uptodate"/>
-  </target>
-  <target name="javadocs-suggest" unless="suggest-javadocs.uptodate" depends="check-suggest-javadocs-uptodate">
-    <ant dir="${common.dir}/suggest" target="javadocs" inheritAll="false">
-      <propertyset refid="uptodate.and.compiled.properties"/>
-    </ant>
-    <property name="suggest-javadocs.uptodate" value="true"/>
-  </target>
-</project>
